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
What it means
Section titled “What it means”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.
The client sends no token
Section titled “The client sends no token”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_varnames an environment variable that holds the token; see Codex. - OAuth. Clients that support MCP authorization read the
WWW-Authenticateheader, 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.
The token is wrong or expired
Section titled “The token is wrong or expired”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.
OAuth cannot run without a terminal
Section titled “OAuth cannot run without a terminal”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.
Related
Section titled “Related”MCPDev is community documentation. It is not affiliated with the Model Context Protocol project or with the vendors of the clients it covers.