Reject an orphan Mcp-Name header when the body omits the named param

Closed
HA
2mo ago
+36-6

classify_inbound_request's Mcp-Name check only ran when the body carried the name-bearing method's param (name_key). When the body omitted it, a present Mcp-Name header went unvalidated entirely -- an intermediary or client could set it to claim a different tool/prompt/resource than the request body actually names, with no rejection.

validate_mcp_param_headers already treats this shape -- a header present with no matching body value -- as a rejection for Mcp-Param-* headers, on the same reasoning: a conforming client never emits the header unless the body value is present, so a header with nothing to match against did not come from this request. Mcp-Name had no equivalent check.

Mirrors that handling: when the named param is absent, an absent header still passes (the param's own absence is INVALID_PARAMS elsewhere, not this rung's concern), but a present header is now rejected HEADER_MISMATCH.

Adds test_header_rung_rejects_orphan_name_header_when_body_omits_the_named_param, parametrized over all of NAME_BEARING_METHODS. Confirmed it fails against the unpatched code (reverting just inbound.py, keeping the test) and passes with the fix.

AI assistance disclosure: I used Claude to help investigate this issue and implement/test the fix; I've reviewed the change and reasoning above and can answer questions about it.

Fixes #3269

Motivation and Context

How Has This Been Tested?

Breaking Changes

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context