cd /news/developer-tools/mcp-python-sdk-v2-migrate-fastmcp-to… · home topics developer-tools article
[ARTICLE · art-85904] src=byteiota.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

MCP Python SDK v2: Migrate FastMCP to MCPServer Now

The MCP Python SDK v2, released stable on July 27, removes the FastMCP class, renaming it to MCPServer, and introduces breaking changes including snake_case field names and context injection. The official migration guide from the Model Context Protocol team details the changes, and most migrations take five minutes. Teams unable to migrate immediately can pin to mcp>=1.28.1,<2, as IBM's mcp-context-forge team did, while v1.x continues to receive critical fixes.

read3 min views2 publishedAug 4, 2026
MCP Python SDK v2: Migrate FastMCP to MCPServer Now
Image: Byteiota (auto-discovered)

MCP Python SDK v2 shipped stable on July 27. If you have a Python MCP server — including one built last week following a tutorial — you have breaking changes waiting. FastMCP

is gone, import paths moved, and every field flipped to snake_case. The good news: most migrations take five minutes. Here’s exactly what to change.

The Rename That Breaks Everything First #

The most immediate change is the class rename: FastMCP

is now MCPServer

. There is no deprecation shim. There is no backward-compatible alias. The old import path simply does not exist in v2. The official migration guide covers the full list — but the rename is the one that breaks your server at startup, before anything else runs.

from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-server")
python
from mcp.server.mcpserver import MCPServer, Context
mcp = MCPServer("my-server")

Everything under mcp.server.fastmcp.*

moved to mcp.server.mcpserver.*

. The ctx.fastmcp

property is now ctx.mcp_server

. One more detail worth catching: the default server name string changes from "FastMCP"

to "mcp-server"

— pass an explicit name if you rely on serverInfo.name

in your client.

snake_case Is Now Everywhere #

All Pydantic model fields switched from camelCase to snake_case for Python access. The JSON wire format is unchanged — but the Python attributes are not. This one hides well: your server may start fine and only fail at runtime when code reads a tool or resource field.

tool.inputSchema

tool.input_schema

result.isError

result.is_error

listing.nextCursor

listing.next_cursor

content.mimeType

content.mime_type

If you serialize models for wire format, pass by_alias=True

: tool.model_dump(by_alias=True, mode="json")

still produces the camelCase JSON that clients expect.

Context Injection Replaces get_context() #

Handler context is now injected as an explicit parameter. mcp.get_context()

is removed. The fix is a one-line signature change — but it’s pervasive if your tools use progress reporting or logging:

@mcp.tool()
async def search(query: str) -> str:
    ctx = mcp.get_context()
    await ctx.report_progress(0, 100)
    return f"Results for: {query}"
php
@mcp.tool()
async def search(query: str, ctx: Context) -> str:
    await ctx.report_progress(0, 100)
    return f"Results for: {query}"

The @mcp.tool()

decorator stays. Only the context acquisition changes.

Transport Parameters Move to run() #

Constructor-level transport arguments no longer exist. Move them to the run()

call:

mcp = FastMCP("Demo", json_response=True, stateless_http=True)
mcp.run(transport="streamable-http")

mcp = MCPServer("Demo")
mcp.run(transport="streamable-http", json_response=True, stateless_http=True)

Not Ready Yet? Pin Your Version #

If your team cannot migrate immediately, pin before an unpinned install auto-upgrades:

mcp>=1.28.1,<2

This is exactly what IBM’s mcp-context-forge team did. SDK v1.x continues to receive critical bug fixes and security patches. The deprecated features — sampling, roots, logging — have a one-year grace period, and a v2 server falls back to legacy behavior for older clients. Pinning is not a cop-out; it’s responsible dependency management while your team plans the migration.

Why FastMCP Had to Go #

The rename reflects a deeper protocol shift. The MCP 2026-07-28 specification eliminates the initialize

handshake and session IDs entirely — any server instance can handle any request. Round-robin load balancers work without sticky sessions. Serverless deployments become straightforward. “FastMCP” made sense as a high-level layer on top of session-based MCP. Once sessions disappear from the protocol, all MCP servers are stateless by design — the name stops meaning anything, and MCPServer

is simply what it is.

Migration Checklist #

  • Update package: pip install "mcp>=2.0"

  • Replace all FastMCP

imports →MCPServer

frommcp.server.mcpserver

  • Update any mcp.server.fastmcp.*

submodule paths - Replace ctx = mcp.get_context()

withctx: Context

parameter in handler signatures - Search codebase for inputSchema

,isError

,nextCursor

,mimeType

— rename each - Move constructor transport params to run()

  • If using HTTP transport directly: swap httpx

forhttpx2

If you built a v1 server from our MCP Server in Python guide, the structure still holds — apply these changes on top. For anything beyond the mechanical renames, the full v2 changelog covers the low-level server API, union type adapter changes, and the new multi-round-trip request pattern.

── more in #developer-tools 4 stories · sorted by recency
── more on @mcp python sdk 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/mcp-python-sdk-v2-mi…] indexed:0 read:3min 2026-08-04 ·