Skip to content

401 Unauthorized / invalid_token from an MCP server

Spec
2026-07-28
Evidence
E2Reproducedarm64
TypeScript SDK (client)
@modelcontextprotocol/client@2.4.0
TypeScript SDK v1
@modelcontextprotocol/sdk@1.32.2
MCP Inspector
@modelcontextprotocol/inspector@2.12.0
Verified

A protected MCP server answers requests without valid credentials with HTTP 401 and a WWW-Authenticate header that tells the client where to find the authorization details. We ran a server that answers every request that way:

Client Message
TypeScript SDK v1 Streamable HTTP error: Error POSTing to endpoint: {"error":"invalid_token","error_description":"Missing or invalid access token"} (code 401)
TypeScript SDK v2, default Error POSTing to endpoint: {"error":"invalid_token",…}
TypeScript SDK v2, versionNegotiation: 'auto' Version negotiation failed: the server requires authorization (HTTP 401) (code CLIENT_HTTP_AUTHENTICATION)
MCP Inspector 2.12.0 --cli {"error":{"code":"auth_required","message":"Interactive OAuth requires a TTY on stdin or stderr (or MCP_AUTO_OPEN_ENABLED=true). For CI/non-interactive runs use --stored-auth-only."}}

The body after Error POSTing to endpoint: is whatever the server sent, so the wording varies.

Either configure a token, or let the client run the server’s OAuth flow:

  • Static token. Many clients have a header or token setting for HTTP servers. In Codex, bearer_token_env_var names an environment variable that holds the token; see Codex.
  • OAuth. Clients that support MCP authorization read the WWW-Authenticate header, open a browser for you to sign in, and store the token. In the client SDKs this needs an auth provider; without one you get the errors above.

A token for a different server, a different environment (staging vs production), or one that has expired gets the same 401. Some servers say invalid_token in the body or in WWW-Authenticate; read both. Get a new token, or sign in again so the client refreshes it.

The Inspector’s CLI refuses to start an interactive sign-in when it has no terminal, as in CI. Sign in once interactively, then use --stored-auth-only in scripts, as the message says.

MCPDev is community documentation. It is not affiliated with the Model Context Protocol project or with the vendors of the clients it covers.