Skip to content
WP EngineDocumentation

Troubleshooting

Fixes for what you’re seeing, organized by symptom. Searching for a specific error code works too — each one is named in the section that resolves it.

Before working through anything here: read the help and next_steps on the error itself. The server generates them from live state and they name your actual site and the actual missing argument, so they are more specific than anything on this page. What follows covers the failures where that isn’t enough, or where the fix isn’t where you’d expect.

Tool failures arrive as a normal response carrying an error.code — not as an HTTP error — so a failing call still looks like a success at the transport layer. Your client should surface the code to you.

The connection is failing before tool discovery.

  1. Confirm the endpoint is exactly https://api.ai.wpengine.com/v1/mcp. The transport is Streamable HTTP, with requests sent as POST.
  2. Confirm the key starts with wpe_pat_, was copied in full, and is sent as Authorization: Bearer — see Authentication. A truncated key fails the same way a missing one does.
  3. On Claude Code, run claude mcp list to confirm the server was registered at all. A server added without --scope user only appears in the directory it was added from.
  4. Reproduce outside your client with MCP Inspector. If Inspector lists tools and your client doesn’t, the problem is client configuration, not the server.

An authentication failure at this stage is a real HTTP 401, unlike tool errors.

The agent can read but can’t change anything

Section titled “The agent can read but can’t change anything”

Symptom: listing sites works, but any attempt to run something fails with unauthorized and the message a personal API key is required for this tool.

You’re using an account API key (the API calls it a project key). Ability tools execute as a WordPress user, and an account key identifies no user, so there’s no one to run as. No scope change fixes this.

Fix: create a user API key and use that instead. Knowledge base tools keep working with either kind of key, which is why reads can succeed while writes fail.

Every site is missing wp_connection_status

Section titled “Every site is missing wp_connection_status”

Not a fault. list_account_sites only annotates connection state when the request identifies a WordPress user, so an account API key gets the field omitted on every site regardless of the real state. Use a user key if you need to see it.

Note also that a revoked connection and a connection that never existed both omit the field — absence doesn’t distinguish them.

The agent says your WordPress user isn’t connected

Section titled “The agent says your WordPress user isn’t connected”

The error code is not_personally_connected.

Registering a site to your account is not the same as connecting yourself to it. The second connection is per person and requires explicit consent in WordPress admin. See The two connections.

  1. Take the connect_url from the error. If the request didn’t name a site and your account has several, it points at one of them as an example — check it’s the site you want.
  2. Log into that site’s WordPress admin first, then open the link. Opening it while logged out drops you at a login screen and loses the flow.
  3. Confirm with Connect WordPress User on the consent screen.
  4. Retry the original request.

The link is the only entry point to this flow — there’s no button to start it manually in WordPress. If the error came back without a connect_url, the server couldn’t tell which site you meant: call list_account_sites, pick the site, and use its URL.

It worked yesterday and now says the connection is stale

Section titled “It worked yesterday and now says the connection is stale”

needs_reconnect. The connection existed and has lapsed. Follow the same four steps as The agent says your WordPress user isn’t connected; the error carries the link. Nothing is wrong with the site registration or your API key.

If it instead reports site_requires_https, the site isn’t served over HTTPS and a WordPress-user connection can’t be established at all. Enable SSL first.

Work down in this order:

  1. Status filter. The tool returns active registrations only unless you pass status. Ask for revoked or suspended to see the rest.
  2. Wrong account. site_not_found deliberately doesn’t distinguish “no such site” from “belongs to someone else.”

If you name the site directly, the two codes tell you different things. site_not_found means nothing matched the identifier you gave — or the site belongs to another account, which is intentionally indistinguishable. site_not_active means the site was found but its registration has been revoked or suspended, so the identifier was right and the site was withdrawn.

The agent can’t find an ability the site definitely has

Section titled “The agent can’t find an ability the site definitely has”
  1. Are you connected to that site? Ability listing and search only cover sites where your WordPress account connection is active.
  2. Is the catalog out of date? Search reads a cached catalog and never syncs it. search_abilities lists every site whose catalog may lag the site under degraded_sites: one that hasn’t synced recently, has never synced, or failed its last sync (abilities_sync_status of error). Ask for that site’s abilities with list_site_abilities, which refreshes an out-of-date catalog, then search again.
  3. Is it withheld? Some abilities are blocked from remote execution and return ability_unavailable. Retrying won’t help; the change has to be made in WordPress admin.

A search with no matches is not an error — it returns found: false with a reason. Only no_semantic_match improves on a rephrase; no_connected_sites means a missing WordPress account connection and empty_catalogs means nothing has synced yet, so retrying either returns the same answer.

Search also drops weak matches rather than padding the result, so a plausible query can come back with nothing. It finds; it doesn’t browse — use list_site_abilities to see everything a site can do.

The two “not found” codes mean different things:

  • knowledge_base_not_found from get_site_knowledge_base — the site has no usable knowledge base. The error carries a setup_url and a three-step repair walkthrough; follow it, then call get_site_knowledge_base again to read the new collection_id.
  • collection_not_found from search or fetch — the collection_id you passed is wrong or stale. Re-read it from get_site_knowledge_base; don’t reuse a cached one.

If search_knowledge_base reports that collection_id is required, call get_site_knowledge_base first — the collection ID isn’t something you can construct from the site ID.

Fetching a document by an unknown ID is not an error: it returns successfully with not_found: true.

The error code is rate_limited. Your agent made too many calls in a short window. There are two separate budgets, and the message says which one you hit:

  • read tool rate limit exceeded — 120 calls/minute across list_account_sites, search_abilities, list_site_abilities, and the knowledge base tools.
  • ability execution rate limit exceeded — run_site_ability only: 30 calls/minute on one site, or 60 across all your sites.

These limits are provisional and may change.

Wait a minute and ask again. Hitting one budget doesn’t affect the other, so a blocked search doesn’t stop you running an ability.

120 reads a minute is far more than a person generates by hand, so if you keep hitting the read limit your agent is probably looping — searching every site repeatedly, or re-reading a knowledge base. Narrow the request: name the one site you mean, or ask a more specific question.

service_unavailable is a different thing. That’s a fault on our side, not your usage. Try again shortly.

ambiguous_outcome means a mutating ability failed in a way that leaves it unknown whether your site applied the change.

This is the only error code with that property. timeout and unavailable are raised only for reads and are explicitly safe to retry, which is why their help text says so.

These are usually self-explanatory from the message that comes with them:

Code What it means
invalid_request An argument failed validation, and the message names the problem. Unknown fields are rejected rather than ignored. If an ability needs one of several argument sets, help lists them.
ability_not_found The name isn’t in that site’s catalog, or isn’t runnable. Check the spelling, or search again.
run_failed Your site rejected the call. The WordPress error is appended to the message — fix that, then retry.
knowledge_base_unavailable Search is temporarily unavailable. Try again shortly.
request_too_large The input exceeds the size cap. Send less.
run_url_untrusted The site is advertising a location inconsistent with its registration. Contact support.
internal_error An unexpected fault on our side. Retry once, then contact support.

Collect the request_id from the error and include it in your support request. It identifies the exact call in our logs. internal_error always carries one and never carries a suggested fix, so it’s the expected case for this path.


Last updated: