Troubleshooting
401 is not the same as 403
Section titled “401 is not the same as 403”When a tool fails because of authorisation, the MCP server returns an error
with specific metadata (mcp/www_authenticate, carrying the
resource_metadata and the list of scopes) so the client knows what to do. The
two codes mean different things and call for different actions:
| Code | What it means | What to do |
|---|---|---|
401 (invalid_token) |
There is no credential, the credential is invalid, or hackÜ rejected it, it expired, it was revoked, it timed out or it failed. | Authorise again through the client’s OAuth flow. Retrying the same call will not help. |
403 (insufficient_scope) |
The credential is valid, but it does not carry the scope that tool needs. | This is a configuration decision, not a transient error: say which scope is missing and ask for it to be added to the credential. Retrying changes nothing. |
One thing that is not obvious: if hackÜ rejects the credential, does not
answer, or takes too long, the MCP server also returns 401 — it does not
assume the failure is about scope. Check the backend metric before assuming the
credential is the problem.
If the client says the credential was rejected
Section titled “If the client says the credential was rejected”- If it is an OAuth connection (Codex, the ChatGPT app, a connector): you have to authorise again from the client. Never paste tokens or passwords into the chat — the flow opens the browser for that.
The 409 when requesting a report is not an error
Section titled “The 409 when requesting a report is not an error”request_report rejects a request if an identical one is already being built,
with 409 and this detail:
{ "detail": "That report was already requested and is still being built. Wait for it rather than asking again.", "report_id": "...", "requested_at": "..."}This is not a failure and should not be retried: tell the person to wait
for the one already running. list_reports shows its status
(ready: true|false) so you know when it is done.
Listing evaluation attempts requires narrowing
Section titled “Listing evaluation attempts requires narrowing”list_evaluation_attempts requires either evaluation_id or user_id —
there is no “give me every attempt”. One real company has 250,244 attempts
on record; without narrowing there is no reasonable page to show. Take the id
from list_evaluations (by evaluation) or from list_users (by person) before
calling it.
