Skip to content

Upgrade a Python server from SDK 1.x (FastMCP) to 2.x (MCPServer)

Spec
2025-11-25 → 2026-07-28
Evidence
E2Reproducedarm64
Python SDK
mcp@2.3.0
Verified

Most Python MCP tutorials were written for SDK 1.x and start with from mcp.server.fastmcp import FastMCP. If your project does not pin the version, a fresh install now gets 2.x and that line fails.

We ran the same 1.x server with mcp==1.30.0 and mcp==2.3.0 and fixed it step by step. The errors below are what we saw.

On 2.3.0, the v1 import fails immediately:

ModuleNotFoundError: No module named 'mcp.server.fastmcp'. This is mcp 2.x, where FastMCP was renamed
to MCPServer (from mcp.server.mcpserver import MCPServer) and other APIs changed; see the migration guide
at https://py.sdk.modelcontextprotocol.io/v2/migration/#fastmcp-renamed-to-mcpserver or pin 'mcp<2'
to keep running v1 code.

If you just need the old code to run, pin the old line: mcp<2 in your requirements. Otherwise rename:

1.x
from mcp.server.fastmcp import FastMCP, Context
mcp = FastMCP("demo")
# 2.x
from mcp.server.mcpserver import MCPServer, Context
mcp = MCPServer("demo")

In 1.x, transport settings went to the constructor:

mcp = FastMCP("demo", host="127.0.0.1", port=8000, stateless_http=True, json_response=True)
mcp.run(transport="streamable-http")

With only the import renamed, 2.3.0 stops with:

TypeError: MCPServer.__init__() got an unexpected keyword argument 'host'

Move them to run():

mcp = MCPServer("demo")
mcp.run(transport="streamable-http", host="127.0.0.1", port=8000, stateless_http=True, json_response=True)

Code that sets them afterwards fails too: mcp.settings.port = 8000 raised ValueError: "Settings" object has no field "port". According to the migration guide, the SDK also no longer reads MCP_* environment variables or .env files, so read those yourself and pass the values in.

After these two steps our server ran on 2.3.0 and answered both a 2025-11-25 initialize and a 2026-07-28 request.

What 1.x 2.x (what we saw)
Default server name FastMCP mcp-server
Reported version when you set none The mcp package version (1.30.0) An empty string
await ctx.info(...) Works Works, with MCPDeprecationWarning: The logging capability is deprecated as of 2026-07-28 (SEP-2577).

Set name and version explicitly, and move log output to Python’s logging module writing to stderr. Logging over MCP is deprecated in the 2026-07-28 spec.

We did not test each of these; they come from the official migration guide. Check the ones your code touches:

  • ctx.fastmcp is now ctx.mcp_server. FastMCPError is now MCPServerError.
  • McpError is now MCPError, imported from mcp.
  • MCPServer.get_context() is gone; declare a ctx: Context parameter on the tool instead.
  • mount_path is gone. Mount the app with Starlette’s Mount (see the HTTP guide).
  • A mounted Streamable HTTP app needs mcp.session_manager.run() in the outer app’s lifespan.
  • Attributes on result and type objects are snake_case: structured_content, is_error, input_schema.
  • Synchronous def tools now run in a worker thread. Use async def if the tool needs the event loop.
  • A missing resource returns -32602 with the URI in the error data.
  • The low-level Server API changed from decorators to constructor arguments such as on_call_tool.

Sources

MCPDev is community documentation. It is not affiliated with the Model Context Protocol project or with the vendors of the clients it covers.