Troubleshooting
This page lists fixes for common Model Context Protocol (MCP) server failures, organized by symptom. You can also search for a specific error code: each code appears in the section that resolves it.
Before you work through this page, read the help and next_steps on the
error itself. The server generates them from live state. They name your
actual site and the actual missing argument, so they’re more specific than
anything on this page. This page covers the failures where that isn’t enough,
or where the fix isn’t where you’d expect.
The server returns a tool failure as a normal response that carries an
error.code, not as an HTTP error. At the transport layer, a failing call
still looks like a success. Your client should show you the code.
Fix a client that shows no tools
Section titled “Fix a client that shows no tools”If your client shows no tools at all, the connection is failing before tool discovery.
- Confirm the endpoint is exactly
https://api.ai.wpengine.com/v1/mcp. The transport is Streamable HTTP, and the client sends requests asPOST. - Confirm the client authenticated with OAuth. In Claude Code, run
/mcp, select the server, and select Authenticate. In Claude Desktop, select Connect on the connector. See Authentication. - In Claude Code, run
claude mcp listto confirm the server is registered. A server added without--scope userappears only in the directory you added it from. - Reproduce the problem outside your client with MCP Inspector. If MCP Inspector lists tools and your client doesn’t, the problem is client configuration, not the server.
Unlike a tool error, an authentication failure at this stage is a real HTTP 401. If sign-in succeeds and every request then fails with HTTP 403
entitlement_required, see
Fix entitlement_required by turning on AI.
Fix forbidden on every tool call
Section titled “Fix forbidden on every tool call”Every tool call fails with forbidden, and the message says the credential is
not accepted for the tool.
This happens when you configure the client with an API key. The MCP server no longer accepts API keys. A key still connects, but every tool call fails. A tool call must come from a user authenticated with OAuth.
Fix:
- Remove the key or token and the
Authorizationheader from the client configuration. - Authenticate with OAuth. See Connect Claude Code or Connect Claude Desktop.
- Retry the request.
Fix a token rejected with HTTP 401 or 403
Section titled “Fix a token rejected with HTTP 401 or 403”The request fails before any tool runs. This is an HTTP error, not the tool
error forbidden.
If you signed in with OAuth but didn’t grant a permission that a tool needs,
the server returns HTTP 403 with
WWW-Authenticate: Bearer error="insufficient_scope". The header names the
scopes to request. A client that supports step-up authorization asks you to sign
in again. Otherwise, sign in again and grant the permissions the tool needs.
The server returns HTTP 401 for a site service token that doesn’t verify. It
returns HTTP 403 with insufficient scope for one that verifies without the
accounts scope. Don’t use a site service token in an MCP client. Authenticate
with OAuth instead. See
Connect Claude Code or
Connect Claude Desktop.
Fix entitlement_required by turning on AI
Section titled “Fix entitlement_required by turning on AI”The server returns entitlement_required when AI isn’t turned on for your
account. The error arrives in one of two ways:
- Every request fails with HTTP 403 before any tool runs. The message is
This account is not entitled to use WP Engine AI APIs.None of the WP Engine accounts you belong to has AI turned on. Your client might show this as a server that fails to connect. - One tool call fails with the same message, or with
AI is not turned on for the WP Engine account this call acts on. The call names an account that has AI turned off.list_accountsleaves those accounts out, so pass anaccount_idthat it returns.
Fix: An account owner accepts the WP Engine AI terms and turns on AI for the account in the WP Engine User Portal. Then retry the request.
Fix not_personally_connected by connecting your WordPress user
Section titled “Fix not_personally_connected by connecting your WordPress user”A tool returns not_personally_connected when your WordPress user isn’t
connected to the site.
Registering a site to your account isn’t the same as connecting yourself to it. The second connection is per person and requires explicit consent in WordPress admin. See The two connections.
If the error names one site, it includes connect_url for that site:
- Log in to that site’s WordPress admin first, then open
connect_url. If you open it while logged out, you land on a login screen and lose the flow. - On the consent screen, confirm with Connect WordPress user.
- Retry the original request.
If the request didn’t name a site, the error has no connect_url. Choose the
site to connect yourself. Your client shouldn’t choose one for you.
- Call
list_account_siteswithlimitandoffset, starting atoffset0. Increaseoffsetbylimituntil you have coveredpagination.totalfrom the first page. A page past the end reportstotal0, so keep the first page’s total. - Each site includes
requires_https, taken from itssite_urlon that same response. Use each site’sdisplay_nameandsite_urlto choose a site whererequires_httpsis false. If every site is true, enable Secure Sockets Layer (SSL) on a site first. Don’t open a connect link for a site whererequires_httpsis true. - Call
list_site_abilitieswith the chosensite_id. That response carries the Connect link when the site can be connected. - Log in to that site’s WordPress admin, open the link, and confirm with Connect WordPress user.
- Retry the original request.
The link is the only entry point to this flow. WordPress has no button to start it manually.
A search_abilities call from a signed-in user with no connected sites doesn’t
return this error. Instead, it returns found: false,
reason: no_connected_sites, and the same help and next_steps.
Fix needs_reconnect on a stale connection
Section titled “Fix needs_reconnect on a stale connection”If a connection that worked before now reports that it’s stale, the error is
needs_reconnect. The connection existed and has lapsed.
Follow the three steps for an error that names one site, in
Fix not_personally_connected by connecting your WordPress user.
The error carries the link. Nothing is wrong with the site registration or your
sign-in.
If the error is site_requires_https instead, the site isn’t served over HTTPS,
and you can’t establish a WordPress user connection at all. Enable SSL first.
The server also returns this code on the first attempt to connect an HTTP site,
before any connection exists. list_account_sites sets requires_https: true
on those sites.
Find a site missing from list_account_sites
Section titled “Find a site missing from list_account_sites”Check these causes in order:
- Check the status filter. Unless you pass
status, the tool returns only active registrations. To see the rest, ask forrevokedorsuspended. - Check the account.
site_not_founddeliberately 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_foundmeans nothing matched the identifier you gave, or the site belongs to another account. The server intentionally doesn’t distinguish the two.site_not_activemeans the server found the site, but its registration is revoked or suspended. The identifier was right, and the site was withdrawn.
Find an ability missing from search results
Section titled “Find an ability missing from search results”If search doesn’t return an ability that the site has, work through these checks:
- Check that you’re connected to the site. Ability listing and search cover only sites where your WordPress account connection is active.
- Check whether the catalog is out of date. Search reads a cached catalog and never syncs it. Under
degraded_sites,search_abilitieslists every site whose catalog might lag the site. That includes a site that hasn’t synced recently, has never synced, or failed its last sync (abilities_sync_statusoferror). Calllist_site_abilitiesfor that site, which refreshes an out-of-date catalog, and then search again. - Check whether the ability is withheld. Some abilities are blocked from remote execution and return
ability_unavailable. Retrying doesn’t help; the change has to happen in WordPress admin.
A search with no matches isn’t an error. It returns found: false with a
reason:
no_semantic_matchis the only reason that improves on a rephrase.no_connected_sitesmeans a missing WordPress account connection. Retrying returns the same answer.empty_catalogsmeans nothing has synced yet. Retrying returns the same answer.
Search also drops weak matches instead of padding the result, so a plausible
query can return nothing. Search finds abilities; it doesn’t browse them. To see
everything a site can do, use list_site_abilities.
Fix knowledge base search failures
Section titled “Fix knowledge base search failures”The two “not found” codes mean different things:
knowledge_base_not_foundfromget_site_knowledge_base— the site has no usable knowledge base. The error carries asetup_urland a three-step repair walkthrough. Follow the walkthrough, then callget_site_knowledge_baseagain to read the newcollection_id.collection_not_foundfrom search or fetch — thecollection_idyou passed is wrong or stale. Read it again fromget_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. You can’t construct the collection ID from the
site ID.
Fetching a document by an unknown ID isn’t an error. The call succeeds and
returns not_found: true.
Fix rate_limited errors
Section titled “Fix rate_limited errors”The server returns rate_limited when your client makes too many calls in a
short window. The server applies two separate budgets, and the message says
which one you hit:
read tool rate limit exceeded— 120 calls per minute acrosslist_accounts,list_account_sites,search_abilities,list_site_abilities, the knowledge base tools, and thewpe_*hosting tools. A hosting tool reports it astoo many hosting tool calls; retry after a short delay.ability execution rate limit exceeded—run_site_abilityonly: 30 calls per minute on one site, or 60 across all your sites.
These limits are provisional, and WP Engine may change them.
Wait a minute, then ask again. Hitting one budget doesn’t affect the other, so a blocked search doesn’t stop you from running an ability.
If you reach the read limit repeatedly, your client is usually repeating calls, such as searching every site or reading a knowledge base again. Narrow the request to a single site or a more specific question.
service_unavailable isn’t a rate limit. It indicates a temporary server-side
issue. Retry the request shortly.
Verify a write after ambiguous_outcome
Section titled “Verify a write after ambiguous_outcome”ambiguous_outcome means a mutating ability failed in a way that leaves it
unknown whether your site applied the change. The write might or might not
have happened.
ambiguous_outcome is the only error code with that property. The server
raises timeout and unavailable only for reads. They’re explicitly safe to
retry, which is why their help text says so.
Look up other error codes
Section titled “Look up other error codes”The message that comes with each of these codes usually explains it:
| Code | What it means |
|---|---|
account_not_found |
The account_id isn’t one you belong to, or doesn’t exist. Call list_accounts and pass one of its values. |
insufficient_scope |
Your sign-in didn’t grant the permission this tool needs. The message names it. Sign in again and grant it. |
insufficient_credits |
The account’s credit balance is exhausted. Add credits in the User Portal; portal_url links there when set. |
billing_account_pending |
AI billing isn’t set up for the account yet. The account owner sets it up in the User Portal. If they set it up recently, try again shortly. |
credits_unavailable |
The credit balance check is temporarily unavailable. Try again shortly. |
invalid_request |
An argument failed validation, and the message names the problem. The server rejects unknown fields instead of ignoring them. 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 server appends the WordPress error to the message. Fix that error, 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 advertises a location that’s inconsistent with its registration. Contact support. |
internal_error |
An unexpected server error. Retry once, then contact support. |
Contact support when nothing here matches
Section titled “Contact support when nothing here matches”Collect the request_id from the error and include it in your support request.
WP Engine support uses it to locate the call. internal_error always includes
a request_id and never includes a suggested fix.