Convert an MCP tool to an Agents SDK function tool. The ``agent`` parameter is optional for backward compatibility with older call sites that used ``MCPUtil.to_function_tool(tool, server, strict)``. When omitted, this helper preserves the historical behavior for static
(
cls,
tool: MCPTool,
server: MCPServer,
convert_schemas_to_strict: bool,
agent: AgentBase | None = None,
failure_error_function: ToolErrorFunction | None = default_tool_error_function,
tool_name_override: str | None = None,
)
| 502 | |
| 503 | @classmethod |
| 504 | def to_function_tool( |
| 505 | cls, |
| 506 | tool: MCPTool, |
| 507 | server: MCPServer, |
| 508 | convert_schemas_to_strict: bool, |
| 509 | agent: AgentBase | None = None, |
| 510 | failure_error_function: ToolErrorFunction | None = default_tool_error_function, |
| 511 | tool_name_override: str | None = None, |
| 512 | ) -> FunctionTool: |
| 513 | """Convert an MCP tool to an Agents SDK function tool. |
| 514 | |
| 515 | The ``agent`` parameter is optional for backward compatibility with older |
| 516 | call sites that used ``MCPUtil.to_function_tool(tool, server, strict)``. |
| 517 | When omitted, this helper preserves the historical behavior for static |
| 518 | policies. If the server uses a callable approval policy, approvals default |
| 519 | to required to avoid bypassing dynamic checks. |
| 520 | """ |
| 521 | tool_public_name = tool_name_override or tool.name |
| 522 | static_meta = cls._extract_static_meta(tool) |
| 523 | invoke_func_impl = functools.partial( |
| 524 | cls.invoke_mcp_tool, |
| 525 | server, |
| 526 | tool, |
| 527 | tool_display_name=tool_public_name, |
| 528 | meta=static_meta, |
| 529 | ) |
| 530 | effective_failure_error_function = server._get_failure_error_function( |
| 531 | failure_error_function |
| 532 | ) |
| 533 | schema, is_strict = copy.deepcopy(tool.inputSchema), False |
| 534 | |
| 535 | # MCP spec doesn't require the inputSchema to have `properties`, but OpenAI spec does. |
| 536 | if "properties" not in schema: |
| 537 | schema["properties"] = {} |
| 538 | |
| 539 | if convert_schemas_to_strict: |
| 540 | # ``ensure_strict_json_schema`` mutates the schema in place and may raise |
| 541 | # partway through, leaving strict-mode artifacts (e.g. ``required`` or |
| 542 | # ``additionalProperties: false``) on a schema we still serve as |
| 543 | # non-strict. Convert a separate copy so the non-strict fallback keeps |
| 544 | # the original schema intact. |
| 545 | try: |
| 546 | schema = ensure_strict_json_schema(copy.deepcopy(schema)) |
| 547 | is_strict = True |
| 548 | except Exception as e: |
| 549 | logger.info(f"Error converting MCP schema to strict mode: {e}") |
| 550 | |
| 551 | needs_approval: ( |
| 552 | bool | Callable[[RunContextWrapper[Any], dict[str, Any], str], Awaitable[bool]] |
| 553 | ) = server._get_needs_approval_for_tool(tool, agent) |
| 554 | |
| 555 | function_tool = _build_wrapped_function_tool( |
| 556 | name=tool_public_name, |
| 557 | description=resolve_mcp_tool_description_for_model(tool), |
| 558 | params_json_schema=schema, |
| 559 | invoke_tool_impl=invoke_func_impl, |
| 560 | on_handled_error=_build_handled_function_tool_error_handler( |
| 561 | span_message="Error running tool (non-fatal)", |