Skip to main content

MCP Agent

A tool-calling agent that uses MCP (Model Context Protocol) tools via AgentVisor™'s policy-enforced MCP Gateway.

Difficulty: Intermediate

Understanding MCP in AgentVisor

This example demonstrates the MCP Gateway - how your agents access external MCP servers (like filesystem, GitHub, or Slack tools). For the opposite direction (exposing your agents as MCP tools to Claude Desktop or Cursor), see MCP Transport.

For architecture details and security model, see MCP Gateway. For SDK API reference, see MCP Module.

What You'll Learn

  • MCP tool discovery from host-configured servers
  • get_mcp_tools() for LangChain integration
  • ReAct pattern with dynamically loaded tools
  • Policy enforcement on MCP tool calls

How It Works

Unlike the QA Agent which defines tools in Python, the MCP Agent loads tools dynamically from external MCP servers configured on the host:

agentvisor.yaml Agent (Python)
┌──────────────────┐ ┌──────────────────┐
│ mcp: │ │ tools = │
│ servers: │────────▶│ get_mcp_tools()│
│ - filesystem │ │ │
│ - github │ │ ReAct loop with │
│ - slack │ │ MCP tools │
└──────────────────┘ └──────────────────┘

The agent never connects to MCP servers directly. All tool calls flow through the host runtime, where they are policy-checked before execution.

Setup

agentvisor template create langgraph/mcp-agent
cd mcp-agent
docker compose up -d

You also need an MCP server to connect to. The example uses the filesystem server from the MCP reference implementations. Create an agentvisor.yaml in your project directory:

mcp:
servers:
- name: filesystem
transport: stdio
command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp/mcp-data"]

Prepare some test data and run:

mkdir -p /tmp/mcp-data
echo 'Hello from MCP!' > /tmp/mcp-data/readme.txt
agentvisor serve .

For more configuration options including remote servers and credential injection, see Configuration Reference: MCP.

Test It

THREAD=$(curl -sX POST http://localhost:8090/threads | jq -r '.thread_id')

# List available files
curl -sX POST "http://localhost:8090/threads/$THREAD/runs?wait=60s" \
-H "Content-Type: application/json" \
-d '{"input": {"messages": [{"role": "user", "content": "List the files available"}]}}'

# Read a file
curl -sX POST "http://localhost:8090/threads/$THREAD/runs?wait=60s" \
-H "Content-Type: application/json" \
-d '{"input": {"messages": [{"role": "user", "content": "Read the readme.txt file"}]}}'

Key Code

Dynamic Tool Loading

from agentvisor.langchain import get_mcp_tools

# Load all MCP tools from host-configured servers as LangChain tools
tools = get_mcp_tools()

No tool definitions in agent code. Tools are discovered at startup from the host's MCP configuration. See MCP SDK Reference for complete API details.

ReAct Graph with MCP Tools

builder = StateGraph(AgentState)
builder.add_node("agent", agent)
builder.add_node("tools", ToolNode(tools)) # MCP tools

builder.add_conditional_edges(
"agent",
should_continue,
{"tools": "tools", "end": END},
)
builder.add_edge("tools", "agent")

Learn More

Next Steps