From b17c00e4b4a7ca162c4ceeb7d40a83699484d854 Mon Sep 17 00:00:00 2001 From: Evan Mattson Date: Mon, 15 Dec 2025 15:55:30 +0900 Subject: [PATCH 1/2] Filter framework kwargs from MCP tool invocations --- python/packages/core/agent_framework/_tools.py | 14 +++++++++++--- .../openai/openai_chat_client_with_local_mcp.py | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/python/packages/core/agent_framework/_tools.py b/python/packages/core/agent_framework/_tools.py index bc16d9edb9..0d8c7183f3 100644 --- a/python/packages/core/agent_framework/_tools.py +++ b/python/packages/core/agent_framework/_tools.py @@ -1409,10 +1409,18 @@ async def _auto_invoke_function( parsed_args: dict[str, Any] = dict(function_call_content.parse_arguments() or {}) # Filter out internal framework kwargs before passing to tools. + # This includes middleware infrastructure, chat options, tool configuration, and other + # framework-specific parameters that should not be forwarded to external tools. + framework_kwargs_to_filter = { + "_function_middleware_pipeline", + "middleware", + "chat_options", + "tools", + "tool_choice", + "thread", + } runtime_kwargs: dict[str, Any] = { - key: value - for key, value in (custom_args or {}).items() - if key not in {"_function_middleware_pipeline", "middleware"} + key: value for key, value in (custom_args or {}).items() if key not in framework_kwargs_to_filter } try: args = tool.input_model.model_validate(parsed_args) diff --git a/python/samples/getting_started/agents/openai/openai_chat_client_with_local_mcp.py b/python/samples/getting_started/agents/openai/openai_chat_client_with_local_mcp.py index 8df65ad8fd..c0747087f4 100644 --- a/python/samples/getting_started/agents/openai/openai_chat_client_with_local_mcp.py +++ b/python/samples/getting_started/agents/openai/openai_chat_client_with_local_mcp.py @@ -16,6 +16,10 @@ metadata through the _meta field of CallToolResult objects. """ +import logging + +logging.basicConfig(level=logging.DEBUG) + async def mcp_tools_on_run_level() -> None: """Example showing MCP tools defined when running the agent.""" From 15f45dd12fb8c9512e9914c318938ccb469b6ed7 Mon Sep 17 00:00:00 2001 From: Evan Mattson Date: Mon, 15 Dec 2025 16:04:56 +0900 Subject: [PATCH 2/2] Fixes --- python/packages/core/agent_framework/_mcp.py | 10 +++++++++- python/packages/core/agent_framework/_tools.py | 14 +++----------- .../openai/openai_chat_client_with_local_mcp.py | 4 ---- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/python/packages/core/agent_framework/_mcp.py b/python/packages/core/agent_framework/_mcp.py index 721af6210c..2ea0f21dec 100644 --- a/python/packages/core/agent_framework/_mcp.py +++ b/python/packages/core/agent_framework/_mcp.py @@ -685,8 +685,16 @@ async def call_tool(self, tool_name: str, **kwargs: Any) -> list[Contents]: raise ToolExecutionException( "Tools are not loaded for this server, please set load_tools=True in the constructor." ) + # Filter out framework kwargs that cannot be serialized by the MCP SDK. + # These are internal objects passed through the function invocation pipeline + # that should not be forwarded to external MCP servers. + filtered_kwargs = { + k: v for k, v in kwargs.items() if k not in {"chat_options", "tools", "tool_choice", "thread"} + } try: - return _mcp_call_tool_result_to_ai_contents(await self.session.call_tool(tool_name, arguments=kwargs)) + return _mcp_call_tool_result_to_ai_contents( + await self.session.call_tool(tool_name, arguments=filtered_kwargs) + ) except McpError as mcp_exc: raise ToolExecutionException(mcp_exc.error.message, inner_exception=mcp_exc) from mcp_exc except Exception as ex: diff --git a/python/packages/core/agent_framework/_tools.py b/python/packages/core/agent_framework/_tools.py index 0d8c7183f3..bc16d9edb9 100644 --- a/python/packages/core/agent_framework/_tools.py +++ b/python/packages/core/agent_framework/_tools.py @@ -1409,18 +1409,10 @@ async def _auto_invoke_function( parsed_args: dict[str, Any] = dict(function_call_content.parse_arguments() or {}) # Filter out internal framework kwargs before passing to tools. - # This includes middleware infrastructure, chat options, tool configuration, and other - # framework-specific parameters that should not be forwarded to external tools. - framework_kwargs_to_filter = { - "_function_middleware_pipeline", - "middleware", - "chat_options", - "tools", - "tool_choice", - "thread", - } runtime_kwargs: dict[str, Any] = { - key: value for key, value in (custom_args or {}).items() if key not in framework_kwargs_to_filter + key: value + for key, value in (custom_args or {}).items() + if key not in {"_function_middleware_pipeline", "middleware"} } try: args = tool.input_model.model_validate(parsed_args) diff --git a/python/samples/getting_started/agents/openai/openai_chat_client_with_local_mcp.py b/python/samples/getting_started/agents/openai/openai_chat_client_with_local_mcp.py index c0747087f4..8df65ad8fd 100644 --- a/python/samples/getting_started/agents/openai/openai_chat_client_with_local_mcp.py +++ b/python/samples/getting_started/agents/openai/openai_chat_client_with_local_mcp.py @@ -16,10 +16,6 @@ metadata through the _meta field of CallToolResult objects. """ -import logging - -logging.basicConfig(level=logging.DEBUG) - async def mcp_tools_on_run_level() -> None: """Example showing MCP tools defined when running the agent."""