对比中了解MCP结构

举报
码乐 发表于 2025/12/04 22:59:20 2025/12/04
【摘要】 1 简介本文给出的 MCP(Message/Tool/Resource 协议)WebSocket 服务实现做成分层解析 + 与传统 MVC 架构对比。先讲实现原理(重点是流程、并发与交互),再深入比较两者的联系与差别,并给出可改进点与工程级注意事项。 2 MCP WebSocket 服务的实现原理(逐步拆解)总体来说,这个服务是一个基于长连接/消息驱动的双向实时代理层,作用是把前端 Web...

1 简介

本文给出的 MCP(Message/Tool/Resource 协议)WebSocket 服务实现做成分层解析 + 与传统 MVC 架构对比。

先讲实现原理(重点是流程、并发与交互),再深入比较两者的联系与差别,并给出可改进点与工程级注意事项。

2 MCP WebSocket 服务的实现原理(逐步拆解)

总体来说,这个服务是一个基于长连接/消息驱动的双向实时代理层,作用是把前端 Web 客户端、内置工具(如发送消息、读历史)以及外部 LLM(示例中为 Claude,支持“交错思考”)联通起来。

核心思想是:用 MCPMessage 作为协议,在 WebSocket 上进行异步 RPC / 事件推送与工具调用,并支持 LLM 在“流式会话”中发起工具调用、等待结果再继续推理(interleaved thinking)。

下面按模块说明关键实现点与行为:

MCP 协议消息(MCPMessage)

JSON 表示的消息结构:{id,type,method,params,result,error}。Type 用于区分初始化、tool_call、tool_result、resource、事件推送等。

通过 JSON 做序列化,前后端及内部组件以此交换工具调用与结果。

WebSocket 连接与会话(MCPSession)

每个客户端连接建立一个 MCPSession(包含 conn、send chan、tools/resources map、ctx、cancel、lastActive)。

sessions(sync.Map)保存活动会话供广播或全局寻找。

两个 goroutine:reader() 持续读消息并交给 handleMessage(并发处理),writer() 从 send channel 写回客户端(串行写,确保 websocket 写线程安全)。

send 是缓冲 channel(容量 256),发送方推送到 channel;如果 channel 满或写超时则默认丢弃(sendJSON 用 select+time.After 来避免阻塞)。

工具(Tool)与资源(Resource)

工具以函数形式暴露(例如 toolSendMessage、toolGetChatHistory):接收 params,返回 result 或 error。

会话内可有会话级工具(s.tools),也有全局工具(globalTools)。

工具调用由 handleToolCall 执行:查工具,执行,返回 tool_result 或 tool_error。

聊天室示例与广播

chatHistory 存在内存(sync.Map roomId -> []ChatMessage)。

broadcastChatMessage 遍历 sessions,把消息 push 到每个 session 的 send channel(非阻塞写,避免单个慢客户端影响整体)。

交错思考(Interleaved Thinking)与 Claude 代理

通过 CallClaudeWithInterleavedThinking 启动流式会话(示例采用 Anthropic/Claude 的 streaming API)。

当 Claude 在生成时触发 ToolUseEvent(想调用工具),服务端把该工具调用转换成 MCP tool_call,调用本地 session.handleToolCall,并把一个等待通道 waitCh 放到 claudeWaiting,让服务端等待工具结果。

当工具执行完成(产生 tool_result),会通过 handleClaudeToolResult 把结果送回等待通道,随后再把结果回填到 Claude 的流(stream.SendToolResult),Claude 继续生成——这个循环就是“交错思考”的核心:LLM 生成→提出工具调用→等待外部工具→工具结果回到 LLM→LLM 继续生成。

并发与容错防护

读写各一 goroutine 保证 WebSocket 线程安全。

mu 做工具地图/资源的并发保护。

send channel 有缓冲并使用 non-blocking 写+超时,防止慢客户端阻塞主流程。

但实现上仍有可能的 race、内存泄漏、阻塞点(后文会详细说明改进建议)。

3 与 MVC 层次架构(Model–View–Controller)的对应与联系

先给出一个映射关系(容易把两者混淆的地方):

  • Model(数据/域层)

在 MCP 中:chatHistory、resources(s.resources)、任何持久化/内存数据结构,以及工具内部使用的数据存储(例如 message 存储、用户资料、房间状态等)。

本质相同:都是表示业务状态与持久化的领域模型或仓库。

  • View(表现层 / 前端)

在 MCP 中:浏览器端的实时 UI(Vue/React)接收 assistant_message、chat_message 等事件并渲染。

不同点:在传统 MVC,View 通常通过 HTTP 请求获得渲染数据或模板返回;在 MCP,这里主要是通过 WebSocket 推送实时事件,UI 更像是订阅者/流消费者。

  • Controller(控制层 / 请求处理)

在 MCP 中:wsHandler + MCPSession.handleMessage / handleToolCall 等方法担当控制器职责:路由、验证、调度工具与资源、组装响应。

不同点:Controller 在 MCP 更像是事件分发/消息路由器和会话协调器,而非单次请求—响应的短生命周期处理器。

所以联系是明确的:MCP 中仍然存在 Model / View / Controller 的角色,但职责边界、交互模型与生命周期有明显差异。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。