08 - MCP (Model Context Protocol) β
1. What is MCP? β
What: MCP (Model Context Protocol) is an open protocol created by Anthropic that standardizes how AI applications connect to external data sources and tools. Think of it as "USB-C for AI" β one standard interface instead of custom integrations for every tool.
Before MCP: With MCP:
βββββββ custom API ββββββββ βββββββ ββββββββ
β App βββββββββββββββββSlack β β App βββMCPββββββββSlack β
β β custom API ββββββββ β β (same ββββββββ
β βββββββββββββββββGitHubβ β β protocol) βGitHubβ
β β custom API ββββββββ β βββMCPββββββββ β
β βββββββββββββββββ DB β β β ββββββββ
βββββββ ββββββββ β βββMCPββββββββ DB β
βββββββ ββββββββ
N apps Γ M tools = NΓM integrations vs. N+M integrations2. Architecture: Host, Client, Server β
Three-layer architecture:
ββββββββββββββββββββββββββββββββββββββββββββ
β HOST APPLICATION β
β (Claude Desktop, VS Code, custom app) β
β β
β ββββββββββββ ββββββββββββ β
β β MCP β β MCP β ... β
β β Client 1 β β Client 2 β β
β ββββββ¬ββββββ ββββββ¬ββββββ β
βββββββββΌβββββββββββββββΌββββββββββββββββββββ
β β
ββββββΌββββββ ββββββΌββββββ
β MCP β β MCP β
β Server A β β Server B β
β (GitHub) β β (DB) β
ββββββββββββ ββββββββββββ| Component | Role | Example |
|---|---|---|
| Host | The AI application that users interact with | Claude Desktop, IDE extension |
| Client | Maintains 1:1 connection with a server | Created by host, one per server |
| Server | Exposes tools, resources, and prompts | GitHub MCP server, database server |
Key design principle: The host controls which servers to connect to and what permissions to grant. Servers are sandboxed β they can only expose capabilities, not directly access the model.
3. Transport: stdio and SSE β
How clients and servers communicate:
stdio (Standard I/O):
Client spawns server as a child process.
Communication via stdin/stdout using JSON-RPC 2.0.
Client β stdin β Server
Client β stdout β Server
stderr β Logging// Client sends request
{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}
// Server responds
{"jsonrpc": "2.0", "id": 1, "result": {"tools": [...]}}Best for: Local servers, CLI tools, same-machine communication.
SSE (Server-Sent Events) / Streamable HTTP:
Client connects via HTTP.
Server β Client: SSE stream for server-initiated messages.
Client β Server: HTTP POST for requests.Best for: Remote servers, web deployments, cloud-hosted tools.
4. Primitives: Tools, Resources, Prompts β
MCP servers expose three types of capabilities:
Tools (model-controlled) β
Functions the model can call. Like function calling, but standardized.
// Server defines a tool
server.tool(
"search_codebase",
"Search for code patterns in the repository",
{
query: z.string().describe("Search query"),
file_pattern: z.string().optional().describe("Glob pattern like '*.ts'")
},
async ({ query, file_pattern }) => {
const results = await grep(query, file_pattern);
return { content: [{ type: "text", text: JSON.stringify(results) }] };
}
);Resources (application-controlled) β
Data the application can read, like files or database records. Identified by URIs.
// Server exposes a resource
server.resource(
"config",
"file:///app/config.json",
async () => ({
contents: [{ uri: "file:///app/config.json", text: configData }]
})
);Prompts (user-controlled) β
Pre-built prompt templates that users can select.
// Server defines a prompt template
server.prompt(
"code_review",
"Review code for best practices",
[{ name: "code", description: "Code to review", required: true }],
async ({ code }) => ({
messages: [{
role: "user",
content: { type: "text", text: `Review this code:\n\n${code}` }
}]
})
);| Primitive | Controlled By | Purpose |
|---|---|---|
| Tools | AI model (decides when to call) | Actions and computations |
| Resources | Application (attaches to context) | Data and file access |
| Prompts | User (selects from menu) | Template workflows |
5. Building an MCP Server β
Using the TypeScript SDK:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "my-tool-server",
version: "1.0.0"
});
// Define a tool
server.tool(
"get_weather",
"Get current weather for a city",
{ city: z.string() },
async ({ city }) => {
const weather = await fetchWeather(city);
return {
content: [{ type: "text", text: `Weather in ${city}: ${weather}` }]
};
}
);
// Start server with stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);Using the Python SDK:
from mcp.server import Server
from mcp.server.stdio import stdio_server
import mcp.types as types
server = Server("my-tool-server")
@server.list_tools()
async def list_tools():
return [types.Tool(
name="get_weather",
description="Get current weather for a city",
inputSchema={
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
)]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_weather":
weather = await fetch_weather(arguments["city"])
return [types.TextContent(type="text", text=f"Weather: {weather}")]
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())6. Configuring MCP in Claude Desktop β
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/server/index.js"],
"env": {
"API_KEY": "your-key"
}
},
"python-server": {
"command": "python",
"args": ["-m", "my_mcp_server"]
}
}
}7. Security Considerations β
Key security principles for MCP:
| Concern | Mitigation |
|---|---|
| Tool permissions | Host should require user approval before tool execution |
| Data exposure | Servers should only expose data the user has access to |
| Prompt injection via tools | Tool results can contain adversarial content β host must sanitize |
| Server authentication | Use API keys/tokens for remote servers |
| Least privilege | Servers should request minimum needed permissions |
| Input validation | Validate all tool arguments with schemas (Zod, JSON Schema) |
Trust boundaries:
User β trusts β Host application
Host β manages β MCP clients
Client β validates β MCP server responses
Server β sandboxed β External systems
The user trusts the host.
The host does NOT blindly trust servers.
Tool calls require user confirmation (or explicit pre-approval).Prompt injection risk: An MCP server returning malicious content in tool results could influence the model. Hosts should treat tool results as untrusted user input.