MCP Directory

FastMCP vs MCP SDK: Which to Build On

FastMCP hides the protocol; the low-level SDK hands it to you — here's exactly when each is the right call.

Hua·June 30, 2026·5 min read
Detailed macro view of a circuit board showcasing microchips and electronic components.
Photo by Pixabay on Pexels

Building an MCP server in Python? Use FastMCP — it turns a decorated function into a working server in about ten lines, and the official SDK's FastMCP class is literally FastMCP v1 vendored in. The choice of FastMCP vs MCP SDK is really a choice about how much of the protocol you want to touch: FastMCP hides it, the lower-level SDK hands it to you. This guide is for people deciding what to build on, not what the acronyms mean.

Short version: default to FastMCP for anything server-shaped, and drop to the raw SDK primitives only when you're writing a client, embedding a server inside another app, or doing something the decorators don't cover.

FastMCP vs the MCP SDK: what's actually different

FastMCP is a Pythonic framework on top of the Model Context Protocol; the MCP SDK is the reference implementation that gives you the protocol's building blocks directly. The confusing part is that they overlap. The official mcp package includes a FastMCP class — it's FastMCP v1, donated upstream by the same author. The standalone fastmcp package (v2) is that idea taken further: auth, server composition, a testing client, deployment helpers.

So there are three things people mean by "the SDK," and they matter:

  • from mcp.server.fastmcp import FastMCP — the vendored v1 inside the official SDK. Decorator-based, batteries-lighter.
  • from fastmcp import FastMCP — the standalone v2 package. Same ergonomics, far more surface area.
  • The low-level mcp.server.Server — raw handlers, no decoration magic. This is "the SDK" when engineers say it's "closer to the metal."

If someone says "just use the SDK," ask which of these they mean. Most of the time the honest answer is "use FastMCP and stop overthinking it." For the conceptual background, see what an MCP server is.

When FastMCP is the right call

Reach for FastMCP whenever you're exposing tools, resources, or prompts and you'd rather write business logic than protocol plumbing. It handles the JSON-RPC framing, generates input schemas from your type hints, and wires up stdio or HTTP transport with one argument.

A minimal server is genuinely this small:

from fastmcp import FastMCP

mcp = FastMCP("weather")

@mcp.tool()
def get_forecast(city: str) -> str:
    """Return today's forecast for a city."""
    return fetch(city)

if __name__ == "__main__":
    mcp.run()  # stdio by default; mcp.run(transport="http") to go remote

That default matters. About 90% of the servers we track run locally over stdio, and mcp.run() gives you exactly that with no config. The Python-heavy corner of the ecosystem leans on this: BlenderMCP, Vizro-MCP, and codemcp are all Python, all stdio — the shape FastMCP is built for. If your server is a wrapper over an SDK you already have in Python, FastMCP is almost always the shorter path.

The v2 package adds the parts you feel later: bearer/OAuth auth, mounting sub-servers under one process, and an in-memory test client so your tests don't spawn subprocesses. Those aren't in the vendored v1, which is the main reason to install fastmcp over mcp alone.

When to drop to the lower-level SDK

Use the raw SDK primitives when you're building a client, embedding a server inside a larger application's own event loop, or when a decorator can't express what you need. FastMCP is a server-authoring tool first; the full SDK is the whole protocol, both ends.

Concrete cases where the low-level API earns its verbosity:

  • You're writing the client, not the server — an agent or app that consumes MCP servers. FastMCP's client helps, but connection lifecycle, sampling, and roots live in the base SDK.
  • Fine-grained control over capabilities and lifespan — custom initialization, resource cleanup, or advertising capabilities FastMCP doesn't wrap yet.
  • You're not in Python. FastMCP is Python (and now a TypeScript port). The MCP Language Server is written in Go against the Go SDK — a reminder that "MCP SDK" isn't one language, and if your host app is Go, Rust, or C#, FastMCP isn't on the table.

The trade is real: the low-level server means writing list_tools / call_tool handlers and your own JSON schemas by hand. You get precision and you pay in lines. For most servers that precision buys nothing.

Side-by-side

The short answer in one view: FastMCP v2 wins on features, the vendored v1 wins on zero dependencies, and the low-level server wins only on control. Here's how they line up.

FastMCP (v2, fastmcp)FastMCP in official SDK (v1)Low-level mcp.server.Server
StyleDecoratorsDecoratorsExplicit handlers
Tool schemaAuto from type hintsAuto from type hintsYou write it
Auth (OAuth/bearer)Built inNot includedDIY
Server compositionYes (mount sub-servers)NoManual
Test clientIn-memoryNoNo
Client-buildingHelper includedLimitedFull protocol
Best forMost serversQuick servers, no extra depClients, deep control, embedding

Rule of thumb: v1 if you want zero extra dependencies and a simple tool server; v2 if you want auth, composition, or tests; low-level only when you've hit a wall. Very few projects hit that wall.

What this doesn't change: the tool budget

Neither framework saves you from the client-side limit, so design tools like they're scarce. Cursor and similar clients degrade past roughly a 40-tool budget across all connected servers, and that ceiling is unrelated to how you built any single server.

FastMCP makes it easy to expose thirty tools, which is exactly the trap. A user who installs your server plus four others is near the ceiling before yours even loads. Ship fewer, sharper tools; fold read variants into one parameterized tool. This is an authoring decision the framework won't make for you — the math is in Cursor's tool limit, and Capabilities shows how real servers spend their budget.

If you're weighing MCP against just calling an API directly, that's a separate decision covered in MCP vs API. And once you've built something, the best MCP servers is a useful bar for what "good" looks like in the wild.

FAQ

Is FastMCP part of the official MCP SDK?

Yes and no. FastMCP 1.0 was donated to the official MCP Python SDK and ships as `mcp.server.fastmcp.FastMCP`. The standalone `fastmcp` package is v2 — the same decorator style plus auth, server composition, and a testing client that the vendored v1 doesn't include.

Is FastMCP free to use?

Yes. FastMCP is open source (Apache-2.0) and free, as is the official MCP SDK. There's no paid tier required to build or run a server; your only costs are wherever you host it if you go remote.

FastMCP vs MCP SDK — which is faster to build with?

FastMCP, clearly. A working tool server is about ten lines because decorators generate the JSON-RPC framing and input schemas from your type hints. The low-level SDK makes you write `list_tools`/`call_tool` handlers and schemas by hand, which only pays off for clients or deep protocol control.

Do I need FastMCP if I'm not using Python?

No — and you usually can't. FastMCP is Python-first (with a TypeScript port). For Go, Rust, or C# you use that language's MCP SDK directly; the Go-based MCP Language Server is one example. The protocol is the same across languages, only the framework ergonomics differ.

When should I use the low-level MCP SDK instead of FastMCP?

Use the low-level SDK when you're building a client (an agent that consumes servers), embedding a server in another app's event loop, or need capabilities the decorators don't wrap yet. For a standard tool server, FastMCP is the better default.

Put this into practice

Browse MCP servers by capability, or check your own setup's tool budget and security.

More essays