Update docs for clarity

This commit is contained in:
Jeremiah Lowin 2025-05-03 20:37:04 -04:00
commit 3100a14416
3 changed files with 247 additions and 610 deletions

783
README.md
View file

@ -12,6 +12,17 @@
<a href="https://trendshift.io/repositories/13266" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13266" alt="jlowin%2Ffastmcp | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</div>
> [!NOTE]
> #### FastMCP 2.0 & The Official MCP SDK
>
> Recognize the `FastMCP` name? You might have used the version integrated into the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk), which was based on **FastMCP 1.0**.
>
> **Welcome to FastMCP 2.0!** This is the actively developed successor, and it significantly expands on 1.0 by introducing powerful client capabilities, server proxying & composition, OpenAPI/FastAPI integration, and more advanced features.
>
> FastMCP 2.0 is the recommended path for building modern, powerful MCP applications. Ready to upgrade or get started? Follow the [installation instructions](https://gofastmcp.com/getting-started/installation), which include specific steps for upgrading from the official MCP SDK.
---
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
@ -29,64 +40,50 @@ 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.
### 📚 Documentation
This readme provides only a high-level overview. For detailed guides, API references, and advanced patterns, please refer to the complete FastMCP documentation at **[gofastmcp.com](https://gofastmcp.com)**.
---
<!-- omit in toc -->
## 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)
- [Installation](#installation)
- [Core Concepts](#core-concepts)
- [The `FastMCP` Server](#the-fastmcp-server)
- [Tools](#tools)
- [Resources](#resources)
- [Resources \& Templates](#resources--templates)
- [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)
- [Prerequisites](#prerequisites)
- [Setup](#setup)
- [Unit Tests](#unit-tests)
- [Static Checks](#static-checks)
- [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)
- Expose data through **Resources** (similar to `GET` requests; load info into context)
- Provide functionality through **Tools** (similar to `POST`/`PUT` requests; execute actions)
- Define interaction patterns through **Prompts** (reusable templates)
- And more!
@ -96,8 +93,9 @@ FastMCP provides a high-level, Pythonic interface for building and interacting w
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:
While the core server concepts of FastMCP 1.0 laid the groundwork and were contributed to the official MCP SDK, **FastMCP 2.0 (this project) is the actively developed successor**, adding significant enhancements and entirely new capabilities like a powerful **client library**, server **proxying**, **composition** patterns, **OpenAPI/FastAPI integration**, and much more.
FastMCP aims to be:
🚀 **Fast:** High-level interface means less code and faster development
@ -107,675 +105,274 @@ FastMCP aims to be:
🔍 **Complete:** FastMCP aims to provide a full implementation of the core MCP specification for both servers and clients
## Key Features
## Installation
### 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:
We recommend installing FastMCP with [uv](https://docs.astral.sh/uv/):
```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
```
![MCP Inspector](/docs/assets/demo-inspector.png)
For full installation instructions, including verification, upgrading from the official MCPSDK, and developer setup, see the [**Installation Guide**](https://gofastmcp.com/getting-started/installation).
## Core Concepts
These are the building blocks for creating MCP servers, using the familiar decorator-based approach.
These are the building blocks for creating MCP servers and clients with FastMCP.
### The `FastMCP` Server
The central object representing your MCP application. It handles connections, protocol details, and routing.
The central object representing your MCP application. It holds your tools, resources, and prompts, manages connections, and can be configured with settings like [authentication providers](https://gofastmcp.com/servers/fastmcp#authentication).
```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"])
# Create a server instance
mcp = FastMCP(name="MyAssistantServer")
```
Learn more in the [**FastMCP Server Documentation**](https://gofastmcp.com/servers/fastmcp).
### 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.
Tools allow LLMs to perform actions by executing your Python functions (sync or async). Ideal for computations, API calls, or side effects (like `POST`/`PUT`). FastMCP handles schema generation from type hints and docstrings. Tools can return various types, including text, JSON-serializable objects, and even images using the [`fastmcp.Image`](https://gofastmcp.com/servers/tools#return-values) helper.
```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)
def multiply(a: float, b: float) -> float:
"""Multiplies two numbers."""
return a * b
```
### Resources
Learn more in the [**Tools Documentation**](https://gofastmcp.com/servers/tools).
Resources expose data to LLMs. They should primarily provide information without significant computation or side effects (like GET requests).
### Resources & Templates
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.
Resources expose read-only data sources (like `GET` requests). Use `@mcp.resource("your://uri")`. Use `{placeholders}` in the URI to create dynamic templates that accept parameters, allowing clients to request specific data subsets.
```python
# Static resource returning simple text
@mcp.resource("config://app-version")
def get_app_version() -> str:
"""Returns the application version."""
return "v2.1.0"
# Static resource
@mcp.resource("config://version")
def get_version():
return "2.0.1"
# 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"]
# Dynamic resource template
@mcp.resource("users://{user_id}/profile")
def get_profile(user_id: int):
# Fetch profile for user_id...
return {"name": f"User {user_id}", "status": "active"}
```
Learn more in the [**Resources & Templates Documentation**](https://gofastmcp.com/servers/resources).
### 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.
Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt()`. Return strings or `Message` objects.
```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?")
]
def summarize_request(text: str) -> str:
"""Generate a prompt asking for a summary."""
return f"Please summarize the following text:\n\n{text}"
```
Learn more in the [**Prompts Documentation**](https://gofastmcp.com/servers/prompts).
### Context
Gain access to MCP server capabilities *within* your tool or resource functions by adding a parameter type-hinted with `fastmcp.Context`.
Access MCP session capabilities within your tools, resources, or prompts by adding a `ctx: Context` parameter. Context provides methods for:
* **Logging:** Log messages to MCP clients with `ctx.info()`, `ctx.error()`, etc.
* **LLM Sampling:** Use `ctx.sample()` to request completions from the client's LLM.
* **HTTP Request:** Use `ctx.http_request()` to make HTTP requests to other servers.
* **Resource Access:** Use `ctx.read_resource()` to access resources on the server
* **Progress Reporting:** Use `ctx.report_progress()` to report progress to the client.
* and more...
To access the context, add a parameter annotated as `Context` to any mcp-decorated function. FastMCP will automatically inject the correct context object when the function is called.
```python
from fastmcp import Context, FastMCP
from fastmcp import FastMCP, Context
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 = FastMCP("My MCP Server")
@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)
async def process_data(uri: str, ctx: Context):
# Log a message to the client
await ctx.info(f"Processing {uri}...")
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)
# Read a resource from the server
data = await ctx.read_resource(uri)
await ctx.info(f"Finished processing {file_uri}")
return f"Processed {total_lines} lines."
# Ask client LLM to summarize the data
summary = await ctx.sample(f"Summarize: {data.content[:500]}")
# Return the summary
return summary.text
```
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.
<Tip>
The below code requires the `pillow` library to be installed.
</Tip>
```python
from mcp.server.fastmcp import FastMCP, Image
from io import BytesIO
try:
from PIL import Image as PILImage
except ImportError:
raise ImportError("Please install the `pillow` library to run this example.")
mcp = FastMCP("My App")
@mcp.tool()
def create_thumbnail(image_path: str) -> Image:
"""Create a thumbnail from an image"""
img = PILImage.open(image_path)
img.thumbnail((100, 100))
buffer = BytesIO()
img.save(buffer, format="PNG")
return Image(data=buffer.getvalue(), format="png")
```
Return the `Image` helper class from your tool to send an image to the client. The `Image` helper class handles the conversion to/from the base64-encoded format required by the MCP protocol. It works with either a path to an image file, or a bytes object.
Learn more in the [**Context Documentation**](https://gofastmcp.com/servers/context).
### MCP Clients
The `Client` class lets you interact with any MCP server (not just FastMCP ones) from Python code:
Interact with *any* MCP server programmatically using the `fastmcp.Client`. It supports various transports (Stdio, SSE, In-Memory) and often auto-detects the correct one. The client can also handle advanced patterns like server-initiated **LLM sampling requests** if you provide an appropriate handler.
Critically, the client allows for efficient **in-memory testing** of your servers by connecting directly to a `FastMCP` server instance via the `FastMCPTransport`, eliminating the need for process management or network calls during tests.
```python
from fastmcp import Client
async with Client("path/to/server") as client:
# Call a tool
result = await client.call_tool("weather", {"location": "San Francisco"})
print(result)
# Read a resource
res = await client.read_resource("db://users/123/profile")
print(res)
async def main():
# Connect via stdio to a local script
async with Client("my_server.py") as client:
tools = await client.list_tools()
print(f"Available tools: {tools}")
result = await client.call_tool("add", {"a": 5, "b": 3})
print(f"Result: {result.text}")
# Connect via SSE
async with Client("http://localhost:8000/sse") as client:
# ... use the client
pass
```
You can connect to servers using any supported transport protocol (Stdio, SSE, FastMCP, etc.). If you don't specify a transport, the `Client` class automatically attempts to detect an appropriate one from your connection string or server object.
#### Client Methods
The `Client` class exposes several methods for interacting with MCP servers.
To use clients to test servers, use the following pattern:
```python
async with Client("path/to/server") as client:
# List available tools
tools = await client.list_tools()
# List available resources
resources = await client.list_resources()
# Call a tool with arguments
result = await client.call_tool("generate_report", {"user_id": 123})
# Read a resource
user_data = await client.read_resource("db://users/123/profile")
# Get a prompt
greeting = await client.get_prompt("welcome", {"name": "Alice"})
# Send progress updates
await client.progress("task-123", 50, 100) # 50% complete
# Basic connectivity testing
await client.ping()
from fastmcp import FastMCP, Client
mcp = FastMCP("My MCP Server")
async def main():
# Connect via in-memory transport
async with Client(mcp) as client:
# ... use the client
```
These methods correspond directly to MCP protocol operations, making it easy to interact with any MCP-compatible server (not just FastMCP ones).
#### Transport Options
FastMCP supports various transport protocols for connecting to MCP servers:
```python
from fastmcp import Client
from fastmcp.client.transports import (
SSETransport,
PythonStdioTransport,
FastMCPTransport
)
# Connect to a server over SSE (common for web-based MCP servers)
async with Client(SSETransport("http://localhost:8000/mcp")) as client:
# Use client here...
# Connect to a Python script using stdio (useful for local tools)
async with Client(PythonStdioTransport("path/to/script.py")) as client:
# Use client here...
# Connect directly to a FastMCP server object in the same process
from your_app import mcp_server
async with Client(FastMCPTransport(mcp_server)) as client:
# Use client here...
```
Common transport options include:
- `SSETransport`: Connect to a server via Server-Sent Events (HTTP)
- `PythonStdioTransport`: Run a Python script and communicate via stdio
- `FastMCPTransport`: Connect directly to a FastMCP server object
- `WSTransport`: Connect via WebSockets
In addition, if you pass a connection string or `FastMCP` server object to the `Client` constructor, it will try to automatically detect the appropriate transport.
#### LLM Sampling
Sampling is an MCP feature that allows a server to request a completion from the client LLM, enabling sophisticated use cases while maintaining security and privacy on the server.
```python
import marvin # Or any other LLM client
from fastmcp import Client, Context, FastMCP
from fastmcp.client.sampling import RequestContext, SamplingMessage, SamplingParams
# -- SERVER SIDE --
# Create a server that requests LLM completions from the client
mcp = FastMCP("Sampling Example")
@mcp.tool()
async def generate_poem(topic: str, context: Context) -> str:
"""Generate a short poem about the given topic."""
# The server requests a completion from the client LLM
response = await context.sample(
f"Write a short poem about {topic}",
system_prompt="You are a talented poet who writes concise, evocative verses."
)
return response.text
@mcp.tool()
async def summarize_document(document_uri: str, context: Context) -> str:
"""Summarize a document using client-side LLM capabilities."""
# First read the document as a resource
doc_resource = await context.read_resource(document_uri)
doc_content = doc_resource[0].content # Assuming single text content
# Then ask the client LLM to summarize it
response = await context.sample(
f"Summarize the following document:\n\n{doc_content}",
system_prompt="You are an expert summarizer. Create a concise summary."
)
return response.text
# -- CLIENT SIDE --
# Create a client that handles the sampling requests
async def sampling_handler(
messages: list[SamplingMessage],
params: SamplingParams,
ctx: RequestContext,
) -> str:
"""Handle sampling requests from the server using your preferred LLM."""
# Extract the messages and system prompt
prompt = [m.content.text for m in messages if m.content.type == "text"]
system_instruction = params.systemPrompt or "You are a helpful assistant."
# Use your preferred LLM client to generate completions
return await marvin.say_async(
message=prompt,
instructions=system_instruction,
)
# Connect them together
async with Client(mcp, sampling_handler=sampling_handler) as client:
result = await client.call_tool("generate_poem", {"topic": "autumn leaves"})
print(result.content[0].text)
```
This pattern is powerful because:
1. The server can delegate text generation to the client LLM
2. The server remains focused on business logic and data handling
3. The client maintains control over which LLM is used and how requests are handled
4. No sensitive data needs to be sent to external APIs
#### Roots Access
FastMCP exposes the MCP roots functionality, allowing clients to specify which file system roots they can access. This creates a secure boundary for tools that need to work with files. Note that the server must account for client roots explicitly.
```python
from fastmcp import Client, RootsList
# Specify file roots that the client can access
roots = ["file:///path/to/allowed/directory"]
async with Client(mcp_server, roots=roots) as client:
# Now tools in the MCP server can access files in the specified roots
await client.call_tool("process_file", {"filename": "data.csv"})
```
Learn more in the [**Client Documentation**](https://gofastmcp.com/clients/client) and [**Transports Documentation**](https://gofastmcp.com/clients/transports).
## Advanced Features
Building on the core concepts, FastMCP v2 introduces powerful features for more complex scenarios:
FastMCP introduces powerful ways to structure and deploy your MCP applications.
### Proxy Servers
Create a FastMCP server that acts as an intermediary, proxying requests to another MCP endpoint (which could be a server or another client connection).
**Use Cases:**
* **Transport Conversion:** Expose a server running on Stdio (like many local tools) over SSE or WebSockets, making it accessible to web clients or Claude Desktop.
* **Adding Functionality:** Wrap an existing server to add authentication, request logging, or modified tool behavior.
* **Aggregating Servers:** Combine multiple backend MCP servers behind a single proxy interface (though `mount` might be simpler for this).
```python
import asyncio
from fastmcp import FastMCP, Client
from fastmcp.client.transports import PythonStdioTransport
# Create a client that connects to the original server
proxy_client = Client(
transport=PythonStdioTransport('path/to/original_stdio_server.py'),
)
# Create a proxy server that connects to the client and exposes its capabilities
proxy = FastMCP.from_client(proxy_client, name="Stdio-to-SSE Proxy")
if __name__ == "__main__":
proxy.run(transport='sse')
```
`FastMCP.from_client` is a class method that connects to the target, discovers its capabilities, and dynamically builds the proxy server instance.
Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.from_client()`. This is especially useful for bridging transports (e.g., remote SSE to local Stdio) or adding a layer of logic to a server you don't control.
Learn more in the [**Proxying Documentation**](https://gofastmcp.com/patterns/proxy).
### Composing MCP Servers
Structure larger MCP applications by creating modular FastMCP servers and "mounting" them onto a parent server. This automatically handles prefixing for tool names and resource URIs, preventing conflicts.
Build modular applications by mounting multiple `FastMCP` instances onto a parent server using `mcp.mount()` (live link) or `mcp.import_server()` (static copy).
```python
from fastmcp import FastMCP
# --- Weather MCP ---
weather_mcp = FastMCP("Weather Service")
@weather_mcp.tool()
def get_forecast(city: str):
return f"Sunny in {city}"
@weather_mcp.resource("data://temp/{city}")
def get_temp(city: str):
return 25.0
# --- News MCP ---
news_mcp = FastMCP("News Service")
@news_mcp.tool()
def fetch_headlines():
return ["Big news!", "Other news"]
@news_mcp.resource("data://latest_story")
def get_story():
return "A story happened."
# --- Composite MCP ---
mcp = FastMCP("Composite")
# Mount sub-apps with prefixes
mcp.mount("weather", weather_mcp) # Tools prefixed "weather/", resources prefixed "weather+"
mcp.mount("news", news_mcp) # Tools prefixed "news/", resources prefixed "news+"
@mcp.tool()
def ping():
return "Composite OK"
if __name__ == "__main__":
mcp.run()
```
This promotes code organization and reusability for complex MCP systems.
Learn more in the [**Composition Documentation**](https://gofastmcp.com/patterns/composition).
### OpenAPI & FastAPI Generation
Leverage your existing web APIs by automatically generating FastMCP servers from them.
Automatically generate FastMCP servers from existing OpenAPI specifications (`FastMCP.from_openapi()`) or FastAPI applications (`FastMCP.from_fastapi()`), instantly bringing your web APIs to the MCP ecosystem.
By default, the following rules are applied:
- `GET` requests -> MCP resources
- `GET` requests with path parameters -> MCP resource templates
- All other HTTP methods -> MCP tools
You can override these rules to customize or even ignore certain endpoints.
**From FastAPI:**
```python
from fastapi import FastAPI
from fastmcp import FastMCP
# Your existing FastAPI application
fastapi_app = FastAPI(title="My Existing API")
@fastapi_app.get("/status")
def get_status():
return {"status": "running"}
@fastapi_app.post("/items")
def create_item(name: str, price: float):
return {"id": 1, "name": name, "price": price}
# Generate an MCP server directly from the FastAPI app
mcp_server = FastMCP.from_fastapi(fastapi_app)
if __name__ == "__main__":
mcp_server.run()
```
**From an OpenAPI Specification:**
```python
import httpx
import json
from fastmcp import FastMCP
# Load the OpenAPI spec (dict)
# with open("my_api_spec.json", "r") as f:
# openapi_spec = json.load(f)
openapi_spec = { ... } # Your spec dict
# Create an HTTP client to make requests to the actual API endpoint
http_client = httpx.AsyncClient(base_url="https://api.yourservice.com")
# Generate the MCP server
mcp_server = FastMCP.from_openapi(openapi_spec, client=http_client)
if __name__ == "__main__":
mcp_server.run()
```
### Handling `stderr`
The MCP spec allows for the server to write anything it wants to `stderr`, and it
doesn't specify the format in any way. FastMCP will forward the server's `stderr`
to the client's `stderr`.
Learn more: [**OpenAPI Integration**](https://gofastmcp.com/patterns/openapi) | [**FastAPI Integration**](https://gofastmcp.com/patterns/fastapi).
## Running Your Server
Choose the method that best suits your needs:
You can run your FastMCP server in several ways:
### Development Mode (Recommended for Building & Testing)
1. **Development (`fastmcp dev`)**: Recommended for building and testing. Provides an interactive testing environment with the MCP Inspector.
```bash
fastmcp dev server.py
# Optionally add temporary dependencies
fastmcp dev server.py --with pandas numpy
```
Use `fastmcp dev` for an interactive testing environment with the MCP Inspector.
2. **FastMCP CLI**: Run your server with the FastMCP CLI. This can autodetect and load your server object and run it with any transport configuration you want.
```bash
fastmcp run path/to/server.py:server_object
```bash
fastmcp dev your_server_file.py
# With temporary dependencies
fastmcp dev your_server_file.py --with pandas --with numpy
# With local package in editable mode
fastmcp dev your_server_file.py --with-editable .
```
# Run as SSE on port 4200
fastmcp run path/to/server.py:server_object --transport sse --port 4200
```
FastMCP will auto-detect the server object if it's named `mcp`, `app`, or `server`. In these cases, you can omit the `:server_object` part unless you need to select a specific object.
### Claude Desktop Integration (For Regular Use)
3. **Direct Execution**: For maximum compatibility with the MCP ecosystem, you can run your server directly as part of a Python script. You will typically do this within an `if __name__ == "__main__":` block in your script:
```python
# Add this to server.py
if __name__ == "__main__":
# Default: runs stdio transport
mcp.run()
Use `fastmcp install` to set up your server for persistent use within the Claude Desktop app. It handles creating an isolated environment using `uv`.
# Example: Run with SSE transport on a specific port
mcp.run(transport="sse", host="127.0.0.1", port=9000)
```
Run your script:
```bash
python server.py
# or using uv to manage the environment
uv run python server.py
```
4. **Claude Desktop Integration (`fastmcp install`)**: The easiest way to make your server persistently available in the Claude Desktop app. It handles creating an isolated environment using `uv`.
```bash
fastmcp install server.py --name "My Analysis Tool"
# Optionally add dependencies and environment variables
fastmcp install server.py --with requests -v API_KEY=123 -f .env
```
```bash
fastmcp install your_server_file.py
# With a custom name in Claude
fastmcp install your_server_file.py --name "My Analysis Tool"
# With extra packages and environment variables
fastmcp install server.py --with requests -v API_KEY=123 -f .env
```
### Direct Execution (For Advanced Use Cases)
See the [**Server Documentation**](https://gofastmcp.com/servers/fastmcp#running-the-server) for more details on transports and configuration.
Run your server script directly for custom deployments or integrations outside of Claude. You manage the environment and dependencies yourself.
Add to your `your_server_file.py`:
```python
if __name__ == "__main__":
mcp.run() # Assuming 'mcp' is your FastMCP instance
```
Run with:
```bash
python your_server_file.py
# or
uv run python your_server_file.py
```
### Server Object Names
If your `FastMCP` instance is not named `mcp`, `server`, or `app`, specify it using `file:object` syntax for the `dev` and `install` commands:
```bash
fastmcp dev my_module.py:my_mcp_instance
fastmcp install api.py:api_app
```
## Examples
Explore the `examples/` directory for code samples demonstrating various features:
* `simple_echo.py`: Basic tool, resource, and prompt.
* `complex_inputs.py`: Using Pydantic models for tool inputs.
* `mount_example.py`: Mounting multiple FastMCP servers.
* `sampling.py`: Using LLM completions within your MCP server.
* `screenshot.py`: Tool returning an Image object.
* `text_me.py`: Tool interacting with an external API.
* `memory.py`: More complex example with database interaction.
## Contributing
Contributions make the open-source community vibrant! We welcome improvements and features.
Contributions are the core of open source! We welcome improvements and features.
<details>
<summary><h3>Open Developer Guide</h3></summary>
#### Prerequisites
### Prerequisites
* Python 3.10+
* [uv](https://docs.astral.sh/uv/)
* [uv](https://docs.astral.sh/uv/) (Recommended for environment management)
#### Setup
### Setup
1. Clone: `git clone https://github.com/jlowin/fastmcp.git && cd fastmcp`
2. Install Env & Dependencies: `uv venv && uv sync` (Activate the `.venv` after creation)
1. Clone the repository:
```bash
git clone https://github.com/jlowin/fastmcp.git
cd fastmcp
```
2. Create and sync the environment:
```bash
uv sync
```
This installs all dependencies, including dev tools.
3. Activate the virtual environment (e.g., `source .venv/bin/activate` or via your IDE).
#### Testing
### Unit Tests
Run the test suite:
FastMCP has a comprehensive unit test suite. All PRs must introduce or update tests as appropriate and pass the full suite.
Run tests using pytest:
```bash
uv run --frozen pytest -vv
pytest
```
#### Formatting & Linting
### Static Checks
We use `ruff` via `pre-commit`.
1. Install hooks: `pre-commit install`
2. Run checks: `pre-commit run --all-files`
FastMCP uses `pre-commit` for code formatting, linting, and type-checking. All PRs must pass these checks (they run automatically in CI).
#### Pull Requests
Install the hooks locally:
```bash
uv run pre-commit install
```
The hooks will now run automatically on `git commit`. You can also run them manually at any time:
```bash
pre-commit run --all-files
# or via uv
uv run pre-commit run --all-files
```
1. Fork the repository.
2. Create a feature branch.
3. Make changes, commit, and push to your fork.
4. Open a pull request against the `main` branch of `jlowin/fastmcp`.
### Pull Requests
Please open an issue or discussion for questions or suggestions!
1. Fork the repository on GitHub.
2. Create a feature branch from `main`.
3. Make your changes, including tests and documentation updates.
4. Ensure tests and pre-commit hooks pass.
5. Commit your changes and push to your fork.
6. Open a pull request against the `main` branch of `jlowin/fastmcp`.
</details>
Please open an issue or discussion for questions or suggestions before starting significant work!

View file

@ -23,7 +23,7 @@ Alternatively, you can install it directly with `pip` or `uv pip`:
```
</CodeGroup>
## Verify Installation
### Verify Installation
To verify that FastMCP is installed correctly, you can run the following command:
@ -42,10 +42,26 @@ Python version: 3.12.2
Platform: macOS-15.3.1-arm64-arm-64bit
FastMCP root path: ~/Developer/fastmcp
```
## Upgrading from the Official MCP SDK
Upgrading from the official MCP SDK's FastMCP 1.0 to FastMCP 2.0 is easy! The core server API is highly compatible, so after you install the `fastmcp` package, just change your import statement from `from mcp.server.fastmcp import FastMCP` to `from fastmcp import FastMCP`.
```python {1-5}
# Before
# from mcp.server.fastmcp import FastMCP
# After
from fastmcp import FastMCP
mcp = FastMCP("My MCP Server")
```
While the 1.0 server API is very stable for common use cases, FastMCP 2.0 introduces many new features (like the Client, proxying, composition) documented throughout this site. Review the documentation for details on new capabilities.
## Installing for Development
If you plan to contribute to FastMCP, you should begin by cloning the repository and using uv to install all dependencies.
If you plan to contribute to FastMCP, you should begin by cloning the repository and using uv to install all dependencies (development dependencies are installed automatically):
```bash
git clone https://github.com/jlowin/fastmcp.git
@ -53,10 +69,26 @@ cd fastmcp
uv sync
```
This will install all dependencies, including ones for development, and create a virtual environment.
This will install all dependencies, including ones for development, and create a virtual environment, which you can activate and use as normal.
To run the tests, use pytest:
### Unit Tests
FastMCP has a comprehensive unit test suite, and all PR's must introduce and pass appropriate tests. To run the tests, use pytest:
```bash
pytest
```
```
### Pre-Commit Hooks
FastMCP uses pre-commit to manage code quality, including formatting, linting, and type-safety. All PR's must pass the pre-commit hooks, which are run as a part of the CI process. To install the pre-commit hooks, run:
```bash
uv run pre-commit install
```
Alternatively, to run pre-commit manually at any time, use:
```bash
pre-commit run --all-files
```

View file

@ -1,5 +1,5 @@
---
title: "Welcome to FastMCP!"
title: "Welcome to FastMCP 2.0!"
sidebarTitle: "Welcome!"
description: The fast, Pythonic way to build MCP servers and clients.
@ -24,6 +24,19 @@ if __name__ == "__main__":
```
## FastMCP 2.0 and the Official MCP SDK
<Tip>
Recognize the `FastMCP` name? You might have used the version integrated into the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk), which was based on **FastMCP 1.0**.
**Welcome to FastMCP 2.0!** This is the [actively developed successor](https://github.com/jlowin/fastmcp), and it significantly expands on v1 by introducing powerful client capabilities, server proxying & composition, OpenAPI/FastAPI integration, and more advanced features.
FastMCP 2.0 is the recommended path for building modern, powerful MCP applications. Ready to upgrade or get started? Follow the [installation instructions](/getting-started/installation), which include specific steps for upgrading.
</Tip>
## What is MCP?
The Model Context Protocol lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. It is often described as "the USB-C port for AI", providing a uniform way to connect LLMs to resources they can use. It may be easier to think of it as an API, but specifically designed for LLM interactions. MCP servers can:
@ -34,17 +47,13 @@ The Model Context Protocol lets you build servers that expose data and functiona
There is a low-level Python SDK available for implementing the protocol directly, but FastMCP aims to make that easier by providing a high-level, Pythonic interface.
<Tip>
FastMCP 1.0 was so successful that it is now included as part of the official [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)!
</Tip>
## 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.
While the core server concepts of FastMCP 1.0 laid the groundwork and were contributed to the official MCP SDK, FastMCP 2.0 (this project) is the actively developed successor, adding significant enhancements and entirely new capabilities like a powerful client library, server proxying, composition patterns, and much more.
FastMCP aims to be:
🚀 **Fast**: High-level interface means less code and faster development
@ -55,5 +64,4 @@ FastMCP aims to be:
🔍 **Complete**: FastMCP aims to provide a full implementation of the core MCP specification
**FastMCP v1** focused on abstracting the most common boilerplate of exposing MCP server functionality, and is now included in the official MCP Python SDK. **FastMCP v2** expands on that foundation to introduce novel functionality mainly focused on simplifying server interactions, including flexible clients, proxying and composition, and deployment.