ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">昨天在给团队实现一个基于大模型的智能编码助手时,我遇到了一个关键问题:如何让LLM能够与我们的代码库、数据库和开发工具交互?当我深入研究Anthropic主导的MCP(Model Context Protocol)后,不禁感到困惑:为什么这些能在模型训练上投入数十亿美元的AI巨头,在工程实践上却如此粗糙?ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;color: rgb(63, 63, 63);"> ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;margin: 0.1em auto 0.5em;border-radius: 8px;box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 8px;height: auto !important;" title="null" src="https://api.ibos.cn/v4/weapparticle/accesswximg?aid=110944&url=aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9vWHFHOEVUdkFlbWljNjNkVnd0WWE2UENpYThTajZRblBnMlRzNTBzNm1tb0R6OXM5N2NlQWliWEhpYWRsN1FVSk5vd2d4SlNxVkNaWmxKeEJXUG81RG5PbkEvNjQwP3d4X2ZtdD1wbmcmYW1w;from=appmsg"/>ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(183, 110, 121);border-radius: 8px;box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px;">MCP是什么?为何突然爆火?ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);">MCP本质上是一个开放协议,用于标准化应用程序如何向LLM提供上下文。用Anthropic的话说,它就像是AI应用的"USB-C接口",提供标准化方式让AI模型连接不同的数据源和工具。ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);">过去一个月,MCP突然爆火,成为让LLM变身为"智能体"并与世界交互的关键技术。同时,IBM推出了Agent Communication Protocol (ACP),Google紧随其后发布了Agent2Agent (A2A)。各大厂商争相布局,MCP的服务器和客户端实现每天都在涌现,可以在ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: inherit;color: rgb(183, 110, 121);">mcp.so和ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: inherit;color: rgb(183, 110, 121);">pulsemcp.com等网站上找到。ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(183, 110, 121);border-radius: 8px;box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px;">MCP核心:简单的JSON-RPC协议ingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);">从本质上讲,MCP是一个预定义了方法/端点的JSON-RPC协议,设计用于与LLM配合使用。这部分设计相对简单清晰,但真正的问题在于它的传输层实现。三种传输方式:一个比一个复杂MCP支持三种主要的传输方式:  stdio方式:简单但有局限stdio方式很直接:启动本地MCP服务器,连接stdout和stdin管道,开始发送JSON数据,使用stderr进行日志记录。虽然这种方式打破了Unix/Linux管道范式,但它简单、易理解,在所有操作系统上都能直接工作。 HTTP+SSE与"Streamable HTTP":过度设计的典范HTTP传输则令人头疼。在HTTP+SSE模式中,为实现全双工通信,客户端首先建立SSE会话(如GET /sse)用于读取数据。第一次读取会提供一个URL,客户端向该URL发送写请求(如POST /a-endpoint?session-id=1234。 更复杂的是所谓的"Streamable HTTP"模式,它试图改进HTTP+SSE,但实际上增加了更多复杂性: 创建新会话的三种方式: 打开SSE连接的四种方式: 请求可能通过三种不同方式得到回答: - • 作为响应
POSTRPC调用而打开的SSE中的事件
这种设计复杂性带来了严重的问题: // 示例:处理不同类型的会话创建请求 functionhandleRequest(req) { if(req.method==='GET'&& !req.headers['mcp-session-id']) { // 创建新会话,返回SSE流 returncreateNewSession(req); }elseif(req.method==='POST'&& !req.headers['mcp-session-id']) { if(req.body&&Object.keys(req.body).length>0) { // 创建新会话并处理RPC调用 returncreateSessionAndHandleRPC(req); }else{ // 创建空会话 returncreateNewSession(req); } }elseif(req.headers['mcp-session-id']) { // 处理现有会话的请求 returnhandleExistingSession(req); } }
为什么不直接使用WebSockets?面对这种过度复杂的设计,一个明显的问题是:为什么不直接使用WebSockets[1]? 让我们比较不同传输方式的优缺点: WebSockets是HTTP上实现类似stdio行为的自然选择: - 2. stdio有类似套接字的输入输出流,HTTP有WebSockets
MCP的安全隐患"Streamable HTTP"的设计引入了几个安全问题: - 1.状态管理漏洞:跨不同连接类型管理会话状态很复杂,可能导致会话劫持、重放攻击或DoS攻击
- 2.攻击面增加:多个会话创建和SSE连接入口点扩大了攻击面
- 3.混淆和隐藏:各种会话创建和响应传递方式可能被用来隐藏恶意活动
实践建议:如何在项目中正确使用MCP如果你决定在项目中使用MCP,我建议: - 1.尽可能使用stdio传输:对于本地应用,这是最简单可靠的选择
- 2.考虑自定义传输层:MCP规范明确指出客户端和服务器可以实现额外的自定义传输机制以满足特定需求
- 3.优先考虑WebSockets:如果需要HTTP传输,考虑使用WebSockets而非官方的SSE或Streamable HTTP方案
- 4.简化授权流程:根据需求选择合适的授权方式,不必被复杂的OAuth2规范束缚
下面是一个使用WebSockets实现MCP的简单示例: // 使用WebSockets实现MCP客户端的简化示例 constws =newWebSocket('ws://mcp-server.example.com/mcp');
ws.onopen=() =>{ // 发送MCP请求 ws.send(JSON.stringify({ jsonrpc:'2.0', id:'1', method:'file.read', params: { path:'/path/to/file.txt' } })); };
ws.onmessage=(event) =>{ constresponse =JSON.parse(event.data); console.log('收到MCP响应:', response); };
我的结论作为一个全栈架构师,我认为MCP代表了一个有价值的尝试,但其实现细节暴露了AI行业在软件工程实践上的不足[1]。与其被过度复杂的传输协议所困扰,不如关注MCP的核心价值:提供标准化方式让AI模型与应用程序交互。 在实际项目中,我们应该优化常见用例,而不是边缘情况。这意味着选择更简单、更成熟的技术栈,而不是盲目跟随最新的复杂设计。 期待未来MCP能够改进传输层设计,采用更符合工程最佳实践的方案。在此之前,我们需要保持批判性思考,选择最适合自己项目的技术路径。 |