---
title: "I wanted to be able to do more with AI on my site, so I gave Claude WP REST API access – with limitations"
date: 2026-07-08
modified: 2026-07-08
author: "Miriam Schwab"
url: "https://miriamschwab.me/claude-wp-rest-api-access-with-limitations/"
markdown_url: "https://miriamschwab.me/claude-wp-rest-api-access-with-limitations.md"
type: post
excerpt: "A conversation about why WordPress core still ships so few AI abilities and the limitations they have got me thinking: why am I making my site fully dependent on Abilities when WordPress has a very robust REST API that I could hook into? It got me looking at my custom Abilities plugin differently. Every ability in it was coded one-by-one: get these posts, update this meta, list these plugins. That covers the things I do often and worked great, but it also meant anything WordPress’s REST API could already do that I hadn’t specifically written a wrapper for didn’t exist for..."
categories:
  - "Artificial Intelligence"
  - "WordPress"
tags:
  - "ai"
  - "plugin"
  - "security"
  - "wordpress"
---
A conversation about why WordPress core still ships so few AI abilities and the limitations they have got me thinking: why am I making my site fully dependent on Abilities when WordPress has a very robust REST API that I could hook into?

It got me looking at my custom Abilities plugin differently. Every ability in it was coded one-by-one: get these posts, update this meta, list these plugins. That covers the things I do often and worked great, but it also meant anything WordPress’s REST API could already do that I hadn’t specifically written a wrapper for didn’t exist for Claude at all, like comments, or another plugin’s own data exposed by an API endpoint, even half the fields on a post.

## Abilities are the wrapper, not the doorway

My plugin is built on the WordPress Abilities API. An ability is a small, named, permission-checked function: this is what it does, this is what it needs to run, here’s its input and output. What actually delivers that function to an AI agent is a separate layer, the transport, which can be REST, WP-CLI, MCP (in my case), GraphQL, etc.

Core’s REST API is already a stable interface WordPress promises not to break. An AI agent doesn’t need a special layer for basic reads and writes, it can just call REST directly, the same way any other client does. The actual reason to build your own ability is narrower than I’d thought: you want something MCP-specific, or logic REST doesn’t have. Otherwise you’re basically rebuilding REST behind a second door for no good reason.

## What supporting the REST API opened up

Giving Claude Read access to REST was a no-brainer, so it can now call any registered REST route on this site with GET.

I needed to be more careful about Write, so we implemented a workflow whereby Claude must always describe what it plans to do, and can only go ahead when I approve it directly. This means that we don’t have to code a fresh ability every time I want Claude to touch something new, and now there’s one write ability that can call any route with a write method, and can only act after Claude spells out the exact request in plain language and I approve it.

We listed specific routes that are blocked no matter what, even if I inadvertently approve them: user accounts (creation, roles, deletion, and password resets all live behind the same endpoint, so we blocked the whole thing, deleting plugins, changing site settings, and permanent delete that skips the trash.

I’m looking forward to seeing when and how these expanded capabilities prove to be useful in my work on this site, and am curious whether any unforeseen issues will arise.
