-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Description
Problem
When creating a fastmcp.Client
with a specified progress_handler
, that handler is automatically injected into all tool calls made via client.call_tool(...)
. This enables consistent progress reporting at the high level.
However, if a downstream library (such as LangChain’s MCP adapter) accesses the underlying mcp.client.session.ClientSession
from the Client
instance, and makes direct calls using call_tool(..., progress_callback=...)
, the top-level progress_handler
is not inherited. As a result, progress reporting is silently lost in these scenarios.
For example:
from fastmcp import Client
from langchain_mcp_adapters.tools import load_mcp_tools
client = Client(transport=mcp_url, progress_handler=progress_handler)
async with client:
tools = await load_mcp_tools(client.session)
# The tools loaded here are called via `client.session.call_tool(...)` without our top-level handler.
This leads to inconsistent developer experience and makes debugging or tracking progress difficult when third-party libraries use the lower-level session.

Proposed Solution
Enhance ClientSession
to accept a default progress_handler
in its constructor. This handler should be applied automatically for all call_tool(...)
invocations unless explicitly overridden.
Proposed behaviour:

This change would:
- Ensure consistent progress reporting across both high-level and low-level usage.
- Allow third-party integrations (like LangChain) to benefit from centralized handler management without needing to manually propagate it.
- Maintain backward compatibility for existing code that does not use or override progress callbacks.
This enhancement will significantly improve interoperability and user experience when integrating with libraries that interact directly with ClientSession
.