mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-22 21:44:18 +02:00
fix: apply prefix to tool name when mounting servers
When mounting a server with a prefix, both the key and name fields
should be updated to include the prefix. Previously only the key was
updated, causing inconsistency between tool.key and tool.name.
This makes tool prefixing consistent with how resources and templates
are already handled.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
72b9acd707
commit
4f7e739a35
2 changed files with 48 additions and 2 deletions
|
|
@ -464,7 +464,12 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
child_tools = await mounted.server.get_tools()
|
||||
for key, tool in child_tools.items():
|
||||
new_key = f"{mounted.prefix}_{key}" if mounted.prefix else key
|
||||
all_tools[new_key] = tool.model_copy(key=new_key)
|
||||
all_tools[new_key] = tool.model_copy(
|
||||
key=new_key,
|
||||
update={"name": f"{mounted.prefix}_{tool.name}"}
|
||||
if mounted.prefix
|
||||
else {},
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Failed to get tools from mounted server {mounted.server.name!r}: {e}"
|
||||
|
|
@ -722,7 +727,9 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
key = tool.key
|
||||
if mounted.prefix:
|
||||
key = f"{mounted.prefix}_{tool.key}"
|
||||
tool = tool.model_copy(key=key)
|
||||
tool = tool.model_copy(
|
||||
key=key, update={"name": f"{mounted.prefix}_{tool.name}"}
|
||||
)
|
||||
# Later mounted servers override earlier ones
|
||||
all_tools[key] = tool
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -972,6 +972,45 @@ class TestAsProxyKwarg:
|
|||
assert lifespan_check.count("start") >= 2
|
||||
|
||||
|
||||
class TestToolNamePrefixing:
|
||||
"""Test that tool names are prefixed when mounted."""
|
||||
|
||||
async def test_tool_name_prefixing(self):
|
||||
"""Test that tool names (not just keys) are prefixed when mounted with a prefix."""
|
||||
# Create a sub-app with a tool
|
||||
sub_app = FastMCP("SubApp")
|
||||
|
||||
@sub_app.tool
|
||||
def my_tool() -> str:
|
||||
return "Tool result"
|
||||
|
||||
# Create main app and mount sub-app with prefix
|
||||
main_app = FastMCP("MainApp")
|
||||
main_app.mount(sub_app, "prefix")
|
||||
|
||||
# Get tools from main app
|
||||
tools = await main_app.get_tools()
|
||||
|
||||
# Should have prefixed key
|
||||
assert "prefix_my_tool" in tools
|
||||
|
||||
# The tool name should also be prefixed
|
||||
tool = tools["prefix_my_tool"]
|
||||
assert tool.name == "prefix_my_tool"
|
||||
assert tool.key == "prefix_my_tool"
|
||||
|
||||
# Test via client to ensure both discovery and calling work
|
||||
async with Client(main_app) as client:
|
||||
# List tools should show prefixed name
|
||||
tool_list = await client.list_tools()
|
||||
tool_names = [t.name for t in tool_list]
|
||||
assert "prefix_my_tool" in tool_names
|
||||
|
||||
# Calling with the prefixed name should work
|
||||
result = await client.call_tool("prefix_my_tool", {})
|
||||
assert result.data == "Tool result"
|
||||
|
||||
|
||||
class TestResourceNamePrefixing:
|
||||
"""Test that resource and resource template names get prefixed when mounted."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue