The first thing to understand about building a Model Context Protocol server is that the question "FastMCP or the official SDK?" is malformed. It assumes two options. There are at least three, and two of them are both called FastMCP.

This is not a riddle. It is the single most reliable way to lose an afternoon.

The two FastMCPs

In 2024, a high-level Python framework called FastMCP — built by Jeremiah Lowin of Prefect — was good enough that it got absorbed into the official MCP Python SDK. That version, FastMCP 1.0, still lives there today. You reach it with:

from mcp.server.fastmcp import FastMCP

It is frozen at the feature set that was merged. It is not getting new capabilities, because the standalone project moved on. After the merge, Lowin kept building — FastMCP 2.0, and now the v3 line — as a separate package you install and import differently:

from fastmcp import FastMCP

Same class name. Same conceptual ancestor. Different code. Occasionally different behavior — there's a standing issue on the official SDK tracker that exists for exactly this reason: people import one, read docs for the other, and watch their server misbehave in ways the documentation swears are impossible.

The name collision is the bug. Decide which FastMCP you mean before you write a line, and never let both into the same project.

So when someone says "use FastMCP," ask which one. The frozen copy inside the SDK is zero extra dependencies and perfectly fine for a straightforward tools-and-resources server. The standalone package is where the ambitious features live.

What you're actually choosing between

Strip away the naming and there are three real postures.

The official MCP SDK for Python — a low-level Server API plus the bundled, frozen FastMCP 1.0 decorators

The official Python SDK is two frameworks in one box. The low-level Server gives you manual handler registration — @server.list_tools(), @server.call_tool(), response objects you construct yourself. You'd choose it when you need full control of the protocol lifecycle: custom initialization, unusual capability negotiation, anything where the ergonomic layer would be in your way. The bundled FastMCP 1.0 is the ergonomic layer — @mcp.tool(), @mcp.resource(), @mcp.prompt() — and for a large fraction of servers it is all you need, with nothing else to install.

The standalone, actively maintained FastMCP (v3) — adds an MCP client, server composition, proxying, OpenAPI/FastAPI generation, auth, deployment and testing
★ 25.7kPythonjlowin/fastmcp

The standalone FastMCP is what you reach for when "define some tools" isn't the whole job. It ships an MCP client, so you can call other servers programmatically (including an in-memory transport that makes testing your own server trivial). It does composition and mounting — stitch several servers into one. It does proxying — wrap an existing server to modify it or bridge transports. It generates a server from an OpenAPI spec or a FastAPI app, which is the fastest way to put an MCP face on an API you already run. Plus auth, deployment, and testing helpers. None of that is in the frozen 1.0. If you want those batteries, the separate package is the answer, and its momentum is real — it has grown to power a large share of MCP servers in the wild.

The official MCP SDK for TypeScript/JavaScript — high-level McpServer, Zod-typed tools, stdio and Streamable HTTP transports

If you're in TypeScript, the whole fork problem evaporates: there's one official SDK and no frozen-versus-evolving split. Instantiate McpServer, register tools with a Zod input schema and an async handler, and pick a transport.

The transport you'll actually use

Whichever stack you choose, you ship over one of two transports. stdio is for local servers a client launches as a subprocess — the default for desktop tools and editors. Streamable HTTP is for remote servers reached over the network; it replaced the older HTTP+SSE transport, which was deprecated in the 2025-03-26 spec revision. If a tutorial has you wiring up a standalone /sse endpoint, it predates the change — build new remote servers on Streamable HTTP instead.

How to choose, in one breath

Building in TypeScript? Use the official SDK's McpServer and stop reading. Building in Python and your server is "expose these tools and resources"? The frozen FastMCP 1.0 inside the official SDK is the smallest correct answer. Need fine protocol control? Drop to the official low-level Server. Need a client, composition, proxying, or to generate a server from an API you already have? Install the standalone fastmcp and import it deliberately — and make sure nothing in your project also imports the one from inside the SDK.

The decision was never about which name has more GitHub stars. It's about how much of the work you want the framework to do, and about refusing to let two libraries with the same class name share a codebase. Get that straight first; everything after it is just writing tools.

For where MCP fits against the alternative of baking tools straight into the model call, see MCP vs function calling; for how MCP compares to agent-to-agent protocols, A2A vs MCP.