diff --git a/README.md b/README.md index 5b6ee6850..c3cd42997 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,105 @@
-### 🎉 FastMCP has been added to the official MCP SDK! 🎉 - -You can now find FastMCP as part of the official Model Context Protocol Python SDK: - -👉 [github.com/modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk) - -*Please note: this repository is no longer maintained.* - ---- - - -


- -
- -
- -# FastMCP 🚀 -The fast, Pythonic way to build MCP servers. +# FastMCP v2 🚀 +Build and interact with MCP applications the fast, Pythonic way. [![PyPI - Version](https://img.shields.io/pypi/v/fastmcp.svg)](https://pypi.org/project/fastmcp) [![Tests](https://github.com/jlowin/fastmcp/actions/workflows/run-tests.yml/badge.svg)](https://github.com/jlowin/fastmcp/actions/workflows/run-tests.yml) [![License](https://img.shields.io/github/license/jlowin/fastmcp.svg)](https://github.com/jlowin/fastmcp/blob/main/LICENSE) -
-[Model Context Protocol (MCP)](https://modelcontextprotocol.io) servers are a new, standardized way to provide context and tools to your LLMs, and FastMCP makes building MCP servers simple and intuitive. Create tools, expose resources, and define prompts with clean, Pythonic code: +[Model Context Protocol (MCP)](https://modelcontextprotocol.io) servers are a standardized way to provide context and tools to your LLMs, and FastMCP makes building *and interacting with* them simple and intuitive. Create tools, expose resources, define prompts, and connect components with clean, Pythonic code. ```python -# demo.py - +# 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() ``` -That's it! Give Claude access to the server by running: - +Run it locally for testing: ```bash -fastmcp install demo.py +fastmcp dev server.py ``` -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. +Install it for use with Claude Desktop: +```bash +fastmcp install 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. -### Key features: -* **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 +## Key Features: -(\*emphasis on *aims*) +* **Simple Server Creation:** Build MCP servers with minimal boilerplate using intuitive decorators (`@tool`, `@resource`, `@prompt`). +* **Powerful Clients:** Programmatically interact with *any* MCP server, regardless of how it was built. +* **Flexible Proxying:** Create proxy servers to expose existing MCP servers or clients with modifications, or **convert between transport protocols** (e.g., expose a Stdio server via SSE for web access). +* **Server Mounting:** Compose complex applications by mounting multiple FastMCP servers together. +* **API Generation:** Automatically create MCP servers from existing **OpenAPI specifications** or **FastAPI applications**. +* **Pythonic Interface:** Designed with familiar Python patterns like decorators and type hints. +* **Context Injection:** Easily access core MCP capabilities like sampling, logging, and progress reporting within your functions. -🚨 🚧 🏗️ *FastMCP is under active development, as is the MCP specification itself. Core features are working but some advanced capabilities are still in progress.* +--- +### FastMCP v1 and v2 + +FastMCP v1's core approach of using the `@tool`, `@resource`, `@prompt` decorators with the `FastMCP` class proved so successful that it became part of the official Model Context Protocol Python SDK! For basic server creation, you can use the upstream version by importing `mcp.server.fastmcp.FastMCP`. + +👉 The **MCP Python SDK** can be found at [github.com/modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk) + +**FastMCP v2 builds upon v1's foundation** and adds the advanced features listed above (Client, Proxy, Mounting, API Generation, and more). + +* **Need just the basics?** Use FastMCP v1 (the official SDK). +* **Need advanced features like clients, proxies, or mounting?** Use FastMCP v2 (this library). + +--- ## Table of Contents +- [Key Features:](#key-features) + - [FastMCP v1 and v2](#fastmcp-v1-and-v2) - [Installation](#installation) - [Quickstart](#quickstart) - [What is MCP?](#what-is-mcp) -- [Core Concepts](#core-concepts) - - [Server](#server) - - [Resources](#resources) +- [Core Concepts (The Foundation)](#core-concepts-the-foundation) + - [The `FastMCP` Server](#the-fastmcp-server) - [Tools](#tools) + - [Resources](#resources) - [Prompts](#prompts) - - [Images](#images) - [Context](#context) + - [Images](#images) +- [Advanced Features](#advanced-features) + - [MCP Client](#mcp-client) + - [Proxy Servers](#proxy-servers) + - [Composing MCP Servers](#composing-mcp-servers) + - [OpenAPI \& FastAPI Generation](#openapi--fastapi-generation) - [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) - - [Echo Server](#echo-server) - - [SQLite Explorer](#sqlite-explorer) - [Contributing](#contributing) - - [Prerequisites](#prerequisites) - - [Installation](#installation-1) - - [Testing](#testing) - - [Formatting](#formatting) - - [Opening a Pull Request](#opening-a-pull-request) + - [Prerequisites](#prerequisites) + - [Setup](#setup) + - [Testing](#testing) + - [Formatting \& Linting](#formatting--linting) + - [Pull Requests](#pull-requests) ## Installation -We strongly recommend installing FastMCP with [uv](https://docs.astral.sh/uv/), as it is required for deploying servers: +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 @@ -103,10 +107,13 @@ 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. -Alternatively, to use the SDK without deploying, you may use pip: - +For development, install with: ```bash -pip install fastmcp +# Clone the repo first +git clone https://github.com/jlowin/fastmcp.git +cd fastmcp +# Install with dev dependencies +uv sync --dev ``` ## Quickstart @@ -115,21 +122,17 @@ 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: @@ -153,19 +156,20 @@ fastmcp dev server.py 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 of these sort of like GET endpoints; they are used to load information into the LLM's context) -- Provide functionality through **Tools** (sort of like POST endpoints; they are used to execute code or otherwise produce a side effect) -- Define interaction patterns through **Prompts** (reusable templates for LLM interactions) +- 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! -There is a low-level [Python SDK](https://github.com/modelcontextprotocol/python-sdk) available for implementing the protocol directly, but FastMCP aims to make that easier by providing a high-level, Pythonic interface. +FastMCP provides a high-level, Pythonic interface for building and interacting with these servers. -## Core Concepts +## Core Concepts (The Foundation) +These are the building blocks for creating MCP servers, using the familiar decorator-based approach. -### Server +### The `FastMCP` Server -The FastMCP server is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing: +The central object representing your MCP application. It handles connections, protocol details, and routing. ```python from fastmcp import FastMCP @@ -173,391 +177,440 @@ from fastmcp import FastMCP # Create a named server mcp = FastMCP("My App") -# Specify dependencies for deployment and development +# Specify dependencies needed when deployed via `fastmcp install` mcp = FastMCP("My App", dependencies=["pandas", "numpy"]) ``` -### Resources - -Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects. Some examples: - -- File contents -- Database schemas -- API responses -- System information - -Resources can be static: -```python -@mcp.resource("config://app") -def get_config() -> str: - """Static configuration data""" - return "App configuration here" -``` - -Or dynamic with parameters (FastMCP automatically handles these as MCP templates): -```python -@mcp.resource("users://{user_id}/profile") -def get_user_profile(user_id: str) -> str: - """Dynamic user data""" - return f"Profile data for user {user_id}" -``` - ### Tools -Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects. They're similar to POST endpoints in a REST API. +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. -Simple calculation example: -```python -@mcp.tool() -def calculate_bmi(weight_kg: float, height_m: float) -> float: - """Calculate BMI given weight in kg and height in meters""" - return weight_kg / (height_m ** 2) -``` +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. -HTTP request example: ```python import httpx +from pydantic import BaseModel + +class UserInfo(BaseModel): + user_id: int + notify: bool = False @mcp.tool() -async def fetch_weather(city: str) -> str: - """Fetch current weather for a city""" - async with httpx.AsyncClient() as client: - response = await client.get( - f"https://api.weather.com/{city}" - ) - return response.text +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) ``` -Complex input handling example: +### 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 -from pydantic import BaseModel, Field -from typing import Annotated +# Static resource returning simple text +@mcp.resource("config://app-version") +def get_app_version() -> str: + """Returns the application version.""" + return "v2.1.0" -class ShrimpTank(BaseModel): - class Shrimp(BaseModel): - name: Annotated[str, Field(max_length=10)] +# 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") - shrimp: list[Shrimp] - -@mcp.tool() -def name_shrimp( - tank: ShrimpTank, - # You can use pydantic Field in function signatures for validation. - extra_names: Annotated[list[str], Field(max_length=10)], -) -> list[str]: - """List all shrimp names in the tank""" - return [shrimp.name for shrimp in tank.shrimp] + extra_names +# 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 are reusable templates that help LLMs interact with your server effectively. They're like "best practices" encoded into your server. A prompt can be as simple as a string: +Prompts define reusable templates or interaction patterns for the LLM. They help guide the LLM on how to use your server's capabilities effectively. -```python -@mcp.prompt() -def review_code(code: str) -> str: - return f"Please review this code:\n\n{code}" -``` +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. -Or a more structured sequence of messages: ```python from fastmcp.prompts.base import UserMessage, AssistantMessage @mcp.prompt() -def debug_error(error: str) -> list[Message]: +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("I'm seeing this error:"), - UserMessage(error), - AssistantMessage("I'll help debug that. What have you tried so far?") + 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 -FastMCP provides an `Image` class that automatically handles image data in your server: +Easily handle image input and output using the `fastmcp.Image` helper class. ```python from fastmcp import FastMCP, Image from PIL import Image as PILImage +import io + +mcp = FastMCP("Image Demo") @mcp.tool() -def create_thumbnail(image_path: str) -> Image: - """Create a thumbnail from an image""" - img = PILImage.open(image_path) +def create_thumbnail(image_data: Image) -> Image: + """Creates a 100x100 thumbnail from the provided image.""" + img = PILImage.open(io.BytesIO(image_data.data)) # Assumes image_data received as Image with bytes img.thumbnail((100, 100)) - - # FastMCP automatically handles conversion and MIME types - return Image(data=img.tobytes(), format="png") + buffer = io.BytesIO() + img.save(buffer, format="PNG") + # Return a new Image object with the thumbnail data + return Image(data=buffer.getvalue(), format="png") @mcp.tool() -def load_image(path: str) -> Image: - """Load an image from disk""" - # FastMCP handles reading and format detection +def load_image_from_disk(path: str) -> Image: + """Loads an image from the specified path.""" + # Handles reading file and detecting format based on extension return Image(path=path) ``` +FastMCP handles the conversion to/from the base64-encoded format required by the MCP protocol. -Images can be used as the result of both tools and resources. +## Advanced Features -### Context +Building on the core concepts, FastMCP v2 introduces powerful features for more complex scenarios: -The Context object gives your tools and resources access to MCP capabilities. To use it, add a parameter annotated with `fastmcp.Context`: +### MCP Client + +The client allows your Python code to interact with *any* MCP server, whether it's built with FastMCP, the official SDK, or another implementation. This is essential for testing, building meta-tools, or integrating MCP servers. ```python -from fastmcp import FastMCP, Context +import asyncio +from fastmcp import Client +from fastmcp.client.transports import StdioTransport # Example transport -@mcp.tool() -async def long_task(files: list[str], ctx: Context) -> str: - """Process multiple files with progress tracking""" - for i, file in enumerate(files): - ctx.info(f"Processing {file}") - await ctx.report_progress(i, len(files)) - - # Read another resource if needed - data = await ctx.read_resource(f"file://{file}") - - return "Processing complete" +async def main(): + # Connect to a server running via standard I/O + # Replace with the actual command to start your target server + client = Client(StdioTransport(command="python", args=["path/to/target_server.py"])) + + async with client: + # Discover tools + tools_result = await client.list_tools() + print(f"Available Tools: {[t.name for t in tools_result.tools]}") + + # Call a tool + add_result = await client.call_tool("add", {"a": 10, "b": 5}) + print(f"Result of add(10, 5): {add_result.content[0].text}") # Output: 15 + + # Read a resource + greeting = await client.read_resource("greeting://Client") + print(f"Resource Content: {greeting.contents[0].text}") # Output: Hello, Client! + +if __name__ == "__main__": + asyncio.run(main()) ``` -The Context object provides: -- Progress reporting through `report_progress()` -- Logging via `debug()`, `info()`, `warning()`, and `error()` -- Resource access through `read_resource()` -- Request metadata via `request_id` and `client_id` +The client supports various transports (`WSTransport`, `SSETransport`, `StdioTransport`, `FastMCPTransport`) and intelligently infers the correct one based on the connection information provided (URL, `FastMCP` instance, command arguments, etc.). -## Running Your Server +### Proxy Servers -There are three main ways to use your FastMCP server, each suited for different stages of development: +Create a FastMCP server that acts as an intermediary, proxying requests to another MCP endpoint (which could be a server or another client connection). -### Development Mode (Recommended for Building & Testing) +**Use Cases:** -The fastest way to test and debug your server is with the MCP Inspector: +* **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). -```bash -fastmcp dev server.py +```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.as_proxy(proxy_client, name="Stdio-to-SSE Proxy") + +if __name__ == "__main__": + proxy.run(transport='sse') ``` -This launches a web interface where you can: -- Test your tools and resources interactively -- See detailed logs and error messages -- Monitor server performance -- Set environment variables for testing +`FastMCP.as_proxy` is an `async` classmethod. It connects to the target, discovers its capabilities, and dynamically builds the proxy server instance. -During development, you can: -- Add dependencies with `--with`: - ```bash - fastmcp dev server.py --with pandas --with numpy - ``` -- Mount your local code for live updates: - ```bash - fastmcp dev server.py --with-editable . - ``` -### Claude Desktop Integration (For Regular Use) -Once your server is ready, install it in Claude Desktop to use it with Claude: +### Composing MCP Servers -```bash -fastmcp install server.py -``` - -Your server will run in an isolated environment with: -- Automatic installation of dependencies specified in your FastMCP instance: - ```python - mcp = FastMCP("My App", dependencies=["pandas", "numpy"]) - ``` -- Custom naming via `--name`: - ```bash - fastmcp install server.py --name "My Analytics Server" - ``` -- Environment variable management: - ```bash - # Set variables individually - fastmcp install server.py -e API_KEY=abc123 -e DB_URL=postgres://... - - # Or load from a .env file - fastmcp install server.py -f .env - ``` - -### Direct Execution (For Advanced Use Cases) - -For advanced scenarios like custom deployments or running without Claude, you can execute your server directly: +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. ```python from fastmcp import FastMCP -mcp = FastMCP("My App") +# --- 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() ``` -Run it with: -```bash -# Using the FastMCP CLI -fastmcp run server.py +This promotes code organization and reusability for complex MCP systems. -# Or with Python/uv directly -python server.py -uv run python server.py +### OpenAPI & FastAPI Generation + +Leverage your existing web APIs by automatically generating FastMCP servers from them. + +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:** -Note: When running directly, you are responsible for ensuring all dependencies are available in your environment. Any dependencies specified on the FastMCP instance are ignored. +```python +import httpx +import json +from fastmcp import FastMCP -Choose this method when you need: -- Custom deployment configurations -- Integration with other services -- Direct control over the server lifecycle +# 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() +``` + +## Running Your Server + +Choose the method that best suits your needs: + +### Development Mode (Recommended for Building & Testing) + +Use `fastmcp dev` for an interactive testing environment with the MCP Inspector. + +```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 . +``` + +### Claude Desktop Integration (For Regular Use) + +Use `fastmcp install` to set up your server for persistent use within the Claude Desktop app. It handles creating an isolated environment using `uv`. + +```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) + +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 -All FastMCP commands will look for a server object called `mcp`, `app`, or `server` in your file. If you have a different object name or multiple servers in one file, use the syntax `server.py:my_server`: +If your `FastMCP` instance is not named `mcp`, `server`, or `app`, specify it using `file:object` syntax for the `dev` and `install` commands: ```bash -# Using a standard name -fastmcp run server.py - -# Using a custom name -fastmcp run server.py:my_custom_server +fastmcp dev my_module.py:my_mcp_instance +fastmcp install api.py:api_app ``` ## Examples -Here are a few examples of FastMCP servers. For more, see the `examples/` directory. +Explore the `examples/` directory for code samples demonstrating various features: -### Echo Server -A simple server demonstrating resources, tools, and prompts: - -```python -from fastmcp import FastMCP - -mcp = FastMCP("Echo") - -@mcp.resource("echo://{message}") -def echo_resource(message: str) -> str: - """Echo a message as a resource""" - return f"Resource echo: {message}" - -@mcp.tool() -def echo_tool(message: str) -> str: - """Echo a message as a tool""" - return f"Tool echo: {message}" - -@mcp.prompt() -def echo_prompt(message: str) -> str: - """Create an echo prompt""" - return f"Please process this message: {message}" -``` - -### SQLite Explorer -A more complex example showing database integration: - -```python -from fastmcp import FastMCP -import sqlite3 - -mcp = FastMCP("SQLite Explorer") - -@mcp.resource("schema://main") -def get_schema() -> str: - """Provide the database schema as a resource""" - conn = sqlite3.connect("database.db") - schema = conn.execute( - "SELECT sql FROM sqlite_master WHERE type='table'" - ).fetchall() - return "\n".join(sql[0] for sql in schema if sql[0]) - -@mcp.tool() -def query_data(sql: str) -> str: - """Execute SQL queries safely""" - conn = sqlite3.connect("database.db") - try: - result = conn.execute(sql).fetchall() - return "\n".join(str(row) for row in result) - except Exception as e: - return f"Error: {str(e)}" - -@mcp.prompt() -def analyze_table(table: str) -> str: - """Create a prompt template for analyzing tables""" - return f"""Please analyze this database table: -Table: {table} -Schema: -{get_schema()} - -What insights can you provide about the structure and relationships?""" -``` +* `simple_echo.py`: Basic tool, resource, and prompt. +* `complex_inputs.py`: Using Pydantic models for tool inputs. +* `mount_example.py`: Mounting multiple FastMCP servers. +* `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. +

Open Developer Guide

-### Prerequisites +#### Prerequisites -FastMCP requires Python 3.10+ and [uv](https://docs.astral.sh/uv/). +* Python 3.10+ +* [uv](https://docs.astral.sh/uv/) -### Installation +#### Setup -For development, we recommend installing FastMCP with development dependencies, which includes various utilities the maintainers find useful. +1. Clone: `git clone https://github.com/jlowin/fastmcp.git && cd fastmcp` +2. Install Env & Dependencies: `uv venv && uv sync --dev` (Activate the `.venv` after creation) +#### Testing + +Run the test suite: ```bash -git clone https://github.com/jlowin/fastmcp.git -cd fastmcp -uv sync +uv run pytest -vv ``` -### Testing +#### Formatting & Linting -Please make sure to test any new functionality. Your tests should be simple and atomic and anticipate change rather than cement complex patterns. +We use `ruff` via `pre-commit`. +1. Install hooks: `pre-commit install` +2. Run checks: `pre-commit run --all-files` -Run tests from the root directory: +#### Pull Requests +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`. -```bash -pytest -vv -``` +Please open an issue or discussion for questions or suggestions! -### Formatting - -FastMCP enforces a variety of required formats, which you can automatically enforce with pre-commit. - -Install the pre-commit hooks: - -```bash -pre-commit install -``` - -The hooks will now run on every commit (as well as on every PR). To run them manually: - -```bash -pre-commit run --all-files -``` - -### Opening a Pull Request - -Fork the repository and create a new branch: - -```bash -git checkout -b my-branch -``` - -Make your changes and commit them: - - -```bash -git add . && git commit -m "My changes" -``` - -Push your changes to your fork: - - -```bash -git push origin my-branch -``` - -Feel free to reach out in a GitHub issue or discussion if you have any questions! - -
+ \ No newline at end of file diff --git a/src/fastmcp/__init__.py b/src/fastmcp/__init__.py index 287058577..d0394d9fa 100644 --- a/src/fastmcp/__init__.py +++ b/src/fastmcp/__init__.py @@ -6,7 +6,14 @@ from importlib.metadata import version from fastmcp.server.server import FastMCP from fastmcp.server.context import Context from fastmcp.client import Client +from fastmcp.utilities.types import Image from . import client, settings __version__ = version("fastmcp") -__all__ = ["FastMCP", "Context", "client", "settings"] +__all__ = [ + "FastMCP", + "Context", + "client", + "settings", + "Image", +]