Skip to content

Streamable HTTP: malformed requests return raw pydantic errors to the client #3698

Open

Description

@john-mihailescu

Initial Checks

Release line

2.x (current stable)
Also applies to latest 1.x

Description

When the Streamable HTTP POST handler rejects a malformed body, it returns the raw exception text to the client (streamable_http.py L580-L596):

  • No "jsonrpc" field → "Validation error: 6 validation errors for union[JSONRPCRequest,...] ... input_value={...} ... https://errors.pydantic.dev/2.14/v/missing"
  • Not JSON → "Parse error: EOF while parsing a value at line 1 column 27"

A security audit of our MCP server flagged this: the errors reveal that the backend is Python, using pydantic (down to the exact version) and the MCP Python SDK, which helps an attacker enumerate the environment.

Expected: fixed messages (Parse error, Invalid JSON-RPC message), with detail in the server log only. The 2026-07-28 path already does this (_streamable_http_modern.py L415).

The same code is on v1.x, which we run. I’d like to fix both if assigned: a few lines plus tests, with no new API.

Related: #3557 (error code on these lines), #3572 (same pydantic text in tool-argument errors).

Disclosure: this issue was drafte by Claude Code and reviewed/iterated by myself and another senior developer. I ran the reproduction and verified the output myself.

Example Code

import json

from mcp.server import MCPServer
from mcp.server.transport_security import TransportSecuritySettings
from starlette.testclient import TestClient

server = MCPServer("repro")


@server.tool()
def echo(text: str) -> str:
    return text


app = server.streamable_http_app(
    stateless_http=True,
    transport_security=TransportSecuritySettings(enable_dns_rebinding_protection=False),
)
headers = {
    "Accept": "application/json, text/event-stream",
    "Content-Type": "application/json",
    "mcp-protocol-version": "2025-06-18",
}
with TestClient(app) as client:
    for body in (
        json.dumps({"id": 1, "method": "tools/call", "params": {"name": "echo", "arguments": {"text": "hi"}}}),
        json.dumps([{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}]),
        '{"jsonrpc": "2.0", "id": 1,',
    ):
        response = client.post("/mcp", content=body, headers=headers)
        print(response.status_code, json.dumps(response.json(), indent=2))

Python & MCP Python SDK

Python 3.12.9
mcp 2.3.0
pydantic 2.14.0

Activity

  1. added
    bugSomething isn't working
    v2Affects the v2 line (2.x on main)
    v1Affects the v1.x maintenance line
    on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingv1Affects the v1.x maintenance linev2Affects the v2 line (2.x on main)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions