Skip to content

feat: support mcp 2.x alongside mcp 1.x - #342

Open
K4bain wants to merge 1 commit into
tadata-org:mainfrom
K4bain:feat/mcp-2-support
Open

feat: support mcp 2.x alongside mcp 1.x#342
K4bain wants to merge 1 commit into
tadata-org:mainfrom
K4bain:feat/mcp-2-support

Conversation

@K4bain

@K4bain K4bain commented Aug 27, 2026

Copy link
Copy Markdown

feat: support mcp 2.x alongside mcp 1.x

Why this matters

mcp 2.x is now out, and this package could not even import against it. Every fresh pip install fastapi-mcp today resolves to mcp 2.x and breaks at setup_server() — the lowlevel Server API was redesigned and almost everything the library used is gone. (PR #331 was the stopgap, capping <2; this PR is the real fix.)

The changes needed to run on 2.x:

  • setup_server() now version-branches on whether the decorator API exists:
    • 1.x — unchanged decorator path.
    • 2.x — tool handlers registered as constructor callbacks (on_list_tools / on_call_tool), each receiving an explicit request context + typed params, returning typed ListToolsResult / CallToolResult.
  • HTTP request-info extraction works on both: 1.x reads the request_ctx ContextVar, 2.x passes the context into the handler. Shared _extract_http_request_info helper.
  • 2.x handlers mirror the 1.x call_tool contract: arguments are validated against the tool's JSON schema and handler exceptions become error results (is_error=True) instead of protocol errors.
  • Dependency cap relaxed to mcp>=1.12.0,<3.0.0. jsonschema declared explicitly (now a direct import).
  • Added tests/_mcp_compat shim so the test suite runs unchanged under both majors, and made the SSE transport parse JSON-RPC version-agnostically via a TypeAdapter.

Verification

  • Full unit suite: 69 passed under mcp 1.12.1 AND mcp 2.1.1 (run twice each).
  • isError -> is_error, inputSchema -> input_schema, and the removed in-memory test helper are all handled compatibly.

Note

I could not regenerate uv.lock locally (no uv on this machine); it should be refreshed with uv lock before merging. I also authored this against my fork (K4bain), mirroring the existing adoption PRs (#331-341) from the maintained community fork.

mcp 2.x redesigned the lowlevel Server API: the list_tools/call_tool
decorators are gone (handlers are now registered as constructor
callbacks), handler signatures gained an explicit request-context and
params argument, and handlers must return typed ListToolsResult /
CallToolResult instead of a bare content list. It also dropped the
in-memory test helper and renamed several fields
(isError -> is_error, inputSchema -> input_schema, and JSONRPCMessage
became a raw Union type).

Change the server to version-branch on whether the decorator API exists:
- mcp 1.x: unchanged decorator path.
- mcp 2.x: constructor-callback handlers with jsonschema argument
  validation and filtered exception results, mirroring the 1.x
  call_tool contract; HTTP request info is still extracted from the
  per-request context (now passed explicitly).
- Relax the dependency cap to mcp>=1.12,<3 and add a tests/_mcp_compat
  shim so the full suite runs under both major versions. The SSE
  transport now parses version-agnostically via a TypeAdapter.

The full unit suite passes under both mcp 1.12.1 and mcp 2.1.1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant