news 2026/5/28 7:45:08

MCP的个人理解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MCP的个人理解

笔记概览

本笔记围绕 Model Context Protocol (MCP) 展开,覆盖以下核心模块:

  1. 协议本质:MCP 的定义、解决的痛点、与传统 Function Calling 的根本区别。
  2. 消息格式:基于 JSON-RPC 2.0 的请求、响应、通知结构。
  3. 实现方式:Host-Client-Server 三层架构的解耦机制。
  4. 项目集成:在 Python Web 应用中用 MCP 包装外部 API(附详细代码拆解)。
  5. 加载时机:工具列表的一次性加载 vs 动态发现。
  6. 隔离方案:多项目/多 Agent 场景下的命名空间、权限、进程隔离。
  7. 实战补充:Claude Code 本地配置实现项目级隔离的层层递进方案。

每一部分都包含技术原理、代码示例(主要针对 Python)、架构图解,并穿插扩展思考、追问方向和实践建议。


1. 协议本质:从函数调用到上下文协议

1.1 MCP 是什么?

MCP(Model Context Protocol)是 Anthropic 提出的开放协议,旨在标准化 AI 模型与外部工具、数据源的交互方式。类比为“AI 应用的 USB-C 接口”——不同工具只要遵循同一套协议,就可以被任何支持 MCP 的模型即插即用地连接。

1.2 要解决的核心痛点

传统 Function Calling 下,每接入一个新工具,开发者需要:

  • 手写适配函数、描述 JSON Schema;
  • 处理认证、错误重试;
  • 把函数签名硬编码为特定 AI 厂商的格式(如 OpenAI 与 Anthropic 不同)。

结果:工具集成与模型强绑定,复用性差
MCP 的解耦思路:工具按协议暴露一次,即可被所有 MCP 兼容的 AI 使用

1.3 MCP 与 Function Calling 的根本不同

对比维度

Function Calling

MCP

定义位置

代码中一次性注入工具列表

工具定义在独立进程(MCP Server)中,通过协议动态获取

交互模式

单次请求-响应

持久化连接,支持工具发现、实时推送、资源订阅

标准化

各厂商格式不统一

开放协议,不绑定模型厂商

生命周期

函数在一次对话上下文中存活

工具服务器独立运行,启动/停止与模型无关

通俗比喻:Function Calling 是写在纸上的固定菜单;MCP 是一家可以随时更新菜单、开放厨房参观、接收实时订单的餐厅。

【延伸】

  • MCP 这种“协议驱动工具”的思想在微服务架构中早有先例(如 gRPC 服务定义)。但在 AI 领域,它可能成为类似“HTTP 之于 Web”的基础设施。
  • 协议标准化可能带来的生态效应:未来会出现 MCP 工具市场,开发者直接发布、复用工具服务器。

【追问】

  • 如果所有 AI 都通过 MCP 调用工具,那么工具的输入输出是否还需要适配不同模型的“偏好”?MCP 的描述规范足够消除差异吗?

2. 消息格式:基于 JSON-RPC 2.0 的统一通信

2.1 基础规范

MCP 底层使用JSON-RPC 2.0,所有消息都是 JSON 对象,通过标准输入/输出(stdio)或 HTTP/SSE 传输。

三种消息类型:

  • 请求(Request):含有id,必须返回响应。
  • 响应(Response):包含与请求相同的id,携带resulterror
  • 通知(Notification):无id,不需要响应,用于单向事件推送。

2.2 示例消息

工具列表请求与响应

// 请求 { "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} } // 响应 { "jsonrpc": "2.0", "id": 1, "result": { "tools": [ { "name": "get_weather", "description": "获取指定城市的当前天气", "inputSchema": { "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] } } ] } }

工具调用请求与响应

// 请求 { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "get_weather", "arguments": { "city": "Beijing" } } } // 响应 { "jsonrpc": "2.0", "id": 2, "result": { "content": [ { "type": "text", "text": "Beijing: 22°C, sunny." } ] } }

资源更新通知(推送)

{ "jsonrpc": "2.0", "method": "notifications/resources/updated", "params": { "uri": "file:///data/report.txt" } }

通知机制是传统 Function Calling 不具备的,它允许工具主动向模型推送信息,而不必依赖轮询。

【延伸】

  • JSON-RPC 2.0 也常用于 WebSocket 通信。MCP 选择它,可能未来会考虑 WebSocket 传输层,以获得更好的双向实时能力。
  • 通知中的resources/updated暗示 MCP 不仅是“工具协议”,还可能是“资源协议”,有潜力构建 AI 可感知的文件系统或知识库。

【试一试】
可以尝试实现一个简单的 MCP Client 和 Server(用 Python 的mcp包),通过 stdio 传递上述 JSON 消息,观察初始化和工具调用流程。


3. 实现方式:客户端-主机-服务器的三层解耦

3.1 架构图

┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ MCP Host │────▶│ MCP Client │────▶│ MCP Server │ │ (AI 应用) │ │ (协议客户端) │ │ (工具实现) │ └─────────────┘ └─────────────┘ └─────────────┘
  • MCP Host:真正发起调用的 AI 应用(如 Claude Desktop、你的 Web 后端)。
  • MCP Client:与一个 Server 1:1 映射,负责连接、收发消息、协议翻译。
  • MCP Server:轻量级服务,暴露工具、资源和能力。

3.2 解耦要点

  • Host 不接触 Server 的通信细节,Client 提供统一接口。
  • 一个 Host 可创建多个 Client,连接不同 Server,实现多工具组合。
  • Server 可用任何语言编写,只要通过 stdio 或 HTTP 产生 JSON-RPC 输出。

3.3 连接生命周期

  1. 初始化:Client 发送initialize请求,协商协议版本和能力。
  2. 正常操作:工具发现、调用、资源读取等。
  3. 关闭:连接断开,释放资源。

【延伸】

  • 这种架构与微服务中的 Service Mesh 相似:数据面(Client/Server)与控制面(Host 的策略)分离。
  • 可以预见到未来会出现“MCP 网关”产品,集中管理多个 Server 的认证、限流和监控。

【追问】

  • 三层架构中,如果 Client 崩溃,Host 能否自动恢复连接?MCP 本身未定义故障转移机制,这是否需要应用层自己实现?

4. 项目集成:在 Python Web 应用中包装外部 API(代码详解)

4.1 场景描述

智能助手 Web 应用需要接入天气查询。我们将外部天气 API 封装为一个 MCP Server,Web 后端通过 MCP Client 与之通信。

4.2 天气服务器(weather_server.py)逐段拆解

import json, asyncio from mcp.server import Server, NotificationOptions from mcp.server.models import InitializationCapabilities from mcp.server.stdio import stdio_server import httpx server = Server("weather-server")
  • asyncio:异步编程库,允许等待网络请求时不阻塞。
  • Server:创建 MCP 服务器实例。
  • stdio_server:基于标准输入输出的传输工具。

注册工具列表

@server.list_tools() async def list_tools(): return [{ "name": "get_weather", "description": "获取指定城市的当前天气", "inputSchema": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"] } }]
  • @server.list_tools()装饰器:当客户端请求tools/list时调用此函数。
  • 返回一个工具定义列表,包含名称、描述和 JSON Schema 参数说明。

注册工具实现

@server.call_tool() async def call_tool(name: str, arguments: dict): if name == "get_weather": city = arguments["city"] async with httpx.AsyncClient() as client: resp = await client.get(f"https://api.weather.com/v1/current?city={city}&key=KEY") data = resp.json() return { "content": [ {"type": "text", "text": f"{city}: {data['temp']}°C, {data['condition']}"} ] }
  • @server.call_tool():处理tools/call请求。
  • 使用httpx.AsyncClient异步调用外部 API,await等待结果。
  • 返回内容必须符合 MCP 规范:{"content": [...]}

启动服务器

async def main(): async with stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationCapabilities(sampling={}, experimental={}, tools={}), notification_options=NotificationOptions() ) if __name__ == "__main__": asyncio.run(main())
  • stdio_server()建立 stdio 通信流。
  • server.run进入事件循环,处理请求。

4.3 Web 应用集成(app.py)及常见陷阱

原始意图代码(有坑)

from fastapi import FastAPI from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client app = FastAPI() session = None async def connect_to_weather_server(): server_params = StdioServerParameters(command="python", args=["weather_server.py"]) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools = await session.list_tools() return session # ❌ 离开 async with 块后 session 就失效了! @app.on_event("startup") async def startup(): global session session = await connect_to_weather_server() # 拿到的 session 已关闭

问题剖析
async with块退出时会自动关闭通信流和会话,返回的session对象已不可用。这是初学者极易犯的错误。

修正版:每次请求临时连接(可运行但不高效)

@app.get("/ask") async def ask(question: str): server_params = StdioServerParameters(command="python", args=["weather_server.py"]) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() result = await session.call_tool("get_weather", {"city": "Beijing"}) return {"answer": result.content[0].text}
  • 每次请求启动一个子进程,用完立即关闭。逻辑正确,但开销大。

生产环境改进方向

  • 使用长连接(如 HTTP/SSE 传输),避免反复启动进程。
  • 用连接池维护一个持久的session,并在 FastAPI 后台任务中维持。

4.4 通俗比喻

Web 应用就像餐厅服务员,客人问天气。服务员不会自己查,而是打电话(stdio)给专属气象员(天气服务器),通过一套标准问答(MCP 协议)获取结果,再转达给客人。气象员是独立的,更换他只需另一个懂协议的人即可,餐厅无需改造。

【延伸】

  • 这个模式本质上就是“工具即服务”(TaaS)。未来 AI 应用可以由多个这样的 MCP Server 微服务组合而成,类似“AI 原生微服务”。
  • 可以思考:是否可以在 Server 侧做结果缓存、限流?MCP 协议本身不限制,但应用层完全可以加上这些能力。

【试一试】
试着将天气服务器改为连接真实的 OpenWeatherMap API,并扩展一个get_forecast工具,体验增加工具的便捷性。


5. 加载时机:一次性加载 vs 动态发现

5.1 启动时一次性加载

Host 启动后,Client 连接 Server 并调用tools/list,将全部工具注入到 AI 的 system prompt 或工具注册表。此后整个会话使用该固定列表。
适用场景:工具数量固定,如企业内部几个稳定的系统。

5.2 按需动态发现

MCP 支持运行时动态改变工具列表:

  • Server 可发送通知notifications/tools/list_changed
  • Client 收到后可重新调用tools/list获取最新工具。
  • 高级用法:Host 可以根据 LLM 推理的需求,临时启动特定的 MCP Server 并查询其工具,实现“懒加载”。

比喻:固定菜单 vs 服务员告知“今日特供”,你可随时追问更新。

【延伸】

  • 动态发现可用于插件系统:用户安装新插件时,Server 通知 Host,AI 立即获得新能力。
  • 在 Agent 协作中,子 Agent 的动态创建和销毁需要这种机制的支持。

【追问】

  • 动态发现增加了系统的复杂性,对 AI 的 prompt 管理提出了挑战:工具频繁变化时,如何保证模型能正确理解当前可用的工具集?

6. 隔离方案:多项目/多 Agent 的命名与权限

6.1 命名冲突

多个 MCP Server 可能拥有同名工具(如search)。
解决方案:命名空间前缀。例如finance/search_transactionshr/search_employees

Client 端可以在聚合工具时自动添加来源前缀:

for server_name, session in server_sessions.items(): for tool in server_tools: tool["name"] = f"{server_name}/{tool['name']}"

6.2 权限隔离

  1. Agent 级隔离:不同 Agent 使用不同 Client 实例,连接各自的 Server 集合,天然隔离。
  2. 工具级访问控制:在 Server 内通过上下文(如认证令牌)检查权限。
  3. 进程/容器隔离:每个 Server 运行在独立进程或容器中,结合网络策略进一步加固。
  4. 传输层安全:HTTP/SSE 传输时使用 TLS 和身份验证头。

多租户架构示例

Agent A (Client A) ──── finance Server Agent B (Client B) ──── hr Server Agent C (Client C) ──── common Server (按需连接)

各个 Agent 仅能看到授权范围内的工具,权限不交叉。

【延伸】

  • 此类权限模型可以借鉴 AWS IAM 的策略语法,定义一个 MCP 权限策略语言,以声明式控制工具和资源的访问。
  • 在多 Agent 协作场景(如 AutoGen、CrewAI)中,Agent 之间的工具隔离成为安全基础。

【试一试】
尝试为你的 MCP Server 增加一个简单的认证:在initialize阶段传入 token,并在每个工具调用前验证。


7. 实战:Claude Code 中的项目级 MCP 配置与隔离

Claude Code 提供了一套层层递进的隔离方法,可以按需组合使用。

7.1 第一层:配置作用域隔离(划清边界)

通过不同优先级的配置文件,让不同项目使用不同的 MCP 服务器集。

配置优先级(由高到低)

  1. 命令行参数--mcp-config <path>(仅当前会话)
  2. 项目根目录.mcp.json(团队共享,可提交 Git)
  3. 项目本地settings.local.json(个人敏感配置,不提交 Git)
  4. 全局~/.claude.json(兜底配置)

实战建议:团队在项目根目录维护.mcp.json,个人敏感连接字符串放在.claude/settings.local.json

7.2 第二层:工具与权限隔离(能力限制)

如果多个项目必须共用同一个 MCP Server(如公司数据库),可通过代理和命名空间进行细粒度控制。

工具过滤示例(使用 mcproxy)

// .mcp.json { "mcpServers": { "secure-db": { "command": "npx", "args": ["-y", "@team-attention/mcproxy", "--", "npx", "-y", "@modelcontextprotocol/server-postgres", "postgresql://..."] } } }

配合.mcproxy.json配置文件:

{ "servers": { "postgres@1.0.0": { "tools": { "query": true, "list_tables": true, "insert": false, "delete": false } } } }

这样仅允许查询,禁止增删改。

命名空间:当多个 Server 拥有同名工具时,MCP 防火墙可自动为工具添加前缀,如github__create_issuejira__create_issue,避免冲突。

7.3 第三层:进程与运行环境隔离(硬隔离)

  • 进程隔离:每个 MCP Server 独立进程,拥有自己的内存空间。
  • 沙箱环境:限制网络访问、文件系统读写,通常用 Docker 容器或 AppArmor 实现。
  • scoped-mcp:一个为复杂场景设计的 Python 包,为每个 Agent 启动专属代理进程,内置凭据隔离、工具过滤和资源分区。

7.4 第四层:企业级纵深防御与审计

建议构建多层防线:

  1. 应用内开关(默认禁用外部工具)
  2. MCP 防火墙(流量过滤、脱敏、审计)
  3. 子 Agent 权限裁剪(最小权限原则)
  4. 系统级沙箱(容器、强制访问控制)

同时建立集中审计日志,记录每一次工具调用的详细信息(谁、时间、项目、工具、参数)。

7.5 总结选择指南

  • 简单省心:用.mcp.jsonsettings.local.json划分项目。
  • 进阶限制:通过mcproxy和命名空间过滤与区分工具。
  • 高安全要求:采用沙箱和scoped-mcp创建安全泡泡。
  • 企业全面管控:部署多层防御 + 审计日志。

【延伸】

  • 审计日志可对接 SIEM 系统,实现对 AI 操作的安全监控和合规性检查。
  • 未来可能出现 MCP 安全标准(类似 OWASP API 安全 Top 10),专门针对 AI 工具调用的威胁建模。

【追问】

  • 在高度动态的 Agent 系统中,如何确保权限策略的实时更新和分发?
  • 代理方式的性能损耗有多大?是否适合高频工具调用场景?
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 7:42:57

伊辛机高阶交互建模与3-SAT问题求解优化

1. 伊辛机与组合优化问题概述在计算复杂性理论中&#xff0c;布尔可满足性问题&#xff08;SAT&#xff09;作为第一个被证明的NP完全问题&#xff0c;一直是计算机科学领域的核心研究对象。3-SAT问题作为SAT问题的特例&#xff0c;要求确定一组三变量析取子句的合取式是否存在…

作者头像 李华
网站建设 2026/5/28 7:42:19

AI编程助手代码可信性检验:四重防线构建可靠开发工作流

1. 项目概述&#xff1a;当AI开始“写”代码&#xff0c;真相住在哪里&#xff1f;最近几年&#xff0c;我身边越来越多的开发者和技术团队开始将AI编程助手&#xff08;比如GitHub Copilot、Cursor&#xff0c;或是各类大模型API&#xff09;引入日常工作流。从自动补全一行代…

作者头像 李华
网站建设 2026/5/28 7:41:37

从理论到实践:LOD层次细节技术选型与切换策略全解析

1. LOD技术基础&#xff1a;从概念到核心流程 第一次接触LOD技术是在2015年做智慧城市项目时&#xff0c;当时场景加载卡顿到让人怀疑人生。直到团队引入LOD方案&#xff0c;帧率直接从个位数飙升到60&#xff0c;这种性能飞跃让我彻底理解了这项技术的价值。**LOD&#xff08;…

作者头像 李华
网站建设 2026/5/28 7:41:19

PMT侧信道攻击原理与Arm架构防护方案

1. 安全漏洞概述&#xff1a;PMT侧信道攻击原理2022年6月公开的Hertzbleed攻击利用现代处理器动态频率调节机制&#xff08;DVFS&#xff09;创建了一个新型侧信道。当CPU检测到功耗接近TDP限制时&#xff0c;会主动降低频率以维持热设计功耗&#xff0c;这种被称为Power-Manag…

作者头像 李华
网站建设 2026/5/28 7:31:31

HashTAG与CALM:多核安全关键系统缓存干扰监控的硬件优化方案

1. 项目概述&#xff1a;多核安全关键系统中的缓存干扰监控难题在汽车电子、航空航天和工业控制这些对安全性和实时性要求极高的领域&#xff0c;多核处理器凭借其强大的并行计算能力&#xff0c;已经成为构建高性能嵌入式系统的首选架构。然而&#xff0c;当多个计算核心共享同…

作者头像 李华