Skip to content

Commit c26ac91

Browse files
author
Fan
committed
feat: add execution parameter to add_tool() for task support declaration
Add ToolExecution parameter to MCPServer.add_tool(), ToolManager.add_tool(), and Tool.from_function() to allow declaring execution.taskSupport per tool as required by MCP spec 2025-11-25. Also pass execution through in MCPServer.list_tools() when converting internal Tool to MCP types.Tool. Fixes #2156
1 parent 62575ed commit c26ac91

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

src/mcp/server/mcpserver/server.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
TextContent,
6868
TextResourceContents,
6969
ToolAnnotations,
70+
ToolExecution,
7071
)
7172
from mcp.types import Prompt as MCPPrompt
7273
from mcp.types import PromptArgument as MCPPromptArgument
@@ -383,6 +384,7 @@ async def list_tools(self) -> list[MCPTool]:
383384
annotations=info.annotations,
384385
icons=info.icons,
385386
_meta=info.meta,
387+
execution=info.execution,
386388
)
387389
for info in tools
388390
]
@@ -465,6 +467,7 @@ def add_tool(
465467
icons: list[Icon] | None = None,
466468
meta: dict[str, Any] | None = None,
467469
structured_output: bool | None = None,
470+
execution: ToolExecution | None = None,
468471
) -> None:
469472
"""Add a tool to the server.
470473
@@ -483,6 +486,8 @@ def add_tool(
483486
- If None, auto-detects based on the function's return type annotation
484487
- If True, creates a structured tool (return type annotation permitting)
485488
- If False, unconditionally creates an unstructured tool
489+
execution: Optional ToolExecution for declaring task support per MCP spec
490+
(e.g. ToolExecution(taskSupport="optional"))
486491
"""
487492
self._tool_manager.add_tool(
488493
fn,
@@ -493,6 +498,7 @@ def add_tool(
493498
icons=icons,
494499
meta=meta,
495500
structured_output=structured_output,
501+
execution=execution,
496502
)
497503

498504
def remove_tool(self, name: str) -> None:

src/mcp/server/mcpserver/tools/base.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from mcp.server.mcpserver.utilities.func_metadata import FuncMetadata, func_metadata
1414
from mcp.shared.exceptions import UrlElicitationRequiredError
1515
from mcp.shared.tool_name_validation import validate_and_warn_tool_name
16-
from mcp.types import Icon, ToolAnnotations
16+
from mcp.types import Icon, ToolAnnotations, ToolExecution
1717

1818
if TYPE_CHECKING:
1919
from mcp.server.context import LifespanContextT, RequestT
@@ -36,6 +36,7 @@ class Tool(BaseModel):
3636
annotations: ToolAnnotations | None = Field(None, description="Optional annotations for the tool")
3737
icons: list[Icon] | None = Field(default=None, description="Optional list of icons for this tool")
3838
meta: dict[str, Any] | None = Field(default=None, description="Optional metadata for this tool")
39+
execution: ToolExecution | None = Field(default=None, description="Optional execution properties for task support")
3940

4041
@cached_property
4142
def output_schema(self) -> dict[str, Any] | None:
@@ -53,6 +54,7 @@ def from_function(
5354
icons: list[Icon] | None = None,
5455
meta: dict[str, Any] | None = None,
5556
structured_output: bool | None = None,
57+
execution: ToolExecution | None = None,
5658
) -> Tool:
5759
"""Create a Tool from a function."""
5860
func_name = name or fn.__name__
@@ -87,6 +89,7 @@ def from_function(
8789
annotations=annotations,
8890
icons=icons,
8991
meta=meta,
92+
execution=execution,
9093
)
9194

9295
async def run(

src/mcp/server/mcpserver/tools/tool_manager.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from mcp.server.mcpserver.exceptions import ToolError
77
from mcp.server.mcpserver.tools.base import Tool
88
from mcp.server.mcpserver.utilities.logging import get_logger
9-
from mcp.types import Icon, ToolAnnotations
9+
from mcp.types import Icon, ToolAnnotations, ToolExecution
1010

1111
if TYPE_CHECKING:
1212
from mcp.server.context import LifespanContextT, RequestT
@@ -51,6 +51,7 @@ def add_tool(
5151
icons: list[Icon] | None = None,
5252
meta: dict[str, Any] | None = None,
5353
structured_output: bool | None = None,
54+
execution: ToolExecution | None = None,
5455
) -> Tool:
5556
"""Add a tool to the server."""
5657
tool = Tool.from_function(
@@ -62,6 +63,7 @@ def add_tool(
6263
icons=icons,
6364
meta=meta,
6465
structured_output=structured_output,
66+
execution=execution,
6567
)
6668
existing = self._tools.get(tool.name)
6769
if existing:

0 commit comments

Comments
 (0)