Spaces:
Running
Running
Merge pull request #185 from jlowin/docs
Browse files- docs/clients/{overview.mdx → client.mdx} +4 -0
- docs/clients/transports.mdx +1 -1
- docs/docs.json +2 -2
- docs/patterns/composition.mdx +65 -52
- docs/patterns/fastapi.mdx +3 -0
- docs/patterns/openapi.mdx +3 -0
- docs/patterns/{proxying.mdx → proxy.mdx} +3 -0
- docs/servers/context.mdx +4 -1
- docs/servers/fastmcp.mdx +16 -136
- docs/snippets/version-badge.mdx +8 -0
- docs/style.css +42 -2
docs/clients/{overview.mdx → client.mdx}
RENAMED
|
@@ -5,6 +5,10 @@ description: Learn how to use the FastMCP Client to interact with MCP servers.
|
|
| 5 |
icon: user-robot
|
| 6 |
---
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
The `fastmcp.Client` provides a high-level, asynchronous interface for interacting with any Model Context Protocol (MCP) server, whether it's built with FastMCP or another implementation. It simplifies communication by handling protocol details and connection management.
|
| 9 |
|
| 10 |
## FastMCP Client
|
|
|
|
| 5 |
icon: user-robot
|
| 6 |
---
|
| 7 |
|
| 8 |
+
import { VersionBadge } from '/snippets/version-badge.mdx'
|
| 9 |
+
|
| 10 |
+
<VersionBadge version="2.0.0" />
|
| 11 |
+
|
| 12 |
The `fastmcp.Client` provides a high-level, asynchronous interface for interacting with any Model Context Protocol (MCP) server, whether it's built with FastMCP or another implementation. It simplifies communication by handling protocol details and connection management.
|
| 13 |
|
| 14 |
## FastMCP Client
|
docs/clients/transports.mdx
CHANGED
|
@@ -7,7 +7,7 @@ icon: link
|
|
| 7 |
|
| 8 |
The FastMCP `Client` relies on a `ClientTransport` object to handle the specifics of connecting to and communicating with an MCP server. FastMCP provides several built-in transport implementations for common connection methods.
|
| 9 |
|
| 10 |
-
While the `Client` often infers the correct transport automatically (see [Client Overview](/clients/
|
| 11 |
|
| 12 |
|
| 13 |
## Stdio Transports
|
|
|
|
| 7 |
|
| 8 |
The FastMCP `Client` relies on a `ClientTransport` object to handle the specifics of connecting to and communicating with an MCP server. FastMCP provides several built-in transport implementations for common connection methods.
|
| 9 |
|
| 10 |
+
While the `Client` often infers the correct transport automatically (see [Client Overview](/clients/client#transport-inference)), you can also instantiate transports explicitly for more control.
|
| 11 |
|
| 12 |
|
| 13 |
## Stdio Transports
|
docs/docs.json
CHANGED
|
@@ -50,14 +50,14 @@
|
|
| 50 |
{
|
| 51 |
"group": "Clients",
|
| 52 |
"pages": [
|
| 53 |
-
"clients/
|
| 54 |
"clients/transports"
|
| 55 |
]
|
| 56 |
},
|
| 57 |
{
|
| 58 |
"group": "Patterns",
|
| 59 |
"pages": [
|
| 60 |
-
"patterns/
|
| 61 |
"patterns/composition",
|
| 62 |
"patterns/decorating-methods",
|
| 63 |
"patterns/openapi",
|
|
|
|
| 50 |
{
|
| 51 |
"group": "Clients",
|
| 52 |
"pages": [
|
| 53 |
+
"clients/client",
|
| 54 |
"clients/transports"
|
| 55 |
]
|
| 56 |
},
|
| 57 |
{
|
| 58 |
"group": "Patterns",
|
| 59 |
"pages": [
|
| 60 |
+
"patterns/proxy",
|
| 61 |
"patterns/composition",
|
| 62 |
"patterns/decorating-methods",
|
| 63 |
"patterns/openapi",
|
docs/patterns/composition.mdx
CHANGED
|
@@ -4,6 +4,9 @@ sidebarTitle: Composition
|
|
| 4 |
description: Combine multiple FastMCP servers into a single, larger application using mounting and importing.
|
| 5 |
icon: puzzle-piece
|
| 6 |
---
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
As your MCP applications grow, you might want to organize your tools, resources, and prompts into logical modules or reuse existing server components. FastMCP supports composition through two methods:
|
| 9 |
|
|
@@ -17,13 +20,31 @@ As your MCP applications grow, you might want to organize your tools, resources,
|
|
| 17 |
- **Teamwork**: Different teams can work on separate FastMCP servers that are later combined.
|
| 18 |
- **Organization**: Keep related functionality grouped together logically.
|
| 19 |
|
| 20 |
-
## Importing
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
The `import_server()` method copies all components (tools, resources, templates, prompts) from one `FastMCP` instance (the *subserver*) into another (the *main server*). A `prefix` is added to avoid naming conflicts.
|
| 23 |
|
| 24 |
```python
|
| 25 |
from fastmcp import FastMCP
|
| 26 |
-
from typing import dict, list
|
| 27 |
import asyncio
|
| 28 |
|
| 29 |
# --- Define Subservers ---
|
|
@@ -114,7 +135,7 @@ await main_mcp.import_server(
|
|
| 114 |
Be cautious when choosing separators. Some MCP clients (like Claude Desktop) might have restrictions on characters allowed in tool names (e.g., `/` might not be supported). The defaults (`_` for names, `+` for URIs) are generally safe.
|
| 115 |
</Warning>
|
| 116 |
|
| 117 |
-
## Mounting
|
| 118 |
|
| 119 |
The `mount()` method creates a **live link** between the `main_mcp` server and the `subserver`. Instead of copying components, requests for components matching the `prefix` are **delegated** to the `subserver` at runtime.
|
| 120 |
|
|
@@ -186,61 +207,19 @@ main_mcp.mount(
|
|
| 186 |
)
|
| 187 |
```
|
| 188 |
|
| 189 |
-
## Comparing Import and Mount
|
| 190 |
-
|
| 191 |
-
| Feature | `import_server` | `mount` |
|
| 192 |
-
|---------|----------------|---------|
|
| 193 |
-
| **Synchronicity** | Async (must be awaited) | Sync |
|
| 194 |
-
| **Composition Type** | One-time copy (static) | Live link (dynamic) |
|
| 195 |
-
| **Updates** | Changes to subserver NOT reflected | Changes to subserver immediately reflected |
|
| 196 |
-
| **Lifespan** | Not managed | Automatically managed |
|
| 197 |
-
| **Best For** | Bundling finalized components | Modular runtime composition |
|
| 198 |
|
| 199 |
## Example: Modular Application
|
| 200 |
|
| 201 |
Here's how a modular application might use `import_server`:
|
| 202 |
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
from fastmcp import FastMCP
|
| 206 |
-
from typing import list
|
| 207 |
-
|
| 208 |
-
text_mcp = FastMCP(name="TextUtilities")
|
| 209 |
-
|
| 210 |
-
@text_mcp.tool()
|
| 211 |
-
def count_words(text: str) -> int:
|
| 212 |
-
"""Counts words in a text."""
|
| 213 |
-
return len(text.split())
|
| 214 |
-
|
| 215 |
-
@text_mcp.resource("resource://stopwords")
|
| 216 |
-
def get_stopwords() -> list[str]:
|
| 217 |
-
"""Return a list of common stopwords."""
|
| 218 |
-
return ["the", "a", "is", "in"]
|
| 219 |
-
|
| 220 |
-
# ------------------------------
|
| 221 |
-
# modules/data_api.py
|
| 222 |
-
from fastmcp import FastMCP
|
| 223 |
-
import random
|
| 224 |
-
from typing import dict
|
| 225 |
-
|
| 226 |
-
data_mcp = FastMCP(name="DataAPI")
|
| 227 |
-
|
| 228 |
-
@data_mcp.tool()
|
| 229 |
-
def fetch_record(record_id: int) -> dict:
|
| 230 |
-
"""Fetches a dummy data record."""
|
| 231 |
-
return {"id": record_id, "value": random.random()}
|
| 232 |
-
|
| 233 |
-
@data_mcp.resource("data://schema/{table}")
|
| 234 |
-
def get_table_schema(table: str) -> dict:
|
| 235 |
-
"""Provides a dummy schema for a table."""
|
| 236 |
-
return {"table": table, "columns": ["id", "value"]}
|
| 237 |
-
|
| 238 |
-
# ------------------------------
|
| 239 |
-
# main_app.py
|
| 240 |
from fastmcp import FastMCP
|
| 241 |
import asyncio
|
| 242 |
-
|
| 243 |
-
|
|
|
|
|
|
|
| 244 |
|
| 245 |
app = FastMCP(name="MainApplication")
|
| 246 |
|
|
@@ -273,8 +252,42 @@ if __name__ == "__main__":
|
|
| 273 |
# Run the server
|
| 274 |
app.run()
|
| 275 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 276 |
|
| 277 |
-
|
|
|
|
| 278 |
- `text_count_words`
|
| 279 |
- `data_fetch_record`
|
| 280 |
- `process_and_analyze`
|
|
|
|
| 4 |
description: Combine multiple FastMCP servers into a single, larger application using mounting and importing.
|
| 5 |
icon: puzzle-piece
|
| 6 |
---
|
| 7 |
+
import { VersionBadge } from '/snippets/version-badge.mdx'
|
| 8 |
+
|
| 9 |
+
<VersionBadge version="2.2.0" />
|
| 10 |
|
| 11 |
As your MCP applications grow, you might want to organize your tools, resources, and prompts into logical modules or reuse existing server components. FastMCP supports composition through two methods:
|
| 12 |
|
|
|
|
| 20 |
- **Teamwork**: Different teams can work on separate FastMCP servers that are later combined.
|
| 21 |
- **Organization**: Keep related functionality grouped together logically.
|
| 22 |
|
| 23 |
+
### Importing vs Mounting
|
| 24 |
+
|
| 25 |
+
The choice of importing or mounting depends on your use case and requirements. In general, importing is best for simpler cases because it copies the imported server's components into the main server, treating them as native integrations. Mounting is best for more complex cases where you need to delegate requests to the subserver at runtime.
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
| Feature | Importing | Mounting |
|
| 29 |
+
|---------|----------------|---------|
|
| 30 |
+
| **Method** | `FastMCP.import_server()` | `FastMCP.mount()` |
|
| 31 |
+
| **Composition Type** | One-time copy (static) | Live link (dynamic) |
|
| 32 |
+
| **Updates** | Changes to subserver NOT reflected | Changes to subserver immediately reflected |
|
| 33 |
+
| **Lifespan** | Not managed | Automatically managed |
|
| 34 |
+
| **Synchronicity** | Async (must be awaited) | Sync |
|
| 35 |
+
| **Best For** | Bundling finalized components | Modular runtime composition |
|
| 36 |
+
|
| 37 |
+
### Proxy Servers
|
| 38 |
+
|
| 39 |
+
FastMCP supports [MCP proxying](/patterns/proxy), which allows you to mirror a local or remote server in a local FastMCP instance. Proxies are fully compatible with both importing and mounting.
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
## Importing (Static Composition)
|
| 43 |
|
| 44 |
The `import_server()` method copies all components (tools, resources, templates, prompts) from one `FastMCP` instance (the *subserver*) into another (the *main server*). A `prefix` is added to avoid naming conflicts.
|
| 45 |
|
| 46 |
```python
|
| 47 |
from fastmcp import FastMCP
|
|
|
|
| 48 |
import asyncio
|
| 49 |
|
| 50 |
# --- Define Subservers ---
|
|
|
|
| 135 |
Be cautious when choosing separators. Some MCP clients (like Claude Desktop) might have restrictions on characters allowed in tool names (e.g., `/` might not be supported). The defaults (`_` for names, `+` for URIs) are generally safe.
|
| 136 |
</Warning>
|
| 137 |
|
| 138 |
+
## Mounting (Live Linking)
|
| 139 |
|
| 140 |
The `mount()` method creates a **live link** between the `main_mcp` server and the `subserver`. Instead of copying components, requests for components matching the `prefix` are **delegated** to the `subserver` at runtime.
|
| 141 |
|
|
|
|
| 207 |
)
|
| 208 |
```
|
| 209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
|
| 211 |
## Example: Modular Application
|
| 212 |
|
| 213 |
Here's how a modular application might use `import_server`:
|
| 214 |
|
| 215 |
+
<CodeGroup>
|
| 216 |
+
```python main.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
from fastmcp import FastMCP
|
| 218 |
import asyncio
|
| 219 |
+
|
| 220 |
+
# Import the servers (see other files)
|
| 221 |
+
from modules.text_server import text_mcp
|
| 222 |
+
from modules.data_server import data_mcp
|
| 223 |
|
| 224 |
app = FastMCP(name="MainApplication")
|
| 225 |
|
|
|
|
| 252 |
# Run the server
|
| 253 |
app.run()
|
| 254 |
```
|
| 255 |
+
```python modules/text_server.py
|
| 256 |
+
from fastmcp import FastMCP
|
| 257 |
+
|
| 258 |
+
text_mcp = FastMCP(name="TextUtilities")
|
| 259 |
+
|
| 260 |
+
@text_mcp.tool()
|
| 261 |
+
def count_words(text: str) -> int:
|
| 262 |
+
"""Counts words in a text."""
|
| 263 |
+
return len(text.split())
|
| 264 |
+
|
| 265 |
+
@text_mcp.resource("resource://stopwords")
|
| 266 |
+
def get_stopwords() -> list[str]:
|
| 267 |
+
"""Return a list of common stopwords."""
|
| 268 |
+
return ["the", "a", "is", "in"]
|
| 269 |
+
```
|
| 270 |
+
|
| 271 |
+
```python modules/data_server.py
|
| 272 |
+
from fastmcp import FastMCP
|
| 273 |
+
import random
|
| 274 |
+
from typing import dict
|
| 275 |
+
|
| 276 |
+
data_mcp = FastMCP(name="DataAPI")
|
| 277 |
+
|
| 278 |
+
@data_mcp.tool()
|
| 279 |
+
def fetch_record(record_id: int) -> dict:
|
| 280 |
+
"""Fetches a dummy data record."""
|
| 281 |
+
return {"id": record_id, "value": random.random()}
|
| 282 |
+
|
| 283 |
+
@data_mcp.resource("data://schema/{table}")
|
| 284 |
+
def get_table_schema(table: str) -> dict:
|
| 285 |
+
"""Provides a dummy schema for a table."""
|
| 286 |
+
return {"table": table, "columns": ["id", "value"]}
|
| 287 |
+
```
|
| 288 |
|
| 289 |
+
</CodeGroup>
|
| 290 |
+
Now, running `main.py` starts a server that exposes:
|
| 291 |
- `text_count_words`
|
| 292 |
- `data_fetch_record`
|
| 293 |
- `process_and_analyze`
|
docs/patterns/fastapi.mdx
CHANGED
|
@@ -4,6 +4,9 @@ sidebarTitle: FastAPI
|
|
| 4 |
description: Generate MCP servers from FastAPI apps
|
| 5 |
icon: square-bolt
|
| 6 |
---
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
|
| 9 |
FastMCP can automatically convert FastAPI applications into MCP servers.
|
|
|
|
| 4 |
description: Generate MCP servers from FastAPI apps
|
| 5 |
icon: square-bolt
|
| 6 |
---
|
| 7 |
+
import { VersionBadge } from '/snippets/version-badge.mdx'
|
| 8 |
+
|
| 9 |
+
<VersionBadge version="2.0.0" />
|
| 10 |
|
| 11 |
|
| 12 |
FastMCP can automatically convert FastAPI applications into MCP servers.
|
docs/patterns/openapi.mdx
CHANGED
|
@@ -4,6 +4,9 @@ sidebarTitle: OpenAPI
|
|
| 4 |
description: Generate MCP servers from OpenAPI specs
|
| 5 |
icon: code-branch
|
| 6 |
---
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
FastMCP can automatically generate an MCP server from an OpenAPI specification. Users only need to provide an OpenAPI specification (3.0 or 3.1) and an API client.
|
| 9 |
|
|
|
|
| 4 |
description: Generate MCP servers from OpenAPI specs
|
| 5 |
icon: code-branch
|
| 6 |
---
|
| 7 |
+
import { VersionBadge } from '/snippets/version-badge.mdx'
|
| 8 |
+
|
| 9 |
+
<VersionBadge version="2.0.0" />
|
| 10 |
|
| 11 |
FastMCP can automatically generate an MCP server from an OpenAPI specification. Users only need to provide an OpenAPI specification (3.0 or 3.1) and an API client.
|
| 12 |
|
docs/patterns/{proxying.mdx → proxy.mdx}
RENAMED
|
@@ -4,6 +4,9 @@ sidebarTitle: Proxying
|
|
| 4 |
description: Use FastMCP to act as an intermediary or change transport for other MCP servers.
|
| 5 |
icon: arrows-retweet
|
| 6 |
---
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
FastMCP provides a powerful proxying capability that allows one FastMCP server instance to act as a frontend for another MCP server (which could be remote, running on a different transport, or even another FastMCP instance). This is achieved using the `FastMCP.from_client()` class method.
|
| 9 |
|
|
|
|
| 4 |
description: Use FastMCP to act as an intermediary or change transport for other MCP servers.
|
| 5 |
icon: arrows-retweet
|
| 6 |
---
|
| 7 |
+
import { VersionBadge } from '/snippets/version-badge.mdx'
|
| 8 |
+
|
| 9 |
+
<VersionBadge version="2.0.0" />
|
| 10 |
|
| 11 |
FastMCP provides a powerful proxying capability that allows one FastMCP server instance to act as a frontend for another MCP server (which could be remote, running on a different transport, or even another FastMCP instance). This is achieved using the `FastMCP.from_client()` class method.
|
| 12 |
|
docs/servers/context.mdx
CHANGED
|
@@ -4,6 +4,7 @@ sidebarTitle: Context
|
|
| 4 |
description: Access MCP capabilities like logging, progress, and resources within your tools.
|
| 5 |
icon: rectangle-code
|
| 6 |
---
|
|
|
|
| 7 |
|
| 8 |
When defining FastMCP [tools](/servers/tools), your functions might need to interact with the underlying MCP session or access server capabilities. FastMCP provides the `Context` object for this purpose.
|
| 9 |
|
|
@@ -174,6 +175,8 @@ The returned content is typically accessed via `content_list[0].content` and can
|
|
| 174 |
|
| 175 |
### LLM Sampling
|
| 176 |
|
|
|
|
|
|
|
| 177 |
Request the client's LLM to generate text based on provided messages. This is useful when your tool needs to leverage the LLM's capabilities to process data or generate responses.
|
| 178 |
|
| 179 |
```python
|
|
@@ -227,7 +230,7 @@ async def generate_example(concept: str, ctx: Context) -> str:
|
|
| 227 |
return f"```python\n{code_example}\n```"
|
| 228 |
```
|
| 229 |
|
| 230 |
-
See [Client Sampling](/clients/
|
| 231 |
|
| 232 |
### Request Information
|
| 233 |
|
|
|
|
| 4 |
description: Access MCP capabilities like logging, progress, and resources within your tools.
|
| 5 |
icon: rectangle-code
|
| 6 |
---
|
| 7 |
+
import { VersionBadge } from '/snippets/version-badge.mdx'
|
| 8 |
|
| 9 |
When defining FastMCP [tools](/servers/tools), your functions might need to interact with the underlying MCP session or access server capabilities. FastMCP provides the `Context` object for this purpose.
|
| 10 |
|
|
|
|
| 175 |
|
| 176 |
### LLM Sampling
|
| 177 |
|
| 178 |
+
<VersionBadge version="2.0.0" />
|
| 179 |
+
|
| 180 |
Request the client's LLM to generate text based on provided messages. This is useful when your tool needs to leverage the LLM's capabilities to process data or generate responses.
|
| 181 |
|
| 182 |
```python
|
|
|
|
| 230 |
return f"```python\n{code_example}\n```"
|
| 231 |
```
|
| 232 |
|
| 233 |
+
See [Client Sampling](/clients/client#llm-sampling) for more details on how clients handle these requests.
|
| 234 |
|
| 235 |
### Request Information
|
| 236 |
|
docs/servers/fastmcp.mdx
CHANGED
|
@@ -225,159 +225,39 @@ The CLI can dynamically find and run FastMCP server objects in your files, but i
|
|
| 225 |
|
| 226 |
## Composing Servers
|
| 227 |
|
| 228 |
-
FastMCP
|
| 229 |
|
| 230 |
-
|
| 231 |
-
2. `mount()`: Live link delegating to subservers (sync)
|
| 232 |
-
|
| 233 |
-
This allows you to organize large applications into logical components, reuse existing FastMCP servers, and create domain-specific servers that can be used independently or composed.
|
| 234 |
-
|
| 235 |
-
### Importing Subservers (Static Composition)
|
| 236 |
-
|
| 237 |
-
The `import_server()` method performs a one-time copy of all components from a subserver into the main server with prefixed names:
|
| 238 |
|
| 239 |
```python
|
|
|
|
| 240 |
from fastmcp import FastMCP
|
| 241 |
import asyncio
|
| 242 |
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
# Create a domain-specific subserver
|
| 247 |
-
weather_mcp = FastMCP(name="WeatherService")
|
| 248 |
-
|
| 249 |
-
@weather_mcp.tool()
|
| 250 |
-
def get_forecast(city: str) -> dict:
|
| 251 |
-
"""Get the weather forecast for a city."""
|
| 252 |
-
return {"city": city, "forecast": "Sunny", "temperature": 72}
|
| 253 |
-
|
| 254 |
-
# Create another domain-specific subserver
|
| 255 |
-
calculator_mcp = FastMCP(name="CalculatorService")
|
| 256 |
-
|
| 257 |
-
@calculator_mcp.tool()
|
| 258 |
-
def add(a: float, b: float) -> float:
|
| 259 |
-
"""Add two numbers."""
|
| 260 |
-
return a + b
|
| 261 |
-
|
| 262 |
-
# Import the subservers with prefixes
|
| 263 |
-
async def setup():
|
| 264 |
-
await main_mcp.import_server("weather", weather_mcp)
|
| 265 |
-
await main_mcp.import_server("calc", calculator_mcp)
|
| 266 |
-
|
| 267 |
-
# Now main_mcp has access to both subservers' tools:
|
| 268 |
-
# - "weather_get_forecast" (from weather_mcp)
|
| 269 |
-
# - "calc_add" (from calculator_mcp)
|
| 270 |
-
|
| 271 |
-
if __name__ == "__main__":
|
| 272 |
-
# Run async setup
|
| 273 |
-
asyncio.run(setup())
|
| 274 |
-
# Then run the server
|
| 275 |
-
main_mcp.run()
|
| 276 |
-
```
|
| 277 |
-
|
| 278 |
-
#### How Import Works
|
| 279 |
-
|
| 280 |
-
When you import a server with `await main_mcp.import_server(prefix, subserver)`:
|
| 281 |
-
|
| 282 |
-
1. All tools from the subserver are copied with prefixed names:
|
| 283 |
-
- `tool_name` becomes `{prefix}_tool_name`
|
| 284 |
-
- Default separator is `_`, but can be customized
|
| 285 |
-
|
| 286 |
-
2. All resources and resource templates are copied with prefixed URIs:
|
| 287 |
-
- `resource://data` becomes `{prefix}+resource://data`
|
| 288 |
-
- Default separator is `+`, but can be customized
|
| 289 |
-
|
| 290 |
-
3. All prompts are copied with prefixed names:
|
| 291 |
-
- `prompt_name` becomes `{prefix}_prompt_name`
|
| 292 |
-
- Default separator is `_`, but can be customized
|
| 293 |
-
|
| 294 |
-
4. This is a **one-time copy** - changes to the subserver after importing won't be reflected in the main server
|
| 295 |
-
|
| 296 |
-
5. The subserver's lifespan is **not** managed by the main server
|
| 297 |
|
| 298 |
-
|
|
|
|
|
|
|
| 299 |
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
```python
|
| 303 |
-
from fastmcp import FastMCP
|
| 304 |
-
|
| 305 |
-
# Create the main server
|
| 306 |
-
main_mcp = FastMCP(name="MainServer")
|
| 307 |
-
|
| 308 |
-
# Create a domain-specific subserver
|
| 309 |
-
weather_mcp = FastMCP(name="WeatherService")
|
| 310 |
-
|
| 311 |
-
@weather_mcp.tool()
|
| 312 |
-
def get_forecast(city: str) -> dict:
|
| 313 |
-
"""Get the weather forecast for a city."""
|
| 314 |
-
return {"city": city, "forecast": "Sunny", "temperature": 72}
|
| 315 |
-
|
| 316 |
-
# Mount the subserver (sync operation)
|
| 317 |
-
main_mcp.mount("weather", weather_mcp)
|
| 318 |
-
|
| 319 |
-
# Later, add another tool to the subserver
|
| 320 |
-
@weather_mcp.tool()
|
| 321 |
-
def get_temperature(city: str) -> float:
|
| 322 |
-
"""Get the current temperature for a city."""
|
| 323 |
-
return 72.5 # Example value
|
| 324 |
-
|
| 325 |
-
# The new tool is automatically available through the main server
|
| 326 |
-
# as "weather_get_temperature"
|
| 327 |
-
|
| 328 |
-
if __name__ == "__main__":
|
| 329 |
-
main_mcp.run()
|
| 330 |
```
|
| 331 |
|
| 332 |
-
##
|
| 333 |
-
|
| 334 |
-
When you mount a server with `main_mcp.mount(prefix, subserver)`:
|
| 335 |
-
|
| 336 |
-
1. A live link is created between the main server and the subserver
|
| 337 |
-
2. Requests for components matching the prefix are delegated to the subserver
|
| 338 |
-
3. Changes to the subserver are **immediately reflected** when accessing through the main server
|
| 339 |
-
4. The subserver's lifespan **is automatically managed** by the main server
|
| 340 |
|
| 341 |
-
|
| 342 |
|
| 343 |
-
|
| 344 |
|
| 345 |
```python
|
| 346 |
-
|
| 347 |
-
await main_mcp.import_server(
|
| 348 |
-
"weather",
|
| 349 |
-
weather_mcp,
|
| 350 |
-
tool_separator="-", # Use "weather-get_forecast" instead of "weather_get_forecast"
|
| 351 |
-
resource_separator=".", # Use "weather.resource://data" instead of "weather+resource://data"
|
| 352 |
-
prompt_separator=":" # Use "weather:prompt_name" instead of "weather_prompt_name"
|
| 353 |
-
)
|
| 354 |
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
weather_mcp,
|
| 359 |
-
tool_separator="-",
|
| 360 |
-
resource_separator=".",
|
| 361 |
-
prompt_separator=":"
|
| 362 |
-
)
|
| 363 |
```
|
| 364 |
|
| 365 |
-
<Warning>
|
| 366 |
-
Some MCP clients may reject certain separators as invalid. For example, Claude Desktop does not support `/` in tool names.
|
| 367 |
-
</Warning>
|
| 368 |
-
|
| 369 |
-
### Comparison
|
| 370 |
-
|
| 371 |
-
| Feature | `import_server()` | `mount()` |
|
| 372 |
-
|---------|------------------|-----------|
|
| 373 |
-
| **Synchronicity** | Async (must be awaited) | Sync |
|
| 374 |
-
| **Composition Type** | One-time copy (static) | Live link (dynamic) |
|
| 375 |
-
| **Updates** | Changes to subserver NOT reflected | Changes immediately reflected |
|
| 376 |
-
| **Lifespan** | Not managed | Automatically managed |
|
| 377 |
-
| **Best For** | Bundling finalized components | Modular runtime composition |
|
| 378 |
-
|
| 379 |
-
For more detailed examples, see the [Server Composition](/patterns/composition) guide.
|
| 380 |
-
|
| 381 |
## Server Configuration
|
| 382 |
|
| 383 |
Server behavior, like transport settings (host, port for SSE) and how duplicate components are handled, can be configured via `ServerSettings`. These settings can be passed during `FastMCP` initialization, set via environment variables (prefixed with `FASTMCP_SERVER_`), or loaded from a `.env` file.
|
|
|
|
| 225 |
|
| 226 |
## Composing Servers
|
| 227 |
|
| 228 |
+
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.
|
| 229 |
|
| 230 |
+
See the [Server Composition](/patterns/composition) guide for full details, best practices, and examples.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
|
| 232 |
```python
|
| 233 |
+
# Example: Importing a subserver
|
| 234 |
from fastmcp import FastMCP
|
| 235 |
import asyncio
|
| 236 |
|
| 237 |
+
main = FastMCP(name="Main")
|
| 238 |
+
sub = FastMCP(name="Sub")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
|
| 240 |
+
@sub.tool()
|
| 241 |
+
def hello():
|
| 242 |
+
return "hi"
|
| 243 |
|
| 244 |
+
main.mount("sub", sub)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
```
|
| 246 |
|
| 247 |
+
## Proxying Servers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
|
| 249 |
+
FastMCP can act as a proxy for any MCP server (local or remote) using `FastMCP.from_client`, 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.
|
| 250 |
|
| 251 |
+
See the [Proxying Servers](/patterns/proxy) guide for details and advanced usage.
|
| 252 |
|
| 253 |
```python
|
| 254 |
+
from fastmcp import FastMCP, Client
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
|
| 256 |
+
backend = Client("http://example.com/mcp/sse")
|
| 257 |
+
proxy = FastMCP.from_client(backend, name="ProxyServer")
|
| 258 |
+
# Now use the proxy like any FastMCP server
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
```
|
| 260 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
## Server Configuration
|
| 262 |
|
| 263 |
Server behavior, like transport settings (host, port for SSE) and how duplicate components are handled, can be configured via `ServerSettings`. These settings can be passed during `FastMCP` initialization, set via environment variables (prefixed with `FASTMCP_SERVER_`), or loaded from a `.env` file.
|
docs/snippets/version-badge.mdx
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export const VersionBadge = ({ version }) => {
|
| 2 |
+
return (
|
| 3 |
+
<span className="version-badge">
|
| 4 |
+
<span className="badge-emoji" aria-hidden="true" style={{ marginRight: '0.3em', verticalAlign: 'middle' }}>✨</span>
|
| 5 |
+
New in version {version}
|
| 6 |
+
</span>
|
| 7 |
+
);
|
| 8 |
+
};
|
docs/style.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
/*
|
| 2 |
p code:not(pre code),
|
| 3 |
table code:not(pre code),
|
| 4 |
li code:not(pre code),
|
|
@@ -9,5 +9,45 @@ h4 code:not(pre code),
|
|
| 9 |
h5 code:not(pre code),
|
| 10 |
h6 code:not(pre code) {
|
| 11 |
color: #f72585 !important;
|
| 12 |
-
background-color:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
}
|
|
|
|
| 1 |
+
/* Code highlighting -- target only inline code elements, not code blocks */
|
| 2 |
p code:not(pre code),
|
| 3 |
table code:not(pre code),
|
| 4 |
li code:not(pre code),
|
|
|
|
| 9 |
h5 code:not(pre code),
|
| 10 |
h6 code:not(pre code) {
|
| 11 |
color: #f72585 !important;
|
| 12 |
+
background-color: rgba(247, 37, 133, 0.09);
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
/* Version badge -- display a badge with the current version of the documentation */
|
| 16 |
+
.version-badge {
|
| 17 |
+
display: inline-flex;
|
| 18 |
+
align-items: center;
|
| 19 |
+
gap: 0.3em;
|
| 20 |
+
padding: 0.32em 1em;
|
| 21 |
+
font-size: 0.92em;
|
| 22 |
+
font-weight: 600;
|
| 23 |
+
letter-spacing: 0.01em;
|
| 24 |
+
color: #7417e5;
|
| 25 |
+
background: #f3e8ff;
|
| 26 |
+
border: 1.5px solid #c084fc;
|
| 27 |
+
border-radius: 6px;
|
| 28 |
+
box-shadow: none;
|
| 29 |
+
vertical-align: middle;
|
| 30 |
+
position: relative;
|
| 31 |
+
transition: box-shadow 0.2s, transform 0.15s;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
.version-badge:hover {
|
| 35 |
+
box-shadow: 0 2px 8px 0 rgba(160, 132, 252, 0.1);
|
| 36 |
+
transform: translateY(-1px) scale(1.03);
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
.dark .version-badge {
|
| 40 |
+
color: #fff;
|
| 41 |
+
background: #312e81;
|
| 42 |
+
border: 1.5px solid #a78bfa;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
.badge-emoji {
|
| 46 |
+
font-size: 1.15em;
|
| 47 |
+
line-height: 1;
|
| 48 |
+
text-shadow: 0 1px 2px #fff, 0 0px 2px #c084fc;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
.dark .badge-emoji {
|
| 52 |
+
text-shadow: 0 1px 2px #312e81, 0 0px 2px #a78bfa;
|
| 53 |
}
|