3535from fastmcp .server .context import Context
3636from fastmcp .server .dependencies import get_context
3737from fastmcp .server .server import FastMCP
38+ from fastmcp .server .tasks .config import TaskConfig
3839from fastmcp .tools .tool import Tool , ToolResult
3940from fastmcp .tools .tool_manager import ToolManager
4041from fastmcp .tools .tool_transform import (
@@ -259,6 +260,8 @@ class ProxyTool(Tool, MirroredComponent):
259260 A Tool that represents and executes a tool on a remote server.
260261 """
261262
263+ task_config : TaskConfig = TaskConfig (mode = "forbidden" )
264+
262265 def __init__ (self , client : Client , ** kwargs : Any ):
263266 super ().__init__ (** kwargs )
264267 self ._client = client
@@ -288,21 +291,36 @@ async def run(
288291 """Executes the tool by making a call through the client."""
289292 async with self ._client :
290293 context = get_context ()
291- # try to get request context meta
292- meta = (
293- dict (context .request_context .meta )
294- if hasattr (context , "request_context" )
295- and hasattr (context .request_context , "meta" )
296- else None
297- )
294+ # Build meta dict from request context
295+ meta : dict [str , Any ] | None = None
296+ if hasattr (context , "request_context" ):
297+ req_ctx = context .request_context
298+ # Start with existing meta if present
299+ if hasattr (req_ctx , "meta" ) and req_ctx .meta :
300+ meta = dict (req_ctx .meta )
301+ # Add task metadata if this is a task request
302+ if (
303+ hasattr (req_ctx , "experimental" )
304+ and hasattr (req_ctx .experimental , "is_task" )
305+ and req_ctx .experimental .is_task
306+ ):
307+ task_metadata = req_ctx .experimental .task_metadata
308+ if task_metadata :
309+ meta = meta or {}
310+ meta ["modelcontextprotocol.io/task" ] = task_metadata .model_dump (
311+ exclude_none = True
312+ )
313+
298314 result = await self ._client .call_tool_mcp (
299315 name = self .name , arguments = arguments , meta = meta
300316 )
301317 if result .isError :
302318 raise ToolError (cast (mcp .types .TextContent , result .content [0 ]).text )
319+ # Preserve backend's meta (includes task metadata for background tasks)
303320 return ToolResult (
304321 content = result .content ,
305322 structured_content = result .structuredContent ,
323+ meta = result .meta ,
306324 )
307325
308326
@@ -311,6 +329,7 @@ class ProxyResource(Resource, MirroredComponent):
311329 A Resource that represents and reads a resource from a remote server.
312330 """
313331
332+ task_config : TaskConfig = TaskConfig (mode = "forbidden" )
314333 _client : Client
315334 _value : str | bytes | None = None
316335
@@ -343,6 +362,7 @@ def from_mcp_resource(
343362 icons = mcp_resource .icons ,
344363 meta = mcp_resource .meta ,
345364 tags = (mcp_resource .meta or {}).get ("_fastmcp" , {}).get ("tags" , []),
365+ task_config = TaskConfig (mode = "forbidden" ),
346366 _mirrored = True ,
347367 )
348368
@@ -366,6 +386,8 @@ class ProxyTemplate(ResourceTemplate, MirroredComponent):
366386 A ResourceTemplate that represents and creates resources from a remote server template.
367387 """
368388
389+ task_config : TaskConfig = TaskConfig (mode = "forbidden" )
390+
369391 def __init__ (self , client : Client , ** kwargs : Any ):
370392 super ().__init__ (** kwargs )
371393 self ._client = client
@@ -386,6 +408,7 @@ def from_mcp_template( # type: ignore[override]
386408 parameters = {}, # Remote templates don't have local parameters
387409 meta = mcp_template .meta ,
388410 tags = (mcp_template .meta or {}).get ("_fastmcp" , {}).get ("tags" , []),
411+ task_config = TaskConfig (mode = "forbidden" ),
389412 _mirrored = True ,
390413 )
391414
@@ -431,6 +454,7 @@ class ProxyPrompt(Prompt, MirroredComponent):
431454 A Prompt that represents and renders a prompt from a remote server.
432455 """
433456
457+ task_config : TaskConfig = TaskConfig (mode = "forbidden" )
434458 _client : Client
435459
436460 def __init__ (self , client : Client , ** kwargs ):
@@ -459,6 +483,7 @@ def from_mcp_prompt(
459483 icons = mcp_prompt .icons ,
460484 meta = mcp_prompt .meta ,
461485 tags = (mcp_prompt .meta or {}).get ("_fastmcp" , {}).get ("tags" , []),
486+ task_config = TaskConfig (mode = "forbidden" ),
462487 _mirrored = True ,
463488 )
464489
0 commit comments