Every AI agent needs tools. But connecting an LLM to a tool has traditionally been a mess of custom integrations, one-off API wrappers, and brittle glue code.
MCP (Model Context Protocol) is Anthropic's answer to this problem. Think of it as "USB-C for AI agents" — a universal standard for connecting AI models to external tools and data sources.
What Is MCP?
MCP defines a standard way for AI models to discover and call tools. It's a client-server protocol:
AI Agent (MCP Client) ←→ MCP Server ←→ External Service/Data
The server exposes tools, resources, and prompts. The client (your AI agent) discovers and calls them.
Why MCP Matters
Before MCP, every AI framework had its own tool integration system:
| Framework | Tool Format | Standardization |
|-----------|------------|-----------------|
| OpenAI | Function calling | OpenAI-specific |
| LangChain | Tool abstractions | Framework-specific |
| Claude | Tool use | Anthropic-specific |
| MCP | Standard protocol | Universal |
MCP means you write a tool server once, and any MCP-compatible agent can use it. One server, many agents.
How MCP Works
MCP uses JSON-RPC over stdio (for local tools) or HTTP+SSE (for remote services):
sequenceDiagram
Agent->>MCP Server: initialize
MCP Server->>Agent: capabilities
Agent->>MCP Server: tools/list
MCP Server->>Agent: [tool definitions]
Agent->>MCP Server: tools/call {name, args}
MCP Server->>Agent: {result}
Writing an MCP Server
Here's a minimal MCP server in Python:
from mcp.server.fastmcp import FastMCP
# Create server
mcp = FastMCP("my-tools")
# Define a tool
@mcp.tool()
def web_search(query: str) -> str:
"""Search the web for information."""
import requests
resp = requests.get(f"https://api.example.com/search?q={query}")
return resp.text
@mcp.tool()
def read_file(path: str) -> str:
"""Read a file from disk."""
with open(path, 'r') as f:
return f.read()
# Run server
if __name__ == "__main__":
mcp.run()
Connecting an Agent
Claude Desktop (built-in MCP support)
{
"mcpServers": {
"my-tools": {
"command": "python",
"args": ["path/to/server.py"]
}
}
}
Hermes Agent (via config)
tools:
mcp_servers:
my-tools:
command: python
args: ["path/to/server.py"]
Any MCP Client
from mcp import Client
client = Client("path/to/server.py")
tools = client.list_tools()
result = client.call_tool("web_search", {"query": "MCP protocol"})
Real-World MCP Servers I Use
| Server | Purpose | How I Use It |
|--------|---------|-------------|
| Filesystem | Read/write files | Agent edits code and saves results |
| GitHub | Repo management | Create PRs, review code, manage issues |
| Firecrawl | Web scraping | Fetch web content for agent analysis |
| PostgreSQL | Database queries | Query production data through agent |
| Playwright | Browser automation | Agent fills forms, takes screenshots |
MCP vs Function Calling
People often ask how MCP differs from OpenAI's function calling:
| Feature | Function Calling | MCP |
|---------|-----------------|-----|
| Scope | Single LLM API | Any MCP client |
| Tool discovery | Defined in API call | Dynamic discovery |
| Transport | HTTP | stdio or HTTP+SSE |
| State management | Stateless | Sessions + notifications |
| Resource access | No | Read/Subscribe to data |
| Prompts | No | Pre-written prompt templates |
MCP is more than just tools — it also supports resources (readable data) and prompts (pre-written templates).
When to Use MCP
MCP is ideal when:
- You want tools reusable across different AI agents
- You need more than simple function calling (notifications, subscriptions)
- You're building a multi-agent system
- You want to separate tool implementation from agent logic
When Not to Use MCP
MCP may be overkill when:
- You need a single, simple function call
- You're prototyping quickly
- Your agent already has built-in tool support
Verdict
MCP is the closest thing we have to a universal standard for AI tool integration. It's not perfect (young ecosystem, limited adoption outside Anthropic/hermes), but the direction is clearly right.
If you're building a new AI agent system, start with MCP. Your future self will thank you when you want to switch models without rewriting all your tool integrations.