MCP解析——通过代码理解模型上下文协议
   
一个动手学习项目,解释 MCP(模型上下文协议) 通过工作Python代码——它是什么,为什么存在,以及它如何使AI工具集成更简单、更强大。
______________________________________________________________________
目录
______________________________________________________________________
什么是MCP?
模型上下文协议(MCP) 是由Anthropic开发(现已广泛采用)的开放标准,定义了 人工智能模型连接到外部工具、数据源和服务的标准化方式.
把它想象成 用于AI工具的USB:
- USB标准化了设备连接到计算机的方式——一个端口,无限兼容设备
- MCP规范了工具如何连接到AI模型——一个协议、无限兼容的工具和AI模型
在MCP之前,每个开发人员都必须在他们的工具和每个AI模型之间构建自定义集成。在MCP之后,您只需构建一次工具服务器,它就可以与任何兼容MCP的AI一起工作。
简而言之
Without MCP: "I need to write code to make my tool work with Claude,
then rewrite it for GPT, then again for Gemini..."
With MCP: "I build an MCP server once. Claude, GPT, Gemini — they
all connect to the same server using the same protocol."______________________________________________________________________
为什么我们需要MCP?
问题:N×M积分
想象一下,你有 5工具 (计算器、数据库、文件系统、天气API、日历)和 4个AI模型 (克劳德,GPT-4,双子座,拉玛)。没有标准:
5 tools × 4 AI models = 20 custom integrations to build and maintain每个集成都有自己的模式格式、调用约定、响应格式、身份验证机制和错误处理——所有这些都是不同的,都是重复的。
解决方案:N+M集成
使用MCP:
5 tools (each as an MCP server) + 4 AI clients (each MCP-compatible)
= 9 total things to build每个工具都是写的 一次 作为MCP服务器。每个AI客户端都是构建的 一次 作为MCP客户端。他们都通过标准协议相互交谈。
MCP解决的其他问题
| 问题 | 没有MCP | 有MCP |
|---|---|---|
| 工具重复使用 | 在应用程序之间复制粘贴代码 | 将任何应用程序指向同一服务器 |
| 可发现性 | 硬编码哪些工具存在 | 客户端在运行时发现工具 |
| 关注点分离 | 工具代码与AI逻辑混合 | 干净分割:服务器=工具,客户端=AI |
| 生态系统 | 每个开发人员都在重新发明轮子 | 不断增长的可重用服务器库 |
| 更新 | 更新工具=更新每个AI应用程序 | 更新服务器=所有客户端都得到它 |
| 安全 | 工具代码在任何地方运行 | 工具代码在受控服务器中运行 |
______________________________________________________________________
MCP的工作原理
建筑
┌─────────────────────────────────────────────────────────────────┐
│ YOUR APPLICATION │
│ │
│ ┌──────────────────┐ ┌─────────────────────────┐ │
│ │ MCP CLIENT │ │ Claude API │ │
│ │ (mcp_client.py) │◄─────────►│ (or GPT / Gemini / ...) │ │
│ └────────┬─────────┘ └─────────────────────────┘ │
│ │ │
│ MCP Protocol │
│ (JSON-RPC over stdio / SSE / WebSocket) │
│ │ │
│ ┌────────▼─────────┐ │
│ │ MCP SERVER │ │
│ │ (mcp_server.py) │ │
│ │ │ │
│ │ Tools exposed: │ │
│ │ • calculate │ │
│ │ • get_weather │ │
│ │ • save_note │ │
│ │ • get_note │ │
│ │ • list_notes │ │
│ │ • get_datetime │ │
│ │ • word_count │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────┘沟通流程(循序渐进)
User types: "What is sqrt(144) + 10^2?"
│
▼
MCP Client sends to Claude API
(includes list of tools discovered from MCP server)
│
▼
Claude thinks: "I need the calculator tool"
Claude responds: tool_use { name: "calculate", input: {...} }
│
▼
MCP Client routes to MCP Server via call_tool()
Server executes the calculation
Server returns: "Result: 112"
│
▼
MCP Client sends tool_result back to Claude
│
▼
Claude responds: "sqrt(144) is 12, and 10² is 100, so the answer is 112."
│
▼
User sees the final answer协议:基于stdio的JSON-RPC
MCP使用 JSON-RPC 2.0 --简单的请求/响应格式。这是客户端和服务器之间实际流动的内容:
// Client → Server: "What tools do you have?"
{ "jsonrpc": "2.0", "method": "tools/list", "id": 1 }
// Server → Client: "Here are my tools"
{ "jsonrpc": "2.0", "result": { "tools": [...] }, "id": 1 }
// Client → Server: "Run the calculator"
{ "jsonrpc": "2.0", "method": "tools/call",
"params": { "name": "calculate", "arguments": { "expression": "sqrt(144)" } },
"id": 2 }
// Server → Client: "Here's the result"
{ "jsonrpc": "2.0", "result": { "content": [{ "type": "text", "text": "Result: 12" }] }, "id": 2 }所有这些都是自动发生的—— mcp Python库处理它。你只需编写工具逻辑,库就可以进行消息传递。
______________________________________________________________________
本项目
MCP服务器内置的工具
| 工具 | 它做什么 | 它展示了什么 |
|---|---|---|
calculate | 安全地评估数学表达式 | 工具可以包装现有的Python库 |
get_weather | 返回任何城市的模拟天气 | 工具可以调用外部API |
save_note | 留一张便条给 data/notes.json | 工具可以读/写文件(有状态) |
get_note | 按键检索笔记 | 工具可以返回存储的数据 |
list_notes | 列出所有已保存的笔记键 | 工具不能有必需的参数 |
get_datetime | 返回当前UTC日期/时间 | 简单实用工具 |
word_count | 统计文本中的单词/字符/句子 | 文本处理工具 |
文件及其目的
| 文件 | 目的 |
|---|---|
server/mcp_server.py | MCP服务器--定义并运行所有7个工具 |
client/mcp_client.py | MCP客户端连接到服务器,使用Claude回答问题 |
examples/01_without_mcp.py | 传统方法——人工智能客户端中硬编码的工具 |
examples/02_with_mcp.py | MCP方法——结果相同,客户端无工具代码 |
______________________________________________________________________
项目结构
mcp_explained/
│
├── README.md ← You are here
├── pyproject.toml ← Project dependencies (uv)
├── requirements.txt ← Same deps for pip users
├── .env.example ← API key template
├── .gitignore
│
├── server/
│ └── mcp_server.py ← THE MCP SERVER
│ Exposes 7 tools via stdio transport
│ Any MCP-compatible AI can connect to this
│
├── client/
│ └── mcp_client.py ← THE MCP CLIENT
│ Connects to server, uses Claude + MCP
│ Interactive CLI + scripted demo mode
│
├── examples/
│ ├── 01_without_mcp.py ← Traditional approach (hardcoded tools)
│ └── 02_with_mcp.py ← MCP approach (dynamic discovery)
│
└── data/
└── notes.json ← Persisted notes (created at runtime)______________________________________________________________________
快速开始
📖 需要更多细节吗? 请参阅 完整的分步安装指南 它涵盖了uv和pip方法、验证步骤、所有运行命令以及完整的故障排除部分。
先决条件
账单备注: 此项目使用 claude-haiku-4-5-20251001 例如(最便宜的型号)。 完整的演示课程费用低于 $0.01.在以下位置添加至少5美元的信用额度 console.anthropic.com/settings/billion.______________________________________________________________________
步骤1——克隆仓库
git clone https://github.com/shashipk/mcp_explained.git
cd mcp_explained______________________________________________________________________
步骤2——安装依赖项
紫外线(推荐):
uv sync使用pip:
python3 -m venv .venv
source .venv/bin/activate # macOS/Linux
pip install -r requirements.txt______________________________________________________________________
步骤3-添加您的API密钥
cp .env.example .env打开 .env 在任何编辑器中,替换占位符:
ANTHROPIC_API_KEY=sk-ant-api03-your-actual-key-here如何获取密钥: 1. 首选 console.anthropic.com/settings/keys 1. 点击 创建密钥,随便命名(例如。mcp-learning) 1. 复制密钥——它以开头sk-ant-...1. 将其粘贴到.env(值周围没有引号)
______________________________________________________________________
第4步——验证一切正常
# Check that all packages are importable
uv run python -c "import mcp, anthropic, dotenv, rich; print('All OK')"
# Expected: All OK
# Confirm your API key loads
uv run python -c "
from dotenv import load_dotenv; import os
load_dotenv('.env', override=True)
key = os.environ.get('ANTHROPIC_API_KEY', '')
print('Key OK' if key.startswith('sk-ant') else 'Key missing — check your .env')
"______________________________________________________________________
建议学习路径
如果您是MCP的新手,请按以下顺序操作:
1. Read "What is MCP?" and "Why Do We Need MCP?" above
↓
2. Run Example 1 (without MCP) — see the problem
uv run python examples/01_without_mcp.py
↓
3. Run Example 2 (with MCP) — see the solution
uv run python examples/02_with_mcp.py
↓
4. Compare the two files side by side in your editor
Open: examples/01_without_mcp.py vs examples/02_with_mcp.py
↓
5. Read the server code with comments
Open: server/mcp_server.py
↓
6. Read the client code with comments
Open: client/mcp_client.py
↓
7. Run the interactive client and experiment
uv run python client/mcp_client.py______________________________________________________________________
运行示例
pip用户注意事项: 如果您使用pip而不是uv,请先激活您的venv:source .venv/bin/activate(macOS/Linux)或.venv\Scripts\activate(Windows) 然后使用python而不是uv run python.
______________________________________________________________________
示例1:没有MCP(旧方法)
uv run python examples/01_without_mcp.py在输出中要注意什么:
- 工具模式在文件中定义(搜索
TOOLS_HARDCODED_IN_THIS_FILE) - 工具逻辑在文件中运行(请参见
execute_tool_locally()) - 要添加新工具,您必须修改此文件
尝试一个自定义问题:
uv run python examples/01_without_mcp.py "What is 15 squared plus sqrt(81)?"______________________________________________________________________
示例2:使用MCP(正确的方式)
uv run python examples/02_with_mcp.py注意事项:
- 此文件中没有工具模式--
session.list_tools()从服务器获取它们 - 此文件中没有工具逻辑--
session.call_tool()在服务器中运行它 - 此文件将自动获得您添加到的任何新工具
server/mcp_server.py
尝试相同的自定义问题:
uv run python examples/02_with_mcp.py "What is 15 squared plus sqrt(81)?"同样的答案。完全不同的架构。
______________________________________________________________________
交互式客户端(完整体验)
# Interactive mode — ask Claude anything
uv run python client/mcp_client.py
# Pass a question directly
uv run python client/mcp_client.py "What is the area of a circle with radius 5?"
# Scripted demo — automatically shows all 7 tools
uv run python client/mcp_client.py --demo尝试涵盖所有7个工具的问题:
# Calculator
"What is log base 2 of 1024, and what is 15 factorial?"
# Weather
"Compare the weather in Tokyo, Mumbai, and New York."
# Notes — try these in sequence
"Save a note called 'mcp-insight' with this text: MCP lets you build tools once and reuse them with any AI."
"What notes do I have saved?"
"Read the note called 'mcp-insight'"
# Word count
"How many words are in: Four score and seven years ago our fathers brought forth on this continent a new nation."
# Date / Time
"What day of the week is it today, and what is the Unix timestamp right now?"______________________________________________________________________
关键概念深度学习
1.MCP服务器(server/mcp_server.py)
MCP服务器是一个带有两个处理程序的Python脚本:
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
app = Server("my-server")
# Handler 1: Tell clients what tools exist
@app.list_tools()
async def list_tools() -> list[types.Tool]:
return [
types.Tool(
name="my_tool",
description="Does something useful", # Claude reads this to decide when to use the tool
inputSchema={"type": "object", "properties": {...}}
)
]
# Handler 2: Execute a tool when called
@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
if name == "my_tool":
result = do_something(arguments)
return [types.TextContent(type="text", text=result)]2.MCP客户端(client/mcp_client.py)
MCP客户端连接到服务器并将其与AI桥接:
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
# 1. Define how to launch the server
server_params = StdioServerParameters(command="python", args=["server/mcp_server.py"])
# 2. Connect
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize() # MCP handshake
tools = await session.list_tools() # discover tools dynamically
result = await session.call_tool(name, args) # execute a tool in the server3.传输层
MCP支持客户端和服务器的多种通信方式:
| 运输 | 用例 | 工作原理 |
|---|---|---|
| 标准 | 本地工具(同一台机器) | 客户端将服务器作为子进程启动;通过stdin/stdout进行通信 |
| SSE(HTTP) | 远程工具(不同的机器) | 服务器作为HTTP端点运行;客户端通过服务器发送的事件进行连接 |
| WebSocket | 双向远程工具 | 全双工连接 |
此项目使用 标准 --最容易在本地设置和运行。在生产环境中,您可以使用SSE或WebSocket通过网络公开服务器,以便多个客户端可以连接。
4.工具模式(JSON模式)
每个工具都用JSON模式描述。Claude使用它来了解要发送哪些参数:
types.Tool(
name="calculate",
description="Evaluate a math expression", # ← Claude reads this to decide WHEN to use the tool
inputSchema={
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "e.g. 'sqrt(144)', '2 + 2 * 10'" # ← Claude reads this to format its call
}
},
"required": ["expression"]
}
)5.代理循环
Claude并没有预先调用所有工具——它一步一步地推理:
Turn 1 → User: "What is sqrt(144)?"
Turn 2 → Claude: tool_use { name: "calculate", input: { "expression": "sqrt(144)" } }
Turn 3 → User: tool_result { content: "Result: 12.0" }
Turn 4 → Claude: "The square root of 144 is 12." [stop_reason: "end_turn"]对于复杂的问题,克劳德可能会在给出最终答案之前,在多个回合中调用多个工具。
6.MCP与本地工具使用
您可能会想:“Claude已经原生支持工具使用——为什么要在上面添加MCP?”
| 特性 | 本机工具使用(无MCP) | 使用MCP |
|---|---|---|
| 工具模式 | 在应用程序中硬编码 | 在可重用服务器中定义 |
| 工具逻辑 | 在应用程序中运行 | 在服务器中运行 |
| 可重用性 | 零--每个应用程序复制粘贴 | 完全--任何MCP客户端都可以连接 |
| 多模型 | 每个模型都必须重写 | 一台服务器适用于所有模型 |
| 发现 | 静态--您预先定义它 | 动态--客户端在运行时询问服务器 |
| 生态系统 | 无-你构建一切 | 数百个可用的社区服务器 |
MCP是一种 标准化层 除了原生工具的使用。客户端仍然发送本机Anthropic格式的工具调用——MCP只是定义了如何在单独的服务器中发现和执行这些工具。
______________________________________________________________________
并排理解代码
同样的问题,两种架构:
无MCP (examples/01_without_mcp.py):
# ❌ Tool schemas defined HERE (in the AI client)
TOOLS = [{"name": "calculate", "description": "...", "input_schema": {...}}]
# ❌ Tool logic runs HERE (in the AI client)
def execute_tool_locally(name, args):
if name == "calculate":
return str(eval(args["expression"], ...))
# ❌ Reuse = copy-paste this entire file into every new app使用MCP (examples/02_with_mcp.py):
# ✅ Tool schemas come FROM the server (zero hardcoding here)
tools_response = await session.list_tools()
anthropic_tools = [{"name": t.name, ...} for t in tools_response.tools]
# ✅ Tool logic runs IN the server (zero implementation code here)
result = await session.call_tool(block.name, block.input)
# ✅ Reuse = point any new app at the same server______________________________________________________________________
MCP生态系统
MCP已被所有主要AI平台采用:
- Anthropic -Claude Desktop,Claude API
- 开放人工智能 --ChatGPT(2025年宣布支持MCP)
- 谷歌 --Gemini(社区MCP客户)
- 微软 --GitHub Copilot,VS Code AI扩展
社区MCP服务器
社区已经构建了数百台即用型MCP服务器:
| 服务器 | 它连接到什么 |
|---|---|
mcp-server-filesystem | 本地文件系统(读/写文件) |
mcp-server-git | Git仓库 |
mcp-server-github | GitHub API(问题、PR、转发) |
mcp-server-postgres | PostgreSQL数据库 |
mcp-server-brave-search | 勇敢的网络搜索 |
mcp-server-puppeteer | 浏览器自动化 |
mcp-server-slack | Slack消息 |
更多信息请访问:
______________________________________________________________________
故障排除
API密钥未加载(ANTHROPIC_API_KEY not set)
如果您在设置密钥后仍看到此错误 .env,您的shell可能已经 ANTHROPIC_API_KEY 设置为空字符串-- load_dotenv 默认情况下不会覆盖现有的shell变量。
此项目中的所有文件都已包含 override=True 要处理此问题:
load_dotenv(Path(__file__).parent.parent / ".env", override=True)如果您仍然有问题,请验证:
# Does the .env file exist and contain the key?
cat .env | grep ANTHROPIC_API_KEY
# Does it load correctly?
uv run python -c "
from dotenv import load_dotenv; import os
load_dotenv('.env', override=True)
key = os.environ.get('ANTHROPIC_API_KEY', '')
print('OK' if key.startswith('sk-ant') else 'Missing or wrong format')
"______________________________________________________________________
credit balance is too low
anthropic.BadRequestError: Your credit balance is too low to access the Anthropic API.在以下位置添加学分 console.anthropic.com/settings/billion5美元的充值足以完成这个项目的数百次运行。
______________________________________________________________________
ModuleNotFoundError: No module named 'mcp'
你在虚拟环境之外运行Python。使用 uv run python 而不是 python:
uv run python examples/01_without_mcp.py # ✓ uses venv
python examples/01_without_mcp.py # ✗ uses system Python或者使用pip,先激活venv:
source .venv/bin/activate
python examples/01_without_mcp.py______________________________________________________________________
服务器似乎挂起,没有输出
server/mcp_server.py 被设计为 由客户端作为子流程启动 --它等待stdin上的JSON-RPC输入。直接运行它不会显示任何输出(这是正确的——它正在等待客户端)。始终运行客户端:
uv run python client/mcp_client.py # ✓ the client launches the server automatically______________________________________________________________________
许可证
麻省理工学院——见 许可证
______________________________________________________________________
作者
作为一个学习项目,通过工作代码了解MCP。如果这对你有帮助,给它一个⭐ 在GitHub上!
______________________________________________________________________
*用途 claude-opus-4-6 对于交互式客户端和 claude-haiku-4-5-20251001 例如(演示更快、更便宜)。*
