Repository navigation
fix(deps): require mcp 2.x (FastMCP renamed to MCPServer) - #1371
dependabot[bot] wants to merge 3 commits into
Conversation
4161266 to
a168209
Compare
Updates the requirements on [mcp](https://github.com/modelcontextprotocol/python-sdk) to permit the latest version. - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](modelcontextprotocol/python-sdk@v1.13.0...v2.2.0) --- updated-dependencies: - dependency-name: mcp dependency-version: 2.2.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
a168209 to
293d81c
Compare
mcp 2.0 moved mcp.server.fastmcp.FastMCP to mcp.server.mcpserver.MCPServer, so widening the requirement to <3 broke 'deadline mcp-server' on import. Import MCPServer and fall back to FastMCP so both 1.x and 2.x work. The in-process call_tool() now returns a CallToolResult instead of a list of content blocks, and Tool.inputSchema is now input_schema; update the integration tests to handle both shapes. Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
Require mcp >= 2.0 instead of supporting both majors, so the server imports MCPServer directly and the integration tests use the 2.x result types (CallToolResult, Tool.input_schema) without compatibility shims. mcp 2.x requires Python 3.10+, so the mcp extra is now gated on python_version >= '3.10'. The CLI's missing-dependency error now also covers a stale mcp 1.x install and suggests upgrading. Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
| "Error: MCP dependencies not installed.\n" | ||
| "Please install them with: pip install 'deadline[mcp]'", | ||
| "Error: MCP dependencies are not installed or are out of date (mcp 2.x is required).\n" | ||
| "Please install them with: pip install --upgrade 'deadline[mcp]'", |
There was a problem hiding this comment.
On Python 3.9 this error message is a dead end. The mcp extra is now mcp >= 2.0, < 3; python_version >= '3.10', so on a 3.9 interpreter the extra resolves to zero packages and pip install --upgrade 'deadline[mcp]' exits 0 having installed nothing. The user then re-runs deadline mcp-server, gets this same message, and loops forever with no hint about the real cause.
Previously the failure was loud: mcp >= 1.13.0, < 2 has requires-python >= 3.10, so pip errored out at install time on 3.9. The marker converts that hard failure into a silent no-op, which makes the runtime message the only signal the user gets — and it currently points at a fix that cannot work.
Suggest naming the interpreter requirement here, e.g.:
"Error: MCP dependencies are not installed or are out of date (mcp 2.x, which requires Python 3.10+, is required).\n"
"Please install them with: pip install --upgrade 'deadline[mcp]'\n"
f"(detected Python {sys.version_info.major}.{sys.version_info.minor})"The docstring at line 27-28 has the same gap.
| """ | ||
|
|
||
| app = FastMCP("deadline-cloud", instructions=INSTRUCTIONS) | ||
| app = MCPServer("deadline-cloud", instructions=INSTRUCTIONS) |
There was a problem hiding this comment.
This module still has zero unit-test coverage, which is the reason the original FastMCP breakage reached users rather than CI.
test/unit/deadline_mcp/test_mcp.py exercises register_api_tools against a MagicMock() app, so it passes against any SDK whatsoever — a MagicMock happily accepts .tool(name=..., description=...). Nothing under test/unit/ imports deadline._mcp.server, so the only thing that actually constructs a real server object and calls list_tools() is test/integ/, which needs live AWS credentials and does not run on PRs. That is exactly how mcp.server.fastmcp going away produced a broken deadline mcp-server with green CI.
Pinning mcp >= 2.0 closes today's hole but not the class of bug: the next rename (or a Tool field change like inputSchema -> input_schema) lands the same way. A credential-free unit test in test/unit/deadline_mcp/test_mcp.py would catch it, since it only needs the in-process server:
@pytest.mark.asyncio
async def test_server_registers_tools_on_real_sdk():
from deadline._mcp import server
tools = await server.app.list_tools()
names = {t.name for t in tools}
assert {f"deadline_{n}" for n in TOOL_REGISTRY} <= names
assert next(t for t in tools if t.name == "deadline_list_queues").input_schemaThis imports the real MCPServer, registers every tool through the real ToolManager, and reads the same Tool fields the integ tests read — no boto3 call, since nothing invokes a tool. It skips cleanly on 3.9 under the existing importorskip("mcp"), and pytest-asyncio is already a test dependency.
| ] | ||
| mcp = [ | ||
| "mcp >= 1.13.0, < 2", | ||
| "mcp >= 2.0, < 3; python_version >= '3.10'", |
There was a problem hiding this comment.
Putting the python_version >= '3.10' marker on an extra turns a loud install failure into a silent no-op on Python 3.9.
Environment markers in an extra filter the requirement rather than rejecting the install. On a 3.9 interpreter this list evaluates to empty, so pip install 'deadline[mcp]' succeeds, exits 0, installs no mcp, and prints nothing — the user has no signal that the extra they asked for was dropped. They only find out later at deadline mcp-server runtime, via the ImportError branch in mcp_server_command.py, which currently tells them to re-run the same install that just no-opped.
Without the marker, the outcome is better: mcp 2.x declares requires-python >= 3.10, so pip fails the resolve on 3.9 with an explicit "requires a different Python" message naming the package and version. That is the diagnostic the user needs, at the moment they can act on it.
Note this is unlike the click markers above at lines 40-41, which are a genuine either/or — both arms are non-empty, so every interpreter still gets a click. Here the 3.9 arm is absent entirely, so the marker only suppresses the error.
Two options, either is fine, but the tradeoff is worth making deliberately:
- Drop the marker and let pip's
requires-pythoncheck fail loudly (extras are opt-in, so this cannot break a plainpip install deadlineon 3.9). - Keep the marker for resolver convenience, but then the runtime message in
mcp_server_command.pymust name the Python 3.10+ requirement, since it becomes the only place the user ever learns about it.
There was a problem hiding this comment.
The silent failure on 3.9 sounds like it'd create a pretty confusing customer experience. Worth addressing?
Updates the requirements on mcp to permit the latest version.
Release notes
Sourced from mcp's releases.
... (truncated)
Commits
9972c21Replace RootModel wrappers with type aliases and TypeAdapter validation (#3470)fd66270docs: refresh translations, and translate pages in parallel (#3458)08a3bc8docs: ask for AI disclosure on comments too (#3459)7bb486adocs: stop presenting the in-memory client as the way to connect (#3443)0c91368Add AuthSettings.validate_token_resource to check a bearer token's resource (...9771e6bKeep following a relative redirect when the endpoint URL carries userinfo (#3...a925e55Bump the locked versions of eight dev and test dependencies (#3449)e8b9486Bump pymdown-extensions from 11.0 to 11.0.1 (#3285)c6762e8Follow redirects only within the MCP endpoint's origin (#3397)5fd3abcSkip automatic docs previews for fork PRs and drop the setup-uv retry steps (...