Skip to main content
If your server starts with from mcp.server.fastmcp import FastMCP, you’re using FastMCP 1.0 — the version bundled with v1 of the mcp package. Upgrading to the standalone FastMCP framework is easy. For most servers, it’s a single import change.
That’s it. Your @mcp.tool, @mcp.resource, and @mcp.prompt decorators, your mcp.run() call, and the rest of your server code all work as-is.
Why upgrade? FastMCP 1.0 pioneered the Pythonic MCP server experience, and we’re proud it was bundled into the mcp package. The standalone FastMCP project has since grown into a full framework for taking MCP servers from prototype to production — with composition, middleware, proxy servers, authentication, and much more. Upgrading gives you access to all of that, plus ongoing updates and fixes.

The SDK v2 Transition

MCP SDK v2 is a substantial, deliberate modernization of the protocol layer, and part of that work rebuilt the high-level server as MCPServer under mcp.server.mcpserver. mcp.server.fastmcp does not exist there — so a FastMCP 1.0 server meets the change the moment its environment resolves mcp to v2:
Often nobody chose that moment. An unpinned mcp dependency, a fresh lockfile, or a rebuilt container picks up the new major version and the module your server imports on line one has moved. Nothing is wrong with your code, and nothing is wrong with the SDK — major versions are exactly where a change like this belongs. Your build just crossed it earlier than you planned to. Pinning the SDK back restores the old module immediately, with no code changes, and buys you time to choose deliberately:

Two Upgrade Paths

From here, both directions are reasonable, and which is less work depends on which API you already write. MCPServer, the SDK’s high-level server, is a capable, well-designed API and the direct continuation of the SDK’s own line. Because it was rebuilt rather than renamed, expect real work: a new class and import, a different decorator call style, and protocol types imported from the standalone mcp_types package with snake_case field names. FastMCP is the import change at the top of this page. It is short for a specific, historical reason: FastMCP 1.0 is early FastMCP — it was contributed into the mcp package, and the standalone project kept developing that same high-level API. The surface you already write against is the surface FastMCP still offers. FastMCP 4 is itself built on MCP SDK v2, so both paths land you on the same modern protocol layer; FastMCP absorbs the adaptation internally rather than asking your code to do it. The claim is narrower than it may sound. It holds for FastMCP 1.0 servers specifically, because of shared lineage — not because one library is better than the other. Both projects are moving the same direction on the same protocol. If you have already moved to SDK v2 and write against MCPServer today, see Upgrading from MCP SDK v2. If your server uses the low-level Server class rather than the high-level one, see Upgrading from the Low-Level SDK v1.

Install

FastMCP 4 is in prerelease, so pin the exact version rather than installing unqualified — a bare pip install fastmcp or uv add fastmcp resolves to the latest stable release, which today is FastMCP 3:
An exact version pin installs even though it’s a prerelease — neither installer needs --pre or --prerelease allow for a version this specific, only for an open-ended range. For a reproducible lockfile that also pins the prerelease protocol dependencies, see Install the v4 Prerelease. FastMCP depends on the mcp package, so the SDK stays installed and importable. What changes is which parts of it you reach for. FastMCP 4 builds on SDK v2, where mcp.server.fastmcp is gone — anything you imported from it needs a new home, and the sections below cover that. mcp.types still resolves (it aliases the standalone mcp_types package), though its fields are snake_case now. Update your import, run your server, and if your tools work, you’re done.

Copy this prompt into any LLM along with your server code to get automated upgrade guidance.

What Might Need Updating

Most servers need nothing beyond the import change. Skim the sections below to see if any apply.

Constructor Settings

If you passed transport settings like host or port directly to FastMCP(), those now belong on run(). This keeps your server definition independent of how it’s deployed:
Nine arguments move this way, and each raises a TypeError naming its own replacement, so you can also just run the server and follow the errors: host, port, log_level, debug, sse_path, message_path, streamable_http_path, json_response, and stateless_http. A second group is rejected with only a generic “unexpected keyword argument” and no hint, which makes these the ones worth reading in advance: Dropping event_store= rather than moving it is the one to watch: it silently disables streamable-HTTP resumability, so a client that reconnects loses the events it missed instead of replaying them. name, instructions, website_url, icons, tools, and lifespan carry over to the constructor unchanged.

Authentication

This is the one case where the import change alone won’t do. FastMCP 1.0 exposed the SDK’s auth plumbing as three separate constructor arguments — token_verifier=, auth_server_provider=, and auth=AuthSettings(...). The first two raise TypeError on FastMCP 4, and while auth= survives as a keyword, its value doesn’t: FastMCP expects one of its own AuthProvider objects rather than the SDK’s settings object. The replacement is a single provider carrying the whole configuration, chosen by what you’re actually doing:
See Authentication for the full set and their configuration.

Context Methods

from fastmcp import Context gets you the injected context object, but four of its methods took a different shape in FastMCP 1.0, and a bare import swap leaves calls that compile and then fail: ctx.report_progress(), ctx.request_id, and ctx.client_id are unchanged.

Prompts

If your prompt functions return mcp.types.PromptMessage objects or raw dicts with role/content keys, upgrade them to FastMCP’s Message class. Or just return a plain string — it’s automatically wrapped as a user message. FastMCP 1.0 silently coerced dicts into messages; standalone FastMCP requires typed Message objects or strings.
Multi-turn prompts return a list of messages. Message takes the text positionally and defaults to the user role, so only the assistant turns need a role:

Other mcp.* Imports

FastMCP 4 builds on MCP SDK v2, which moved the protocol types into a standalone mcp_types package and re-exports it as mcp.types — so from mcp.types import X keeps working. The field names did change, from camelCase to snake_case (inputSchemainput_schema, mimeTypemime_type, and so on). For everything else SDK v2 changed, see Upgrading from FastMCP 3, which covers the same protocol rebuild from the FastMCP side. Where FastMCP provides its own API for the same thing, it’s worth switching over rather than importing the protocol type: For protocol types without a FastMCP equivalent, import them from mcp_types directly.

Decorated Functions

In FastMCP 1.0, @mcp.tool replaced your function with a FunctionTool object. Now decorators return your original function unchanged, so decorated functions stay callable for testing, reuse, and composition:
Code that reads .name, .description, or other component attributes off the decorated result needs updating. This is uncommon — most servers never touch the tool object. When you do need the component itself, reach it through the server with await mcp.get_tool("greet").

Verifying the Upgrade

Run your server the way you always have. To confirm every component came across, inspect the server with the FastMCP CLI:
The output lists every tool, resource, template, and prompt your server exposes, so a component that failed to register shows up here rather than at the first client call.

Looking Ahead

The MCP ecosystem is evolving fast. Part of FastMCP’s job is to absorb that complexity on your behalf — as the protocol and its tooling grow, we do the work so your server code doesn’t have to change. The SDK v1 to v2 transition is the clearest example so far: an entire protocol layer was rewritten underneath FastMCP 4, and the servers on this page cross it with one line.