From 6ec5aaf4915fdb59ca020b2c1b927c2a1c2bdcba Mon Sep 17 00:00:00 2001 From: Pyhroff Date: Mon, 26 Oct 2026 14:41:27 +0530 Subject: [PATCH] fix(shared): strip HTTP optional whitespace before comparing Mcp-Name (#3763) --- src/mcp/shared/inbound.py | 5 +++-- tests/shared/test_inbound.py | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mcp/shared/inbound.py b/src/mcp/shared/inbound.py index e33d6f502f..8fd4abd409 100644 --- a/src/mcp/shared/inbound.py +++ b/src/mcp/shared/inbound.py @@ -170,9 +170,10 @@ def decode_header_value(value: str | None) -> str | None: """ if value is None: return None - m = _B64_SENTINEL.fullmatch(value) + trimmed = value.strip(' \t') + m = _B64_SENTINEL.fullmatch(trimmed) if m is None: - return value + return trimmed payload = m.group("payload") try: decoded = base64.b64decode(payload, validate=True) diff --git a/tests/shared/test_inbound.py b/tests/shared/test_inbound.py index 561eff24b0..3842bf4010 100644 --- a/tests/shared/test_inbound.py +++ b/tests/shared/test_inbound.py @@ -311,6 +311,14 @@ def test_header_rung_rejects_missing_or_mismatched_name_header_for_name_bearing_ assert_rejected(classify_inbound_request(body, headers=headers), HEADER_MISMATCH) +def test_header_rung_accepts_whitespace_padded_name_header() -> None: + """Spec-mandated / RFC 9110: HTTP optional whitespace in Mcp-Name is stripped before comparison.""" + body = envelope("tools/call", extra_params={"name": "echo"}) + headers = matching_headers(body) + result = classify_inbound_request(body, headers=headers | {MCP_NAME_HEADER: " echo \t"}) + assert isinstance(result, InboundModernRoute) + + def test_header_rung_decodes_base64_sentinel_before_comparing_name() -> None: """Spec-mandated: servers MUST decode the `=?base64?...?=` sentinel before comparing `Mcp-Name`.""" body = envelope("tools/call", extra_params={"name": "résumé"})