Skip to content

feat(core): add support for MCP 2026 stateless draft and auto-negotiation fallback#703

Open
anubhav756 wants to merge 10 commits into
anubhav-test-infrafrom
anubhav-mcp-draft
Open

feat(core): add support for MCP 2026 stateless draft and auto-negotiation fallback#703
anubhav756 wants to merge 10 commits into
anubhav-test-infrafrom
anubhav-mcp-draft

Conversation

@anubhav756

@anubhav756 anubhav756 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Description

This PR standardizes the Python SDK's version opt-in strategy for the upcoming stateless draft and introduces protocol auto-negotiation fallback to ensure smooth backward compatibility with older servers.

Note

This PR is stacked on top of the test infrastructure changes in #706.

Changes:

  • Protocol Constants (protocol.py):
    • Introduces the Protocol.MCP_DRAFT constant mapped to "DRAFT-2026-v1" to give developers a safe way to opt into testing the draft spec without hardcoding ephemeral version strings.
    • Maintains Protocol.MCP_LATEST mapped to the stable 2025-11-25 release to ensure production workloads remain unaffected.
  • Auto-Negotiation Fallback (client.py & mcp.py):
    • Implements fallback protocol negotiation during client initialization.
    • If a client requests the draft protocol but the older server returns a single older version string (instead of throwing a -32004 UnsupportedProtocolVersionError), the transport layer now safely raises a ProtocolNegotiationError.
    • The client catches this error and cleanly re-initializes the session using the older server's preferred protocol.
  • E2E Testing (test_e2e_mcp.py):
    • Adds test_protocol_fallback_e2e to verify smooth protocol negotiation downgrades against older servers. Leveraging the dual-server harness from the base PR, this test proves that a client requesting MCP_DRAFT successfully falls back when hitting port 5000, but correctly utilizes the draft protocol on port 5001.

@anubhav756 anubhav756 requested a review from a team as a code owner June 26, 2026 07:46
@anubhav756 anubhav756 changed the title refactor(core): enforce MCP_LATEST for draft specs and remove upgrade warnings feat(core): update protocol definitions to use MCP_LATEST for draft specs Jun 26, 2026

@Yuan325 Yuan325 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this PR, or move some of the part from #704 to here. There seems to be some redundant code (updating MCP_LATEST to the draft specs) that will be reverted in the next PR.

@anubhav756

Copy link
Copy Markdown
Contributor Author

Please remove this PR, or move some of the part from #704 to here. There seems to be some redundant code (updating MCP_LATEST to the draft specs) that will be reverted in the next PR.

Merged #704 in this one.

@anubhav756 anubhav756 requested a review from Yuan325 July 1, 2026 14:43
@anubhav756 anubhav756 changed the title feat(core): update protocol definitions to use MCP_LATEST for draft specs feat(core): add support for MCP 2026 draft and auto-negotiation fallback Jul 1, 2026
@anubhav756 anubhav756 force-pushed the anubhav-mcp-draft branch 2 times, most recently from 5a88785 to fc0c7cd Compare July 1, 2026 14:56
@anubhav756 anubhav756 changed the base branch from anubhav-sep-2243 to anubhav-test-infra July 1, 2026 14:59
@anubhav756 anubhav756 changed the title feat(core): add support for MCP 2026 draft and auto-negotiation fallback feat(core): add support for MCP 2026 stateless draft and auto-negotiation fallback Jul 1, 2026

@Yuan325 Yuan325 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve with a comment for clarification~

…tion fallback (#704)

* feat(core): add support for MCP 2026 stateless draft and auto-negotiation fallback

* fix: Keep the MCP_LATEST to stable version but point MCP_DRAFT to 2026 draft

* chore: fix integration tests

* chore: delint

* chore: fix tests

* test: increase integration test coverage

* chore: delint

* test: integrate the draft build with dual testing modes

* fix(tests): correct pytest async fixtures and auto-format with black/isort

* fix(tests): use pytest.fixture for sync fixtures and fix isort formatting

* fix(tests): update binary URL for draft testing in all packages

* chore: fix integration tests url and lint errors

* chore: test with mcp-v202606 branch to fix unknown flag error

* fix(test): core fallback and adk toolset import

* chore: format files

* Revert "chore: format files"

This reverts commit ee00b9e.

* chore(test): fix line length in bucket name selection

* chore: bump TOOLBOX_VERSION to v1.6.0

* test: parameterize integration tests to run comprehensively for both stable and draft MCP versions
Previously, the protocol fallback error (-32004) was correctly handled if returned inside an HTTP 400 Bad Request. However, if it was returned inside an HTTP 200 OK response, the SDK failed to extract the fallback version and would instead raise a generic RuntimeError.

This commit updates the `error` checking logic inside the 200 OK path to correctly extract the supported versions array and raise a ProtocolNegotiationError, along with corresponding unit tests.
Parameterizing tests with http_session causes pytest-asyncio to rapidly create and destroy multiple event loops. This occasionally leaks ResourceWarnings on teardown which caused test_tool_init_basic to fail because it asserts no warnings were raised. We now explicitly ignore ResourceWarning so we only catch business logic warnings.
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.

4 participants