mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 15:19:10 +02:00
320 lines
11 KiB
Text
320 lines
11 KiB
Text
---
|
|
title: The FastMCP Server
|
|
sidebarTitle: Overview
|
|
description: The core FastMCP server class for building MCP applications with tools, resources, and prompts.
|
|
icon: server
|
|
---
|
|
|
|
import { VersionBadge } from "/snippets/version-badge.mdx"
|
|
|
|
The central piece of a FastMCP application is the `FastMCP` server class. This class acts as the main container for your application's tools, resources, and prompts, and manages communication with MCP clients.
|
|
|
|
## Creating a Server
|
|
|
|
Instantiating a server is straightforward. You typically provide a name for your server, which helps identify it in client applications or logs.
|
|
|
|
```python
|
|
from fastmcp import FastMCP
|
|
|
|
# Create a basic server instance
|
|
mcp = FastMCP(name="MyAssistantServer")
|
|
|
|
# You can also add instructions for how to interact with the server
|
|
mcp_with_instructions = FastMCP(
|
|
name="HelpfulAssistant",
|
|
instructions="""
|
|
This server provides data analysis tools.
|
|
Call get_average() to analyze numerical data.
|
|
""",
|
|
)
|
|
```
|
|
|
|
The `FastMCP` constructor accepts several arguments:
|
|
|
|
* `name`: (Optional) A human-readable name for your server. Defaults to "FastMCP".
|
|
* `instructions`: (Optional) Description of how to interact with this server. These instructions help clients understand the server's purpose and available functionality.
|
|
* `lifespan`: (Optional) An async context manager function for server startup and shutdown logic.
|
|
* `tags`: (Optional) A set of strings to tag the server itself.
|
|
* `tools`: (Optional) A list of tools (or functions to convert to tools) to add to the server. In some cases, providing tools programmatically may be more convenient than using the `@mcp.tool` decorator.
|
|
* `**settings`: Keyword arguments corresponding to additional `ServerSettings` configuration
|
|
|
|
## Components
|
|
|
|
FastMCP servers expose several types of components to the client:
|
|
|
|
### Tools
|
|
|
|
Tools are functions that the client can call to perform actions or access external systems.
|
|
|
|
```python
|
|
@mcp.tool
|
|
def multiply(a: float, b: float) -> float:
|
|
"""Multiplies two numbers together."""
|
|
return a * b
|
|
```
|
|
|
|
See [Tools](/servers/tools) for detailed documentation.
|
|
|
|
### Resources
|
|
|
|
Resources expose data sources that the client can read.
|
|
|
|
```python
|
|
@mcp.resource("data://config")
|
|
def get_config() -> dict:
|
|
"""Provides the application configuration."""
|
|
return {"theme": "dark", "version": "1.0"}
|
|
```
|
|
|
|
See [Resources & Templates](/servers/resources) for detailed documentation.
|
|
|
|
### Resource Templates
|
|
|
|
Resource templates are parameterized resources that allow the client to request specific data.
|
|
|
|
```python
|
|
@mcp.resource("users://{user_id}/profile")
|
|
def get_user_profile(user_id: int) -> dict:
|
|
"""Retrieves a user's profile by ID."""
|
|
# The {user_id} in the URI is extracted and passed to this function
|
|
return {"id": user_id, "name": f"User {user_id}", "status": "active"}
|
|
```
|
|
|
|
See [Resources & Templates](/servers/resources) for detailed documentation.
|
|
|
|
### Prompts
|
|
|
|
Prompts are reusable message templates for guiding the LLM.
|
|
|
|
```python
|
|
@mcp.prompt
|
|
def analyze_data(data_points: list[float]) -> str:
|
|
"""Creates a prompt asking for analysis of numerical data."""
|
|
formatted_data = ", ".join(str(point) for point in data_points)
|
|
return f"Please analyze these data points: {formatted_data}"
|
|
```
|
|
|
|
See [Prompts](/servers/prompts) for detailed documentation.
|
|
|
|
## Tag-Based Filtering
|
|
|
|
<VersionBadge version="2.8.0" />
|
|
|
|
FastMCP supports tag-based filtering to selectively expose components based on configurable include/exclude tag sets. This is useful for creating different views of your server for different environments or users.
|
|
|
|
Components can be tagged when defined using the `tags` parameter:
|
|
|
|
```python
|
|
@mcp.tool(tags={"public", "utility"})
|
|
def public_tool() -> str:
|
|
return "This tool is public"
|
|
|
|
@mcp.tool(tags={"internal", "admin"})
|
|
def admin_tool() -> str:
|
|
return "This tool is for admins only"
|
|
```
|
|
|
|
|
|
The filtering logic works as follows:
|
|
- **Include tags**: If specified, only components with at least one matching tag are exposed
|
|
- **Exclude tags**: Components with any matching tag are filtered out
|
|
- **Precedence**: Exclude tags always take priority over include tags
|
|
|
|
<Tip>
|
|
To ensure a component is never exposed, you can set `enabled=False` on the component itself. To learn more, see the component-specific documentation.
|
|
</Tip>
|
|
|
|
You configure tag-based filtering when creating your server:
|
|
|
|
```python
|
|
# Only expose components tagged with "public"
|
|
mcp = FastMCP(include_tags={"public"})
|
|
|
|
# Hide components tagged as "internal" or "deprecated"
|
|
mcp = FastMCP(exclude_tags={"internal", "deprecated"})
|
|
|
|
# Combine both: show admin tools but hide deprecated ones
|
|
mcp = FastMCP(include_tags={"admin"}, exclude_tags={"deprecated"})
|
|
```
|
|
|
|
This filtering applies to all component types (tools, resources, resource templates, and prompts) and affects both listing and access.
|
|
|
|
## Running the Server
|
|
|
|
FastMCP servers need a transport mechanism to communicate with clients. You typically start your server by calling the `mcp.run()` method on your `FastMCP` instance, often within an `if __name__ == "__main__":` block in your main server script. This pattern ensures compatibility with various MCP clients.
|
|
|
|
```python
|
|
# my_server.py
|
|
from fastmcp import FastMCP
|
|
|
|
mcp = FastMCP(name="MyServer")
|
|
|
|
@mcp.tool
|
|
def greet(name: str) -> str:
|
|
"""Greet a user by name."""
|
|
return f"Hello, {name}!"
|
|
|
|
if __name__ == "__main__":
|
|
# This runs the server, defaulting to STDIO transport
|
|
mcp.run()
|
|
|
|
# To use a different transport, e.g., HTTP:
|
|
# mcp.run(transport="streamable-http", host="127.0.0.1", port=9000)
|
|
```
|
|
|
|
FastMCP supports several transport options:
|
|
- STDIO (default, for local tools)
|
|
- Streamable HTTP (recommended for web services)
|
|
- SSE (legacy web transport, deprecated)
|
|
|
|
The server can also be run using the FastMCP CLI.
|
|
|
|
For detailed information on each transport, how to configure them (host, port, paths), and when to use which, please refer to the [**Running Your FastMCP Server**](/deployment/running-server) guide.
|
|
|
|
|
|
## Composing Servers
|
|
|
|
<VersionBadge version="2.2.0" />
|
|
|
|
FastMCP supports composing multiple servers together using `import_server` (static copy) and `mount` (live link). This allows you to organize large applications into modular components or reuse existing servers.
|
|
|
|
See the [Server Composition](/servers/composition) guide for full details, best practices, and examples.
|
|
|
|
```python
|
|
# Example: Importing a subserver
|
|
from fastmcp import FastMCP
|
|
import asyncio
|
|
|
|
main = FastMCP(name="Main")
|
|
sub = FastMCP(name="Sub")
|
|
|
|
@sub.tool
|
|
def hello():
|
|
return "hi"
|
|
|
|
# Mount directly
|
|
main.mount(sub, prefix="sub")
|
|
```
|
|
|
|
## Proxying Servers
|
|
|
|
<VersionBadge version="2.0.0" />
|
|
|
|
FastMCP can act as a proxy for any MCP server (local or remote) using `FastMCP.as_proxy`, letting you bridge transports or add a frontend to existing servers. For example, you can expose a remote SSE server locally via stdio, or vice versa.
|
|
|
|
See the [Proxying Servers](/servers/proxy) guide for details and advanced usage.
|
|
|
|
```python
|
|
from fastmcp import FastMCP, Client
|
|
|
|
backend = Client("http://example.com/mcp/sse")
|
|
proxy = FastMCP.as_proxy(backend, name="ProxyServer")
|
|
# Now use the proxy like any FastMCP server
|
|
```
|
|
|
|
## Server Configuration
|
|
|
|
Servers can be configured using a combination of initialization arguments, global settings, and transport-specific settings.
|
|
|
|
### Server-Specific Configuration
|
|
|
|
Server-specific settings are passed when creating the `FastMCP` instance and control server behavior:
|
|
|
|
```python
|
|
from fastmcp import FastMCP
|
|
|
|
# Configure server-specific settings
|
|
mcp = FastMCP(
|
|
name="ConfiguredServer",
|
|
dependencies=["requests", "pandas>=2.0.0"], # Optional server dependencies
|
|
include_tags={"public", "api"}, # Only expose these tagged components
|
|
exclude_tags={"internal", "deprecated"}, # Hide these tagged components
|
|
on_duplicate_tools="error", # Handle duplicate registrations
|
|
on_duplicate_resources="warn",
|
|
on_duplicate_prompts="replace",
|
|
)
|
|
```
|
|
|
|
### Global Settings
|
|
|
|
Global settings affect all FastMCP servers and can be configured via environment variables (prefixed with `FASTMCP_`) or in a `.env` file:
|
|
|
|
```python
|
|
import fastmcp
|
|
|
|
# Access global settings
|
|
print(fastmcp.settings.log_level) # Default: "INFO"
|
|
print(fastmcp.settings.mask_error_details) # Default: False
|
|
print(fastmcp.settings.resource_prefix_format) # Default: "path"
|
|
```
|
|
|
|
Common global settings include:
|
|
- **`log_level`**: Logging level ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"), set with `FASTMCP_LOG_LEVEL`
|
|
- **`mask_error_details`**: Whether to hide detailed error information from clients, set with `FASTMCP_MASK_ERROR_DETAILS`
|
|
- **`resource_prefix_format`**: How to format resource prefixes ("path" or "protocol"), set with `FASTMCP_RESOURCE_PREFIX_FORMAT`
|
|
|
|
### Transport-Specific Configuration
|
|
|
|
Transport settings are provided when running the server and control network behavior:
|
|
|
|
```python
|
|
# Configure transport when running
|
|
mcp.run(
|
|
transport="streamable-http",
|
|
host="0.0.0.0", # Bind to all interfaces
|
|
port=9000, # Custom port
|
|
log_level="DEBUG", # Override global log level
|
|
)
|
|
|
|
# Or for async usage
|
|
await mcp.run_async(
|
|
transport="streamable-http",
|
|
host="127.0.0.1",
|
|
port=8080,
|
|
)
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Settings can be configured via environment variables:
|
|
|
|
```bash
|
|
# Global settings
|
|
export FASTMCP_LOG_LEVEL=DEBUG
|
|
export FASTMCP_MASK_ERROR_DETAILS=True
|
|
export FASTMCP_RESOURCE_PREFIX_FORMAT=protocol
|
|
```
|
|
|
|
### Custom Tool Serialization
|
|
|
|
<VersionBadge version="2.2.7" />
|
|
|
|
By default, FastMCP serializes tool return values to JSON when they need to be converted to text. You can customize this behavior by providing a `tool_serializer` function when creating your server:
|
|
|
|
```python
|
|
import yaml
|
|
from fastmcp import FastMCP
|
|
|
|
# Define a custom serializer that formats dictionaries as YAML
|
|
def yaml_serializer(data):
|
|
return yaml.dump(data, sort_keys=False)
|
|
|
|
# Create a server with the custom serializer
|
|
mcp = FastMCP(name="MyServer", tool_serializer=yaml_serializer)
|
|
|
|
@mcp.tool
|
|
def get_config():
|
|
"""Returns configuration in YAML format."""
|
|
return {"api_key": "abc123", "debug": True, "rate_limit": 100}
|
|
```
|
|
|
|
The serializer function takes any data object and returns a string representation. This is applied to **all non-string return values** from your tools. Tools that already return strings bypass the serializer.
|
|
|
|
This customization is useful when you want to:
|
|
- Format data in a specific way (like YAML or custom formats)
|
|
- Control specific serialization options (like indentation or sorting)
|
|
- Add metadata or transform data before sending it to clients
|
|
|
|
<Tip>
|
|
If the serializer function raises an exception, the tool will fall back to the default JSON serialization to avoid breaking the server.
|
|
</Tip>
|