Client Overview
Learn how to use the FastMCP Client to interact with MCP servers.
New in version: 2.0.0
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.
FastMCP Client
The FastMCP Client architecture separates the protocol logic (Client
) from the connection mechanism (Transport
).
Client
: Handles sending MCP requests (liketools/call
,resources/read
), receiving responses, and managing callbacks.Transport
: Responsible for establishing and maintaining the connection to the server (e.g., via WebSockets, SSE, Stdio, or in-memory).
Transports
Clients must be initialized with a transport
. You can either provide an already instantiated transport object, or provide a transport source and let FastMCP attempt to infer the correct transport to use.
The following inference rules are used to determine the appropriate ClientTransport
based on the input type:
ClientTransport
Instance: If you provide an already instantiated transport object, it’s used directly.FastMCP
Instance: Creates aFastMCPTransport
for efficient in-memory communication (ideal for testing). This also works with a FastMCP 1.0 server created viamcp.server.fastmcp.FastMCP
.Path
orstr
pointing to an existing file:- If it ends with
.py
: Creates aPythonStdioTransport
to run the script usingpython
. - If it ends with
.js
: Creates aNodeStdioTransport
to run the script usingnode
.
- If it ends with
AnyUrl
orstr
pointing to a URL that begins withhttp://
orhttps://
:- Creates a
StreamableHttpTransport
- Creates a
MCPConfig
or dictionary matching MCPConfig schema: Creates a client that connects to one or more MCP servers specified in the config.- Other: Raises a
ValueError
if the type cannot be inferred.
You can also initialize a client from an MCP configuration dictionary or MCPConfig
file:
For more control over connection details (like headers for SSE, environment variables for Stdio), you can instantiate the specific ClientTransport
class yourself and pass it to the Client
. See the Transports page for details.
Multi-Server Clients
New in version: 2.4.0
FastMCP supports creating clients that connect to multiple MCP servers through a single client interface using a standard MCP configuration format (MCPConfig
). This configuration approach makes it easy to connect to multiple specialized servers or create composable systems with a simple, declarative syntax.
The MCP configuration format follows an emerging standard and may evolve as the specification matures. FastMCP will strive to maintain compatibility with future versions, but be aware that field names or structure might change.
When you create a client with an MCPConfig
containing multiple servers:
- FastMCP creates a composite client that internally mounts all servers using their config names as prefixes
- Tools and resources from each server are accessible with appropriate prefixes in the format
servername_toolname
andprotocol://servername/resource/path
- You interact with this as a single unified client, with requests automatically routed to the appropriate server
If your configuration has only a single server, FastMCP will create a direct client to that server without any prefixing.
Client Usage
Connection Lifecycle
The client operates asynchronously and must be used within an async with
block. This context manager handles establishing the connection, initializing the MCP session, and cleaning up resources upon exit.
You can make multiple calls to the server within the same async with
block using the established session.
Client Methods
The Client
provides methods corresponding to standard MCP requests:
The standard client methods return user-friendly representations that may change as the protocol evolves. For consistent access to the complete data structure, use the *_mcp
methods described later.
Tool Operations
list_tools()
: Retrieves a list of tools available on the server.call_tool(name: str, arguments: dict[str, Any] | None = None, timeout: float | None = None, progress_handler: ProgressHandler | None = None)
: Executes a tool on the server.- Arguments are passed as a dictionary. FastMCP servers automatically handle JSON string parsing for complex types if needed.
- Returns a list of content objects (usually
TextContent
orImageContent
). - The optional
timeout
parameter limits the maximum execution time (in seconds) for this specific call, overriding any client-level timeout. - The optional
progress_handler
parameter receives progress updates during execution, overriding any client-level progress handler.
Resource Operations
list_resources()
: Retrieves a list of static resources.list_resource_templates()
: Retrieves a list of resource templates.read_resource(uri: str | AnyUrl)
: Reads the content of a resource or a resolved template.
Prompt Operations
list_prompts()
: Retrieves available prompt templates.get_prompt(name: str, arguments: dict[str, Any] | None = None)
: Retrieves a rendered prompt message list.
Raw MCP Protocol Objects
New in version: 2.2.7
The FastMCP client attempts to provide a “friendly” interface to the MCP protocol, but sometimes you may need access to the raw MCP protocol objects. Each of the main client methods that returns data has a corresponding *_mcp
method that returns the raw MCP protocol objects directly.
The standard client methods (without _mcp
) return user-friendly representations of MCP data, while *_mcp
methods will always return the complete MCP protocol objects. As the protocol evolves, changes to these user-friendly representations may occur and could potentially be breaking. If you need consistent, stable access to the full data structure, prefer using the *_mcp
methods.
Available raw MCP methods:
list_tools_mcp()
: Returnsmcp.types.ListToolsResult
call_tool_mcp(name, arguments)
: Returnsmcp.types.CallToolResult
list_resources_mcp()
: Returnsmcp.types.ListResourcesResult
list_resource_templates_mcp()
: Returnsmcp.types.ListResourceTemplatesResult
read_resource_mcp(uri)
: Returnsmcp.types.ReadResourceResult
list_prompts_mcp()
: Returnsmcp.types.ListPromptsResult
get_prompt_mcp(name, arguments)
: Returnsmcp.types.GetPromptResult
complete_mcp(ref, argument)
: Returnsmcp.types.CompleteResult
These methods are especially useful for debugging or when you need to access metadata or fields that aren’t exposed by the simplified methods.
Additional Features
Pinging the Server
The client can be used to ping the server to verify connectivity.
Session Management
When using stdio transports, clients support a keep_alive
feature (enabled by default) that maintains subprocess sessions between connection contexts. You can manually control this behavior using the client’s close()
method.
When keep_alive=False
, the client will automatically close the session when the context manager exits.
For detailed examples and configuration options, see Session Management in Transports.
Timeouts
New in version: 2.3.4
You can control request timeouts at both the client level and individual request level:
Timeout behavior varies between transport types:
- With SSE transport, the per-request (tool call) timeout always takes precedence, regardless of which is lower.
- With HTTP transport, the lower of the two timeouts (client or tool call) takes precedence.
For consistent behavior across all transports, we recommend explicitly setting timeouts at the individual tool call level when needed, rather than relying on client-level timeouts.
Error Handling
When a call_tool
request results in an error on the server (e.g., the tool function raised an exception), the client.call_tool()
method will raise a fastmcp.exceptions.ClientError
.
Other errors, like connection failures, will raise standard Python exceptions (e.g., ConnectionError
, TimeoutError
).
The client transport often has its own error-handling mechanisms, so you can not always trap errors like those raised by call_tool
outside of the async with
block. Instead, you can use call_tool_mcp()
to get the raw mcp.types.CallToolResult
object and handle errors yourself by checking its isError
attribute.