Skip to content

fix(mcp): support mcp SDK v2 alongside v1 - #68

Merged
JacobCoffee merged 3 commits into
mainfrom
fix/mcp-v2-compat
Oct 11, 2026
Merged

JacobCoffee merged 3 commits into
mainfrom
fix/mcp-v2-compat

Conversation

@JacobCoffee

Copy link
Copy Markdown
Owner

What was wrong

The mcp extra declared mcp>=1.0.0 with no upper bound. mcp 2.x renamed FastMCP to MCPServer and moved it to mcp.server.mcpserver, so a fresh install that resolves mcp 2.x made the from mcp.server.fastmcp import FastMCP import fail silently, and debug_toolbar.mcp.is_available() reported the MCP integration as unusable.

Separately, mcp 2.x rejects Context injection on resources whose URI has no template variables, which our two static resources (debug://requests, debug://config) relied on to reach toolbar storage.

What changed

  • Added a v1/v2 import fallback (mcp.server.fastmcp.FastMCP/Context, falling back to mcp.server.mcpserver.MCPServer/Context) in server.py, resources.py, and tools.py, guarded with TYPE_CHECKING so the type checker still sees a concrete FastMCP type.
  • create_mcp_server now builds the shared MCPContext once and passes it directly into register_resources, instead of resources reading it off ctx.request_context.lifespan_context. This removes the need for a ctx: Context parameter on the two static resources, which is what mcp 2.x rejected.
  • Removed a get_config() reference to a non-existent DebugToolbarConfig.slow_request_threshold_ms attribute, which always raised AttributeError when that resource was read (surfaced by ty once MCPContext's type flowed through more precisely after the above refactor).
  • Raised the mcp lower bound from >=1.0.0 to >=1.21.1: every mcp release from 1.0.0 through 1.21.0 fails to import against a freshly resolved (current) pydantic, so the old floor was dishonest.
  • Added a regression test asserting the two static resource handlers take no parameters (fails on the old code, where they required ctx, because such handlers are registered as templates with 0 matched URI vars rather than as real static resources).

How verified

  • uv run pytest tests/unit/mcp/ — 50 passed, 1 skipped, against the locked mcp 1.22.0.
  • Same suite against a throwaway uv run --with 'mcp==2.3.0' env — 50 passed, 1 skipped.
  • make ci (lint, fmt, type-check, tests, docs) passes.
  • Manual end-to-end over stdio transport with a real mcp.ClientSession (spawning python -m debug_toolbar.mcp), calling list_tools/call_tool/list_resources/read_resource, against both mcp 1.22.0 and mcp 2.3.0.
  • examples/mcp_server_example.py's create_app() still builds the Litestar app; no tests/examples/ suite exists yet on main (PR test: add tests for example apps #65 not merged).

The mcp extra declared mcp>=1.0.0 with no upper bound. mcp 2.x renamed
FastMCP to MCPServer and moved it to mcp.server.mcpserver, so a fresh
install resolving mcp 2.x made the import fail silently and
is_available() report the MCP integration as unusable.

- Add a v1/v2 import fallback for FastMCP/Context in server.py,
  resources.py, and tools.py.
- mcp 2.x rejects Context injection on resources with no URI template
  variables. Pass the toolbar's MCPContext into register_resources
  directly instead of reading it off ctx.request_context.lifespan_context,
  removing the need for a ctx parameter on the two static resources
  (debug://requests, debug://config).
- Drop a get_config() reference to a non-existent
  DebugToolbarConfig.slow_request_threshold_ms attribute that always
  raised AttributeError when the resource was read; surfaced once the
  MCPContext type flowed through more precisely after the refactor above.
- Raise the mcp lower bound to the oldest version that actually imports
  cleanly against currently resolvable pydantic (1.21.1); mcp>=1.0.0
  through 1.21.0 fail to import under a fresh resolve.

Verified end-to-end over stdio with an mcp ClientSession (list_tools,
call_tool, list_resources, read_resource) against both mcp 1.22.0
(locked) and mcp 2.3.0 (throwaway uv --with env).
Copilot AI balanced review requested due to automatic review settings October 11, 2026 01:07

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI balanced review requested due to automatic review settings October 11, 2026 01:07

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@JacobCoffee
JacobCoffee enabled auto-merge (squash) October 11, 2026 01:07
@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://JacobCoffee.github.io/debug-toolbar/pr-preview/pr-68/

Built to branch gh-pages at 2026-10-11 01:20 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Copilot AI balanced review requested due to automatic review settings October 11, 2026 01:19

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@JacobCoffee
JacobCoffee merged commit 1f491ff into main Oct 11, 2026
24 checks passed
@JacobCoffee
JacobCoffee deleted the fix/mcp-v2-compat branch October 11, 2026 01:29
@JacobCoffee JacobCoffee mentioned this pull request Oct 11, 2026
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.

2 participants