Skip to content

Commit 6ec5aaf

Browse files
committed
fix(shared): strip HTTP optional whitespace before comparing Mcp-Name (#3763)
1 parent a525a3d commit 6ec5aaf

2 files changed

Lines changed: 11 additions & 2 deletions

File tree

‎src/mcp/shared/inbound.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ def decode_header_value(value: str | None) -> str | None:
170170
"""
171171
if value is None:
172172
return None
173-
m = _B64_SENTINEL.fullmatch(value)
173+
trimmed = value.strip(' \t')
174+
m = _B64_SENTINEL.fullmatch(trimmed)
174175
if m is None:
175-
return value
176+
return trimmed
176177
payload = m.group("payload")
177178
try:
178179
decoded = base64.b64decode(payload, validate=True)

‎tests/shared/test_inbound.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,14 @@ def test_header_rung_rejects_missing_or_mismatched_name_header_for_name_bearing_
311311
assert_rejected(classify_inbound_request(body, headers=headers), HEADER_MISMATCH)
312312

313313

314+
def test_header_rung_accepts_whitespace_padded_name_header() -> None:
315+
"""Spec-mandated / RFC 9110: HTTP optional whitespace in Mcp-Name is stripped before comparison."""
316+
body = envelope("tools/call", extra_params={"name": "echo"})
317+
headers = matching_headers(body)
318+
result = classify_inbound_request(body, headers=headers | {MCP_NAME_HEADER: " echo \t"})
319+
assert isinstance(result, InboundModernRoute)
320+
321+
314322
def test_header_rung_decodes_base64_sentinel_before_comparing_name() -> None:
315323
"""Spec-mandated: servers MUST decode the `=?base64?...?=` sentinel before comparing `Mcp-Name`."""
316324
body = envelope("tools/call", extra_params={"name": "résumé"})

0 commit comments

Comments
 (0)