Update python-mcp-client sample code for MCP SDK 2.x - #825
Open
lpozo wants to merge 1 commit into
Open
Conversation
The MCP Python SDK released 2.0 on 2026-07-28, which renamed FastMCP to MCPServer and moved mcp.server.fastmcp.* to mcp.server.mcpserver.*. The sample code's pyproject.toml allowed mcp>=1.20.0, so a fresh `uv sync` resolved to 2.x and the server failed on its first import with ModuleNotFoundError. Also fixes a Windows incompatibility that readers reported in the tutorial comments. The client wrapped the server process in a POSIX shell (`sh -c "... 2>/dev/null"`) purely to silence server stderr. On Windows, `sh` isn't on PATH and /dev/null doesn't exist, so stdio_client() failed to spawn the subprocess. Launching sys.executable directly and routing stderr through the SDK's own errlog parameter works identically on Windows, macOS, and Linux. Changes: - mcp_server.py: FastMCP -> MCPServer - mcp_client.py: drop the `sh -c` wrapper for sys.executable + errlog - pyproject.toml: pin mcp>=2.2.0,<3 - uv.lock: regenerate (mcp 1.18.0 -> 2.2.0, openai 2.6.0 -> 3.11.0) The lockfile was already out of sync before this change, pinning mcp>=1.17.0 against a pyproject that specified >=1.20.0. Verified with `uv run python -m mcp_client mcp_server/mcp_server.py --members`, which lists the server's tool, prompt, and resource correctly on mcp 2.2.0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The MCP Python SDK released 2.0 on 2026-07-28 (2.2.0 is current), renaming
FastMCPtoMCPServerand movingmcp.server.fastmcp.*tomcp.server.mcpserver.*. This folder'spyproject.tomlallowedmcp>=1.20.0with no upper bound, so a freshuv synctoday resolves to 2.x and the sample server dies on its first import withModuleNotFoundError: No module named 'mcp.server.fastmcp'.This also fixes a Windows bug that two readers reported on Build a Python MCP Client to Test Servers From Your Terminal (2025-11-24 and 2026-05-03) and that Bartosz diagnosed in the thread. The client wrapped the server process in a POSIX shell,
sh -c "{sys.executable} {server_path} 2>/dev/null", purely to silence the server's stderr. On Windows,shisn't on PATH and/dev/nulldoesn't exist, sostdio_client()can't spawn the subprocess and the app dumps a stacktrace. Runningsys.executabledirectly and passing the SDK's ownerrlogparameter behaves the same on Windows, macOS, and Linux.What changed
mcp_server/mcp_server.py:FastMCP→MCPServermcp_client/mcp_client.py: dropped thesh -cwrapper forsys.executable+errlog, addedimport ospyproject.toml:mcp>=1.20.0→mcp>=2.2.0,<3uv.lock: regeneratedOnly the server's import and constructor needed changing. Every client-side API the tutorial teaches —
ClientSession,StdioServerParameters,stdio_client(),.list_tools()/.list_prompts()/.list_resources(), and.call_tool()withresult.content[0].text— is unchanged in 2.x, and the migration guide's client-side breaks (the removedcursorparam,timedelta→ float timeouts) don't apply because this code never used either.Two incidental fixes: the lockfile was already out of sync before this change, pinning
mcp>=1.17.0against a pyproject that said>=1.20.0; andgreeting_prompt()returned"Great {name} kindly."where the tutorial says"Greet".openaimoves to 3.11.0 in the regenerated lock — I checkedhandlers.py'sOpenAI()and.chat.completions.create()usage against it and no code change was needed.Testing
uv run python -m mcp_client mcp_server/mcp_server.py --memberslists the server's tool, prompt, and resource correctly on mcp 2.2.0, andcall_tool()round-trips. The Windows path wasn't tested on a Windows machine — the fix removes the POSIX-only dependency, which is what broke.Ran
ruff format --check,ruff check, anddircheck.pylocally with ruff 0.14.1 and all pass.Related
Matches the tutorial update in CMS post 2355, a clone of 2015 that isn't published yet. Python MCP Server: Connect LLMs to Your Data has the same 2.x break with a larger blast radius, since
FastMCPis that tutorial's subject — out of scope here, still needs its own fix.🤖 Generated with Claude Code