Skip to content

Commit e62d2dd

Browse files
authored
Manually set _key after model_copy (#1357)
1 parent d4fc44f commit e62d2dd

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

src/fastmcp/utilities/components.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ def get_meta(
9292
return meta or None
9393

9494
def with_key(self, key: str) -> Self:
95-
return self.model_copy(update={"_key": key})
95+
# `model_copy` has an `update` parameter but it doesn't work for certain private attributes
96+
# https://github.com/pydantic/pydantic/issues/12116
97+
# So we manually set the private attribute here instead
98+
copy = self.model_copy()
99+
copy._key = key
100+
return copy
96101

97102
def __eq__(self, other: object) -> bool:
98103
if type(self) is not type(other):

tests/server/test_mount.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from fastmcp.client import Client
99
from fastmcp.client.transports import FastMCPTransport, SSETransport
1010
from fastmcp.server.proxy import FastMCPProxy
11+
from fastmcp.tools.tool import Tool
12+
from fastmcp.tools.tool_transform import TransformedTool
1113
from fastmcp.utilities.tests import caplog_for_fastmcp
1214

1315

@@ -18,22 +20,29 @@ async def test_mount_simple_server(self):
1820
"""Test mounting a simple server and accessing its tool."""
1921
# Create main app and sub-app
2022
main_app = FastMCP("MainApp")
21-
sub_app = FastMCP("SubApp")
2223

2324
# Add a tool to the sub-app
24-
@sub_app.tool
25-
def sub_tool() -> str:
25+
def tool() -> str:
2626
return "This is from the sub app"
2727

28+
sub_tool = Tool.from_function(tool)
29+
30+
transformed_tool = TransformedTool.from_tool(
31+
name="transformed_tool", tool=sub_tool
32+
)
33+
34+
sub_app = FastMCP("SubApp", tools=[transformed_tool, sub_tool])
35+
2836
# Mount the sub-app to the main app
2937
main_app.mount(sub_app, "sub")
3038

3139
# Get tools from main app, should include sub_app's tools
3240
tools = await main_app.get_tools()
33-
assert "sub_sub_tool" in tools
41+
assert "sub_tool" in tools
42+
assert "sub_transformed_tool" in tools
3443

3544
async with Client(main_app) as client:
36-
result = await client.call_tool("sub_sub_tool", {})
45+
result = await client.call_tool("sub_tool", {})
3746
assert result.data == "This is from the sub app"
3847

3948
async def test_mount_with_custom_separator(self):

0 commit comments

Comments
 (0)