diff --git a/src/fastmcp/server/proxy.py b/src/fastmcp/server/proxy.py index 1493e730e..c388c4d3c 100644 --- a/src/fastmcp/server/proxy.py +++ b/src/fastmcp/server/proxy.py @@ -117,6 +117,7 @@ class ProxyToolManager(ToolManager, ProxyManagerMixin): return ToolResult( content=result.content, structured_content=result.structured_content, + meta=result.meta, ) diff --git a/tests/server/proxy/test_proxy_server.py b/tests/server/proxy/test_proxy_server.py index 72eab2518..3a4344f63 100644 --- a/tests/server/proxy/test_proxy_server.py +++ b/tests/server/proxy/test_proxy_server.py @@ -14,6 +14,7 @@ from fastmcp.client import Client from fastmcp.client.transports import FastMCPTransport, StreamableHttpTransport from fastmcp.exceptions import ToolError from fastmcp.server.proxy import FastMCPProxy, ProxyClient +from fastmcp.tools.tool import ToolResult from fastmcp.tools.tool_transform import ( ToolTransformConfig, ) @@ -216,6 +217,23 @@ class TestTools: async with Client(proxy_server) as client: await client.call_tool("error_tool", {}) + async def test_call_tool_forwards_meta(self, fastmcp_server, proxy_server): + """Test that metadata from proxied tool results is properly forwarded.""" + + @fastmcp_server.tool + def tool_with_meta(value: str) -> ToolResult: + """A tool that returns metadata in its result.""" + return ToolResult( + content=f"Result: {value}", + meta={"custom_key": "custom_value", "processed": True}, + ) + + async with Client(proxy_server) as client: + result = await client.call_tool("tool_with_meta", {"value": "test"}) + + assert result.content[0].text == "Result: test" # type: ignore[attr-defined] + assert result.meta == {"custom_key": "custom_value", "processed": True} + async def test_proxy_can_overwrite_proxied_tool(self, proxy_server): """ Test that a tool defined on the proxy can overwrite the proxied tool with the same name.