MCP — Model Context Protocol
Understand MCP: the open standard that lets AI agents connect to any tool, data source, or service through a unified protocol. Learn the architecture, primitives, and how it changes AI development.
Understand MCP: the open standard that lets AI agents connect to any tool, data source, or service through a unified protocol. Learn the architecture, primitives, and how it changes AI development. This hands-on tutorial focuses on practical implementation of mcp — model context protocol concepts.
MCP — Model Context Protocol
Before MCP, connecting an AI agent to a tool meant writing custom integration code for every single combination of model + tool. OpenAI's format, Anthropic's format, LangChain's format — all different. MCP changes everything.
MCP (Model Context Protocol) is an open standard created by Anthropic that defines how AI models communicate with external tools, data sources, and services — in a unified, vendor-neutral way.
Think of MCP the same way you think of USB-C: one standard port that any device can plug into. Before USB-C, every manufacturer had their own cable. MCP is the USB-C of AI tool integration.
1. Why MCP Exists — The Problem It Solves
Before MCP: The N×M Problem
Every model needed its own custom integration for every tool — N models × M tools = N×M pieces of code to build and maintain.
After MCP: The N+M Solution
Write one MCP Server per tool. Any MCP-compatible AI client can use it instantly. N models + M servers — no custom glue code.
2. MCP Architecture
MCP follows a classic client-server architecture:
| Component | Role | Examples |
|---|---|---|
| Host | The AI-powered app that uses MCP clients | Claude Desktop, Cursor IDE, your custom app |
| MCP Client | Lives inside the host, speaks the MCP protocol | Anthropic SDK client, LangChain MCP adapter |
| MCP Server | Exposes capabilities (tools, resources, prompts) | Filesystem server, GitHub server, your custom server |
| Transport | How client and server communicate | stdio (local), HTTP + SSE (remote) |
3. The Three MCP Primitives
MCP defines exactly three things a server can expose:
🔧 Tools (Model-controlled actions)
Tools are functions the AI model can call to take actions. The model decides when to call them based on context.
# What a tool definition looks like (Python SDK)
@mcp.tool()
def search_web(query: str, max_results: int = 5) -> list[dict]:
"""Search the web and return results.
Args:
query: The search query string
max_results: Maximum number of results to return
"""
# Your implementation here
results = web_search_api(query, limit=max_results)
return results
When the AI wants to call this tool, MCP sends:
{
"method": "tools/call",
"params": {
"name": "search_web",
"arguments": {
"query": "MCP protocol tutorial",
"max_results": 3
}
}
}
📄 Resources (Application-controlled data)
Resources are read-only data that the host application exposes to the AI — like files, database rows, or API responses. The application controls when to expose them.
@mcp.resource("file://{path}")
def read_file(path: str) -> str:
"""Read a file from the local filesystem."""
with open(path, "r") as f:
return f.read()
@mcp.resource("db://users/{user_id}")
def get_user(user_id: str) -> dict:
"""Fetch a user record from the database."""
return db.query(f"SELECT * FROM users WHERE id = {user_id}")
💬 Prompts (User-controlled templates)
Prompts are reusable prompt templates that users can invoke. They can be parameterized and include multiple messages.
@mcp.prompt()
def code_review_prompt(language: str, code: str) -> list[dict]:
"""A structured prompt for code review."""
return [
{
"role": "user",
"content": f"Please review this {language} code for bugs, style, and performance:\n\n```{language}\n{code}\n```"
}
]
4. Transport Mechanisms
MCP supports two ways for clients and servers to communicate:
| Transport | How it works | Best for |
|---|---|---|
| stdio | Client spawns server as a subprocess, communicates via stdin/stdout | Local tools, file system, CLI tools |
| HTTP + SSE | Client sends HTTP POST, server responds via Server-Sent Events stream | Remote services, cloud APIs, multi-user apps |
5. The MCP Lifecycle
Here's what happens when a client connects to an MCP server:
6. MCP vs Function Calling — What's the Difference?
This is a common source of confusion. Here's how they differ:
| Feature | Function Calling | MCP |
|---|---|---|
| Scope | Model-specific API feature | Open, vendor-neutral protocol |
| Data types | Tools only | Tools + Resources + Prompts |
| Reusability | Per-model, per-app code | Write once, use with any MCP client |
| Discovery | Hardcoded in prompt | Dynamic via tools/list at runtime |
| State | Stateless per API call | Stateful persistent connection |
| Think of it as | An LLM feature | An infrastructure standard |
MCP is built on top of function calling — but adds the protocol layer that makes integrations reusable and portable.
7. The MCP Ecosystem — Official Servers
Anthropic and the community maintain a growing library of ready-to-use MCP servers:
| Server | What it exposes | Use case |
|---|---|---|
| filesystem | Read/write local files and directories | Coding agents, document editors |
| github | Repos, issues, PRs, commits | AI coding assistants |
| postgres | SQL queries, schema inspection | AI data analysts |
| brave-search | Web search results | Research agents |
| slack | Channels, messages, users | Workplace automation agents |
| memory | Knowledge graph storage | Persistent agent memory |
| puppeteer | Browser automation, screenshots | Web scraping agents |
8. Using MCP in Claude Desktop
The easiest way to experience MCP is with Claude Desktop. Configure it in claude_desktop_config.json:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/yourname/Documents"],
"env": {}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "your_token_here"
}
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://user:pass@localhost/mydb"
}
}
}
}
After saving, restart Claude Desktop. Claude can now read your files, query GitHub, and run SQL — all through a secure, local MCP connection.
9. Using MCP Programmatically (Python)
import asyncio
from anthropic import Anthropic
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def run_agent_with_mcp():
"""Run a Claude agent connected to an MCP filesystem server."""
# 1. Define the MCP server to connect to
server_params = StdioServerParameters(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "./project"],
)
# 2. Connect to the MCP server
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# 3. Initialize the connection
await session.initialize()
# 4. Discover available tools
tools_response = await session.list_tools()
tools = [
{
"name": t.name,
"description": t.description,
"input_schema": t.inputSchema,
}
for t in tools_response.tools
]
print(f"Available tools: {[t['name'] for t in tools]}")
# 5. Run Claude with MCP tools
client = Anthropic()
messages = [{"role": "user", "content": "List all Python files in the project"}]
while True:
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=4096,
tools=tools,
messages=messages,
)
# If Claude wants to use a tool
if response.stop_reason == "tool_use":
tool_use = next(b for b in response.content if b.type == "tool_use")
# Call the tool through MCP
result = await session.call_tool(tool_use.name, tool_use.input)
# Feed result back to Claude
messages.append({"role": "assistant", "content": response.content})
messages.append({
"role": "user",
"content": [{"type": "tool_result", "tool_use_id": tool_use.id, "content": str(result)}]
})
else:
# Final response
print("Agent:", response.content[0].text)
break
asyncio.run(run_agent_with_mcp())
Output:
Available tools: ['read_file', 'write_file', 'list_directory', 'create_directory', 'delete_file']
Agent: I found the following Python files in the project:
- main.py
- utils/helpers.py
- models/user.py
- tests/test_main.py
10. Security Model
MCP is designed with security in mind:
- User consent: The host must explicitly configure which servers to connect to
- Sandboxed processes: stdio servers run as isolated subprocesses
- Scoped access: You configure exactly which directories/APIs a server can touch
- No network by default: stdio servers can't make outbound network calls unless you code it
AI Mentor
AssistantConfused about "MCP Model Context Protocol AI agents tools resources prompts architecture client server"? Ask our AI mentor for a simplified explanation.
Quiz
Quiz
Question 1 of 4What problem does MCP primarily solve for AI developers?
Key Takeaways
✅ MCP is an open standard by Anthropic that solves the N×M tool integration problem.
✅ MCP has three primitives: Tools (actions), Resources (data), Prompts (templates).
✅ stdio transport is for local servers; HTTP + SSE is for remote/cloud servers.
✅ MCP servers are reusable — write once, connect from Claude, Cursor, or your own app.
✅ MCP is built on JSON-RPC 2.0 with a standard handshake and discovery lifecycle.
✅ Security is enforced by the host — user consent + scoped access by design.
What's Next?
Now that you understand what MCP is and how it works, the next chapter teaches you how to build your own MCP Server from scratch — including real tools, resources, and deployment patterns.
Keep building! 🚀