Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/fastmcp/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,19 @@ def __init__(
) -> None:
self.name = name or self.generate_name()

self.transport = cast(ClientTransportT, infer_transport(transport))
client_kwargs = {
"progress_handler": progress_handler,
"sampling_handler": sampling_handler,
"elicitation_handler": elicitation_handler,
"log_handler": log_handler,
"message_handler": message_handler,
"timeout": timeout,
"auto_initialize": auto_initialize,
"init_timeout": init_timeout,
"client_info": client_info,
"auth": auth,
}
self.transport = cast(ClientTransportT, infer_transport(transport, **client_kwargs))
if auth is not None:
self.transport._set_auth(auth)

Expand Down
12 changes: 9 additions & 3 deletions src/fastmcp/client/transports.py
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ class MCPConfigTransport(ClientTransport):
```
"""

def __init__(self, config: MCPConfig | dict, name_as_prefix: bool = True):
def __init__(self, config: MCPConfig | dict, name_as_prefix: bool = True, **client_kwargs: Any):
from fastmcp.utilities.mcp_config import mcp_config_to_servers_and_transports

if isinstance(config, dict):
Expand All @@ -961,7 +961,7 @@ def __init__(self, config: MCPConfig | dict, name_as_prefix: bool = True):
self._composite_server = FastMCP[Any](name=name)

for name, server, transport in mcp_config_to_servers_and_transports(
self.config
self.config, **client_kwargs
):
self._underlying_transports.append(transport)
self._composite_server.mount(
Expand Down Expand Up @@ -1000,6 +1000,9 @@ def infer_transport(transport: FastMCP1Server) -> FastMCPTransport: ...
@overload
def infer_transport(transport: MCPConfig) -> MCPConfigTransport: ...

@overload
def infer_transport(transport: MCPConfig, **client_kwargs: Any) -> MCPConfigTransport: ...


@overload
def infer_transport(transport: dict[str, Any]) -> MCPConfigTransport: ...
Expand Down Expand Up @@ -1032,6 +1035,7 @@ def infer_transport(
| MCPConfig
| dict[str, Any]
| str,
**client_kwargs: Any,
) -> ClientTransport:
"""
Infer the appropriate transport type from the given transport argument.
Expand Down Expand Up @@ -1107,8 +1111,10 @@ def infer_transport(

# if the transport is a config dict or MCPConfig
elif isinstance(transport, dict | MCPConfig):
print(f"client_kwargs: {client_kwargs}")
Comment thread
cegersdoerfer marked this conversation as resolved.
Outdated
inferred_transport = MCPConfigTransport(
config=cast(dict | MCPConfig, transport)
config=cast(dict | MCPConfig, transport),
**client_kwargs,
)

# the transport is an unknown type
Expand Down
3 changes: 2 additions & 1 deletion src/fastmcp/mcp_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def _to_server_and_underlying_transport(
self,
server_name: str | None = None,
client_name: str | None = None,
**client_kwargs: Any,
) -> tuple[FastMCP[Any], ClientTransport]:
"""Turn the Transforming MCPServer into a FastMCP Server and also return the underlying transport."""
from fastmcp import FastMCP
Expand All @@ -104,7 +105,7 @@ def _to_server_and_underlying_transport(
transport: ClientTransport = super().to_transport() # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue, reportUnknownVariableType] # ty: ignore[unresolved-attribute]
transport = cast(ClientTransport, transport)

client: Client[ClientTransport] = Client(transport=transport, name=client_name)
client: Client[ClientTransport] = Client(transport=transport, name=client_name, **client_kwargs)

wrapped_mcp_server = FastMCP.as_proxy(
name=server_name,
Expand Down
5 changes: 5 additions & 0 deletions src/fastmcp/server/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,16 @@ async def run(
arguments: dict[str, Any],
context: Context | None = None,
) -> ToolResult:
from fastmcp.utilities.types import find_kwarg_by_type
Comment thread
cegersdoerfer marked this conversation as resolved.
Outdated
"""Executes the tool by making a call through the client."""
async with self._client:
context = get_context()
# try to get request context meta
meta = dict(context.request_context.meta) if hasattr(context, 'request_context') and hasattr(context.request_context, 'meta') else None
result = await self._client.call_tool_mcp(
name=self.name,
arguments=arguments,
meta=meta
)
if result.isError:
raise ToolError(cast(mcp.types.TextContent, result.content[0]).text)
Expand Down
11 changes: 8 additions & 3 deletions src/fastmcp/utilities/mcp_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@

def mcp_config_to_servers_and_transports(
config: MCPConfig,
**client_kwargs: Any,
) -> list[tuple[str, FastMCP[Any], ClientTransport]]:
"""A utility function to convert each entry of an MCP Config into a transport and server."""
return [
mcp_server_type_to_servers_and_transports(name, mcp_server)
mcp_server_type_to_servers_and_transports(name, mcp_server, **client_kwargs)
for name, mcp_server in config.mcpServers.items()
]


def mcp_server_type_to_servers_and_transports(
name: str,
mcp_server: MCPServerTypes,
**client_kwargs: Any,
) -> tuple[str, FastMCP[Any], ClientTransport]:
"""A utility function to convert each entry of an MCP Config into a transport and server."""

Expand All @@ -44,14 +46,17 @@ def mcp_server_type_to_servers_and_transports(
if isinstance(mcp_server, TransformingRemoteMCPServer | TransformingStdioMCPServer):
server, transport = mcp_server._to_server_and_underlying_transport(
server_name=server_name,
client_name=client_name,
client_name=client_name
)
Comment thread
cegersdoerfer marked this conversation as resolved.
else:
print("non transforming server")
Comment thread
cegersdoerfer marked this conversation as resolved.
Outdated
transport = mcp_server.to_transport()
client: ProxyClient[StreamableHttpTransport | SSETransport | StdioTransport] = (
ProxyClient(transport=transport, name=client_name)
ProxyClient(transport=transport, name=client_name, **client_kwargs)
)

server = FastMCP.as_proxy(name=server_name, backend=client)
print(f"new proxy server: {server}")
print(f"proxy server progress handler: {client._progress_handler}")
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

return name, server, transport
Loading