Skip to content

Update python-mcp-client sample code for MCP SDK 2.x - #825

Open
lpozo wants to merge 1 commit into
masterfrom
update-mcp-client-sdk-v2
Open

Update python-mcp-client sample code for MCP SDK 2.x#825
lpozo wants to merge 1 commit into
masterfrom
update-mcp-client-sdk-v2

Conversation

@lpozo

@lpozo lpozo commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

The MCP Python SDK released 2.0 on 2026-07-28 (2.2.0 is current), renaming FastMCP to MCPServer and moving mcp.server.fastmcp.* to mcp.server.mcpserver.*. This folder's pyproject.toml allowed mcp>=1.20.0 with no upper bound, so a fresh uv sync today resolves to 2.x and the sample server dies on its first import with ModuleNotFoundError: 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, sh isn't on PATH and /dev/null doesn't exist, so stdio_client() can't spawn the subprocess and the app dumps a stacktrace. Running sys.executable directly and passing the SDK's own errlog parameter behaves the same on Windows, macOS, and Linux.

What changed

  • mcp_server/mcp_server.py: FastMCPMCPServer
  • mcp_client/mcp_client.py: dropped the sh -c wrapper for sys.executable + errlog, added import os
  • pyproject.toml: mcp>=1.20.0mcp>=2.2.0,<3
  • uv.lock: regenerated
package was now
mcp 1.18.0 2.2.0
openai 2.6.0 3.11.0

Only 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() with result.content[0].text — is unchanged in 2.x, and the migration guide's client-side breaks (the removed cursor param, 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.0 against a pyproject that said >=1.20.0; and greeting_prompt() returned "Great {name} kindly." where the tutorial says "Greet". openai moves to 3.11.0 in the regenerated lock — I checked handlers.py's OpenAI() 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 --members lists the server's tool, prompt, and resource correctly on mcp 2.2.0, and call_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, and dircheck.py locally 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 FastMCP is that tutorial's subject — out of scope here, still needs its own fix.

🤖 Generated with Claude Code

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

1 participant