# FastMCP v2 🚀
The fast, Pythonic way to build MCP servers and clients.
[](https://gofastmcp.com)
[](https://pypi.org/project/fastmcp)
[](https://github.com/jlowin/fastmcp/actions/workflows/run-tests.yml)
[](https://github.com/jlowin/fastmcp/blob/main/LICENSE)
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is a new, standardized way to provide context and tools to your LLMs, and FastMCP makes building MCP servers and clients simple and intuitive. Create tools, expose resources, define prompts, and connect components with clean, Pythonic code.
```python
# server.py
from fastmcp import FastMCP
mcp = FastMCP("Demo 🚀")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
if __name__ == "__main__":
mcp.run()
```
Run the server locally:
```bash
fastmcp run server.py
```
FastMCP handles the complex protocol details and server management, letting you focus on building great tools and applications. It's designed to feel natural to Python developers.
## Table of Contents
- [What is MCP?](#what-is-mcp)
- [Why FastMCP?](#why-fastmcp)
- [Key Features](#key-features)
- [Servers](#servers)
- [Clients](#clients)
- [What's New in v2?](#whats-new-in-v2)
- [Documentation](#documentation)
- [Installation](#installation)
- [Quickstart](#quickstart)
- [Core Concepts](#core-concepts)
- [The `FastMCP` Server](#the-fastmcp-server)
- [Tools](#tools)
- [Resources](#resources)
- [Prompts](#prompts)
- [Context](#context)
- [Images](#images)
- [MCP Clients](#mcp-clients)
- [Client Methods](#client-methods)
- [Transport Options](#transport-options)
- [LLM Sampling](#llm-sampling)
- [Roots Access](#roots-access)
- [Advanced Features](#advanced-features)
- [Proxy Servers](#proxy-servers)
- [Composing MCP Servers](#composing-mcp-servers)
- [OpenAPI \& FastAPI Generation](#openapi--fastapi-generation)
- [Handling `stderr`](#handling-stderr)
- [Running Your Server](#running-your-server)
- [Development Mode (Recommended for Building \& Testing)](#development-mode-recommended-for-building--testing)
- [Claude Desktop Integration (For Regular Use)](#claude-desktop-integration-for-regular-use)
- [Direct Execution (For Advanced Use Cases)](#direct-execution-for-advanced-use-cases)
- [Server Object Names](#server-object-names)
- [Examples](#examples)
- [Contributing](#contributing)
- [Prerequisites](#prerequisites)
- [Setup](#setup)
- [Testing](#testing)
- [Formatting \& Linting](#formatting--linting)
- [Pull Requests](#pull-requests)
## What is MCP?
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions. MCP servers can:
- Expose data through **Resources** (think GET endpoints; load info into context)
- Provide functionality through **Tools** (think POST/PUT endpoints; execute actions)
- Define interaction patterns through **Prompts** (reusable templates)
- And more!
FastMCP provides a high-level, Pythonic interface for building and interacting with these servers.
## Why FastMCP?
The MCP protocol is powerful but implementing it involves a lot of boilerplate - server setup, protocol handlers, content types, error management. FastMCP handles all the complex protocol details and server management, so you can focus on building great tools. It's designed to be high-level and Pythonic; in most cases, decorating a function is all you need.
FastMCP aims to be:
🚀 **Fast:** High-level interface means less code and faster development
🍀 **Simple:** Build MCP servers with minimal boilerplate
🐍 **Pythonic:** Feels natural to Python developers
🔍 **Complete:** FastMCP aims to provide a full implementation of the core MCP specification for both servers and clients
## Key Features
### Servers
- **Create** servers with minimal boilerplate using intuitive decorators
- **Proxy** existing servers to modify configuration or transport
- **Compose** servers into complex applications
- **Generate** servers from OpenAPI specs or FastAPI objects
### Clients
- **Interact** with MCP servers programmatically
- **Connect** to any MCP server using any transport
- **Test** your servers without manual intervention
- **Innovate** with core MCP capabilities like LLM sampling
## What's New in v2?
FastMCP 1.0 made it so easy to build MCP servers that it's now part of the [official Model Context Protocol Python SDK](https://github.com/modelcontextprotocol/python-sdk)! For basic use cases, you can use the upstream version by importing `mcp.server.fastmcp.FastMCP` (or installing `fastmcp=1.0`).
Based on how the MCP ecosystem is evolving, FastMCP 2.0 builds on that foundation to introduce a variety of new features (and more experimental ideas). It adds advanced features like proxying and composing MCP servers, as well as automatically generating them from OpenAPI specs or FastAPI objects. FastMCP 2.0 also introduces new client-side functionality like LLM sampling.
## Documentation
📚 FastMCP's documentation is available at [gofastmcp.com](https://gofastmcp.com).
---
### Installation
We strongly recommend installing FastMCP with [uv](https://docs.astral.sh/uv/), as it is required for deploying servers via the CLI:
```bash
uv pip install fastmcp
```
Note: on macOS, uv may need to be installed with Homebrew (`brew install uv`) in order to make it available to the Claude Desktop app.
For development, install with:
```bash
# Clone the repo first
git clone https://github.com/jlowin/fastmcp.git
cd fastmcp
# Install with dev dependencies
uv sync
```
### Quickstart
Let's create a simple MCP server that exposes a calculator tool and some data:
```python
# server.py
from fastmcp import FastMCP
# Create an MCP server
mcp = FastMCP("Demo")
# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""Get a personalized greeting"""
return f"Hello, {name}!"
```
You can install this server in [Claude Desktop](https://claude.ai/download) and interact with it right away by running:
```bash
fastmcp install server.py
```

## Core Concepts
These are the building blocks for creating MCP servers, using the familiar decorator-based approach.
### The `FastMCP` Server
The central object representing your MCP application. It handles connections, protocol details, and routing.
```python
from fastmcp import FastMCP
# Create a named server
mcp = FastMCP("My App")
# Specify dependencies needed when deployed via `fastmcp install`
mcp = FastMCP("My App", dependencies=["pandas", "numpy"])
```
### Tools
Tools allow LLMs to perform actions by executing your Python functions. They are ideal for tasks that involve computation, external API calls, or side effects.
Decorate synchronous or asynchronous functions with `@mcp.tool()`. FastMCP automatically generates the necessary MCP schema based on type hints and docstrings. Pydantic models can be used for complex inputs.
```python
import httpx
from pydantic import BaseModel
class UserInfo(BaseModel):
user_id: int
notify: bool = False
@mcp.tool()
async def send_notification(user: UserInfo, message: str) -> dict:
"""Sends a notification to a user if requested."""
if user.notify:
# Simulate sending notification
print(f"Notifying user {user.user_id}: {message}")
return {"status": "sent", "user_id": user.user_id}
return {"status": "skipped", "user_id": user.user_id}
@mcp.tool()
def get_stock_price(ticker: str) -> float:
"""Gets the current price for a stock ticker."""
# Replace with actual API call
prices = {"AAPL": 180.50, "GOOG": 140.20}
return prices.get(ticker.upper(), 0.0)
```
### Resources
Resources expose data to LLMs. They should primarily provide information without significant computation or side effects (like GET requests).
Decorate functions with `@mcp.resource("your://uri")`. Use curly braces `{}` in the URI to define dynamic resources (templates) where parts of the URI become function parameters.
```python
# Static resource returning simple text
@mcp.resource("config://app-version")
def get_app_version() -> str:
"""Returns the application version."""
return "v2.1.0"
# Dynamic resource template expecting a 'user_id' from the URI
@mcp.resource("db://users/{user_id}/email")
async def get_user_email(user_id: str) -> str:
"""Retrieves the email address for a given user ID."""
# Replace with actual database lookup
emails = {"123": "alice@example.com", "456": "bob@example.com"}
return emails.get(user_id, "not_found@example.com")
# Resource returning JSON data
@mcp.resource("data://product-categories")
def get_categories() -> list[str]:
"""Returns a list of available product categories."""
return ["Electronics", "Books", "Home Goods"]
```
### Prompts
Prompts define reusable templates or interaction patterns for the LLM. They help guide the LLM on how to use your server's capabilities effectively.
Decorate functions with `@mcp.prompt()`. The function should return the desired prompt content, which can be a simple string, a `Message` object (like `UserMessage` or `AssistantMessage`), or a list of these.
```python
from fastmcp.prompts.base import UserMessage, AssistantMessage
@mcp.prompt()
def ask_review(code_snippet: str) -> str:
"""Generates a standard code review request."""
return f"Please review the following code snippet for potential bugs and style issues:\n```python\n{code_snippet}\n```"
@mcp.prompt()
def debug_session_start(error_message: str) -> list[Message]:
"""Initiates a debugging help session."""
return [
UserMessage(f"I encountered an error:\n{error_message}"),
AssistantMessage("Okay, I can help with that. Can you provide the full traceback and tell me what you were trying to do?")
]
```
### Context
Gain access to MCP server capabilities *within* your tool or resource functions by adding a parameter type-hinted with `fastmcp.Context`.
```python
from fastmcp import Context, FastMCP
mcp = FastMCP("Context Demo")
@mcp.resource("system://status")
async def get_system_status(ctx: Context) -> dict:
"""Checks system status and logs information."""
await ctx.info("Checking system status...")
# Perform checks
await ctx.report_progress(1, 1) # Report completion
return {"status": "OK", "load": 0.5, "client": ctx.client_id}
@mcp.tool()
async def process_large_file(file_uri: str, ctx: Context) -> str:
"""Processes a large file, reporting progress and reading resources."""
await ctx.info(f"Starting processing for {file_uri}")
# Read the resource using the context
file_content_resource = await ctx.read_resource(file_uri)
file_content = file_content_resource[0].content # Assuming single text content
lines = file_content.splitlines()
total_lines = len(lines)
for i, line in enumerate(lines):
# Process line...
if (i + 1) % 100 == 0: # Report progress every 100 lines
await ctx.report_progress(i + 1, total_lines)
await ctx.info(f"Finished processing {file_uri}")
return f"Processed {total_lines} lines."
```
The `Context` object provides:
* Logging: `ctx.debug()`, `ctx.info()`, `ctx.warning()`, `ctx.error()`
* Progress Reporting: `ctx.report_progress(current, total)`
* Resource Access: `await ctx.read_resource(uri)`
* Request Info: `ctx.request_id`, `ctx.client_id`
* Sampling (Advanced): `await ctx.sample(...)` to ask the connected LLM client for completions.
### Images
Easily handle image outputs using the `fastmcp.Image` helper class.