mcp package’s Server class — writing list_tools() and call_tool() handlers, hand-crafting JSON Schema dicts, and wiring up transport boilerplate — this guide is for you. FastMCP replaces all of that machinery with a declarative, Pythonic API where your functions are the protocol surface.
The core idea: instead of telling the SDK what your tools look like and then separately implementing them, you write ordinary Python functions and let FastMCP derive the protocol layer from your code. Type hints become JSON Schema. Docstrings become descriptions. Return values are serialized automatically. The plumbing you wrote to satisfy the protocol just disappears.
This guide covers upgrading from v1 of the
mcp package. We’ll provide a separate guide when v2 ships.Already using FastMCP 1.0 via
from mcp.server.fastmcp import FastMCP? Your upgrade is simpler — see the FastMCP 1.0 upgrade guide instead.Copy this prompt into any LLM along with your server code to get automated upgrade guidance.
Install
mcp package as a transitive dependency, so you don’t lose access to anything.
Server and Transport
TheServer class requires you to choose a transport, connect streams, build initialization options, and run an event loop. FastMCP collapses all of that into a constructor and a run() call.
Server class, you’d wire up Starlette routes and SseServerTransport or StreamableHTTPSessionManager. With FastMCP:
Tools
This is where the difference is most dramatic. TheServer class requires two handlers — one to describe your tools (with hand-written JSON Schema) and another to dispatch calls by name. FastMCP eliminates both by deriving everything from your function signature.
@mcp.tool function is self-contained: its name becomes the tool name, its docstring becomes the description, its type annotations become the JSON Schema, and its return value is serialized automatically. No routing. No schema dictionaries. No content-type wrappers.
Type Mapping
When converting yourinputSchema to Python type hints:
| JSON Schema | Python Type |
|---|---|
{"type": "string"} | str |
{"type": "number"} | float |
{"type": "integer"} | int |
{"type": "boolean"} | bool |
{"type": "array", "items": {"type": "string"}} | list[str] |
{"type": "object"} | dict |
Optional property (not in required) | param: str | None = None |
Return Values
With theServer class, tools return list[types.TextContent | types.ImageContent | ...]. In FastMCP, return plain Python values — strings, numbers, dicts, lists, dataclasses, Pydantic models — and serialization is handled for you.
For images or other non-text content, FastMCP provides helpers:
Resources
TheServer class uses three handlers for resources: list_resources() to enumerate them, list_resource_templates() for URI templates, and read_resource() to serve content — all with manual routing by URI. FastMCP replaces all three with per-resource decorators.
@mcp.resource decorator — FastMCP detects {placeholders} in the URI and automatically registers a template. The function parameter user_id maps directly to the {user_id} placeholder.
Prompts
Same pattern: theServer class uses list_prompts() and get_prompt() with manual routing. FastMCP uses one decorator per prompt.
str from a prompt function automatically wraps it as a user message. For multi-turn prompts, return a list[Message]:
Request Context
TheServer class exposes request context through server.request_context, which gives you the raw ServerSession for sending notifications. FastMCP replaces this with a typed Context object injected into any function that declares it.
Context object provides logging (ctx.debug(), ctx.info(), ctx.warning(), ctx.error()), progress reporting (ctx.report_progress()), resource subscriptions, session state, and more. See Context for the full API.
Complete Example
A full server upgrade, showing how all the pieces fit together:What’s Next
Once you’ve upgraded, you have access to everything FastMCP provides beyond the basics:- Server composition — Mount sub-servers to build modular applications
- Middleware — Add logging, rate limiting, error handling, and caching
- Proxy servers — Create a proxy to any existing MCP server
- OpenAPI integration — Generate an MCP server from an OpenAPI spec
- Authentication — Built-in OAuth and token verification
- Testing — Test your server directly in Python without running a subprocess

