[Draft] Introduce a module for rewriting Tools
In this PR, I've collected some of my thoughts on tool re-writing.
The tool_transform function in this PR offers the ability to:
- Modify top-level arguments of an existing tool (e.g., setting constant values, providing new defaults, changing descriptions).
- Add new primitive parameters that are not passed to the original tool but are available to custom hook functions.
- Execute custom logic before a tool call (e.g., logging, input validation, conditional logic via
pre_call_hook). - Process the response from a tool before returning it (e.g., filtering, transforming, logging, rejecting via
post_call_hook).
It does it entirely within the existing tool infrastructure without any changes to FastMCP.
Simple transformations look like this (update name):
proxy_tool(
proxied_tools["convert_time"],
server=frontend_server,
name="transformed_convert_time",
)
``
As Code:
proxied_mcp_server = FastMCP.as_proxy(remote_mcp_client)
proxied_tools = await proxied_mcp_server.get_tools()
frontend_server = FastMCP("Frontend Server")
proxy_tool(
proxied_tools["convert_time"],
server=frontend_server,
name="transformed_convert_time",
description="Converts a time from New York to another timezone.",
parameter_overrides=[
ToolParameter[str](
name="source_timezone",
description="The timezone of the time to convert.",
constant="America/New_York", # Source Timezone is now required to be America/New_York
),
ToolParameter[str](
name="time",
description="The time to convert. Must be in the format HH:MM. Default is 3:00.",
default="3:00", # Time now defaults to 3:00
),
# No override of the override the target_timezone parameter
],
)
With a Loader class for loading basic transformations from yaml and `proxy_mcp_server_with_overrides` for one-shot mcp server + proxy
@jlowin I have cleaned this up a bunch
The latest version of this is vendored into here https://github.com/strawgate/fastmcp-agents/tree/main/src/fastmcp_agents/vendored/tool_transformer
The new setup is to either call transform_tool as before or build the Tool Override model:
tool_override = ToolOverride(
name="transformed_convert_time",
description="Converts a time from New York to another timezone.",
parameter_overrides=[
ToolParameter[str](
name="source_timezone",
description="The timezone of the time to convert.",
constant="America/New_York", # Source Timezone is now required to be America/New_York
),
ToolParameter[str](
name="time",
description="The time to convert. Must be in the format HH:MM. Default is 3:00.",
default="3:00", # Time now defaults to 3:00
),
# No override of the override the target_timezone parameter
]
)
And then you can apply it to any FastMCP Tool:
wrapped_tool = tool_override.apply_to_tool(tool)
Closed via https://github.com/jlowin/fastmcp/pull/745#event-18065040147