Short answer
Serve one MCP endpoint that accepts POST and answers with JSON or an event stream. A 405 on GET is allowed by the spec for a server that doesn’t stream to the client, so only POST needs to work. A 406 comes from servers, often built on an SDK, that reject requests whose Accept header lacks application/json or text/event-stream. A 403 usually means your Origin or Host check rejected the request.
What each error means, and the fix
01
405 Method Not Allowed
“HTTP GET or DELETE to the MCP endpoint: respond with 405 Method Not Allowed.” MCP specification, Streamable HTTP (2026-07-28)
A 405 on GET or DELETE is a valid answer from a server that only handles requests and responses, and clients built to the spec handle it. A 405 on POST is the real problem. It often means the URL points to an old HTTP+SSE endpoint, but a proxy or route that only allows GET can cause it too. Replace it with a Streamable HTTP endpoint, or serve both while older clients still connect.
02
406 Not Acceptable
“The client MUST include an Accept header listing both application/json and text/event-stream as supported content types.” MCP specification, Streamable HTTP (2026-07-28)
The spec requires clients to send both content types in Accept. The 406 status itself comes from some SDKs, not from the spec. If you wrote the client, add both to every request. If a third-party client sends a narrower header, relaxing the check on your server is a choice you make for compatibility.
03
403 Forbidden or Invalid Host
“If the Origin header is present and invalid, servers MUST respond with HTTP 403 Forbidden.” MCP specification, Streamable HTTP (2026-07-28)
Servers must answer 403 when an Origin header is present and invalid; the spec doesn’t require rejecting a request that sends no Origin. Behind a tunnel, Claude’s docs note that the TypeScript SDK’s createMcpExpressApp() accepts only localhost, 127.0.0.1 and [::1] in the Host header, and answers 403 with Invalid Host, unless you pass your public hostname in allowedHosts.
04
Session ID errors
Errors such as missing or invalid session ID come from the 2025-11-25 transport, where a server could require one. The 2026-07-28 revision drops sessions, so a server that serves only that revision ignores the header. Google’s Connected Apps supports the specification up to 2025-11-25, so a server listed there should negotiate 2025-11-25 and keep that revision’s session behavior.
Checked against the vendor’s docs on : MCP specification: Streamable HTTP (2026-07-28); MCP specification: Transports (2025-11-25); Google: Connected Apps MCP server optimization; Anthropic: Test a connector.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- $2,500MCP Connector for your SaaSAn MCP server over your existing REST API, so your product works inside Claude, and in ChatGPT with OAuth sign-in.See scope and start
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
Related: Claude connector authorization failed · ChatGPT MCP OAuth redirect URI errors · How to add an MCP server to your SaaS