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.

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 MCP request that reaches WordPress, so a sign-in row with nothing after it is strong evidence the request never arrived, and the plugin is not the thing to debug. Something in front of WordPress stopped it, usually a CDN or firewall.

The case we have seen confirmed is Cloudflare’s Block AI Bots setting, along with Super Bot Fight Mode. 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, either turn Block AI Bots off under Security, Bots, or add a rule that skips bot protection for the /mcp path so the rest of your site stays covered. Other CDNs and security plugins have the same kind of exception.

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.

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.