Skip to content

Troubleshooting

The symptoms people hit most, with the fix. More get added as they come up.

When OAuth is enabled, clients find your site by fetching two documents under /.well-known/: /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server. WordPress serves both, but the request has to actually reach WordPress. Some servers deny anything that starts with a dot before PHP runs, and that blocks discovery.

On nginx the usual cause is a dotfile deny rule (location ~ /\. { deny all; }). Add a more specific block ahead of it so /.well-known/ falls through to WordPress:

location ^~ /.well-known/ {
try_files $uri $uri/ /index.php?$args;
}

The ^~ prefix tells nginx to prefer this block over the dotfile deny. Other hidden files stay denied.

Apache usually works as-is, because the WordPress .htaccess sends anything that is not a real file to index.php, /.well-known/ included. If a host or security plugin is blocking dotfiles, look for that rule (often in the vhost or a hardening snippet, not WordPress itself) and let /.well-known/ through.

To check, request https://your-site/.well-known/oauth-protected-resource. A working setup returns a JSON document instead of a 403 or 404.

When an agent cannot connect and you do not know why, open the Connection tab and click Check my connection (the Connection Doctor, new in 1.8.0). It runs the checks from your own server and names the fix, for example a host that strips the Authorization header. The entries below cover the causes it does not reach, such as a CDN or firewall blocking the /mcp path or a local site with a self-signed certificate.

ChatGPT will not connect and reports a discovery failure

Section titled “ChatGPT will not connect and reports a discovery failure”

ChatGPT and Claude add themselves as a client the first time you connect them, using dynamic client registration. It has its own switch on the Settings tab. With that switch off neither one can register, and ChatGPT reports a discovery failure rather than naming the setting that caused it.

From 1.7.2 it is on by default, and sites that never changed the old default-off setting are switched on when they update. If you turned it off yourself, turn it back on before you add the connector.

Sign-in finishes, the client says it is connected, and no ability call ever lands.

Open the Activity Log. From 1.7.2 it records every tool call, every sign-in, and the requests that reach WordPress and fail, as (transport) rows, at most five of each kind per source address every ten minutes. A request that succeeds without calling a tool, such as listing tools, leaves no row. A sign-in with no tool calls after it usually points at something in front of WordPress, most often a CDN or firewall, rather than at the plugin.

The case we have seen confirmed is Cloudflare’s AI bot blocking, along with Super Bot Fight Mode. That was the Block AI Bots setting, which Cloudflare now replaces with Configure AI bot policies under Security Settings. You sign in through your own browser, so that part succeeds. The MCP request that follows comes from the AI client’s servers with an AI user agent, and gets blocked at the edge before WordPress ever sees it.

To confirm, open your CDN’s firewall or security event log and look for a blocked request to your MCP endpoint, whose path ends in /mcp, from the AI client’s IP range around the time you tried to connect. The entry names the rule that blocked it.

The fix is to let that endpoint through. On Cloudflare, open Security Settings and use Configure AI bot policies to allow the AI client’s traffic: set the policy that matches the block in your security events to Allow. Cloudflare has deprecated the older Block AI Bots switch from 15 September 2026, so if you still use it, turn it off. If you cannot allow that traffic across the whole zone, add a custom rule with the Skip action for the /mcp path that skips Super Bot Fight Mode rules, so the rest of your site stays covered. Cloudflare does not let a Skip rule skip Bot Fight Mode on the Free plan. Retry the connection after any change and check that the call lands in the Activity Log. Other CDNs and security plugins have the same kind of exception.

If your site uses WP Engine’s Global Edge Security, check it first. In the User Portal, open the environment’s Insights menu, go to Traffic and Security, then the Settings tab, and look at Edge traffic rules. Traffic and Security shows only for production environments that have an active Global Edge Security domain. A rule for a bot category blocks that traffic before it reaches WordPress, so remove the one that covers your AI client. WP Engine also rate-limits some AI bots across its platform, and you cannot turn that off yourself. If the agent’s calls fail with HTTP 429 errors on WP Engine, contact WP Engine support and ask them to review the limit for your site.

Windows MCP clients cannot launch the npx shim by name. Wrap it in cmd: set command to cmd and put /c, npx at the front of args. The Connection tab has a Windows tab that generates this for you.

Local stacks like DDEV, Local, and Valet serve a self-signed certificate that Node rejects, so the proxy never reaches WordPress. For local testing only, add NODE_TLS_REJECT_UNAUTHORIZED set to 0 to the env block (the Connection tab adds it automatically when it detects a local site).

The agent refuses to edit an Elementor or Divi page

Section titled “The agent refuses to edit an Elementor or Divi page”

Since 1.7.4 this is deliberate. Elementor, Divi, Beaver Builder, and Avada store their layout outside the normal post content, so a write aimed at one of those pages used to report success and leave the page exactly as it was. The plugin now checks first and refuses the call with an error naming the builder that owns the page.

The write did not fail silently and there is nothing to fix in the plugin. Edit that page in its own builder, or move the content into a normal WordPress editor page if you want an agent to maintain it. The abilities covered are update post, update page, update content item, replace in post, and restore revision; a site-wide replace skips builder-owned posts and reports the count separately.

OptimizePress is not detected yet, so a write to an OptimizePress page still goes through without this warning.

Claude says “Structured content does not match the tool’s output schema”

Section titled “Claude says “Structured content does not match the tool’s output schema””

This one showed up with WooCommerce orders and products through bridged tools. Claude rejected the whole result with an error saying the content does not match the tool’s output schema. The source plugin declared strict formats for some fields, and real values did not always fit them: an order date with no timezone, or a product URL left empty. A strict client checks every value against the declared format and throws the result away when one fails.

Update to 1.8.1 or later. Bridged tools no longer advertise those strict formats, and the values themselves are unchanged. Then use Refresh tools list in Claude so it drops the schema it cached before the update. Input schemas, the plugin’s own aafm/* tools and WordPress core’s validation were not touched by this fix.

For the full cause and fix, see the output schema error explained.

On a WPML site the agent lists or summarizes one language and behaves as though the translations are not there. Two related symptoms show up with it. The agent is told more items exist than it can actually read, because a list came back in one language while the count reported every language. And creating a menu item is reported as a failure even though the item was created.

The cause is that WPML filters content by language on every request. An agent arrives over MCP with no browser session, no cookie, and no language code in the URL, so it lands in whatever WPML treats as the default, and every read quietly inherits that filter. Nothing errors. The list just comes back short, and the agent has no way to tell that it did.

Update to 1.3.2 or newer. From that version the content reads (posts, pages, search, terms, media, products, and single-item reads) take an optional language argument and report back which language they returned, so the agent knows what it is looking at. A single-item read can fetch a specific translation. The count abilities share the list’s language scope, so the count and the list agree. The menu-item tools resolve the item by id, so an item that was created is found and reported as created.

To check, ask the agent for a list of posts in a language that is not your default. The result reports the language it returned, and it should match the one you asked for.

My agent now gets an error where it used to succeed

Section titled “My agent now gets an error where it used to succeed”

If an operation started returning an error right after updating to 1.7.5, the likely explanation is that it was failing silently before and you are only now being told.

A batch of paths in 1.7.5 moved from failing open to failing closed. WordPress hands back the same value for “there is nothing here” and “the read did not complete”, so code that took those values at face value could treat a failed database read as a real answer and report success on work that never happened. Post, block and template writes now confirm what actually landed, a failed token revoke no longer reports success, and a read that could not complete raises an error instead of returning a plausible-looking result.

An upgrade sweep confirmed none of the new failure branches fire under healthy conditions, so a persistent error here points at something real on the site rather than at the change itself. Check the Activity Log entry for the failed call, then look at database health and any persistent object cache. The longer version is in absent and unknown are not the same answer.