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.

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).

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.