--- 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: A human-readable name for your server Description of how to interact with this server. These instructions help clients understand the server's purpose and available functionality An async context manager function for server startup and shutdown logic A set of strings to tag the server itself 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 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 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 To ensure a component is never exposed, you can set `enabled=False` on the component itself. To learn more, see the component-specific documentation. 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., Streamable HTTP: # mcp.run(transport="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 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 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", ) ``` ### Constructor Parameters Optional server dependencies list with package specifications Only expose components with at least one matching tag Hide components with any matching tag How to handle duplicate tool registrations How to handle duplicate resource registrations How to handle duplicate prompt registrations ### 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="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="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 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 If the serializer function raises an exception, the tool will fall back to the default JSON serialization to avoid breaking the server.