Skip to content
AI Agent How-To

Home › MCP server setup guides

How to Connect an AI Agent to an MCP Server (Python Client)

Intermediate ~5 min read Last tested October 2026

Updated 2026-10-15

Claude Desktop and Cursor are MCP clients, but your own agent can be one too. This guide connects a Python agent to any stdio MCP server, converts the server’s tools into LLM tool definitions, and routes tool calls back to the server.

Prerequisites

  • Python 3.10+, pip install mcp openai
  • An MCP server to connect to. We use the one from Build an MCP server in Python, but any stdio server works (for example npx -y @modelcontextprotocol/server-filesystem /tmp).

Steps

1. Open a client session

# mcp_agent.py
import asyncio, json
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from openai import OpenAI

SERVER = StdioServerParameters(command="python", args=["server.py"])
llm = OpenAI()

2. Convert MCP tools to OpenAI tool definitions

MCP tools already carry a JSON Schema in inputSchema, so the mapping is direct:

def to_openai_tools(mcp_tools):
    return [{"type": "function", "function": {
        "name": t.name,
        "description": t.description or "",
        "parameters": t.inputSchema}} for t in mcp_tools]

3. Run the agent loop, calling tools through the session

async def main(goal: str):
    async with stdio_client(SERVER) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = (await session.list_tools()).tools
            print("Tools:", [t.name for t in tools])
            messages = [{"role": "user", "content": goal}]
            for _ in range(8):
                msg = llm.chat.completions.create(model="gpt-4.1-mini", messages=messages,
                        tools=to_openai_tools(tools)).choices[0].message
                if not msg.tool_calls:
                    print(msg.content); return
                messages.append(msg)
                for call in msg.tool_calls:
                    result = await session.call_tool(call.function.name,
                                 json.loads(call.function.arguments or "{}"))
                    text = "\n".join(c.text for c in result.content if c.type == "text")
                    messages.append({"role": "tool", "tool_call_id": call.id, "content": text})

asyncio.run(main("What's the weather in Lisbon right now?"))

4. Run it

python mcp_agent.py

The client launches the server as a subprocess, lists its tools, and the model calls current_weather with Lisbon’s coordinates.

5. Connect to a remote (HTTP) server instead

from mcp.client.streamable_http import streamablehttp_client

async with streamablehttp_client("https://example.com/mcp") as (read, write, _):
    async with ClientSession(read, write) as session:
        ...

Using a framework instead

  • OpenAI Agents SDK: from agents.mcp import MCPServerStdio and pass mcp_servers=[...] to Agent.
  • LangChain/LangGraph: the langchain-mcp-adapters package loads MCP tools as LangChain tools.

Common errors

McpError: Connection closed right away: the server crashed on start. Run its command by hand to see the traceback.

result.isError is true: the tool raised an exception. The error text is in result.content. Pass it back to the model so it can correct its arguments.

Hangs on initialize(): the server writes non-protocol text to stdout. Servers must log to stderr only.