Invalid Origin header (403)
- Spec
2026-07-28- Evidence
- E2Reproducedarm64
- TypeScript SDK v2 (Node HTTP)
@modelcontextprotocol/node@2.1.2- Python SDK
mcp@2.3.0- Verified
What it means
Section titled “What it means”The specification says servers must validate the Origin header and answer 403 Forbidden when it is present and invalid. Browsers add Origin to cross-site requests; desktop and command-line clients normally do not. With Origin: https://evil.example.com we got:
| Server | Response |
|---|---|
TypeScript SDK v2 with localhostOriginValidation() |
403 {"jsonrpc":"2.0","error":{"code":-32000,"message":"Invalid Origin: evil.example.com"},"id":null} |
Python SDK 2.3.0, streamable-http on 127.0.0.1 |
403 Invalid Origin header |
A request with Origin: http://localhost:8504 passed both servers’ checks: the defaults trust localhost origins only.
A web page calls the server
Section titled “A web page calls the server”If you are building a web client, an MCP App host, or a browser extension, its origin must be on the server’s allow list:
- TypeScript SDK: replace
localhostOriginValidation()withoriginValidation(['app.example.com']). - Python SDK: pass
transport_security=TransportSecuritySettings(allowed_origins=["https://app.example.com"], allowed_hosts=[...])tomcp.run("streamable-http", ...). We tested this; requests from that origin returned200.
Passing the Origin check is not enough for a browser to read the response. The server must also send CORS headers, or the browser blocks it: see Blocked by CORS policy.
Check it yourself
Section titled “Check it yourself”Send the same request with and without the Origin your web app uses:
curl -i -X POST http://127.0.0.1:8000/mcp \ -H 'content-type: application/json' \ -H 'accept: application/json, text/event-stream' \ -H 'MCP-Protocol-Version: 2026-07-28' \ -H 'Mcp-Method: tools/list' \ -H 'Origin: https://app.example.com' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'403 with Invalid Origin means the allow list does not include that origin. 200 without the header but 403 with it confirms the check is the only problem. Both servers we tested gave 200 once the origin was allowed, and still 403 for any other.
Related
Section titled “Related”Sources
MCPDev is community documentation. It is not affiliated with the Model Context Protocol project or with the vendors of the clients it covers.