Answers
Why does an MCP server list tools fine but return 401 when I call one?
Short answer
That is lazy authorisation, and it is deliberate. Catalogue methods — initialize, ping, tools/list — answer without credentials so directories can read the tool list. Only a paid action, tools/call, requires a token, and it answers 401 with a WWW-Authenticate header. That 401 is exactly what triggers the OAuth sign-in flow in Claude; a 200 there would leave the header ignored and the client stuck.
- Methods that work unauthenticated
- initialize, ping, tools/list, prompts/list, resources/list
- Method that requires a token
- tools/call
- Challenge header
- WWW-Authenticate: Bearer …, resource_metadata="…", scope="mcp"
- Accepted credentials
- OAuth 2.1 access token (bb_at_…) or API key (bb_live_…)
- Transport
- Streamable HTTP, stateless — GET and DELETE answer 405
Facts on this page were checked against the live platform on .
Why is the catalogue open at all?
MCP directories, client pickers and registry crawlers need to know what a server offers before anyone signs in. If tools/list demanded a token, the server would appear in those catalogues as an empty box, and a user deciding whether to connect would have nothing to look at.
Nothing behind those methods costs money or touches an account, so the split is clean: read the menu freely, pay to order. The moment a call could spend a balance — tools/call — a token is required.
Why must the answer be 401 and not 403 or 200?
Connector-style clients, Claude among them, start their OAuth discovery on a 401. The response carries WWW-Authenticate: Bearer with a resource_metadata pointer, the client fetches that protected-resource document, finds the authorisation server, registers itself dynamically and walks the user through consent.
Return 200 with an error payload instead and the header is never inspected — the client reports a tool failure and no sign-in ever starts. Return 403 and it reads as *authenticated but not allowed*, which stops discovery too. This is the single most common reason a self-hosted MCP server refuses to connect to Claude.
One practical detail if you are building your own: the header value must be a valid ByteString. A non-ASCII character in a client name or scope description makes the runtime throw while serialising the response, and the client sees a transport error instead of a challenge.
How do I authenticate against BananaBanana's MCP server?
Two ways, both ending at the same billing path. OAuth 2.1 is what Claude and other connector-style clients use: add the server URL, approve the consent screen, done — no key to paste. A personal API key (bb_live_…, created in your profile) suits Cursor, VS Code, Codex and anything that takes a static Authorization: Bearer header.
The endpoint is https://bananabanana.pro/api/mcp. Tokens are scoped to that resource, so a token issued for another audience is rejected even if it is otherwise valid.
What to do about it
Check which method failed
If initialize and tools/list succeed and only tools/call returns 401, nothing is broken — the server is asking you to sign in.
Look at the WWW-Authenticate header
It carries resource_metadata. Fetch that URL: it names the authorisation server the client should register with.
Sign in or paste a key
Connector-style clients complete OAuth on their own. Config-file clients need Authorization: Bearer bb_live_… added to the server entry.
Retry the tool call
The same request now succeeds. Expensive tools answer with a price quote first and charge nothing until you confirm.
Where this is documented
Longer reads on the same thing
More on this question
Does the free tool list mean anonymous users can generate?
No. Every paid tool goes through tools/call, which always requires a token. Agents that would rather pay per call than hold an account use the separate x402 endpoint instead.
My client sends the key but still gets 401.
Check the header shape — it must be Authorization: Bearer bb_live_…, one space, no quotes — and check the URL. The MCP endpoint is /api/mcp; the /mcp path is the human documentation page.
Why does the server answer 405 to GET?
The transport is stateless Streamable HTTP: everything is a POST of JSON-RPC. There is no SSE stream to open and no session to delete, so GET and DELETE are rejected.
How long does an OAuth token last?
Access tokens live one hour; refresh tokens last 90 days and rotate on use. Reusing a revoked refresh token invalidates the whole connection as a safety measure.
Questions next door
Try it on your own prompt
New accounts start with $0.20 of balance — no card, nothing expires.