Unsupported Media Type: Content-Type must be application/json (415)
- Spec
2026-07-28- Evidence
- E2Reproducedarm64
- TypeScript SDK (server)
@modelcontextprotocol/server@2.4.0- Python SDK
mcp@2.3.0- Verified
What it means
Section titled “What it means”We sent a POST with Content-Type: text/plain:
| Server | Response |
|---|---|
| TypeScript SDK v2 | 415 {"jsonrpc":"2.0","error":{"code":-32000,"message":"Unsupported Media Type: Content-Type must be application/json"},"id":null} |
| Python SDK 2.3.0 | 400 Invalid Content-Type header |
The request is not sent as JSON
Section titled “The request is not sent as JSON”curl -d without a -H 'content-type: application/json' header sends application/x-www-form-urlencoded. Some HTTP libraries send text/plain for string bodies. Set the header explicitly:
curl -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' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'With the header set, both servers returned 200 and the tool list.
A body that is labeled as JSON but is not valid JSON gets a different answer: 400 with JSON-RPC code -32700. The TypeScript server said Parse error: Invalid JSON, the Python server just Parse error. Check the quoting of the -d argument, especially on Windows, where cmd.exe does not treat single quotes as quotes.
Why the two servers answer differently
Section titled “Why the two servers answer differently”The examples in the Streamable HTTP specification send Content-Type: application/json, but the specification names no status code for a request without it (we checked on 2026-10-29). The TypeScript SDK uses the HTTP status meant for it, 415, with a JSON-RPC error body. The Python SDK answers 400 with a plain-text body, so a client that only shows the status code says “Bad Request” and nothing more. If you see a bare 400 from a Python server, check Content-Type along with the other headers.
Related
Section titled “Related”- 406 Not Acceptable: the other header every request needs.
MCPDev is community documentation. It is not affiliated with the Model Context Protocol project or with the vendors of the clients it covers.