fastmcp icon indicating copy to clipboard operation
fastmcp copied to clipboard

[Draft] Introduce a module for rewriting Tools

Open strawgate opened this issue 7 months ago • 1 comments

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

strawgate avatar May 26 '25 01:05 strawgate

@jlowin I have cleaned this up a bunch

strawgate avatar May 29 '25 18:05 strawgate

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)

strawgate avatar Jun 03 '25 13:06 strawgate

Closed via https://github.com/jlowin/fastmcp/pull/745#event-18065040147

strawgate avatar Jun 10 '25 02:06 strawgate