Begin adding docs

This commit is contained in:
Jeremiah Lowin 2025-04-12 14:38:32 -04:00
commit dc995af9d8
9 changed files with 338 additions and 1 deletions

53
docs/docs.json Normal file
View file

@ -0,0 +1,53 @@
{
"$schema": "https://mintlify.com/docs.json",
"background": {
"color": {
"dark": "#222831",
"light": "#EEEEEE"
},
"decoration": "windows"
},
"colors": {
"dark": "#EA5455",
"light": "#EA5455",
"primary": "#EA5455"
},
"description": "The fast, Pythonic way to build MCP servers.",
"footer": {
"socials": {
"github": "https://github.com/jlowin/fastmcp"
}
},
"name": "FastMCP",
"navbar": {
"primary": {
"href": "https://github.com/jlowin/fastmcp",
"type": "github"
}
},
"navigation": {
"groups": [
{
"group": "Get Started",
"pages": [
"getting-started/welcome",
"getting-started/installation",
"getting-started/quickstart"
]
},
{
"group": "Servers",
"pages": []
},
{
"group": "Clients",
"pages": []
},
{
"group": "Deployment",
"pages": []
}
]
},
"theme": "mint"
}

View file

@ -0,0 +1,62 @@
---
title: Installation
icon: arrow-down-to-line
---
## Install FastMCP
We recommend using [uv](https://docs.astral.sh/uv/getting-started/installation/) to install and manage FastMCP.
If you plan to use FastMCP in your project, you can add it as a dependency with:
```bash
uv add fastmcp
```
Alternatively, you can install it directly with `pip` or `uv pip`:
<CodeGroup>
```bash uv
uv pip install fastmcp
```
```bash pip
pip install fastmcp
```
</CodeGroup>
## Verify Installation
To verify that FastMCP is installed correctly, you can run the following command:
```bash
fastmcp version
```
You should see output like the following:
```bash
$ fastmcp version
FastMCP version: 0.4.2.dev41+ga077727.d20250410
MCP version: 1.6.0
Python version: 3.12.2
Platform: macOS-15.3.1-arm64-arm-64bit
FastMCP root path: ~/Developer/fastmcp
```
## Installing for Development
If you plan to contribute to FastMCP, you should begin by cloning the repository and using uv to install all dependencies.
```bash
git clone https://github.com/jlowin/fastmcp.git
cd fastmcp
uv sync
```
This will install all dependencies, including ones for development, and create a virtual environment.
To run the tests, use pytest:
```bash
pytest
```

View file

@ -0,0 +1,127 @@
---
title: Quickstart
icon: rocket
---
Welcome! This guide will help you quickly set up FastMCP and run your first MCP server.
If you haven't already installed FastMCP, follow the [installation instructions](/docs/getting-started/installation).
## Creating a FastMCP Server
A FastMCP server is a collection of tools, resources, and other MCP components. To create a server, start by instantiating the `FastMCP` class.
Create a new file called `my_server.py` and add the following code:
```python my_server.py
from fastmcp import FastMCP
mcp = FastMCP("My MCP Server")
```
That's it! You've created a FastMCP server, albeit a very boring one. Let's add a tool to make it more interesting.
## Adding a Tool
To add a tool that returns a simple greeting, write a function and decorate it with `@mcp.tool` to register it with the server:
```python my_server.py {5-7}
from fastmcp import FastMCP
mcp = FastMCP("My MCP Server")
@mcp.tool
def greet(name: str) -> str:
return f"Hello, {name}!"
```
## Testing the Server
To test the server, create a FastMCP client and point it at the server object.
```python my_server.py {1, 9-16}
from fastmcp import FastMCP, Client
mcp = FastMCP("My MCP Server")
@mcp.tool
def greet(name: str) -> str:
return f"Hello, {name}!"
client = Client(mcp)
async def call_tool(name: str):
async with client:
result = await client.call_tool("greet", {"name": name})
print(result)
asyncio.run(call_tool("Ford"))
```
There are a few things to note here:
- Clients are asynchronous, so we need to use `asyncio.run` to run the client.
- We must enter a client context (`async with client:`) before using the client. You can make multiple client calls within the same context.
## Running the server
In order to run the server with Python, we need to add a `run` statement to the `__main__` block of the server file.
```python my_server.py {9-10}
from fastmcp import FastMCP, Client
mcp = FastMCP("My MCP Server")
@mcp.tool
def greet(name: str) -> str:
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run()
```
This lets us run the server with `python my_server.py`, using the default `stdio` transport, which is the standard way to expose an MCP server to a client.
<Tip>
Why do we need the `if __name__ == "__main__":` block?
Within the FastMCP ecosystem, this line may be unecessary. However, including it ensures that your FastMCP server runs for all users and clients in a consistent way and is therefore recommended as best practice.
</Tip>
### Interacting with the Python server
Now that the server can be executed with `python my_server.py`, we can interact with it like any other MCP server.
In a new file, create a client and point it at the server file:
```python my_client.py
from fastmcp import Client
client = Client("my_server.py")
async def call_tool(name: str):
async with client:
result = await client.call_tool("greet", {"name": name})
print(result)
asyncio.run(call_tool("Ford"))
```
### Using the FastMCP CLI
To have FastMCP run the server for us, we can use the `fastmcp run` command. This will start the server and keep it running until it is stopped. By default, it will use the `stdio` transport, which is a simple text-based protocol for interacting with the server.
```bash
fastmcp run my_server.py:mcp
```
Note that FastMCP *does not* require the `__main__` block in the server file, and will ignore it if it is present. Instead, it looks for the server object provided in the CLI command (here, `mcp`). If no server object is provided, `fastmcp run` will automatically search for servers called "mcp", "app", or "server" in the file.
<Tip>
We pointed our client at the server file, which is recognized as a Python MCP server and executed with `python my_server.py` by default. This exceutes the `__main__` block of the server file. There are other ways to run the server, which are described in the [server configuration](/docs/getting-started/configuration) guide.
</Tip>

View file

@ -0,0 +1,56 @@
---
title: "Welcome to FastMCP!"
sidebarTitle: "Welcome!"
description: The fast, Pythonic way to build MCP servers.
icon: hand-wave
---
[Model Context Protocol](https://modelcontextprotocol.io/) (MCP) 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, define prompts, and more with clean, Pythonic code:
```python {1, 3, 5, 11}
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()
```
## What is MCP?
The Model Context Protocol (MCP) 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:
- 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)
- And more!
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.
FastMCP aims to be:
- **Fast**: High-level interface means less code and faster development
- **Simple**: Build MCP servers with minimal boilerplate
- **Pythonic**: Feels natural to Python developers
- **Complete**: FastMCP aims to provide a full implementation of the core MCP specification
**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.

13
docs/style.css Normal file
View file

@ -0,0 +1,13 @@
/* Target inline code elements with higher specificity */
p code,
table code,
li code,
h1 code,
h2 code,
h3 code,
h4 code,
h5 code,
h6 code {
color: #ea5455 !important;
background-color: #ea54551a !important;
}

View file

@ -1,7 +1,7 @@
[project]
name = "fastmcp"
dynamic = ["version"]
description = "An ergonomic MCP interface"
description = "The fast, Pythonic way to build MCP servers."
authors = [{ name = "Jeremiah Lowin" }]
dependencies = [
"dotenv>=0.9.9",

View file

@ -133,6 +133,7 @@ def _import_server(file: Path, server_object: str | None = None):
sys.exit(1)
module = importlib.util.module_from_spec(spec)
breakpoint()
spec.loader.exec_module(module)
# If no object specified, try common server names
@ -323,6 +324,8 @@ def run(
# Import and get server object
server = _import_server(file, server_object)
logger.info(f'Found server "{server.name}" in {file}')
# Run the server
kwargs = {}
if transport:

View file

@ -208,6 +208,28 @@ class PythonStdioTransport(StdioTransport):
self.script_path = script_path
class FastMCPStdioTransport(StdioTransport):
"""Transport for running FastMCP servers using the FastMCP CLI."""
def __init__(
self,
script_path: str | Path,
args: list[str] | None = None,
env: dict[str, str] | None = None,
cwd: str | None = None,
):
script_path = Path(script_path).resolve()
if not script_path.is_file():
raise FileNotFoundError(f"Script not found: {script_path}")
if not str(script_path).endswith(".py"):
raise ValueError(f"Not a Python script: {script_path}")
super().__init__(
command="fastmcp", args=["run", str(script_path)], env=env, cwd=cwd
)
self.script_path = script_path
class NodeStdioTransport(StdioTransport):
"""Transport for running Node.js scripts."""

View file

@ -137,6 +137,7 @@ class FastMCP(Generic[LifespanResultT]):
Args:
transport: Transport protocol to use ("stdio" or "sse")
"""
logger.info(f'Starting server "{self.name}"...')
anyio.run(self.run_async, transport)
def _setup_handlers(self) -> None: