MCP(Model Context Protocol)

MCP(Model Context Protocol,模型上下文协议)是当前 AI Agent 工程体系中核心的基础技术之一。对于希望让 AI agent(如 OpenAI Codex)不仅完成代码理解,还能主动读取项目状态、调用测试工具、操作业务系统、诊断问题并辅助研发的场景,MCP 提供了标准化的能力接入范式。

一、MCP协议概述

1.1 定义

MCP 是一种开放协议,用于标准化大语言模型应用与外部数据源、工具和服务之间的集成方式。

简单来说,MCP 为 AI 应用访问外部世界定义了一套统一的交互接口规范。它规定的是 AI 应用如何发现外部能力、如何描述工具、如何传递参数、如何获取结果,以及如何协商能力与权限。

1.2 解决的问题

假设我们正在开发一款 AI 编程助手,希望它能够:

  • 访问 GitHub 仓库,读取 Issue、PR 与代码文件
  • 运行单元测试,查询测试报告与覆盖率
  • 获取 ALS 平台的项目状态、标注任务与模型训练进度
  • 调用工业相机诊断接口,读取设备运行参数

如果没有 MCP,需要分别为 GitHub API、测试系统、ALS 后端、硬件控制服务做定制化适配,每种 AI 应用都要重复一次工具对接工作。

MCP 的价值在于在 AI 应用与外部工具之间建立统一的协议边界:开发者将已有业务能力封装为 MCP Server,即可被所有兼容 MCP 的 Host 调用,本质是软件工程中"封装差异、标准化接口"思想在 AI 工具领域的延伸。

1.3 协议定位

MCP 的设计思路深受 Language Server Protocol(LSP)启发:

  • LSP 让 VS Code 等编辑器通过统一协议使用语言服务器的补全、跳转、诊断能力
  • MCP 让 AI 应用通过统一协议接入外部上下文与工具能力

二者功能不同,但采用了一致的"协议解耦"设计思想。因此:

  • MCP 不负责提升模型能力,负责定义模型应用连接外部能力的方式
  • MCP 不替代 REST API,通常在已有 API 之上增加 AI 可发现、可调用的适配层

二、架构:Host、Client、Server 三级角色

MCP 采用 Client-Server 架构,但其角色定义与传统 Web 体系存在差异,是理解协议的第一道门槛。

2.1 三类角色

MCP Host:AI 应用宿主

即面向用户的 AI 应用,例如 Codex、Claude Code、VS Code Agent 或自研 AI Agent。承担整个交互流程的控制职责:用户交互、模型推理、上下文管理、工具调度、权限审批。一个 Host 可以管理多个 MCP Client,分别对接不同的能力提供方。

MCP Client:协议客户端

Host 内部负责 MCP 通信的组件,实现协议通信、服务端能力发现、工具调用与结果接收。一个 Host 通常创建多个 MCP Client,每个 Client 对应一个 MCP Server。Client 是软件组件,不一定是独立进程。

MCP Server:能力提供方

负责暴露可访问的数据、工具与提示模板。它可以是:

  • 本地启动的 Python 进程
  • 部署在远端的 HTTP 服务
  • 封装现有数据库/REST API 的适配层
  • 对接设备诊断接口的本地服务

MCP Server 并不要求部署在远程机器上,一个本地运行的程序同样可以作为 MCP Server。

2.2 MCP Server 与业务后端的关系

MCP Server 不重复实现原有业务逻辑。

以 ALS 平台为例,其已有 FastAPI 后端、任务调度、模型管理与数据存储体系,合理的架构是:

AI Host → ALS MCP Server(协议转换、参数校验、权限控制、结果结构化)→ 现有 FastAPI 业务后端

MCP 优先作为 AI 接入层存在,而非替代业务层。例如 get_training_status 工具仅负责调用现有训练任务查询接口,将后端返回值转换为适合 AI 消费的结构化结果,避免维护两套业务实现。

三、底层通信原理:数据层与传输层分层设计

MCP 的通信机制分为两层:

  • 数据层(Data Layer):定义消息结构与交互语义
  • 传输层(Transport Layer):定义消息的物理传递方式

3.1 数据层:基于 JSON-RPC 2.0

MCP 以 JSON-RPC 2.0 作为基础消息协议。JSON-RPC 是一种轻量远程过程调用协议:调用方通过 JSON 消息指定目标方法与参数,被调用方返回对应结果。

基础请求结构示例:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_training_status",
    "arguments": {
      "task_id": "train_001"
    }
  }
}

注:以上示例省略了新版 MCP 要求的 _meta 元数据字段,符合 2026-07-28 规范的请求还需携带协议版本、客户端能力等信息。

字段说明:

字段 含义
jsonrpc JSON-RPC 协议版本,固定为 2.0
id 请求标识,用于关联请求与响应
method 待执行的远程操作名称
params 请求参数,包含工具名、调用参数等
result 响应中的执行结果(成功时存在)
error 协议层错误信息(出错时存在)

简化响应示例:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "Training completed"
      }
    ],
    "isError": false
  }
}

请求与响应通过相同的 id 关联。除了 Request/Response 模式,JSON-RPC 还定义了 Notification(无 id 字段,不要求响应),MCP 基于此进一步约定了 tools/list、tools/call、resources/read 等方法的语义与消息结构。

3.2 传输层:stdio 与 Streamable HTTP

目前 MCP 支持两种主流传输方式。

(1)stdio(标准输入/输出)

Host 启动一个本地子进程,通过标准输入(stdin)与标准输出(stdout)交换协议消息。

  • 场景:Codex 调用本地 Python 工具、项目诊断脚本、开发机自动化程序
  • 注意:stdout 是协议通道,不可用于调试日志输出,否则会破坏消息流;调试日志应输出至 stderr 或通过 SDK 规范化日志机制处理。
(2)Streamable HTTP(可流式传输 HTTP)

通过 HTTP POST 传递 JSON-RPC 消息,结合 SSE(Server-Sent Events)实现服务端到客户端的流式事件推送。

  • 场景:远程服务、团队共享能力、多客户端接入、生产环境部署
  • 注意:旧版独立 SSE Transport 已被 Streamable HTTP 取代,新项目不建议使用旧式 SSE 传输;但 SSE 技术本身仍在新传输中作为事件通道使用。

3.3 2026-07-28 版:无状态通信

早期 MCP 包含 initialize 握手流程,协商版本与能力并建立会话上下文;新版采用无状态协议:

  • 协议版本与客户端能力随每个请求的 _meta 字段携带
  • 每个请求原则上可由不同的服务实例处理,无需依赖协议级会话状态

请求元数据示例:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 10,
  "method": "tools/list",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {},
      "io.modelcontextprotocol/clientInfo": {
        "name": "als-agent",
        "version": "1.0.0"
      }
    }
  }
}

无状态协议 ≠ 业务应用不能保存状态。训练任务、用户权限等业务状态仍可存储在数据库中,通过标识访问;改变的是通信层的会话依赖,而非所有业务都必须无状态化。

新版同时提供 server/discover 方法用于发现协议版本与服务端能力,客户端可选择直接发起业务请求,并非每次调用前都必须执行发现流程。

3.4 工具调用流程

以查询 ALS 训练进度为例,完整链路如下:

  1. 用户向 Host 提出查询需求
  2. Host 调用 MCP Client 执行 tools/list 获取可用工具
  3. Server 返回工具定义与 JSON Schema
  4. Host 将工具描述注入模型上下文
  5. 模型根据用户意图选择 get_training_status 工具并生成参数
  6. Host 通过 Client 发起 tools/call 请求
  7. MCP Server 调用后端业务接口查询任务状态
  8. Server 返回结构化执行结果
  9. Host 将结果交付模型进行分析
  10. 模型生成最终回答呈现给用户

分层逻辑:模型负责决策(用哪个工具、传什么参数),协议层负责执行(发请求、收结果),业务层负责真实操作。这三层解耦是设计可测试、可维护 AI Agent 的关键。

四、三大能力:Tools、Resources、Prompts

Tools、Resources、Prompts 是 MCP 定义的三类服务器端能力,分别对应"执行操作、提供数据、引导交互"三类场景。

4.1 Tools:让 AI 执行外部操作

Tool 是可被 AI 应用调用的函数,是 MCP 最关键的能力。Server 对外公布工具的名称、描述与输入参数结构,客户端通过 tools/list 发现、tools/call 执行。

Tool 的核心是 inputSchema,基于 JSON Schema 描述合法输入参数,让 AI 不仅知道"有这个函数",还知道"需要什么参数、参数是什么类型、什么时候该调用"。

工具定义示例:

json 复制代码
{
  "name": "get_training_status",
  "description": "Get the status of a training task",
  "inputSchema": {
    "type": "object",
    "properties": {
      "task_id": {
        "type": "string",
        "description": "Training task identifier"
      }
    },
    "required": ["task_id"]
  }
}

调用后 Server 可返回文本、结构化数据或其他内容块,也可通过 outputSchema 描述预期输出结构。Tool 不限于修改型操作,查询类操作同样可以封装为 Tool,区别在于它以"可调用函数"的形式提供能力。

4.2 Resources:为 AI 提供上下文数据

Resource 是 MCP Server 对外提供的可读取数据资源,通过 URI 唯一标识,例如:

bash 复制代码
als://config/classes
als://projects/1001/summary
als://training/1001/metrics

客户端通过 resources/list 查看资源列表,通过 resources/read 读取资源内容。同时支持 URI 模板(如 als://projects/{project_id}/summary),无需为每个实例单独注册资源。

Resource 的定位是向 AI 提供项目配置、文档、数据摘要、数据库结构等上下文信息,由 Host 决定呈现、选择与加载策略。

4.3 Prompts:提供可复用交互模板

Prompts 是由 MCP Server 提供的提示模板,面向用户而非模型。用户从客户端菜单中选择模板、填写参数后,渲染结果直接进入对话。

例如 ALS 可提供 analyze_training_failure、review_annotation_quality、generate_dataset_report 等模板,用户选择后自动生成标准化的问题引导。对应方法为 prompts/list 与 prompts/get。

4.4 能力对比

比较维度 Tools Resources Prompts
作用 执行函数操作 提供上下文数据 提供交互模板
触发主体 模型自动选用 Host 策略加载 用户/应用选择
标识方式 工具名称 URI 模板名称
方法 tools/call resources/read prompts/get
ALS 场景示例 运行测试、启动训练 读取类别配置、项目摘要 诊断训练失败、生成数据报告

注:以上为标准交互定位,并非刚性规则。例如 Host 可自动选取资源,Tool 也可仅执行只读操作。

五、高级协议机制

Tools Resources Prompts定义了"提供什么能力",高级机制则解决"如何可靠、高效地运行这些能力"。

5.1 动态能力发现与缓存

MCP 可通过 server/discover、tools/list、resources/list、prompts/list 动态获取当前可用能力。服务端能力变更时,可通过通知机制主动同步。

2026-07-28 规范为列表响应引入缓存提示:

json 复制代码
{
  "ttlMs": 300000,
  "cacheScope": "private"
}
  • ttlMs:缓存建议有效期(毫秒)
  • cacheScope:缓存共享范围

缓存机制可减少重复加载开销,降低协议调用成本。对于开发助手类场景,工具列表的稳定性还会影响上下文占用与 Prompt Cache 效率,因此并非暴露的工具越多越好。

5.2 Multi Round-Trip Requests:多轮往返请求

针对需要用户确认、补充信息的场景(如删除项目前的二次确认),新版 MCP 引入 Multi Round-Trip Requests(MRTR)机制:

  1. 客户端发起操作请求
  2. 服务端返回 input_required 结果,包含待补充信息与 requestState
  3. Host 向用户征求确认或补充输入
  4. 客户端携带输入结果与 requestState 重新发起请求
  5. 服务端验证后处理并返回最终结果

该设计更适配无状态 HTTP 服务,无需依赖长连接反向调用通道。但 Elicitation 仅负责交互机制,不替代业务安全校验------操作前仍需在服务端验证权限、对象与有效性。

5.3 Subscriptions:变化通知订阅

MCP 支持服务端向客户端推送数据变化通知。客户端通过 subscriptions/listen 建立订阅流,指定接收的通知类型;资源更新、工具列表变化等事件可通过通知机制传递。

对于高吞吐实时数据(如逐帧图像、高频指标),不应将 MCP 作为数据总线;更合理的方案是原有传输链路保留数据采集能力,MCP 仅提供查询入口、摘要订阅或结果引用。

5.4 Extensions:扩展机制

2026 版 MCP 正式建立扩展框架,特殊能力可独立演进,无需全部纳入协议核心。值得关注的扩展包括:

扩展 用途 ALS 适用场景
Tasks 长时间异步任务管理与结果轮询 模型训练、批量标注
MCP Apps 在支持的 Host 中展示交互 UI 训练指标看板、质检报表
Skills over MCP 提供可发现的 Agent 工作流指导 故障诊断与运维流程

扩展均为可选能力,不能默认所有 Host 都完整支持。以 Tasks 为例,它允许服务端返回持久任务句柄,客户端通过接口查询进度与结果,适合长时间数据集处理等场景,比同步阻塞调用更合理。

六、实战开发:基于 Python SDK v2 开发 MCP Server

本节使用官方 Python SDK v2 完成最小 MCP Server 开发。Python 适合快速封装已有 API、文件系统与开发工具;即使业务后端为 C++,也可使用 Python 编写 MCP 适配层,通过既有接口调用后端服务。

6.1 开发环境搭建

官方 Python SDK v2 要求 Python 3.11 及以上。

使用 uv 安装:

bash 复制代码
mkdir als-mcp-demo && cd als-mcp-demo
uv init
uv add "mcp[cli]"

使用 pip 安装:

bash 复制代码
python -m pip install "mcp[cli]"

注意:v2 版本服务端主类为 from mcp.server import MCPServer

6.2 最小服务实现

新建 als_mcp_server.py:

python 复制代码
from mcp.server import MCPServer
from mcp.server.mcpserver.exceptions import ToolError

mcp = MCPServer("ALS-Demo")

# 演示数据,实际场景对接后端API
TASKS = {
    "train_001": {
        "status": "running",
        "epoch": 42,
        "total_epochs": 100,
        "loss": 0.185,
    }
}

@mcp.tool()
def get_training_status(task_id: str) -> dict:
    """Return the current status of an ALS training task."""
    if task_id not in TASKS:
        raise ToolError(f"Task not found: {task_id}")
    return {
        "task_id": task_id,
        **TASKS[task_id],
    }

@mcp.resource("als://project/overview")
def get_project_overview() -> str:
    """Read the ALS demo project overview."""
    return (
        "Project: ALS Demo\n"
        "Framework: MCP Python SDK v2\n"
        "Data source: in-memory demonstration\n"
    )

@mcp.prompt()
def diagnose_training(task_id: str) -> str:
    """Start a training failure diagnosis workflow."""
    return f"请分析训练任务 {task_id} 的失败原因,先查询状态与错误日志,再检查数据集配置与运行环境,最后给出修复建议。"

if __name__ == "__main__":
    mcp.run()

该示例已覆盖三类核心能力:

  • @mcp.tool():根据函数签名与类型注解自动生成输入 Schema
  • @mcp.resource():将 URI 映射到资源处理函数
  • @mcp.prompt():注册可复用提示模板

6.3 使用 MCP Inspector 调试

官方提供 MCP Inspector 调试工具,启动命令:

bash 复制代码
uv run mcp dev als_mcp_server.py

该命令启动调试 UI(依赖 Node.js 与 npx),可在界面中测试工具调用、资源读取与提示渲染,验证协议交互正确性。

6.4 切换为 HTTP 服务

若需通过网络访问,可修改启动方式:

python 复制代码
if __name__ == "__main__":
    mcp.run(
        transport="streamable-http",
        host="127.0.0.1",
        port=8000,
    )

或通过 CLI 指定传输方式:

bash 复制代码
uv run mcp run als_mcp_server.py --transport streamable-http

默认 HTTP 端点为 [http://127.0.0.1:8000/mcp](http://127.0.0.1:8000/mcp),仅用于本地开发,不可直接暴露公网。

6.5 客户端开发示例

MCP 独立于大语言模型,普通 Python 程序也可作为 Client 调用服务:

python 复制代码
import asyncio
from mcp import Client

async def main():
    async with Client("[http://127.0.0.1:8000/mcp](http://127.0.0.1:8000/mcp)") as client:
        # 查询可用工具
        tools = await client.list_tools()
        for tool in tools.tools:
            print(f"{tool.name}: {tool.description}")
        
        # 调用工具
        result = await client.call_tool(
            "get_training_status",
            {"task_id": "train_001"},
        )
        print(result.structured_content)

if __name__ == "__main__":
    asyncio.run(main())

6.6 与 FastAPI 集成

若已有 FastAPI/Starlette 后端,MCP Server 无需独立部署。官方 SDK 可生成 ASGI 应用:

python 复制代码
mcp_app = mcp.streamable_http_app()

该 ASGI 应用可独立运行,也可挂载到现有应用中。注意 :挂载场景下必须由父应用管理 MCP 生命周期,显式进入 mcp.session_manager.run(),否则会出现会话管理器未初始化错误。生产环境还需配置主机校验、认证与授权机制。

七、集成实践:接入 OpenAI Codex

Codex 可作为 MCP Host,连接本地或远程 MCP Server,将工具能力融入编程助手工作流。

7.1 接入本地 stdio Server

使用 Codex CLI 添加本地服务:

bash 复制代码
codex mcp add als-demo -- python /absolute/path/als_mcp_server.py

建议使用虚拟环境中 Python 解释器的绝对路径,确保依赖环境正确。

也可通过配置文件 ~/.codex/config.toml 配置:

toml 复制代码
[mcp_servers.als_demo]
command = "/absolute/path/.venv/bin/python"
args = ["/absolute/path/als_mcp_server.py"]
enabled = true
enabled_tools = ["get_training_status"]
default_tools_approval_mode = "prompt"

执行 codex mcp list 查看已配置服务,在 Codex TUI 中使用 /mcp 命令查看可用服务。

7.2 接入 HTTP Server

若已启动本地 HTTP 服务:

bash 复制代码
codex mcp add als-http --url [http://127.0.0.1:8000/mcp](http://127.0.0.1:8000/mcp)

与 stdio 模式的区别:HTTP 模式需服务端预先运行;stdio 模式由 Codex 自动启动子进程。

7.3 工具权限与审批管控

Codex 支持工具白名单、禁用工具、超时、审批模式等配置,例如:

toml 复制代码
[mcp_servers.als_demo]
command = "/absolute/path/.venv/bin/python"
args = ["/absolute/path/als_mcp_server.py"]
enabled_tools = ["get_training_status"]
default_tools_approval_mode = "prompt"
tool_timeout_sec = 30

安全原则:Host 层审批只是第一道防线,不能替代 MCP Server 自身的权限控制。有副作用的操作必须在业务服务层独立验证身份与授权。

八、技术边界

MCP 常与 Function Calling、REST API、RAG、Agent 等概念同时出现,但其定位与解决的问题各不相同。

8.1 与 Function Calling

Function Calling 是模型与应用之间的工具调用机制,解决"模型如何生成结构化工具调用请求 ";MCP 是应用与外部工具服务之间的标准协议,解决"如何通过标准协议发现和调用外部工具"。

完整链路:

复制代码
用户 → Codex/Agent → 模型推理 → Function Calling → MCP Client → MCP Server → 业务API → 返回结果

二者可组合使用,但无必然绑定关系------MCP Client 完全可在没有大模型的场景下独立调用服务。

8.2 与 REST API

REST API 是面向通用业务客户端的服务接口风格;MCP 将同样的业务能力封装为 AI 可发现、可调用的工具形式。MCP Server 内部仍可调用 REST API,二者是封装关系而非替代关系。

为现有系统增加 MCP 能力时,无需将全部接口改写为 MCP,仅需对 AI 场景所需的能力做适配封装。

8.3 与 RAG

RAG(检索增强生成)是通过检索外部知识增强模型回答的方法;MCP 可为检索系统提供标准化的工具接入接口。

链路示例:

复制代码
Agent → MCP Tool: search_project_knowledge → 全文/向量检索 → 返回文档片段 → 模型分析生成

RAG 是知识检索与生成方案,MCP 是接入检索系统的协议层。

8.4 与 AI Agent

AI Agent 通常包含目标理解、任务规划、工具使用、状态管理、结果评估等完整能力;MCP 主要为其中的工具与上下文接入提供标准接口。

各技术核心职责:

技术 职责
LLM 语言理解、推理与内容生成
Function Calling 生成结构化工具调用参数
MCP 标准化外部能力的发现、访问与调用
REST API 提供通用业务服务
RAG 检索外部知识,增强生成效果
Agent 围绕任务协调模型、工具与执行过程

MCP 只解决工具连接标准化问题,Agent 的可靠性还取决于任务分解、状态管理、错误恢复、反馈闭环、权限体系与执行验证。

九、安全与工程化设计

MCP 工具可能具备文件读写、数据库访问、命令执行甚至设备控制能力,安全边界设计至关重要。官方规范强调用户控制、数据隐私、工具安全与授权机制四大原则。

9.1 威胁模型

#mermaid-svg-YaWyO6TwEYWYMrKB{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YaWyO6TwEYWYMrKB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YaWyO6TwEYWYMrKB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YaWyO6TwEYWYMrKB .error-icon{fill:#552222;}#mermaid-svg-YaWyO6TwEYWYMrKB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YaWyO6TwEYWYMrKB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YaWyO6TwEYWYMrKB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YaWyO6TwEYWYMrKB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YaWyO6TwEYWYMrKB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YaWyO6TwEYWYMrKB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YaWyO6TwEYWYMrKB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YaWyO6TwEYWYMrKB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YaWyO6TwEYWYMrKB .marker.cross{stroke:#333333;}#mermaid-svg-YaWyO6TwEYWYMrKB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YaWyO6TwEYWYMrKB p{margin:0;}#mermaid-svg-YaWyO6TwEYWYMrKB .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YaWyO6TwEYWYMrKB .cluster-label text{fill:#333;}#mermaid-svg-YaWyO6TwEYWYMrKB .cluster-label span{color:#333;}#mermaid-svg-YaWyO6TwEYWYMrKB .cluster-label span p{background-color:transparent;}#mermaid-svg-YaWyO6TwEYWYMrKB .label text,#mermaid-svg-YaWyO6TwEYWYMrKB span{fill:#333;color:#333;}#mermaid-svg-YaWyO6TwEYWYMrKB .node rect,#mermaid-svg-YaWyO6TwEYWYMrKB .node circle,#mermaid-svg-YaWyO6TwEYWYMrKB .node ellipse,#mermaid-svg-YaWyO6TwEYWYMrKB .node polygon,#mermaid-svg-YaWyO6TwEYWYMrKB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YaWyO6TwEYWYMrKB .rough-node .label text,#mermaid-svg-YaWyO6TwEYWYMrKB .node .label text,#mermaid-svg-YaWyO6TwEYWYMrKB .image-shape .label,#mermaid-svg-YaWyO6TwEYWYMrKB .icon-shape .label{text-anchor:middle;}#mermaid-svg-YaWyO6TwEYWYMrKB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YaWyO6TwEYWYMrKB .rough-node .label,#mermaid-svg-YaWyO6TwEYWYMrKB .node .label,#mermaid-svg-YaWyO6TwEYWYMrKB .image-shape .label,#mermaid-svg-YaWyO6TwEYWYMrKB .icon-shape .label{text-align:center;}#mermaid-svg-YaWyO6TwEYWYMrKB .node.clickable{cursor:pointer;}#mermaid-svg-YaWyO6TwEYWYMrKB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YaWyO6TwEYWYMrKB .arrowheadPath{fill:#333333;}#mermaid-svg-YaWyO6TwEYWYMrKB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YaWyO6TwEYWYMrKB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YaWyO6TwEYWYMrKB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YaWyO6TwEYWYMrKB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YaWyO6TwEYWYMrKB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YaWyO6TwEYWYMrKB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YaWyO6TwEYWYMrKB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YaWyO6TwEYWYMrKB .cluster text{fill:#333;}#mermaid-svg-YaWyO6TwEYWYMrKB .cluster span{color:#333;}#mermaid-svg-YaWyO6TwEYWYMrKB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YaWyO6TwEYWYMrKB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YaWyO6TwEYWYMrKB rect.text{fill:none;stroke-width:0;}#mermaid-svg-YaWyO6TwEYWYMrKB .icon-shape,#mermaid-svg-YaWyO6TwEYWYMrKB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YaWyO6TwEYWYMrKB .icon-shape p,#mermaid-svg-YaWyO6TwEYWYMrKB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YaWyO6TwEYWYMrKB .icon-shape .label rect,#mermaid-svg-YaWyO6TwEYWYMrKB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YaWyO6TwEYWYMrKB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YaWyO6TwEYWYMrKB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YaWyO6TwEYWYMrKB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-YaWyO6TwEYWYMrKB .host>*{fill:#EEF4FF!important;stroke:#4C7DF0!important;stroke-width:1.5px!important;color:#1B3A8F!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .host span{fill:#EEF4FF!important;stroke:#4C7DF0!important;stroke-width:1.5px!important;color:#1B3A8F!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .host tspan{fill:#1B3A8F!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .guard>*{fill:#FFF6E5!important;stroke:#E8A33D!important;stroke-width:2px!important;color:#8A5200!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .guard span{fill:#FFF6E5!important;stroke:#E8A33D!important;stroke-width:2px!important;color:#8A5200!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .guard tspan{fill:#8A5200!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .mcp>*{fill:#EAF8F0!important;stroke:#2FA36B!important;stroke-width:1.5px!important;color:#14603C!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .mcp span{fill:#EAF8F0!important;stroke:#2FA36B!important;stroke-width:1.5px!important;color:#14603C!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .mcp tspan{fill:#14603C!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .target>*{fill:#F4F0FF!important;stroke:#7B61FF!important;stroke-width:1.5px!important;color:#3B2A8C!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .target span{fill:#F4F0FF!important;stroke:#7B61FF!important;stroke-width:1.5px!important;color:#3B2A8C!important;}#mermaid-svg-YaWyO6TwEYWYMrKB .target tspan{fill:#3B2A8C!important;} MCP Server
LLM / Host
受控访问
请求
放行
安全控制边界
身份认证
授权
参数验证
人工确认
不可信决策输入
工具调用申请
受限工具能力
业务 API · 数据库 · 设备

原则:模型生成的参数不能直接等同于经过授权的操作指令。即使参数符合 JSON Schema,也必须在服务端独立校验权限、操作范围与有效性。

9.2 主要风险

风险类型 场景 防护方式
Prompt Injection 外部文档诱导模型执行危险操作 将工具返回内容视为不可信数据,做输出校验
越权访问 工具读取其他用户数据 服务端权限校验、数据隔离
路径穿越 通过路径参数访问任意文件 路径规范化、限制允许访问目录
SSRF 通过 URL 工具访问内网资源 地址校验、网络访问限制
凭证泄露 日志或结果包含 Token 凭证隔离、敏感信息脱敏
任意代码执行 工具提供不受限 Shell 能力 沙盒隔离、命令白名单、最小权限原则

对于本地 stdio Server,需注意其由 Host 启动,恶意 Server 可获得对应进程权限;对于 HTTP Server,生产环境必须配置 HTTPS、认证授权、目标服务限制与安全检查。

9.3 工业设备的操作边界

对于机械臂、工业相机、PLC 等实体设备,建议将 AI 能力划分为三级:

  1. 只读观察:读取设备状态、日志、参数、诊断数据,优先开放
  2. 受控验证:在仿真/测试环境执行预定义操作,严格授权
  3. 真实执行:真实设备运动、参数写入、生产控制,独立安全联锁

涉及真实物理操作时,设备控制器的安全联锁、运动边界、工况校验、操作员确认必须独立生效,不能由模型决策绕过。

9.4 可观测性设计

生产级 MCP Server 至少应记录:工具名称、请求标识、执行耗时、调用结果、错误分类、业务任务标识、权限决策。可通过 Python logging、结构化日志、OpenTelemetry 实现。

高频调用场景需配置超时、并发限制、速率限制与缓存策略。避免将大规模图片、点云、完整日志直接塞入单次工具响应,优先返回统计信息、摘要或可按需读取的资源引用。

总结

层次 知识 工程目标
基础层 Host、Client、Server 角色定义 理解架构职责边界
协议层 JSON-RPC、stdio、Streamable HTTP 理解完整调用链路
核心能力 Tools、Resources、Prompts 设计合理的 MCP 接口
高级机制 能力发现、MRTR、Tasks、订阅 处理复杂交互场景
开发层 官方 Python SDK v2 编写与调试服务端
安全层 授权、输入校验、最小权限原则 规避危险操作
集成层 Codex、FastAPI、现有业务 API 接入实际项目
工程层 日志、测试、超时、状态管理 保障长期可靠运行

从协议本身看,MCP 的核心并不复杂,它是建立在 JSON-RPC 之上的一套标准化能力描述与交互机制。

真正的难点不在于写出 @mcp.tool(),而在于如何将复杂软件的内部能力,转换为语义明确、参数受控、结果可验证、权限可管理的工具接口。

相关推荐
王中阳Go3 小时前
网页上答对、接口里答错:同一个知识库,差的不是模型是入口
人工智能·后端·架构
郝琳3 小时前
真实 flaky 18.3%,CI 报 0%,让 Agent 修测试,它删掉了被测的变量
后端·ai编程
一级新生3 小时前
Dify 接入大模型:本地还是云端?实战与选型
人工智能·大模型·dify·ollama
潜龙95273 小时前
AI 驱动的移动端自动化开源项目调研报告
人工智能·测试相关
数聚天成DeepSData3 小时前
外部标注需求里该写清哪几项,样例包才验收得动
人工智能·深度学习·机器学习·数据集·deepsdata
2601_962071004 小时前
MiMo-V2.6-Flash 深度解析:相比上一代 V2.5,它到底改了什么
人工智能
AIGC_Dev4 小时前
电商 AI 作图软件哪个好用?2026 主流商品图工具对比推荐
大数据·人工智能·ai工具·电商美工
2601_958352904 小时前
一款模块通吃15类语音产品?AN-93如何实现录音笔、门禁、IPC的快速适配
前端·人工智能·嵌入式硬件·回声消除·降噪处理
亿佰特物联网应用专家4 小时前
物联网无线数据传输模块选型方法论:主流技术全景、四步决策法与多模融合趋势
网络·人工智能·物联网·工业无线模块选型·物联网无线模块选型