Skip to content

fix: reject initialize protocol version conflicts#2639

Open
he-yufeng wants to merge 1 commit into
modelcontextprotocol:mainfrom
he-yufeng:fix/streamable-http-init-version-conflict
Open

fix: reject initialize protocol version conflicts#2639
he-yufeng wants to merge 1 commit into
modelcontextprotocol:mainfrom
he-yufeng:fix/streamable-http-init-version-conflict

Conversation

@he-yufeng
Copy link
Copy Markdown

Summary

  • reject initialize requests when the mcp-protocol-version header conflicts with initialize.params.protocolVersion
  • keep initialize requests without the protocol-version header on the existing compatibility path
  • move existing initialize session-id validation behind a small helper to keep the POST handler readable

Fixes #2618

To verify

  • .\.venv\Scripts\python.exe -m pytest tests\shared\test_streamable_http.py -q -k "protocol_version"
  • .\.venv\Scripts\python.exe -m ruff check src\mcp\server\streamable_http.py tests\shared\test_streamable_http.py
  • .\.venv\Scripts\python.exe -m ruff format --check src\mcp\server\streamable_http.py tests\shared\test_streamable_http.py
  • .\.venv\Scripts\pyright.exe src\mcp\server\streamable_http.py tests\shared\test_streamable_http.py
  • git diff --check upstream/main..HEAD

@he-yufeng
Copy link
Copy Markdown
Author

Pushed a test-only follow-up for the coverage gate. The HTTP mismatch path was already covered through the live server test, but that path runs out of process, so I added an in-process regression test for the 400 response branch.

Verified locally:

  • .\.venv\Scripts\python.exe -m pytest tests\shared\test_streamable_http.py -q -k "protocol_version_mismatch"
  • .\.venv\Scripts\python.exe -m ruff check src\mcp\server\streamable_http.py tests\shared\test_streamable_http.py
  • .\.venv\Scripts\python.exe -m ruff format --check src\mcp\server\streamable_http.py tests\shared\test_streamable_http.py
  • .\.venv\Scripts\pyright.exe src\mcp\server\streamable_http.py tests\shared\test_streamable_http.py
  • git diff --check upstream/main..HEAD

@he-yufeng he-yufeng force-pushed the fix/streamable-http-init-version-conflict branch from 0b83197 to 2cb41c3 Compare May 19, 2026 02:25
@he-yufeng he-yufeng force-pushed the fix/streamable-http-init-version-conflict branch from 2cb41c3 to 95fe1b8 Compare June 7, 2026 00:23
@he-yufeng
Copy link
Copy Markdown
Author

Rebased this onto current upstream/main and resolved the StreamableHTTP in-process transport test refactor conflict.

The mismatch coverage is now in the current async in-process style, so the old socket/requests test shape was not brought back.

Validated locally on Windows:

  • PYTHONUTF8=1 uv run pytest tests/shared/test_streamable_http.py -q -k "protocol_version_header or initialize_protocol_version_mismatch or backwards_compatibility_no_protocol_version" (5 passed)
  • PYTHONUTF8=1 uv run ruff check src/mcp/server/streamable_http.py tests/shared/test_streamable_http.py
  • PYTHONUTF8=1 uv run ruff format --check src/mcp/server/streamable_http.py tests/shared/test_streamable_http.py
  • PYTHONUTF8=1 uv run pyright src/mcp/server/streamable_http.py tests/shared/test_streamable_http.py
  • PYTHONUTF8=1 uv run python -m py_compile src/mcp/server/streamable_http.py tests/shared/test_streamable_http.py
  • git diff --check upstream/main..HEAD

@he-yufeng he-yufeng force-pushed the fix/streamable-http-init-version-conflict branch from 95fe1b8 to 9ab85e1 Compare June 7, 2026 00:30
@he-yufeng
Copy link
Copy Markdown
Author

Follow-up after the Ubuntu matrix failure: the tests themselves passed, but strict-no-cover caught an old pragma: no cover on the request-header validation branch that is now covered by the updated in-process tests.

I removed that stale pragma and revalidated locally on Windows:

  • PYTHONUTF8=1 uv run pytest tests/shared/test_streamable_http.py -q -k "protocol_version_header or initialize_protocol_version_mismatch or backwards_compatibility_no_protocol_version" (5 passed)
  • PYTHONUTF8=1 uv run ruff check src/mcp/server/streamable_http.py tests/shared/test_streamable_http.py
  • PYTHONUTF8=1 uv run ruff format --check src/mcp/server/streamable_http.py tests/shared/test_streamable_http.py
  • PYTHONUTF8=1 uv run pyright src/mcp/server/streamable_http.py tests/shared/test_streamable_http.py
  • PYTHONUTF8=1 uv run python -m py_compile src/mcp/server/streamable_http.py tests/shared/test_streamable_http.py
  • git diff --check upstream/main..HEAD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streamable HTTP server accepts mismatched MCP-Protocol-Version header and body protocolVersion on initialize

1 participant