Skip to content

Governance concepts

Other MCP-for-WordPress plugins sell how many tools they expose. This one sells control. You add reach as you build trust, not all at once, and every call to this plugin’s tools is checked and logged before it runs. Six ideas hold that together.

The agent connects as a real WordPress user through OAuth or an Application Password, never an admin-equivalent key, and it can only do what that user can do. Over OAuth the connection takes the capabilities of whichever account approves it in the browser, so approve while logged in as the account you want the agent to be. Approving as an administrator gives the agent administrator reach, and the consent screen warns you when that is what you are about to do. With an Application Password you pick the account up front, so generate it on a dedicated low-privilege user.

Nothing this plugin serves is exposed until you enable it, and an update never switches on a tool it serves. On a fresh install every ability is off.

A connection only sees the plugin’s own tools that its user can call, and every call re-checks that capability before it runs. Discovery and execution are gated separately, so an agent cannot call a tool it was somehow shown. Since 1.7.8, bridged tools from other plugins whose own check needs an item id list for anyone who can edit posts, and the source plugin still decides each call. Sites can raise that floor with the aafm_bridge_discovery_capability filter.

Every call to this plugin’s tools is recorded, denied attempts included, with the principal and the argument keys and the identifiers it touched, never free-text content. For a failed call to another plugin’s bridged ability it also keeps that plugin’s error code, never its message. It lives in your own database and can be cleared from the admin.

Since 1.5.0 the log is an audit trail of governance as well as of calls. Every ability you switch on or off and every setting you change lands there too. Each row carries an event type, plus a detail column that names what changed and links to the object’s edit screen. So the log now answers a second question: who gave the agent this reach, and when. Before that release, enabling an ability was written with no audit trail at all.

Since 1.9.0 the admin log also shows each call’s connection and source IP address, records how long the tool ran, and notes why a denied call was refused, for example that a meta key is not on the allowlist. That reason stays in the log. The agent gets the same refusal message as before. You can search and filter the log by user, connection, tool, plugin, date and text, follow it live, and export the filtered rows. If you want to be told rather than look, alerts are optional and off by default.

There is no arbitrary option or meta access and no code execution. Uploads are checked by their real bytes against an image allow-list, whether the image arrives as inline data or, since 1.7.4, is fetched from an HTTPS URL by the upload media from URL ability. That ability is off until you enable it, refuses private, loopback, and link-local addresses, follows no redirects, and caps the size. It is the only outbound fetch the plugin will make on a call’s behalf. A created user gets the site default role, never admin, and the last administrator can never be removed. Anything destructive is off by default and capability-gated, and deletes go to Trash where the ability supports it.

Elementor, Divi, Beaver Builder, and Avada keep their layout outside the normal post content. Before 1.7.4 a write aimed at one of those pages would report success and change nothing you could see on the front end, which is the worst kind of failure: the log said done, the page said otherwise.

Since 1.7.4 the plugin checks who owns a page before it writes, and refuses the call with an error naming the builder responsible. It covers update post, update page, update content item, replace in post, and restore revision, and a site-wide replace skips those posts and counts them separately rather than pretending it changed them.

This is a guard, not an integration. The plugin gains no ability to read or edit Elementor, Divi, or Beaver Builder layouts, and it does not claim to. Avada is the one exception, and only because it has two abilities of its own that read Fusion Builder markup and replace text without disturbing the shortcode tree. OptimizePress is not covered yet.

The plugin contacts no AI provider and sends no telemetry. Your AI client connects in, and no site content leaves on the plugin’s own initiative. It sends three things by itself. The Connection tab’s checks are requests your site makes to its own address. The media upload from a URL, added in 1.7.4, fetches the single address passed to that one call, only when you have switched that ability on, and never sends your content or credentials. Alert emails, added in 1.9.0, go out through WordPress’s own mail only if you turn alerts on, and never include call content, a user name or an IP address.

WordPress 6.9 ships the Abilities API, and the official MCP Adapter comes bundled with this plugin, so there is nothing else to install. Agent Abilities for MCP registers a curated, governed set of abilities on top of them rather than inventing its own protocol or transport, so there is no bespoke server to trust and the plugin inherits the standard’s behavior. What it adds is the governance layer described above.

Everything above covers the tools this plugin serves through its own endpoint. The bundled MCP Adapter also has a default server that other plugins can publish tools to. Tools on that server are not governed by this plugin: its read-only mode, allowlists, IP allowlist, rate limit and audit log do not apply to them, and this plugin’s own tools are never on it. A Settings switch (Automatic, Always on, Always off) controls that server, and Always off keeps it closed.

  • Safety controls: optional guards you can switch on.
  • FAQ: admin access, data handling, and how this differs from the REST API.