# How to Integrate MCP Tools and Hosted MCP Tools into Agents in openai-agents-python

> Learn to integrate MCP tools and hosted MCP tools into your agents using the openai-agents-python SDK. Discover automatic discovery or direct invocation methods.

- Repository: [OpenAI/openai-agents-python](https://github.com/openai/openai-agents-python)
- Tags: how-to-guide
- Published: 2026-04-17

---

**The openai-agents-python SDK enables MCP tool integration by passing `MCPServer` instances to an Agent's `mcp_servers` parameter for automatic discovery, or by wrapping specific tools in `HostedMCPTool` objects for direct invocation.**

The OpenAI Agents SDK (`openai-agents-python`) ships with native support for the Model Context Protocol (MCP), allowing agents to discover and invoke external tools hosted on MCP servers. This integration enables your agents to leverage specialized capabilities from external processes or remote services without hardcoding tool implementations. Whether you need automatic tool discovery from a running server or prefer to explicitly wrap specific MCP tools for direct agent use, the SDK provides dedicated utilities in the `agents.mcp` package.

## MCP Architecture and Core Components

The MCP implementation in `openai-agents-python` centers on several key classes that handle server lifecycle, tool conversion, and execution flow.

- **`MCPServer`** – Abstract base class in [`src/agents/mcp/server.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/mcp/server.py) defining the interface for MCP backends, with concrete implementations like `MCPServerStdio` for local processes.
- **`MCPServerManager`** – Context manager in [`src/agents/mcp/manager.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/mcp/manager.py) that starts and stops one or more MCP servers during an agent run.
- **`HostedMCPTool`** – Wrapper class in [`src/agents/tool.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/tool.py) that converts an MCP tool definition into a standard function tool the LLM can invoke directly.
- **`MCPUtil`** – Utility class in [`src/agents/mcp/util.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/mcp/util.py) providing `to_function_tool()` and `to_mcp_tool()` for converting between MCP definitions and SDK objects.
- **`MCPListToolsItem`** – Run item type in [`src/agents/items.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/items.py) representing the initial tool discovery request sent to MCP servers.

## Method 1: Automatic Tool Discovery via MCPServer

The simplest way to **integrate MCP tools** is to pass a list of `MCPServer` instances to the `Agent` constructor via the `mcp_servers` parameter. The SDK automatically discovers available tools before the first model turn.

When you configure an agent with `mcp_servers`, the run-loop performs the following actions:

1. **Server initialization** – The `MCPServerManager` initializes all configured servers before the first agent turn.
2. **Tool discovery** – The agent emits a `MCPListToolsItem` to enumerate available tools from each server.
3. **Conversion** – The `MCPUtil.to_function_tool()` helper transforms each `McpTool` definition (defined in [`src/agents/tool.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/tool.py)) into a `FunctionTool` that gets injected into the model request payload.
4. **Invocation** – When the LLM calls an MCP tool, the SDK creates an `MCPApprovalRequestItem`, routes it through `HostedMCPTool`, and forwards the request to the appropriate `MCPServer`.

```python
from agents import Agent
from agents.mcp.server import MCPServerStdio

# Configure a local MCP server via stdio

server = MCPServerStdio(
    command="python -m my_mcp_server",
    env={}
)

# Create an agent with automatic MCP tool discovery

agent = Agent(
    name="MCPAgent",
    model="gpt-4o-mini",
    mcp_servers=[server],  # Tools discovered automatically

)

response = agent.run("What tools are available?")

```

## Method 2: Direct Integration with HostedMCPTool

For scenarios requiring explicit tool control or when you want to expose a specific MCP tool without running discovery, use the **`HostedMCPTool`** class. This approach wraps a single MCP tool as a standard function tool that you append directly to the agent's `tools` list.

The `HostedMCPTool` constructor requires:

- **`tool_config`**: An `McpTool` definition created via `MCPUtil.to_mcp_tool()`.
- **`server_name`**: The identifier tying the tool to a specific `MCPServer` instance.

```python
from agents import Agent, HostedMCPTool
from agents.mcp.server import MCPServerStdio
from agents.mcp.util import MCPUtil

server = MCPServerStdio(command="python -m my_mcp_server")

# Define the MCP tool metadata explicitly

tool_config = MCPUtil.to_mcp_tool(
    name="list_documents",
    description="Return a list of document IDs available to the agent.",
    parameters={"type": "object", "properties": {}}
)

# Wrap as a hosted tool

hosted_tool = HostedMCPTool(
    tool_config=tool_config,
    server_name=server.server_name
)

# Add to agent's tools list

agent = Agent(
    name="HostedToolAgent",
    model="gpt-4o-mini",
    mcp_servers=[server],
    tools=[hosted_tool]
)

```

## Understanding the MCP Execution Flow

When an agent invokes an MCP tool, the SDK orchestrates a specific request-response lifecycle defined in [`src/agents/run_internal/run_steps.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/run_internal/run_steps.py) and [`src/agents/items.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/items.py).

**Approval Request Phase**

The LLM generates a tool call targeting an MCP-hosted function. The SDK creates a `ToolRunMCPApprovalRequest` (internal step) and surfaces it as an `MCPApprovalRequestItem`. The `HostedMCPTool` instance associated with the specific server handles the approval callback.

**Execution Phase**

Upon approval, the SDK forwards the request to the `MCPServer` implementation. For stdio servers, this involves writing the JSON-RPC request to the process's stdin and parsing the response from stdout.

**Response Phase**

The MCP server returns the tool result, which the SDK wraps as an `MCPApprovalResponseItem` in [`src/agents/items.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/items.py). This item feeds back into the conversation history for the next model turn.

## Complete Example: Building an MCP Server and Client

Below is a complete workflow demonstrating both server implementation and agent integration.

### Step 1: Create a Simple MCP Server

This example server implements the required `list_tools` and `call_tool` methods via stdio:

```python

# my_mcp_server.py

import json
import sys

def handle_request(req: dict) -> dict:
    if req["type"] == "list_tools":
        return {
            "type": "list_tools_response",
            "tools": [
                {
                    "name": "echo",
                    "description": "Return the supplied text unchanged.",
                    "parameters": {
                        "type": "object",
                        "properties": {"text": {"type": "string"}},
                        "required": ["text"]
                    }
                }
            ]
        }
    
    if req["type"] == "call_tool" and req["tool"] == "echo":
        return {
            "type": "call_tool_response",
            "output": req["arguments"]["text"]
        }
    
    return {"type": "error", "message": "unknown request"}

# Process stdin/stdout loop

for line in sys.stdin:
    payload = json.loads(line)
    response = handle_request(payload)
    print(json.dumps(response), flush=True)

```

### Step 2: Register for Automatic Discovery

```python
from agents import Agent
from agents.mcp.server import MCPServerStdio

server = MCPServerStdio(command="python -m my_mcp_server")

agent = Agent(
    name="AutoDiscoveryAgent",
    model="gpt-4o-mini",
    mcp_servers=[server]
)

result = agent.run("Please call the echo tool with text 'Hello MCP'")
print(result.content)  # Output: Hello MCP

```

### Step 3: Use HostedMCPTool for Explicit Registration

```python
from agents import Agent, HostedMCPTool
from agents.mcp.util import MCPUtil
from agents.mcp.server import MCPServerStdio

# Reuse the same server configuration

server = MCPServerStdio(command="python -m my_mcp_server")

# Explicitly define the echo tool

echo_config = MCPUtil.to_mcp_tool(
    name="echo",
    description="Echo back the provided text.",
    parameters={
        "type": "object",
        "properties": {"text": {"type": "string"}},
        "required": ["text"]
    }
)

hosted_echo = HostedMCPTool(
    tool_config=echo_config,
    server_name=server.server_name
)

agent = Agent(
    name="ExplicitToolAgent",
    model="gpt-4o-mini",
    mcp_servers=[server],  # Still required for connection management

    tools=[hosted_echo]
)

```

## Summary

- **Automatic discovery** requires passing `MCPServer` instances to the `mcp_servers` parameter when constructing an `Agent`; the SDK handles tool enumeration via `MCPListToolsItem` and conversion through `MCPUtil.to_function_tool()` in [`src/agents/mcp/util.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/mcp/util.py).
- **Direct tool exposure** utilizes `HostedMCPTool` from [`src/agents/tool.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/tool.py) to wrap specific MCP tools as regular function tools, bypassing the discovery step while requiring the server in `mcp_servers` for connection lifecycle management.
- **Server lifecycle** is managed by `MCPServerManager` in [`src/agents/mcp/manager.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/mcp/manager.py), which orchestrates startup and shutdown of stdio or SSE servers.
- **Execution flow** involves `MCPApprovalRequestItem` and `MCPApprovalResponseItem` from [`src/agents/items.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/items.py), with the internal step represented by `ToolRunMCPApprovalRequest` in [`src/agents/run_internal/run_steps.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/run_internal/run_steps.py).

## Frequently Asked Questions

### What is the difference between using `mcp_servers` and `HostedMCPTool`?

Passing servers to `mcp_servers` enables **automatic tool discovery**, where the agent queries the server for all available tools on the first turn using `MCPListToolsItem`. In contrast, `HostedMCPTool` allows you to **manually expose specific tools** by defining the tool schema upfront with `MCPUtil.to_mcp_tool()` and adding the wrapper directly to the agent's `tools` list. Both methods require the server to be present in `mcp_servers` to manage the connection lifecycle.

### How does the SDK handle MCP tool approvals?

When an LLM invokes an MCP tool, the SDK creates an `MCPApprovalRequestItem` (defined in [`src/agents/items.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/items.py)) and pauses the model turn. The `HostedMCPTool` instance associated with the target server processes the request. Once approved (either by default policy or callback), the SDK forwards the request to the `MCPServer` implementation and wraps the result in an `MCPApprovalResponseItem` for the next conversation turn.

### Can I use remote MCP servers with the openai-agents-python SDK?

Yes. While `MCPServerStdio` in [`src/agents/mcp/server.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/mcp/server.py) handles local subprocesses, the abstract `MCPServer` base class supports custom implementations for remote connections. You can subclass `MCPServer` to implement SSE (Server-Sent Events) or HTTP-based MCP servers, then pass these instances to the agent's `mcp_servers` parameter exactly like local stdio servers.

### Where does the automatic tool discovery happen in the source code?

Automatic discovery is orchestrated in [`src/agents/mcp/util.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/mcp/util.py) via `MCPUtil.to_function_tool()`, which converts `McpTool` definitions into `FunctionTool` objects. The discovery request itself originates as a `MCPListToolsItem` from [`src/agents/items.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/items.py), processed during the agent run initialization phase managed by `MCPServerManager` in [`src/agents/mcp/manager.py`](https://github.com/openai/openai-agents-python/blob/main/src/agents/mcp/manager.py).