AI Agent 从入门到封神:24 讲打造你的超级智能体~系列文章09:MCP协议详解:AI Agent的“USB-C接口“
·
MCP协议详解:AI Agent的"USB-C接口",一次接入万物互联 🔌
导读:2025年最火的Agent协议是什么?毫无疑问是MCP(Model Context Protocol)!它由Anthropic提出,被称为AI界的"USB-C接口"——一个协议统一所有工具接入。今天我们从原理到实战,彻底搞懂MCP为什么被称为"游戏规则改变者"!🏆
一、为什么需要MCP?先理解痛点 😤
1.1 MCP出现前的"混沌时代"
在MCP之前,每个Agent框架都有自己的工具接入方式:
问题一目了然:
- 🔴 3个Agent × 3个工具 = 9种适配方式
- 🔴 每新增一个工具,需要为每个框架写一套适配代码
- 🔴 工具开发者需要为每个框架维护不同的版本
- 🔴 N个Agent × M个工具 = N×M种适配,复杂度爆炸!
1.2 MCP的解决方案
MCP的效果:
- ✅ 3个Agent + 3个工具 = 只需要6次接入(而不是9次)
- ✅ 新增工具只需实现一次MCP Server,所有Agent都能用
- ✅ N个Agent + M个工具 = N+M次接入,复杂度线性增长!
💡 一句话总结:MCP就是AI工具界的USB-C——一个接口标准,万物互联。
二、MCP协议的核心架构 🏗️
2.1 三大角色
| 角色 | 类比 | 职责 | 示例 |
|---|---|---|---|
| 🏠 MCP Host | 你的电脑 | 运行Agent的应用程序 | IDE、聊天应用、Agent框架 |
| 🔌 MCP Client | USB-C接口 | 在Host中,负责连接Server | LangChain MCP Client |
| 🖨️ MCP Server | USB-C设备 | 提供工具/资源的服务 | 数据库Server、搜索Server |
2.2 架构图
2.3 MCP提供的三种能力
| 能力 | 说明 | 类比 | 示例 |
|---|---|---|---|
| 🔧 Tools(工具) | 模型可调用的函数 | USB设备的"功能" | 搜索、查询、计算 |
| 📦 Resources(资源) | 可读取的数据 | USB设备的"存储" | 文件内容、数据库记录 |
| 📋 Prompts(提示模板) | 预定义的提示词模板 | USB设备的"说明书" | 代码审查模板、分析模板 |
三、MCP vs 传统方案:全面对比 📊
| 维度 | 传统Function Calling | MCP协议 |
|---|---|---|
| 工具定义 | 每个框架自定义 | 统一的JSON Schema |
| 通信协议 | 直接函数调用 | JSON-RPC 2.0 |
| 传输方式 | 进程内调用 | HTTP/SSE 或 stdio |
| 工具发现 | 硬编码注册 | 动态发现 |
| 跨框架 | ❌ 不兼容 | ✅ 完全兼容 |
| 热插拔 | ❌ 需要重启 | ✅ 支持 |
| 安全机制 | 各自实现 | 统一的安全模型 |
| 生态复用 | 低(重复造轮子) | 高(一次开发,到处使用) |
🔥 核心优势:MCP让工具开发者只需要写一次,就能被所有支持MCP的Agent框架使用。这极大地促进了工具生态的繁荣。
四、MCP Server开发实战 🛠️
4.1 环境准备
# 安装MCP SDK
pip install mcp
# MCP Server基于Python开发,非常简单
4.2 第一个MCP Server:天气查询
"""
weather_server.py - 天气查询MCP Server
"""
from mcp.server import Server
from mcp.types import Tool, TextContent
import json
# 创建Server实例
server = Server("weather-server")
# 定义工具
@server.tool()
async def get_weather(city: str) -> str:
"""获取指定城市的天气信息。
Args:
city: 城市名称,如'北京'、'上海'、'广州'
"""
# 实际的天气API调用逻辑
weather_data = {
"北京": {"temp": 25, "weather": "晴", "humidity": 40},
"上海": {"temp": 22, "weather": "多云", "humidity": 65},
"广州": {"temp": 28, "weather": "小雨", "humidity": 80},
}
data = weather_data.get(city)
if data:
return json.dumps({
"city": city,
"temperature": f"{data['temp']}°C",
"weather": data["weather"],
"humidity": f"{data['humidity']}%"
}, ensure_ascii=False)
return f"暂无{city}的天气数据"
@server.tool()
async def get_forecast(city: str, days: int = 3) -> str:
"""获取城市未来几天的天气预报。
Args:
city: 城市名称
days: 预报天数,默认3天
"""
# 模拟预报数据
forecast = []
for i in range(days):
forecast.append({
"date": f"第{i+1}天",
"temp_high": f"{25+i}°C",
"temp_low": f"{18+i}°C",
"weather": ["晴", "多云", "阴"][i % 3]
})
return json.dumps({"city": city, "forecast": forecast}, ensure_ascii=False)
# 启动Server
if __name__ == "__main__":
import asyncio
from mcp.server.stdio import stdio_server
async def main():
async with stdio_server() as (read, write):
await server.run(read, write)
asyncio.run(main())
4.3 第二个MCP Server:数据库查询
"""
database_server.py - 数据库查询MCP Server
"""
from mcp.server import Server
import json
import sqlite3
server = Server("database-server")
@server.tool()
async def query_database(sql: str) -> str:
"""执行SQL查询语句(只支持SELECT)。
Args:
sql: SQL查询语句,如 'SELECT * FROM users LIMIT 10'
"""
try:
conn = sqlite3.connect("my_database.db")
cursor = conn.execute(sql)
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
conn.close()
result = {
"columns": columns,
"rows": [dict(zip(columns, row)) for row in rows],
"row_count": len(rows)
}
return json.dumps(result, ensure_ascii=False)
except Exception as e:
return f"查询错误:{str(e)}"
@server.tool()
async def list_tables() -> str:
"""列出数据库中所有的表。"""
conn = sqlite3.connect("my_database.db")
cursor = conn.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = [row[0] for row in cursor.fetchall()]
conn.close()
return json.dumps({"tables": tables}, ensure_ascii=False)
@server.resource("schema://tables")
async def get_schema() -> str:
"""获取数据库的表结构信息。"""
conn = sqlite3.connect("my_database.db")
cursor = conn.execute("SELECT name, sql FROM sqlite_master WHERE type='table'")
schemas = {name: sql for name, sql in cursor.fetchall()}
conn.close()
return json.dumps(schemas, ensure_ascii=False)
五、MCP Client接入实战 🔗
5.1 在Agent中接入MCP Server
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
# 配置MCP Server连接
server_params = StdioServerParameters(
command="python",
args=["weather_server.py"]
)
# 连接MCP Server并加载工具
async def create_agent():
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# 从MCP Server加载工具
tools = await load_mcp_tools(session)
# 创建Agent
agent = create_react_agent(
model=ChatOpenAI(model="gpt-4o"),
tools=tools,
prompt="你是一个能查天气的AI助手。"
)
# 运行Agent
result = await agent.ainvoke({
"messages": [("user", "北京今天天气怎么样?")]
})
print(result["messages"][-1].content)
5.2 多MCP Server同时接入
# 同时接入多个MCP Server
servers = {
"weather": StdioServerParameters(command="python", args=["weather_server.py"]),
"database": StdioServerParameters(command="python", args=["database_server.py"]),
"filesystem": StdioServerParameters(command="python", args=["filesystem_server.py"]),
}
all_tools = []
for name, params in servers.items():
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await load_mcp_tools(session)
all_tools.extend(tools)
# Agent现在拥有了所有MCP Server的工具!
agent = create_react_agent(
model=ChatOpenAI(model="gpt-4o"),
tools=all_tools,
)
六、MCP生态系统一览 🌍
6.1 已有的MCP Server
| 类别 | MCP Server | 功能 | 状态 |
|---|---|---|---|
| 🔍 搜索 | Brave Search | 网络搜索 | ✅ 官方 |
| 📁 文件 | Filesystem | 文件读写 | ✅ 官方 |
| 🗄️ 数据库 | PostgreSQL/SQLite | 数据库操作 | ✅ 社区 |
| 💻 代码 | GitHub | 代码仓库操作 | ✅ 官方 |
| 📧 邮件 | Gmail | 邮件收发 | ✅ 社区 |
| 🌐 浏览器 | Puppeteer | 网页自动化 | ✅ 官方 |
| 📊 数据 | Google Drive | 文档管理 | ✅ 社区 |
| 🎨 设计 | Figma | 设计稿读取 | ✅ 社区 |
6.2 MCP与其他协议对比
| 协议 | 提出者 | 定位 | 适用范围 |
|---|---|---|---|
| MCP | Anthropic | Agent↔工具 | 工具接入 |
| A2A | Agent↔Agent | Agent间协作 | |
| OpenAPI | 业界 | 应用↔应用 | REST API描述 |
| Function Calling | OpenAI | 模型↔工具 | 单模型工具调用 |
💡 关系理解:MCP和A2A是互补的——MCP解决Agent怎么使用工具,A2A解决Agent之间怎么协作。两者结合 = 完整的Agent互联网。
七、MCP的安全机制 🔒
7.1 安全挑战
Agent能调用工具了,安全问题也随之而来:
| 风险 | 描述 | 严重性 |
|---|---|---|
| 🔴 工具滥用 | Agent调用了不该调用的工具 | 高 |
| 🔴 数据泄露 | 通过工具泄露敏感数据 | 高 |
| 🟡 权限越界 | Agent执行了超出权限的操作 | 中 |
| 🟡 注入攻击 | 恶意输入诱导Agent调用危险工具 | 中 |
7.2 MCP的安全设计
| 安全机制 | 说明 |
|---|---|
| 🔐 权限控制 | 每个Server可以定义工具的访问权限 |
| ✅ 用户确认 | 敏感操作需要用户手动确认 |
| 📝 审计日志 | 所有工具调用都有完整记录 |
| 🚧 沙箱隔离 | Server运行在独立进程中 |
八、本期小结 📝
| 知识点 | 核心内容 |
|---|---|
| MCP是什么 | Model Context Protocol,Agent工具接入的统一标准 |
| 为什么需要 | 解决N×M适配问题,变成N+M |
| 三大角色 | Host(宿主)、Client(客户端)、Server(服务端) |
| 三种能力 | Tools(工具)、Resources(资源)、Prompts(模板) |
| 开发难度 | 非常简单!几十行代码就能写一个MCP Server |
🔥 MCP是2025年Agent领域最重要的基础设施。 它让Agent的工具生态从"各自为战"变成"统一标准",就像USB-C统一了充电接口一样。学会开发MCP Server,你的工具就能被全世界所有Agent使用!
📢 下期预告:《从零实现一个MCP Server:让你的Agent操控数据库、搜索引擎和API》—— 光说不练假把式!下期带你完整实现一个功能丰富的MCP Server!🔧
📌 三连走起!MCP,Agent生态的基石! 💪
📚 专栏第9/24期,工具与协议篇进行中…
作者:高炉炼铁智能化技术研究者,专注钢铁冶金与人工智能 交叉领域。
👍 如果觉得有帮助,请点赞、收藏、转发!
版权归作者所有,未经许可请勿抄袭,套用,商用(或其它具有利益性行为)。
🔔 关注专栏,不错过后续精彩内容
更多推荐




所有评论(0)