mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-19 20:14:17 +02:00
fix(server): preserve mounted tool task metadata (#3632)
* fix(server): preserve mounted tool task metadata * fix(server): move task execution metadata to base tool * cleanup: remove stale import, tighten execution metadata guard --------- Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
This commit is contained in:
parent
b1505ba5d7
commit
59a126a0b6
4 changed files with 41 additions and 21 deletions
|
|
@ -104,6 +104,7 @@ class FastMCPProviderTool(Tool):
|
|||
tags=tool.tags,
|
||||
annotations=tool.annotations,
|
||||
task_config=tool.task_config,
|
||||
execution=tool.execution,
|
||||
meta=tool.get_meta(),
|
||||
title=tool.title,
|
||||
icons=tool.icons,
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class Tool(FastMCPComponent):
|
|||
elif self.annotations and self.annotations.title:
|
||||
title = self.annotations.title
|
||||
|
||||
return MCPTool(
|
||||
mcp_tool = MCPTool(
|
||||
name=overrides.get("name", self.name),
|
||||
title=overrides.get("title", title),
|
||||
description=overrides.get("description", self.description),
|
||||
|
|
@ -204,6 +204,15 @@ class Tool(FastMCPComponent):
|
|||
), # ty:ignore[unknown-argument]
|
||||
)
|
||||
|
||||
if (
|
||||
self.task_config.supports_tasks()
|
||||
and "execution" not in overrides
|
||||
and not self.execution
|
||||
):
|
||||
mcp_tool.execution = ToolExecution(taskSupport=self.task_config.mode)
|
||||
|
||||
return mcp_tool
|
||||
|
||||
@classmethod
|
||||
def from_function(
|
||||
cls,
|
||||
|
|
|
|||
|
|
@ -18,9 +18,8 @@ from typing import (
|
|||
)
|
||||
|
||||
import anyio
|
||||
import mcp.types
|
||||
from mcp.shared.exceptions import McpError
|
||||
from mcp.types import ErrorData, Icon, ToolAnnotations, ToolExecution
|
||||
from mcp.types import ErrorData, Icon, ToolAnnotations
|
||||
from pydantic import Field
|
||||
from pydantic.json_schema import SkipJsonSchema
|
||||
|
||||
|
|
@ -91,24 +90,6 @@ class FunctionTool(Tool):
|
|||
fn: SkipJsonSchema[Callable[..., Any]]
|
||||
return_type: Annotated[SkipJsonSchema[Any], Field(exclude=True)] = None
|
||||
|
||||
def to_mcp_tool(
|
||||
self,
|
||||
**overrides: Any,
|
||||
) -> mcp.types.Tool:
|
||||
"""Convert the FastMCP tool to an MCP tool.
|
||||
|
||||
Extends the base implementation to add task execution mode if enabled.
|
||||
"""
|
||||
# Get base MCP tool from parent
|
||||
mcp_tool = super().to_mcp_tool(**overrides)
|
||||
|
||||
# Add task execution mode per SEP-1686
|
||||
# Only set execution if not overridden and task execution is supported
|
||||
if self.task_config.supports_tasks() and "execution" not in overrides:
|
||||
mcp_tool.execution = ToolExecution(taskSupport=self.task_config.mode)
|
||||
|
||||
return mcp_tool
|
||||
|
||||
@classmethod
|
||||
def from_function(
|
||||
cls,
|
||||
|
|
|
|||
|
|
@ -473,6 +473,35 @@ class TestMountedTaskList:
|
|||
assert child_task.task_id in task_ids
|
||||
|
||||
|
||||
class TestMountedTaskMetadata:
|
||||
"""Test task metadata exposure for mounted tools."""
|
||||
|
||||
async def test_mounted_tool_list_preserves_task_support_metadata(self):
|
||||
"""Mounted tools should preserve execution.taskSupport in tools/list."""
|
||||
child = FastMCP("child")
|
||||
|
||||
@child.tool(task=True)
|
||||
async def foo() -> dict[str, bool]:
|
||||
return {"ok": True}
|
||||
|
||||
parent = FastMCP("parent")
|
||||
parent.mount(child)
|
||||
|
||||
child_tools = await child.list_tools()
|
||||
parent_tools = await parent.list_tools()
|
||||
|
||||
child_tool = next(t for t in child_tools if t.name == "foo")
|
||||
parent_tool = next(t for t in parent_tools if t.name == "foo")
|
||||
|
||||
child_mcp_tool = child_tool.to_mcp_tool(name=child_tool.name)
|
||||
parent_mcp_tool = parent_tool.to_mcp_tool(name=parent_tool.name)
|
||||
|
||||
assert child_mcp_tool.execution is not None
|
||||
assert parent_mcp_tool.execution is not None
|
||||
assert child_mcp_tool.execution.taskSupport == "optional"
|
||||
assert parent_mcp_tool.execution.taskSupport == "optional"
|
||||
|
||||
|
||||
class TestMountedTaskConfigModes:
|
||||
"""Test TaskConfig mode enforcement for mounted tools."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue