Skip to content

feat(python): add MCPToolProvider for MCP server integration#565

Open
cornelcroi wants to merge 1 commit into
mainfrom
feat/python-mcp-tool-provider
Open

feat(python): add MCPToolProvider for MCP server integration#565
cornelcroi wants to merge 1 commit into
mainfrom
feat/python-mcp-tool-provider

Conversation

@cornelcroi

Copy link
Copy Markdown
Collaborator

Issue Link (REQUIRED)

Fixes #299

Summary

Changes

Adds MCPToolProvider — a subclass of AgentTools that connects to one or more MCP servers (stdio or SSE transport) and exposes their tools transparently inside the existing tool_config mechanism. No changes to any existing agent, classifier, or orchestrator.

  • New file: python/src/agent_squad/tools/mcp_tool_provider.py
    • MCPServerConfig dataclass covering stdio (command, args, env) and SSE (url, headers) transports
    • MCPToolProvider(AgentTools) with lazy connection, tool caching, and routing back to the correct server per tool call
    • to_bedrock_format(), to_anthropic_format(), to_openai_format() — pass MCP's JSON Schema through directly
    • isError results from MCP surfaced as error strings to the model
  • python/setup.cfg: new mcp = mcp>=1.0.0 optional extra, added to all
  • python/src/agent_squad/__init__.py: guarded re-export (silent skip when mcp not installed)
  • 16 unit tests — all passing

User experience

Before: no MCP support.

After:

from agent_squad.tools import MCPToolProvider, MCPServerConfig
from agent_squad.agents import BedrockLLMAgent
from agent_squad.agents.bedrock_llm_agent import BedrockLLMAgentOptions

agent = BedrockLLMAgent(BedrockLLMAgentOptions(
    name="my-agent",
    description="An agent with MCP tools",
    tool_config={
        "tool": MCPToolProvider([
            MCPServerConfig(type="stdio", command="uvx", args=["my-mcp-server"]),
            MCPServerConfig(type="sse", url="http://localhost:3000/sse"),
        ])
    }
))

Install: pip install agent-squad[mcp]

Checklist

  • I have performed a self-review of this change
  • Changes have been tested
  • Changes are documented
  • I have linked this PR to an existing issue (required)

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Adds MCPToolProvider as a drop-in AgentTools subclass that connects to
one or more MCP servers (stdio or SSE) and exposes their tools transparently
inside the existing tool_config mechanism — no changes to existing agents.

Closes #299

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
headers: Optional[dict[str, str]] = None


class MCPToolProvider(AgentTools):
try:
from .tools.mcp_tool_provider import MCPToolProvider, MCPServerConfig
__all__ = ["MCPToolProvider", "MCPServerConfig"]
except ImportError:

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b490814bbb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

connect lazily via :meth:`tool_handler`.
"""
result = []
for tool_name, (_session, mcp_tool) in self._tool_map.items():

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Populate MCP tools before formatting

When a fresh MCPToolProvider is passed to BedrockLLMAgent or AnthropicAgent as in the new example, the agents build the model request by calling to_bedrock_format()/to_claude_format() before tool_handler() ever runs. These formatters only iterate self._tool_map, which is empty until _ensure_connected() has been awaited, so the first request is sent with no MCP tools and the model never has a chance to call them. Please connect/list tools before formatting in the async agent path, or otherwise avoid returning an empty tool list on first use.

Useful? React with 👍 / 👎.

mock_stdio_params_cls = MagicMock()

with (
patch("agent_squad.tools.mcp_tool_provider.ClientSession", mock_client_session_cls),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Install or stub MCP before patching provider

In the Python CI workflow I checked, dependencies are installed only from python/test_requirements.txt, which does not include mcp. These tests claim to mock MCP, but patch("agent_squad.tools.mcp_tool_provider.ClientSession", ...) imports the package before the patch can apply; without the extra installed, agent_squad.tools is not importable and every test in this file errors during fixture setup. Add mcp to the test environment or stub the mcp modules in sys.modules before importing the provider.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: MCP Servers and Tools

1 participant