Jump to section
What Is FastMCP Three Pillars Advanced Server Features Interactive Apps (UI) Clients What We Could Build FastMCP vs Raw MCP

What Is FastMCP

FastMCP is the standard Python framework for building MCP servers, clients, and applications. FastMCP 1.0 was incorporated into the official MCP Python SDK in 2024. Today it powers ~70% of MCP servers across all languages and downloads 1M times per day.

The core promise: declare a Python function, and FastMCP handles everything else — schema generation, validation, protocol lifecycle, transport negotiation, auth. You write business logic; the MCP layer "just works."

1M
Downloads / Day
70%
MCP Servers (all languages)
24k
GitHub Stars
v3
Current Version
💡
The big picture: FastMCP is not just a connector library. It's a full application platform — you can build long-running agents, interactive dashboards, authenticated APIs, and distributed task schedulers, all surfaced through the MCP protocol.
🏛

The Three Pillars

Servers
Expose tools, resources, and prompts to LLMs. This is where you build — from simple wrappers to authenticated, middleware-equipped, background-task-capable services.

Core primitives: @mcp.tool, @mcp.resource, @mcp.prompt
Apps NEW v3
Give tools interactive UIs rendered directly in the conversation. Not just text — charts, tables, forms, dashboards, real-time data. Built in pure Python, no frontend skills required.

Return a PrefabApp and the host renders it.
Clients
Connect to any MCP server — local or remote, with full transport support (SSE, stdio, HTTP). Programmatic or CLI. Handles auth, protocol lifecycle, and callbacks automatically.
⚙️

Advanced Server Features

The stuff most MCPs don't do

Most MCP connectors are thin wrappers around an API. FastMCP goes far further — here are the features that turn a connector into a production service.

🕐 Background Tasks NEW v2.14

Long-running operations shouldn't block the conversation. FastMCP implements the MCP background task protocol (SEP-1686) — add task=True to any tool and it becomes async-capable.

How it works
Client starts an operation → gets a task ID immediately → polls for progress → retrieves result when ready. Powered by Docket (Prefect's distributed task scheduler, open-sourced).
Production capabilities
Redis backend for persistence + horizontal scaling. Multiple workers pulling from the same queue. Task progress reporting to clients in real time. Handles millions of concurrent tasks.
@mcp.tool(task=True)
async def process_large_report(files: list[str], progress: Progress = Progress()) -> str:
    """Generate report from 50+ files — runs in background."""
    await progress.set_total(len(files))
    for file in files:
        await progress.set_message(f"Processing {file}")
        # ... do work ...
        await progress.increment()
    return "Done"

# Scale horizontally with additional workers
# fastmcp tasks worker server.py
BackendUse ForPickup LatencyScaling
In-MemoryDev / single-process~250msSingle process only
RedisProductionSingle-digit msHorizontal — add workers

🔀 Middleware

Intercept, modify, or block every request and response flowing through your server. Add rate limiting, custom logging, input sanitisation, or request transformation — all in one place.

@mcp.middleware
async def audit_logger(request, call_next):
    # Log every tool call with metadata
    logger.info(f"Tool call: {request.tool} | User: {request.context.user_id}")
    response = await call_next(request)
    logger.info(f"Tool result: {response.status}")
    return response

💬 Elicitation

Your server can ask the user a question mid-execution — structured forms, confirmation dialogs, approvals. The conversation pauses, the user responds, your tool continues. Think "human in the loop" workflows.

@mcp.tool
async def delete_campaign(campaign_id: str, ctx: Context):
    """Delete a campaign after confirmation."""
    result = await ctx.elicit(
        message=f"Delete campaign {campaign_id}? This can't be undone.",
        response_type=ConfirmOrDeny,
    )
    if result.action == "confirm":
        db.delete(campaign_id)
        return "Deleted."

🧠 Sampling (Server → LLM)

A FastMCP server can make its own LLM calls back to the host model. This enables agentic tools that reason, classify, summarise, or chain LLM calls — entirely server-side, no separate API keys needed.

@mcp.tool
async def classify_ticket(ticket_text: str, ctx: Context) -> str:
    result = await ctx.sample(f"Classify this support ticket: {ticket_text}")
    return result.text  # LLM did the classification

🔐 Authentication

Built-in auth for production deployments. Supports OAuth 2.0, Bearer tokens, API keys, and JWT. Integrates with Auth0, Clerk, Supabase, and custom providers.

⚠️
Why this matters for us: Any connector we build that touches customer data (Notion, Slack, Asana) should have per-user auth scoping, not shared credentials. FastMCP makes this first-class.

🧩 Server Composition

Mount multiple FastMCP servers under namespaces to build federated tool registries. A master server can aggregate tools from five sub-servers, with automatic namespace collision handling.

master = FastMCP("Master")
master.mount("/crm", crm_server)   # tools exposed as crm_get_contact, etc.
master.mount("/hr", hr_server)
master.mount("/ops", ops_server)

🔄 Transforms

Programmatically modify tool schemas or filter results before they reach the LLM. Strip sensitive fields, rename parameters for better AI understanding, add descriptions dynamically.


🔋 Lifespan + Dependency Injection

Run code on startup/shutdown — initialise database connections, load ML models, warm caches. Inject shared resources into tools via a typed dependency system (similar to FastAPI's Depends).

@asynccontextmanager
async def lifespan(server: FastMCP):
    db = await connect_database()
    yield {"db": db}     # injected into all tools
    await db.close()

mcp = FastMCP("MyServer", lifespan=lifespan)

Full Feature List (Server)

Background Tasks
Async ops + progress
Middleware
Intercept all calls
Elicitation
Ask user mid-run
Sampling
Server makes LLM calls
Auth
OAuth, JWT, Bearer
Composition
Mount sub-servers
Transforms
Modify schemas/results
Lifespan
Startup/shutdown hooks
Dependencies
Inject shared resources
Storage
Persistent backends
Telemetry
OpenTelemetry built-in
Pagination
Large result sets
🖥

Apps — Interactive UIs in the Conversation

Biggest differentiator · v3

This is FastMCP's most distinctive capability. MCP tools normally return text. FastMCP Apps let tools return interactive UIs rendered directly inside the conversation window — charts the user can hover over, forms that submit data, sortable tables, dashboards with live state.

You write pure Python. The host renders the component library (Prefab UI). No frontend skills required.

🧱 Prefab Apps v3.1
Add app=True to any tool and return Prefab components — charts, tables, progress bars, metrics cards, forms, toggles. Python declarative syntax, interactive output. No JavaScript.
Bar / Line / Pie Charts Data Tables Forms Metrics
🏗 FastMCPApp v3.2
Multi-tool apps where the UI calls backend tools. Manages visibility (model sees entry points, UI sees backends). Stable identifiers that survive server composition. Think full CRUD apps in-conversation.
Multi-step workflows Form → save → update Backend isolation
🤖 Generative UI v3.2
The LLM writes the UI at runtime. Provider registers tools that let the model write Prefab Python, execute it in a sandbox, and stream the result — the user watches the dashboard build up live.
LLM-designed layouts Streaming One-liner setup
📝 Custom HTML Low-level
Full control — your own HTML, CSS, JavaScript, any framework. Communicate with the host via the MCP Apps extension SDK. Use for maps, 3D visualisations, video, custom widgets.
Any JS framework Maps / 3D Custom interactions
# Prefab App — Revenue chart in ~10 lines of Python
@mcp.tool(app=True)
def revenue_dashboard(year: int) -> PrefabApp:
    """Show annual revenue as an interactive bar chart."""
    data = db.get_revenue(year)
    with Column(gap=4, css_class="p-6") as view:
        Heading(f"{year} Revenue")
        BarChart(data=data, series=[ChartSeries(data_key="revenue")], x_axis="quarter")
        DataTable(data=data)
    return PrefabApp(view=view)
🛠
Local dev server: fastmcp dev apps server.py launches a browser preview at localhost:8080 with auto-reload, MCP inspector, and live JSON-RPC traffic view. No host client needed. Build and test UIs before connecting to Claude.
🔌

Clients — Connect to Any MCP Server

FastMCP's client layer lets you call any MCP server programmatically — from scripts, workflows, or other agents. Handles transports, auth, and protocol lifecycle automatically.

Transport support
SSE (Server-Sent Events), stdio, HTTP Streamable. Just pass a URL — FastMCP negotiates the rest. Works with local processes and remote hosted servers equally.
Programmatic orchestration
Call tools, read resources, and fetch prompts in Python code. Build multi-agent pipelines where one agent calls another via MCP — composable at the protocol level.
async with Client("https://gofastmcp.com/mcp") as client:
    result = await client.call_tool("search", {"query": "FastMCP deployment"})
    resources = await client.list_resources()
    # Full protocol access — tools, resources, prompts
🚀

What We Could Build — Fourth Use Cases

Applied to our context
📊 Live Report Dashboard in Chat
Weekly AI report as an interactive Prefab app rather than a static HTML file. Bar charts hover-enabled, tables sortable, metrics with RAG indicators — all rendered in the conversation. Carly opens it without leaving Claude.
Apps Prefab UI Report pipeline
📋 RFP Builder with Background Processing
Submit an RFP for processing, get a task ID, and receive progress updates as it runs — no timeout, no blocking. Large RFPs (100+ questions) handled asynchronously with per-question confidence scoring streamed back.
Background Tasks Progress tracking Redis backend
🔐 Authenticated Multi-Tenant MCP
A single Fourth iQ MCP server that scopes per CSM's data — customer A's CSM sees only their accounts, using OAuth. Middleware enforces tenancy. One server, many users, correct data isolation.
Auth Middleware Multi-tenant
✅ Approval Workflow Tool
Use Elicitation to build tools that pause and ask for human approval mid-run — "Delete this Asana task?" with a confirmation form. Structured confirmation dialogs before irreversible actions.
Elicitation Human-in-loop Safety gates
🧩 Federated Tool Registry
Mount the Notion connector, Slack connector, Asana connector, and M365 connector into one master server using Composition. One connection point for Claude, all tools namespaced cleanly. Simplifies MCP config management.
Composition Namespacing Single endpoint
🤖 Generative EBR Builder
Feed customer data to GenerativeUI — the LLM designs the EBR dashboard at runtime based on the account's specific metrics. No fixed template. Streams the UI build as the LLM writes it. Different layout per account.
Generative UI Streaming EBR Builder
⚖️

FastMCP vs Raw MCP

Capability Raw MCP FastMCP
Setup Manual schema, transport, lifecycle code One decorator, done
Interactive UI Not supported ✅ Prefab Apps, Generative UI, Custom HTML
Long-running ops Blocks the client ✅ Background tasks with progress + Redis backend
Auth Build from scratch ✅ OAuth / Bearer / JWT built-in, Auth0/Clerk integrations
Middleware Manual wrapping ✅ Declarative intercept layer for all calls
Asking the user Not supported ✅ Elicitation — pause mid-tool for structured user input
LLM calls from server Separate API key / complexity ✅ Sampling — call the host LLM from within any tool
Multi-server Manual routing ✅ Composition — mount servers under namespaces
Deployment DIY ✅ Prefect Horizon (free), Docker, any cloud
Testing Complex mock setup ✅ Built-in testing utilities
🎯
Bottom line: FastMCP is not a wrapper around the MCP spec — it's a production application platform that happens to speak MCP. The connectors we build today can evolve into full apps with background processing, interactive UIs, and auth without changing frameworks.
🔗

Key Links

Docs home
gofastmcp.com — includes MCP server for docs search
Background Tasks
GitHub
Deployment
prefect.io/horizon — free hosting for FastMCP servers