Skip to content

docs review: MCP to_openai_tool() DRY refactor (PraisonAI PR #3366) — verify existing MCP + tool-search pages stay accurate #2393

Description

@MervinPraison

Source change

What changed in the SDK

A new shared helper is added next to fix_array_schemas in praisonaiagents/mcp/mcp_schema_utils.py:

def build_openai_tool_dict(name: str, description: str, input_schema: Any) -> Dict[str, Any]:
    """
    Build an OpenAI function-calling tool dict for an MCP tool.

    DRY: This centralizes the OpenAI tool-dict construction (including the
    ``__praisonai_deferrable__`` marker) that was previously duplicated across
    ``mcp_sse``, ``mcp_http_stream``, and ``mcp_websocket``.
    """
    return {
        "type": "function",
        "function": {
            "name": name,
            "description": description,
            "parameters": fix_array_schemas(input_schema),
        },
        "__praisonai_deferrable__": True,  # Mark MCP tools as deferrable for tool search
    }

The three per-transport tool classes now delegate to it in a single line:

File Class Before After
praisonaiagents/mcp/mcp_http_stream.py HTTPStreamMCPTool.to_openai_tool 12-line inline dict construction return build_openai_tool_dict(self.name, self.description, self.input_schema)
praisonaiagents/mcp/mcp_sse.py SSEMCPTool.to_openai_tool 12-line inline dict construction return build_openai_tool_dict(self.name, self.description, self.input_schema)
praisonaiagents/mcp/mcp_websocket.py WebSocketMCPTool.to_openai_tool 12-line inline dict construction return build_openai_tool_dict(self.name, self.description, self.input_schema)

Deliberately untouched: the MCP-class dispatcher to_openai_tool in mcp.py (praisonaiagents/mcp/mcp.py:922), and each transport class's public to_openai_tools() wrapper.

Documentation impact assessment

Verdict: No user-facing documentation update is required. This is a pure internal DRY refactor. Output dicts are byte-identical, including the __praisonai_deferrable__ marker, and no public method signatures or import paths change. Under the "user-focused, non-developer, agent-centric" docs principle from AGENTS.md, this refactor has zero surface area for a user-facing page.

The auto-generated SDK reference at docs/sdk/reference/praisonaiagents/functions/MCP-to_openai_tool.mdx will be regenerated by the parity system on the next generate_docs_parity.py --copy-docs run; no manual edit needed.

Existing PraisonAIDocs references verified

Every current mention of the affected symbols was re-read against the refactored SDK and remains accurate. No wording change required.

File Line Text Still accurate?
docs/features/tool-search.mdx 219 **MCP tools**: Automatically marked with __praisonai_deferrable__ = True ✅ Yes — the marker still resolves to True from the shared helper.
docs/features/tool-search.mdx 148–149 enabled / threshold_pct params reference "deferrable schema tokens" ✅ Yes — deferrable classification is unchanged.
features/mcp/index.mdx 108 | to_openai_tool() | Converts tools to OpenAI format | (methods table) ✅ Yes — method exists, signature unchanged, return value unchanged.
docs/sdk/reference/praisonaiagents/functions/MCP-to_openai_tool.mdx 34–41 Signature / return docstring ✅ Yes — auto-generated; regenerate on next parity run for freshness.
docs/features/mcp.mdx, docs/features/mcp-three-layers.mdx, docs/features/mcp-client-protocol.mdx, docs/features/mcp-lifecycle.mdx, docs/features/mcp-recipe-server.mdx, docs/features/mcp-resources-and-prompts.mdx, docs/features/mcp-scoped-api-keys.mdx, docs/features/mcp-sse-security.mdx, docs/features/mcp-stdio-server-transport.mdx, docs/concepts/mcp.mdx Describe the four transports (stdio / SSE / HTTP Stream / WebSocket) and MCP usage from the agent perspective ✅ Yes — none reference the extracted helper or the internal dict-construction code path.

Also confirmed: no PraisonAIDocs page references build_openai_tool_dict, mcp_schema_utils, HTTPStreamMCPTool, SSEMCPTool, or WebSocketMCPTool (searched with grep across docs/ and features/). The refactor introduces no new user-callable symbol that would need documenting.

Recommended disposition

For the next docs agent that picks this up:

  1. Default action: close as no-op. Verified no page requires an edit. This issue exists purely for traceability so every PraisonAI PR has a corresponding docs-side review record.
  2. Optional (nice-to-have, not required): re-run python3 src/praisonai/scripts/generate_docs_parity.py --copy-docs so the auto-generated MCP-to_openai_tool.mdx picks up the refreshed source-line link — the current href points to mcp/mcp.py#L567, which is still correct for the MCP-class dispatcher (not part of this refactor), so this is cosmetic.
  3. Do NOT create a new page describing build_openai_tool_dict — per the AGENTS.md "user-focused, non-developer" principle, internal shared helpers are out of scope for the docs site.
  4. Do NOT modify docs/concepts/mcp.mdx — per the folder-placement rules, docs/concepts/ is human-approved only, and this change gives no reason to touch it anyway.

Verification trail

Executed against a fresh clone of both repos at the current main heads:

# 1. Confirmed the three transports now delegate to the shared helper
grep -n "build_openai_tool_dict" src/praisonai-agents/praisonaiagents/mcp/*.py
#   mcp_http_stream.py:39, mcp_http_stream.py:154
#   mcp_schema_utils.py:41
#   mcp_sse.py:27, mcp_sse.py:114
#   mcp_websocket.py:31, mcp_websocket.py:356

# 2. Confirmed no PraisonAIDocs page references the helper or the internal classes
grep -rn "build_openai_tool_dict\|mcp_schema_utils\|HTTPStreamMCPTool\|SSEMCPTool\|WebSocketMCPTool" docs/ features/
#   (no matches)

# 3. Confirmed all existing mentions of the affected public symbols are still accurate
grep -rn "to_openai_tool\|__praisonai_deferrable__" docs/ features/
#   → matches shown in the table above; all remain correct.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claudeTrigger Claude Code analysisdocumentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions