Programmatic client for interacting with MCP servers through a well-typed, Pythonic interface.
New in version 2.0.0The central piece of MCP client applications is the fastmcp.Client class. This class provides a programmatic interface for interacting with any Model Context Protocol (MCP) server, handling protocol details and connection management automatically.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
Creating the foundation for agentic or LLM-based clients with structured, type-safe operations
All client operations require using the async with context manager for proper connection lifecycle management.
This is not an agentic client - it requires explicit function calls and provides direct control over all MCP operations. Use it as a building block for higher-level systems.
The client automatically infers the appropriate transport based on the input:
FastMCP instance → In-memory transport (perfect for testing)
File path ending in .py → Python Stdio transport
File path ending in .js → Node.js Stdio transport
URL starting with http:// or https:// → HTTP transport
MCPConfig dictionary → Multi-server client
Copy
from fastmcp import Client, FastMCP# Examples of transport inferenceclient_memory = Client(FastMCP("TestServer"))client_script = Client("./server.py")client_http = Client("https://api.example.com/mcp")
For testing and development, always prefer the in-memory transport by passing a FastMCP server directly to the client. This eliminates network complexity and separate processes.
New in version 2.4.0Create 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.
The client operates asynchronously and uses context managers for connection management:
Copy
async def example(): client = Client("my_mcp_server.py") # Connection established here async with client: print(f"Connected: {client.is_connected()}") # Make multiple calls within the same session tools = await client.list_tools() result = await client.call_tool("greet", {"name": "World"}) # Connection closed automatically here print(f"Connected: {client.is_connected()}")
Resources are data sources that the client can read, either static or templated.
Copy
async with client: # List available resources resources = await client.list_resources() # Read a resource content = await client.read_resource("file:///config/settings.json") print(content[0].text)
Prompts are reusable message templates that can accept arguments.
Copy
async with client: # List available prompts prompts = await client.list_prompts() # Get a rendered prompt messages = await client.get_prompt("analyze_data", {"data": [1, 2, 3]}) print(messages.messages)
When you enter the client context manager, the client automatically performs an MCP initialization handshake with the server. This handshake exchanges capabilities, server metadata, and instructions. The result is available through the initialize_result property.
Copy
from fastmcp import Client, FastMCPmcp = FastMCP(name="MyServer", instructions="Use the greet tool to say hello!")@mcp.tooldef 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"Version: {client.initialize_result.serverInfo.version}") print(f"Instructions: {client.initialize_result.instructions}") print(f"Capabilities: {client.initialize_result.capabilities.tools}")
In advanced scenarios, you might want precise control over when initialization happens. For example, you may need custom error handling, want to defer initialization until after other setup, or need to measure initialization timing separately.Disable automatic initialization and call initialize() manually:
Copy
from fastmcp import Client# Disable automatic initializationclient = 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()
The initialize() method is idempotent - calling it multiple times returns the cached result from the first successful call.
Transports - Configure connection methods and parameters
Authentication - Set up OAuth and bearer token authentication
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.