mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 07:09:11 +02:00
* Archive v3 docs under /v3 and publish v4 as the primary version * Label primary docs version v4.0.0 (alpha 1) * Add What's New in v4 page; fix upgrade-guide phrasing; point banner at What's New * Rewrite What's New around v4's new capabilities, not the sampling deprecation * Lead What's New with the SDK v2 engine swap and the SEPs it brings * State ships now (link Session State); tasks arrive next alpha * Exclude docs/v3 frozen snapshots from doc-example import validation
237 lines
8.4 KiB
Text
237 lines
8.4 KiB
Text
---
|
|
title: The FastMCP Client
|
|
sidebarTitle: Overview
|
|
description: Programmatic client for interacting with MCP servers through a well-typed, Pythonic interface.
|
|
icon: user-robot
|
|
---
|
|
|
|
import { VersionBadge } from '/snippets/version-badge.mdx'
|
|
|
|
<VersionBadge version="2.0.0" />
|
|
|
|
The `fastmcp.Client` class provides a programmatic interface for interacting with any MCP server. It handles protocol details and connection management automatically, letting you focus on the operations you want to perform.
|
|
|
|
The FastMCP Client is designed for deterministic, controlled interactions rather than autonomous behavior, making it ideal for testing MCP servers during development, building deterministic applications that need reliable MCP interactions, and creating the foundation for agentic or LLM-based clients with structured, type-safe operations.
|
|
|
|
<Note>
|
|
This is a programmatic client that requires explicit function calls and provides direct control over all MCP operations. Use it as a building block for higher-level systems.
|
|
</Note>
|
|
|
|
## Creating a Client
|
|
|
|
You provide a server source and the client automatically infers the appropriate transport mechanism.
|
|
|
|
```python
|
|
import asyncio
|
|
from fastmcp import Client, FastMCP
|
|
|
|
# In-memory server (ideal for testing)
|
|
server = FastMCP("TestServer")
|
|
client = Client(server)
|
|
|
|
# HTTP server
|
|
client = Client("https://example.com/mcp")
|
|
|
|
# Local Python script
|
|
client = Client("my_mcp_server.py")
|
|
|
|
async def main():
|
|
async with client:
|
|
# Basic server interaction
|
|
await client.ping()
|
|
|
|
# List available operations
|
|
tools = await client.list_tools()
|
|
resources = await client.list_resources()
|
|
prompts = await client.list_prompts()
|
|
|
|
# Execute operations
|
|
result = await client.call_tool("example_tool", {"param": "value"})
|
|
print(result)
|
|
|
|
asyncio.run(main())
|
|
```
|
|
|
|
All client operations require using the `async with` context manager for proper connection lifecycle management.
|
|
|
|
## Choosing a Transport
|
|
|
|
The client automatically selects a transport based on what you pass to it, but different transports have different characteristics that matter for your use case.
|
|
|
|
**In-memory transport** connects directly to a FastMCP server instance within the same Python process. Use this for testing and development where you want to eliminate subprocess and network complexity. The server shares your process's environment and memory space.
|
|
|
|
```python
|
|
from fastmcp import Client, FastMCP
|
|
|
|
server = FastMCP("TestServer")
|
|
client = Client(server) # In-memory, no network or subprocess
|
|
```
|
|
|
|
**STDIO transport** launches a server as a subprocess and communicates through stdin/stdout pipes. This is the standard mechanism used by desktop clients like Claude Desktop. The subprocess runs in an isolated environment, so you must explicitly pass any environment variables the server needs.
|
|
|
|
```python
|
|
from fastmcp import Client
|
|
|
|
# Simple inference from file path
|
|
client = Client("my_server.py")
|
|
|
|
# With explicit environment configuration
|
|
client = Client("my_server.py", env={"API_KEY": "secret"})
|
|
```
|
|
|
|
**HTTP transport** connects to servers running as web services. Use this for production deployments where the server runs independently and manages its own lifecycle.
|
|
|
|
```python
|
|
from fastmcp import Client
|
|
|
|
client = Client("https://api.example.com/mcp")
|
|
```
|
|
|
|
See [Transports](/clients/transports) for detailed configuration options including authentication headers, session persistence, and multi-server configurations.
|
|
|
|
## Configuration-Based Clients
|
|
|
|
<VersionBadge version="2.4.0" />
|
|
|
|
Create clients from MCP configuration dictionaries, which can include multiple servers. While there is no official standard for MCP configuration format, FastMCP follows established conventions used by tools like Claude Desktop.
|
|
|
|
```python
|
|
config = {
|
|
"mcpServers": {
|
|
"weather": {
|
|
"url": "https://weather-api.example.com/mcp"
|
|
},
|
|
"assistant": {
|
|
"command": "python",
|
|
"args": ["./assistant_server.py"]
|
|
}
|
|
}
|
|
}
|
|
|
|
client = Client(config)
|
|
|
|
async with client:
|
|
# Tools are prefixed with server names
|
|
weather_data = await client.call_tool("weather_get_forecast", {"city": "London"})
|
|
response = await client.call_tool("assistant_answer_question", {"question": "What's the capital of France?"})
|
|
|
|
# Resources use prefixed URIs
|
|
icons = await client.read_resource("weather://weather/icons/sunny")
|
|
```
|
|
|
|
## Connection Lifecycle
|
|
|
|
The client uses context managers for connection management. When you enter the context, the client establishes a connection and performs an MCP initialization handshake with the server. This handshake exchanges capabilities, server metadata, and instructions.
|
|
|
|
```python
|
|
from fastmcp import Client, FastMCP
|
|
|
|
mcp = FastMCP(name="MyServer", instructions="Use the greet tool to say hello!")
|
|
|
|
@mcp.tool
|
|
def greet(name: str) -> str:
|
|
"""Greet a user by name."""
|
|
return f"Hello, {name}!"
|
|
|
|
async with Client(mcp) as client:
|
|
# Initialization already happened automatically
|
|
print(f"Server: {client.initialize_result.serverInfo.name}")
|
|
print(f"Instructions: {client.initialize_result.instructions}")
|
|
print(f"Capabilities: {client.initialize_result.capabilities.tools}")
|
|
```
|
|
|
|
For advanced scenarios where you need precise control over when initialization happens, disable automatic initialization and call `initialize()` manually:
|
|
|
|
```python
|
|
from fastmcp import Client
|
|
|
|
client = Client("my_mcp_server.py", auto_initialize=False)
|
|
|
|
async with client:
|
|
# Connection established, but not initialized yet
|
|
print(f"Connected: {client.is_connected()}")
|
|
print(f"Initialized: {client.initialize_result is not None}") # False
|
|
|
|
# Initialize manually with custom timeout
|
|
result = await client.initialize(timeout=10.0)
|
|
print(f"Server: {result.serverInfo.name}")
|
|
|
|
# Now ready for operations
|
|
tools = await client.list_tools()
|
|
```
|
|
|
|
## Operations
|
|
|
|
FastMCP clients interact with three types of server components.
|
|
|
|
**Tools** are server-side functions that the client can execute with arguments. Call them with `call_tool()` and receive structured results.
|
|
|
|
```python
|
|
async with client:
|
|
tools = await client.list_tools()
|
|
result = await client.call_tool("multiply", {"a": 5, "b": 3})
|
|
print(result.data) # 15
|
|
```
|
|
|
|
See [Tools](/clients/tools) for detailed documentation including version selection, error handling, and structured output.
|
|
|
|
**Resources** are data sources that the client can read, either static or templated. Access them with `read_resource()` using URIs.
|
|
|
|
```python
|
|
async with client:
|
|
resources = await client.list_resources()
|
|
content = await client.read_resource("file:///config/settings.json")
|
|
print(content[0].text)
|
|
```
|
|
|
|
See [Resources](/clients/resources) for detailed documentation including templates and binary content.
|
|
|
|
**Prompts** are reusable message templates that can accept arguments. Retrieve rendered prompts with `get_prompt()`.
|
|
|
|
```python
|
|
async with client:
|
|
prompts = await client.list_prompts()
|
|
messages = await client.get_prompt("analyze_data", {"data": [1, 2, 3]})
|
|
print(messages.messages)
|
|
```
|
|
|
|
See [Prompts](/clients/prompts) for detailed documentation including argument serialization.
|
|
|
|
## Callback Handlers
|
|
|
|
The client supports callback handlers for advanced server interactions. These let you respond to server-initiated requests and receive notifications.
|
|
|
|
```python
|
|
from fastmcp import Client
|
|
from fastmcp.client.logging import LogMessage
|
|
|
|
async def log_handler(message: LogMessage):
|
|
print(f"Server log: {message.data}")
|
|
|
|
async def progress_handler(progress: float, total: float | None, message: str | None):
|
|
print(f"Progress: {progress}/{total} - {message}")
|
|
|
|
async def sampling_handler(messages, params, context):
|
|
# Integrate with your LLM service here
|
|
return "Generated response"
|
|
|
|
client = Client(
|
|
"my_mcp_server.py",
|
|
log_handler=log_handler,
|
|
progress_handler=progress_handler,
|
|
sampling_handler=sampling_handler,
|
|
timeout=30.0
|
|
)
|
|
```
|
|
|
|
Each handler type has its own documentation:
|
|
|
|
- **[Sampling](/clients/sampling)** - Respond to server LLM requests
|
|
- **[Elicitation](/clients/elicitation)** - Handle server requests for user input
|
|
- **[Progress](/clients/progress)** - Monitor long-running operations
|
|
- **[Logging](/clients/logging)** - Handle server log messages
|
|
- **[Roots](/clients/roots)** - Provide local context to servers
|
|
|
|
<Tip>
|
|
The FastMCP Client is designed as a foundational tool. Use it directly for deterministic operations, or build higher-level agentic systems on top of its reliable, type-safe interface.
|
|
</Tip>
|