Large Language ModelsGenerate imagesGenerate videos

FastMCP vs MCP SDK: Which Python Framework to Use?

FastMCP and the official MCP Python SDK now share a protocol layer but not an API. This article sets the two side by side on imports, auth, composition, testing, install size and migration pain, so you can pick the right one for your next MCP server.

FastMCP vs MCP SDK: Which Python Framework to Use?
Cristian Da Conceicao
Founder of Picasso IA

You paste from mcp.server.fastmcp import FastMCP from a tutorial into a fresh project, run it, and Python answers with a ModuleNotFoundError. Nothing is wrong with your setup. The official SDK renamed that class, the standalone FastMCP project kept going on its own, and the two libraries now share a name, a protocol layer, and a lot of confused developers.

Here is the short answer. As of October 2026, the official mcp package sits at 2.3.0 and the standalone fastmcp package at 4.0.11. Pick FastMCP when you want server composition, proxying, OpenAPI import, built-in auth providers, and an in-process test client. Pick the official MCP SDK when you want the smallest dependency tree, direct control over protocol primitives, and no extra framework between your code and the spec.

💡 Quick verdict: If you are building a Model Context Protocol server that real users will hit and you are unsure, start with FastMCP. For a simple server, switching to the official SDK later is a five-minute edit. Going the other way means rebuilding features that FastMCP gave you for free.

Why Two Libraries Share One Name

How FastMCP Ended Up in the SDK

Jeremiah Lowin built FastMCP so that writing an MCP server would feel like writing an ordinary Python function. That high-level API was good enough that Anthropic's official Python SDK absorbed it in 2024 as FastMCP 1.0, living at mcp.server.fastmcp. The standalone project never stopped. It kept shipping under its own package name, reached 3.0 GA on February 18, 2026, and moved from a personal GitHub account to the PrefectHQ/fastmcp repository as Prefect adopted it as core infrastructure.

Today it is maintained by Jeremiah Lowin and Nate Nowack under the Apache-2.0 license. The project says it powers about 70% of MCP servers across all languages, a self-reported number worth taking with a grain of salt.

Developer hands typing Python code for an MCP server

What Changed in SDK v2

SDK v2 made the split official. The bundled FastMCP class is now MCPServer, and the old import path was removed outright:

# SDK v1 (bundled FastMCP, gone in v2)
from mcp.server.fastmcp import FastMCP

# SDK v2
from mcp.server import MCPServer

# Standalone FastMCP
from fastmcp import FastMCP

If you still need the old behavior, the v1 line lives in maintenance mode. Install it with uv add "mcp[cli]<2".

You are not choosing between two rival implementations of the protocol. FastMCP 4 builds on the same SDK v2 protocol layer, so the real question is how much framework you want sitting on top of it.

Side by Side: The Quick Comparison

Here is how the two stack up on the things that decide most projects:

FeatureOfficial MCP SDK 2.3.0FastMCP 4.0.11
Installuv add "mcp[cli]"uv add fastmcp
Server classMCPServerFastMCP
Importfrom mcp.server import MCPServerfrom fastmcp import FastMCP
Python version3.10+3.10+
Transportsstdio, Streamable HTTP, SSEstdio, HTTP, SSE
Decorator style@mcp.tool() only@mcp.tool or @mcp.tool()
Server compositionNot built inMount servers inside each other
Proxying other serversNot built inBuilt in
OpenAPI to toolsNot built inOpenAPIProvider
Auth setupThree separate settingsOne auth= provider (JWT, OAuth, GitHub, Google)
ObservabilityNative OpenTelemetryMiddleware hooks
Installed sizeAbout 41 MB, 36 packagesAbout 65 MB, 66 packages
Maintained byThe MCP projectPrefect

The install size figures come from a side-by-side test published on October 5, 2026, so your numbers will shift with platform and extras.

Top-down view of a desk with a notebook diagram of two branching options

Minimal Server in Both Libraries

Day-one code is nearly identical. In both libraries, type hints become JSON Schema and docstrings become tool descriptions. Here is the official SDK version:

from mcp.server import MCPServer

mcp = MCPServer("Demo")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
    """Greet someone by name."""
    return f"Hello, {name}!"

And the FastMCP version:

from fastmcp import FastMCP

mcp = FastMCP("Demo")

@mcp.tool
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
    """Greet someone by name."""
    return f"Hello, {name}!"

if __name__ == "__main__":
    mcp.run()

With the SDK's cli extra you can try the first one using mcp dev server.py. The second runs with a plain python server.py.

Small Syntax Differences That Bite

Most migration bugs come from details like these:

  • Parentheses: the SDK's MCPServer requires @mcp.tool(). A bare @mcp.tool raises a TypeError. FastMCP accepts both.
  • Transport name: the SDK calls it "streamable-http". FastMCP calls it "http".
  • Transport settings: in SDK v2, host and port moved out of the constructor and into the run() call.
  • Context properties: ctx.mcp_server in the SDK becomes ctx.fastmcp in FastMCP, and ctx.log(level, data) becomes ctx.log(message, level=...).

What the Official SDK Does Best

A Lighter Dependency Footprint

The official package is the smaller install. In the October 2026 measurements, mcp 2.3.0 brought 36 packages and about 41 MB into site-packages, while fastmcp 4.0.11 brought 66 packages and about 65 MB. That gap is the price of the extras: auth providers, OpenAPI tooling, proxying, and the client library.

Why it matters in practice:

  • Fewer packages to audit when a security team reviews every transitive dependency.
  • Smaller container images for servers that run as many small replicas.
  • Less upgrade surface when a vulnerability lands in code your server never used.

Cold import time is a weaker argument. The same measurements swung widely between runs on one machine, so do not choose a library over a few hundred milliseconds of startup.

Low-angle view down a data center aisle between server racks

Direct Control of the Protocol

The official SDK keeps a low-level Server class next to the friendly MCPServer. In v2 every handler follows one shape, async (ctx, params) -> result, with no decorators and no automatic wrapping:

from mcp.server import Server, ServerRequestContext
from mcp.types import CallToolRequestParams, CallToolResult, TextContent

async def call_tool(ctx: ServerRequestContext, params: CallToolRequestParams) -> CallToolResult:
    return CallToolResult(content=[TextContent(type="text", text="ok")])

server = Server("Bookshop", on_call_tool=call_tool)

You write the request handling yourself, which means more typing and more power. SDK v2 also adds protocol-level tools that you reach most directly here:

  • Resolve and Elicit: a tool parameter filled by a function you write, invisible to the model, which can stop and ask the user a question mid-call.
  • First-class Client: from mcp import Client negotiates the connection for you, with no nested ClientSession and manual initialization.
  • Built-in OpenTelemetry: every request is traced through middleware.
  • Response caching: cache_hints on the server and cache support in the client.
  • Dual protocol support: a single deployment can serve clients on both the 2025 and 2026 protocol revisions.

The 2026-07-28 protocol revision drops the initialize handshake and session IDs on Streamable HTTP, so a plain load balancer can spread requests across stateless replicas. Both libraries sit on the same protocol layer, but the SDK is where you configure it directly.

Macro close-up of mechanical watch gears with tweezers

What FastMCP Adds on Top

FastMCP's pitch is simple: the things you end up writing around a server anyway, already written.

Composition and Proxying

FastMCP can mount one server inside another, so a weather server and a billing server can live in separate modules and still appear as one endpoint with path prefixes. It can also proxy a third-party MCP server, which lets you wrap an existing server with your own auth. The official SDK has neither as a built-in feature.

Version 3.0 rebuilt this around providers. Tools no longer have to live in one file: a FileSystemProvider finds them in a directory and reloads them when they change.

Two developers reviewing a whiteboard of boxes and arrows

OpenAPI Import and Auth Providers

If your company already runs a REST API, OpenAPIProvider turns an OpenAPI spec or a FastAPI app into MCP tools without rewriting each endpoint by hand.

Auth gets the same treatment. FastMCP folds the SDK's three separate parameters (token_verifier, auth_server_provider, and auth=AuthSettings) into one auth= provider, with built-in support for JWT, OAuth, GitHub, and Google. Adding GitHub login becomes a configuration choice instead of a weekend project. Tools can also ask the client's LLM for help through ctx.sample().

Testing Without a Network

FastMCP's Client accepts a server object directly, so a test runs in-process with no ports, no subprocesses, and no flaky timeouts:

import asyncio
from fastmcp import Client, FastMCP

mcp = FastMCP("Demo")

@mcp.tool
def add(a: int, b: int) -> int:
    return a + b

async def main():
    async with Client(mcp) as client:
        result = await client.call_tool("add", {"a": 2, "b": 3})
        print(result.data)  # 5

asyncio.run(main())

In-process testing is one of the advantages FastMCP's own migration notes call out, and it makes a fast pytest suite easy to build.

Laptop terminal showing a row of passing test results

Where Each One Falls Short

Neither choice is free. Both come with a bill that arrives later. Teams that pick FastMCP pay in version churn and a bigger dependency count, and teams that pick the SDK pay in code they write themselves.

FastMCP Moves Fast

FastMCP went from 3.0 GA in February 2026 to 4.0.11 by October, so expect major versions to arrive quickly. Pin the range in your project file, for example fastmcp>=4,<5, and read release notes before every bump.

It also installs about 30 more packages than the SDK. Prefect sells a hosted platform, Horizon, for deployment and access control. The library itself is Apache-2.0 and runs anywhere you can run Python.

SDK v2 Breaks Old Code

If you are upgrading a v1 server, budget real time. The v2 release notes list these breaking changes:

  • The WebSocket transport (mcp[ws]) was removed.
  • The experimental Tasks API was removed and moved to an extension.
  • McpError is now MCPError, and an MCPError raised inside a tool becomes a protocol error that the model never sees.
  • The mount_path parameter is gone.
  • Sync handlers now run on a worker thread instead of the event loop.
  • On Streamable HTTP, the lifespan runs once at startup, not once per session.
  • The HTTP client moved from httpx to httpx2.

A small startup team discussing a project around a long table

Pick the Right One in Minutes

Hiker holding a paper map at a fork in a forest trail

Skip the feature hunt and match your situation to this table:

Your situationPick
Wrap an existing REST API or FastAPI appFastMCP
Combine several servers behind one endpointFastMCP
Add GitHub, Google, or OAuth loginFastMCP
Strict dependency review in a locked-down environmentOfficial SDK
Custom protocol behavior at the handler levelOfficial SDK
Weekend prototype with one toolEither

Picture a three-person team that wants an AI assistant to read its internal orders API. With an OpenAPI spec already in place, OpenAPIProvider removes most of the endpoint-by-endpoint work, and the single auth= provider handles company login. Now picture a platform team building an audited gateway that must pass strict dependency review. That team lands on the SDK and gains the lower-level handlers it needs. Neither team made a mistake. They started from different constraints.

Choose FastMCP When

  • You are shipping something users will log in to.
  • You want one auth= setting instead of three.
  • You expect to grow from one server to several.
  • You prefer the shorter @mcp.tool decorator and fast in-process tests.

Choose the Official SDK When

  • You want the fewest dependencies and the smallest image.
  • You need to handle raw requests and responses yourself.
  • Your team standardizes on the reference implementation from the MCP project.
  • You want OpenTelemetry and Resolve or Elicit support straight from the base package.

Switching Between Them Later

The two libraries share a protocol layer, so moving between them is mostly mechanical. Going from the SDK to FastMCP looks like this:

- from mcp.server import MCPServer
+ from fastmcp import FastMCP

- mcp = MCPServer("orders")
+ mcp = FastMCP("orders")

- @mcp.tool()
+ @mcp.tool

Then change "streamable-http" to "http" in your run() call, rename ctx.mcp_server to ctx.fastmcp, and merge your three auth settings into one provider. Going the other way, reverse those edits and plan to replace composition, proxying, and OpenAPI import with your own code.

Run your tests after each step. If you wrote them with an in-process client, the whole check takes seconds.

Build Your Own With Picasso IA

An MCP server is only as useful as what sits behind its tools. Picasso IA offers an MCP connector and a developer API for image generation, image editing, and video generation, so a client such as Claude Desktop can create visuals through tools you never had to build. Those jobs are asynchronous: you submit one, then poll for the result. That submit-then-poll shape is a handy pattern for your own servers too, with one tool that returns a job ID and a second tool that checks its status.

Draft Your Server on PicassoIA

You can have an LLM write the first draft of either version. Here is the quick route with Claude Sonnet 5, a model built for coding tasks:

  1. Open the Claude Sonnet 5 page on PicassoIA.
  2. Fill the required Prompt field, for example: "Write an MCP server in Python using FastMCP with two tools, one that adds numbers and one that fetches a weather summary, plus a pytest file using the in-process client."
  3. Set effort: leave it on low for quick edits, or raise it for a tricky multi-file bug.
  4. Keep max tokens at the default 8,192 for a full server file, and use system prompt to fix a coding style once.
  5. Attach an image if you have one, such as a screenshot of an error, then generate and paste the code into your project.

Ask for both versions in one request and diff them yourself. If you want a second opinion on the code, GPT 5.6 Sol is built for complex coding tasks and makes a good reviewer.

Relaxed developer closing a laptop at golden hour

Once your server runs, give it something fun to do. Open Picasso IA, try the image and video models, and see what a few well-written prompts produce. Then wire your favorite tool into your own MCP server and let your next project create its own visuals. Your first image is one prompt away.

Share this article