Agent AtlasAI Agent 知识库
04.04记忆与知识 · Memory & Knowledge

MCP:模型上下文协议

Host、Client、Server 三角色,Tools、Resources、Prompts 三原语,以及权限与供应链安全。

MCP 解决的是一个很具体的问题:每个 AI 应用都要为每个工具写一遍集成。它把「N 个客户端 × M 个工具」的平方问题,变成「各自实现一次协议」。

为什么需要协议

假设你有 5 个 AI 应用(IDE、聊天客户端、客服系统、内部助手、自动化平台),要接 20 个数据源(文件、数据库、Git、工单、日历……)。没有协议时,最坏需要 100 个集成。

MCP(Model Context Protocol)定义了一套标准接口:工具方实现一次 Server,应用方实现一次 Client,任意组合都能工作。

图 1 · MCP 的三角色
Host用户使用的 AI 应用
管理多个 Client
→
Client与一个 Server 一对一
处理协议与生命周期
→
Server暴露 Tools / Resources / Prompts
本地进程或远程服务
Host 决定把哪些工具放进模型上下文;Client 负责连接;Server 负责能力。

三个原语

原语控制方用途例子
Tools模型可执行动作查询订单、发消息、跑测试
Resources应用可读取的数据文件、数据库记录、日志
Prompts用户可复用提示模板「代码审查」「周报生成」

理解区别很重要:

  • Tool 有副作用,需要权限与审计;
  • Resource 是只读上下文,通常由应用决定何时加载;
  • Prompt 是用户主动选择的模板,不是模型自动调用。

此外还有客户端能力(Server 可以反向请求 Host):

  • Sampling:Server 请求 Host 用模型生成内容;
  • Roots:Host 告诉 Server 可访问的目录范围;
  • Elicitation:Server 向用户索取补充信息。

传输方式

方式场景特点
stdio本地进程简单、无网络、随 Host 启动
Streamable HTTP远程服务可跨网络、支持认证、可多客户端

早期的 HTTP+SSE 方式已逐步被 Streamable HTTP 取代。选择原则:本地工具用 stdio,团队共享/云端工具用 HTTP。

一次调用的过程

text
1. 初始化:协商协议版本与能力
2. 发现:client 拉取 tools/list、resources/list、prompts/list
3. 选择:Host 把相关工具描述放入模型上下文
4. 调用:模型输出 tool call → client 发送 tools/call
5. 执行:server 校验参数、执行、返回 content
6. 回填:结果进入模型上下文,继续循环

MCP 只规定「怎么通信」,不规定「模型怎么选工具」。选择仍由 Host 和模型决定。

写一个 MCP Server

用 Python 的 FastMCP,十几行就能跑:

python
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("acme-docs")

DOCS = {
    "refund": "退款需在签收后 7 天内申请,商品需保持完好。",
    "shipping": "默认顺丰,偏远地区 3–5 天。",
}


@mcp.tool()
def search_docs(query: str, limit: int = 5) -> list[dict]:
    """检索 ACME 内部文档。

    Args:
        query: 关键词,尽量简短。
        limit: 返回条数,1-10。
    """
    q = query.lower()
    hits = [{"id": k, "text": v} for k, v in DOCS.items() if q in k or q in v.lower()]
    return hits[: max(1, min(limit, 10))]


@mcp.resource("docs://{doc_id}")
def read_doc(doc_id: str) -> str:
    """按 ID 读取文档全文。"""
    if doc_id not in DOCS:
        raise ValueError(f"未知文档:{doc_id}")
    return DOCS[doc_id]


@mcp.prompt()
def summarize_doc(doc_id: str) -> str:
    """生成文档摘要的提示模板。"""
    return f"请用三条要点总结文档 {doc_id},每条不超过 30 字。"


if __name__ == "__main__":
    mcp.run()  # 默认 stdio

客户端配置(以支持 MCP 的桌面客户端为例):

json
{
  "mcpServers": {
    "acme-docs": {
      "command": "python",
      "args": ["C:/path/to/server.py"],
      "env": { "DOCS_TOKEN": "..." }
    }
  }
}

远程服务则配置 URL 与认证头,由客户端完成 OAuth 或 token 交换。

设计一个好 Server

工具要小而清晰

text
✓ search_orders(query, status, limit)
✓ get_order(order_id)
✓ create_refund(order_id, amount, idempotency_key)
✗ manage_orders(action, payload)

一个工具只做一类事。参数少、枚举优先、描述写清「何时不用」。这些原则与〈工具设计〉完全一致。

不要把危险能力直接暴露

  • 不要暴露 execute_sql,除非有强沙箱与只读账号;
  • 不要暴露 run_shell,除非在隔离环境且有人工确认;
  • 文件访问限制在 roots 指定目录;
  • 写操作要求幂等键与权限检查;
  • 返回结果裁剪,避免把整页 HTML 塞进上下文。

分页与截断

MCP 的返回会进入模型上下文。列表接口必须支持 limit / cursor,并在结果里标明是否截断。

json
{
  "items": [...],
  "next_cursor": "abc",
  "truncated": true
}

认证与授权

远程 MCP Server 应使用标准的 OAuth 2.1 流程,而不是让用户把长期 token 贴在配置里。要点:

  • 每个用户/租户独立授权;
  • token 有最小 scope;
  • 不要把用户 token 透传给下游(confused deputy);
  • 记录调用审计;
  • 支持撤销。

安全风险

MCP 扩大了攻击面。常见风险:

风险说明缓解
工具投毒工具描述里藏恶意指令,诱导模型调用审查来源、固定版本、限制工具数量
Rug pull首次审核后,Server 更新恶意行为锁定版本/哈希,监控变更
跨 Server 影子恶意 Server 冒充可信工具名命名空间、白名单
间接提示注入Resource 内容包含恶意指令外部内容视为数据、权限隔离
过度授权Server 拿到过多 scope最小权限、按用户授权
数据外泄工具把上下文拼进 URL/邮件出站白名单、DLP、人工确认
供应链依赖包被篡改依赖审计、签名、沙箱
MCP 不是安全边界

协议只负责连接。权限、沙箱、审计、人工审批必须由 Host 和 Server 自己实现。接入第三方 Server 前,先假设它可能恶意。

什么时候不该用 MCP

  • 只有一个应用、一个工具:直接写函数更简单;
  • 工具需要极低延迟:多一层进程/网络有开销;
  • 工具需要复杂的事务语义:MCP 不提供分布式事务;
  • 团队没有能力审计第三方 Server:先别接。

MCP 适合「多个客户端要复用同一批能力」的场景。它是集成层,不是 Agent 框架。

与其他协议的关系

text
MCP   连接 Agent ↔ 工具/数据
A2A   连接 Agent ↔ Agent
AG-UI 连接 Agent ↔ 前端界面

三者解决不同层的问题,可以组合使用。不要把它们混为一谈。

检查清单

  • 工具粒度小、描述清晰、参数受控
  • 读写分离,写操作幂等且需授权
  • 文件/网络访问限制在明确范围
  • 返回结果裁剪、分页、标注截断
  • 远程服务使用 OAuth,scope 最小化
  • 第三方 Server 经过审查并锁定版本
  • 调用有审计日志
  • 不把 MCP 当安全边界

小结

  • MCP 用统一协议解决 N×M 集成问题。
  • Host / Client / Server 三角色,Tools / Resources / Prompts 三原语。
  • 本地用 stdio,远程用 Streamable HTTP + OAuth。
  • 工具设计与普通 Function Calling 原则一致:小、清晰、可恢复。
  • 安全靠权限、隔离、审计,不靠协议本身。

下一篇看最接近「通用」也最脆弱的形态:浏览器与计算机使用 Agent。

读完了?进度会保存在本地浏览器。
内容会持续修订。发现错误或想补充,欢迎反馈。 遇到问题?查排查手册 →