Spaces:
Running
Running
Jeremiah Lowin commited on
Commit ·
925b34b
1
Parent(s): 09d1b8e
Update README.md
Browse files
README.md
CHANGED
|
@@ -42,10 +42,11 @@ FastMCP handles the complex protocol details and server management, letting you
|
|
| 42 |
## Key Features:
|
| 43 |
|
| 44 |
* **Simple Server Creation:** Build MCP servers with minimal boilerplate using intuitive decorators (`@tool`, `@resource`, `@prompt`).
|
| 45 |
-
* **
|
| 46 |
-
* **Proxy MCP Servers:** 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).
|
| 47 |
* **Compose MCP Servers:** Compose complex applications by mounting multiple FastMCP servers together.
|
| 48 |
* **API Generation:** Automatically create MCP servers from existing **OpenAPI specifications** or **FastAPI applications**.
|
|
|
|
|
|
|
| 49 |
* **Pythonic Interface:** Designed with familiar Python patterns like decorators and type hints.
|
| 50 |
* **Context Injection:** Easily access core MCP capabilities like sampling, logging, and progress reporting within your functions.
|
| 51 |
|
|
@@ -80,10 +81,12 @@ FastMCP v1's core approach of using the `@tool`, `@resource`, `@prompt` decorato
|
|
| 80 |
- [Context](#context)
|
| 81 |
- [Images](#images)
|
| 82 |
- [Advanced Features](#advanced-features)
|
| 83 |
-
- [MCP Client](#mcp-client)
|
| 84 |
- [Proxy Servers](#proxy-servers)
|
| 85 |
- [Composing MCP Servers](#composing-mcp-servers)
|
| 86 |
- [OpenAPI \& FastAPI Generation](#openapi--fastapi-generation)
|
|
|
|
|
|
|
|
|
|
| 87 |
- [Running Your Server](#running-your-server)
|
| 88 |
- [Development Mode (Recommended for Building \& Testing)](#development-mode-recommended-for-building--testing)
|
| 89 |
- [Claude Desktop Integration (For Regular Use)](#claude-desktop-integration-for-regular-use)
|
|
@@ -340,38 +343,6 @@ FastMCP handles the conversion to/from the base64-encoded format required by the
|
|
| 340 |
|
| 341 |
Building on the core concepts, FastMCP v2 introduces powerful features for more complex scenarios:
|
| 342 |
|
| 343 |
-
### MCP Client
|
| 344 |
-
|
| 345 |
-
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.
|
| 346 |
-
|
| 347 |
-
```python
|
| 348 |
-
import asyncio
|
| 349 |
-
from fastmcp import Client
|
| 350 |
-
from fastmcp.client.transports import StdioTransport # Example transport
|
| 351 |
-
|
| 352 |
-
async def main():
|
| 353 |
-
# Connect to a server running via standard I/O
|
| 354 |
-
# Replace with the actual command to start your target server
|
| 355 |
-
client = Client(StdioTransport(command="python", args=["path/to/target_server.py"]))
|
| 356 |
-
|
| 357 |
-
async with client:
|
| 358 |
-
# Discover tools
|
| 359 |
-
tools_result = await client.list_tools()
|
| 360 |
-
print(f"Available Tools: {[t.name for t in tools_result.tools]}")
|
| 361 |
-
|
| 362 |
-
# Call a tool
|
| 363 |
-
add_result = await client.call_tool("add", {"a": 10, "b": 5})
|
| 364 |
-
print(f"Result of add(10, 5): {add_result.content[0].text}") # Output: 15
|
| 365 |
-
|
| 366 |
-
# Read a resource
|
| 367 |
-
greeting = await client.read_resource("greeting://Client")
|
| 368 |
-
print(f"Resource Content: {greeting.contents[0].text}") # Output: Hello, Client!
|
| 369 |
-
|
| 370 |
-
if __name__ == "__main__":
|
| 371 |
-
asyncio.run(main())
|
| 372 |
-
```
|
| 373 |
-
|
| 374 |
-
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.).
|
| 375 |
|
| 376 |
### Proxy Servers
|
| 377 |
|
|
@@ -509,6 +480,80 @@ if __name__ == "__main__":
|
|
| 509 |
mcp_server.run()
|
| 510 |
```
|
| 511 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 512 |
## Running Your Server
|
| 513 |
|
| 514 |
Choose the method that best suits your needs:
|
|
@@ -569,6 +614,7 @@ Explore the `examples/` directory for code samples demonstrating various feature
|
|
| 569 |
* `simple_echo.py`: Basic tool, resource, and prompt.
|
| 570 |
* `complex_inputs.py`: Using Pydantic models for tool inputs.
|
| 571 |
* `mount_example.py`: Mounting multiple FastMCP servers.
|
|
|
|
| 572 |
* `screenshot.py`: Tool returning an Image object.
|
| 573 |
* `text_me.py`: Tool interacting with an external API.
|
| 574 |
* `memory.py`: More complex example with database interaction.
|
|
|
|
| 42 |
## Key Features:
|
| 43 |
|
| 44 |
* **Simple Server Creation:** Build MCP servers with minimal boilerplate using intuitive decorators (`@tool`, `@resource`, `@prompt`).
|
| 45 |
+
* **Proxy MCP Servers:** 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).
|
|
|
|
| 46 |
* **Compose MCP Servers:** Compose complex applications by mounting multiple FastMCP servers together.
|
| 47 |
* **API Generation:** Automatically create MCP servers from existing **OpenAPI specifications** or **FastAPI applications**.
|
| 48 |
+
* **Powerful Clients:** Programmatically interact with *any* MCP server, regardless of how it was built.
|
| 49 |
+
* **LLM Sampling:** Request completions from client LLMs directly within your MCP tools.
|
| 50 |
* **Pythonic Interface:** Designed with familiar Python patterns like decorators and type hints.
|
| 51 |
* **Context Injection:** Easily access core MCP capabilities like sampling, logging, and progress reporting within your functions.
|
| 52 |
|
|
|
|
| 81 |
- [Context](#context)
|
| 82 |
- [Images](#images)
|
| 83 |
- [Advanced Features](#advanced-features)
|
|
|
|
| 84 |
- [Proxy Servers](#proxy-servers)
|
| 85 |
- [Composing MCP Servers](#composing-mcp-servers)
|
| 86 |
- [OpenAPI \& FastAPI Generation](#openapi--fastapi-generation)
|
| 87 |
+
- [MCP Client](#mcp-client)
|
| 88 |
+
- [LLM Sampling](#llm-sampling)
|
| 89 |
+
- [Roots Access](#roots-access)
|
| 90 |
- [Running Your Server](#running-your-server)
|
| 91 |
- [Development Mode (Recommended for Building \& Testing)](#development-mode-recommended-for-building--testing)
|
| 92 |
- [Claude Desktop Integration (For Regular Use)](#claude-desktop-integration-for-regular-use)
|
|
|
|
| 343 |
|
| 344 |
Building on the core concepts, FastMCP v2 introduces powerful features for more complex scenarios:
|
| 345 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 346 |
|
| 347 |
### Proxy Servers
|
| 348 |
|
|
|
|
| 480 |
mcp_server.run()
|
| 481 |
```
|
| 482 |
|
| 483 |
+
### MCP Client
|
| 484 |
+
|
| 485 |
+
The `Client` class lets you interact with any MCP server (not just FastMCP ones) from Python code:
|
| 486 |
+
|
| 487 |
+
```python
|
| 488 |
+
from fastmcp import Client
|
| 489 |
+
|
| 490 |
+
async with Client("path/to/server") as client:
|
| 491 |
+
# Call a tool
|
| 492 |
+
result = await client.call_tool("weather", {"location": "San Francisco"})
|
| 493 |
+
print(result)
|
| 494 |
+
|
| 495 |
+
# Read a resource
|
| 496 |
+
res = await client.read_resource("db://users/123/profile")
|
| 497 |
+
print(res)
|
| 498 |
+
```
|
| 499 |
+
|
| 500 |
+
You can connect to servers using any supported transport protocol (Stdio, SSE, FastMCP, etc.). If you don't specify a transport, the `Client` class automatically attempts to detect an appropriate one from your connection string or server object.
|
| 501 |
+
|
| 502 |
+
#### LLM Sampling
|
| 503 |
+
|
| 504 |
+
Sampling is an MCP feature that allows a server to request a completion from the client LLM, enabling sophisticated use cases while maintaining security and privacy on the server.
|
| 505 |
+
|
| 506 |
+
```python
|
| 507 |
+
import marvin # Or any other LLM client
|
| 508 |
+
from fastmcp import Client, Context, FastMCP
|
| 509 |
+
from fastmcp.client.sampling import RequestContext, SamplingMessage, SamplingParams
|
| 510 |
+
|
| 511 |
+
# -- Create a server that requests LLM completions from the client
|
| 512 |
+
|
| 513 |
+
mcp = FastMCP("Sampling Example")
|
| 514 |
+
|
| 515 |
+
@mcp.tool()
|
| 516 |
+
async def generate_poem(topic: str, context: Context) -> str:
|
| 517 |
+
"""Generate a short poem about the given topic."""
|
| 518 |
+
response = await context.sample(
|
| 519 |
+
f"Write a short poem about {topic}",
|
| 520 |
+
system_prompt="You are a talented poet who writes concise, evocative verses."
|
| 521 |
+
)
|
| 522 |
+
return response.text
|
| 523 |
+
|
| 524 |
+
# -- Create a client that handles the sampling requests
|
| 525 |
+
|
| 526 |
+
async def sampling_handler(
|
| 527 |
+
messages: list[SamplingMessage],
|
| 528 |
+
params: SamplingParams,
|
| 529 |
+
ctx: RequestContext,
|
| 530 |
+
) -> str:
|
| 531 |
+
# Use your preferred LLM client to generate completions
|
| 532 |
+
return await marvin.say_async(
|
| 533 |
+
message=[m.content.text for m in messages if m.content.type == "text"],
|
| 534 |
+
instructions=params.systemPrompt,
|
| 535 |
+
)
|
| 536 |
+
|
| 537 |
+
# Connect them together
|
| 538 |
+
async with Client(mcp, sampling_handler=sampling_handler) as client:
|
| 539 |
+
result = await client.call_tool("generate_poem", {"topic": "autumn leaves"})
|
| 540 |
+
print(result.content[0].text)
|
| 541 |
+
```
|
| 542 |
+
|
| 543 |
+
#### Roots Access
|
| 544 |
+
|
| 545 |
+
FastMCP exposes the MCP roots functionality, allowing clients to specify which file system roots they can access. This creates a secure boundary for tools that need to work with files. Note that the server must account for client roots explicitly.
|
| 546 |
+
|
| 547 |
+
```python
|
| 548 |
+
from fastmcp import Client, RootsList
|
| 549 |
+
|
| 550 |
+
# Specify file roots that the client can access
|
| 551 |
+
roots = ["file:///path/to/allowed/directory"]
|
| 552 |
+
|
| 553 |
+
async with Client(mcp_server, roots=roots) as client:
|
| 554 |
+
# Now tools in the MCP server can access files in the specified roots
|
| 555 |
+
await client.call_tool("process_file", {"filename": "data.csv"})
|
| 556 |
+
```
|
| 557 |
## Running Your Server
|
| 558 |
|
| 559 |
Choose the method that best suits your needs:
|
|
|
|
| 614 |
* `simple_echo.py`: Basic tool, resource, and prompt.
|
| 615 |
* `complex_inputs.py`: Using Pydantic models for tool inputs.
|
| 616 |
* `mount_example.py`: Mounting multiple FastMCP servers.
|
| 617 |
+
* `sampling.py`: Using LLM completions within your MCP server.
|
| 618 |
* `screenshot.py`: Tool returning an Image object.
|
| 619 |
* `text_me.py`: Tool interacting with an external API.
|
| 620 |
* `memory.py`: More complex example with database interaction.
|