MCP 协议到底解决了什么问题
2026/6/3 10:01:37 网站建设 项目流程

本文面向:想理解 MCP 协议设计动机、或想把自己的能力暴露给 AI 工具的开发者。
预计阅读时间:12 分钟
最终效果:理解 MCP 的 Host / Client / Server 模型、stdio 传输、工具注册,以及它与 Function Calling 的区别和适用边界。

一个恼人的现实

你有 10 个 AI 编程工具——Claude Code、Cursor、Copilot、Windsurf、Cline……每个都能调用外部工具。你想让它们都能访问你的 ChatCrystal 知识库。

没有 MCP 的世界里,你需要:

  • 为每个工具写一个插件/扩展,适配各自的工具注册格式
  • 处理每个工具不同的通信协议(有的用 stdio,有的用 HTTP,有的用 WebSocket)
  • 维护 N 个独立的集成代码,每次 API 变更都要同步更新

这就是 MCP 要解决的问题:给 AI 工具的外部能力集成定义一个统一标准

MCP 是什么

MCP(Model Context Protocol)是 Anthropic 在 2024 年底发布的开放协议。它的定位很清晰:

MCP 是一个开放协议,标准化了应用程序向 LLM 提供上下文的方式。

用一个类比:USB-C 统一了充电接口,MCP 统一了 AI 工具的"能力接口"。不管你是 Claude Code 还是 Cursor,只要支持 MCP 协议,就能接入任何 MCP Server 提供的工具。

核心概念

MCP 定义了三个角色:

  • Host:AI 应用本身(如 Claude Code、Cursor)
  • Client:Host 内部的 MCP 客户端,负责与 Server 通信
  • Server:提供工具/资源的服务端(如 ChatCrystal 的 MCP Server)
┌─────────────────────────────────────────┐ │ Host (Claude Code / Cursor / ...) │ │ ┌─────────────────────────────────┐ │ │ │ MCP Client │ │ │ │ ← stdio / HTTP → │ │ │ └─────────────────────────────────┘ │ └─────────────────────────────────────────┘ ↕ ┌─────────────────────────────────────────┐ │ MCP Server (ChatCrystal) │ │ - search_knowledge │ │ - get_note │ │ - list_notes │ │ - get_relations │ │ - recall_for_task │ │ - validate_task_memory │ │ - write_task_memory │ └─────────────────────────────────────────┘

传输层:stdio 是主力

MCP 支持两种传输方式:

stdio(标准输入/输出)

最常用的方式。Host 启动 MCP Server 作为子进程,通过 stdin/stdout 通信:

{"mcpServers":{"chatcrystal":{"command":"crystal","args":["mcp"]}}}

当 Claude Code 启动时,它会执行crystal mcp,这个进程在后台持续运行。Claude Code 通过 stdin 发送 JSON-RPC 请求,MCP Server 通过 stdout 返回响应。

stdio 的优势是零配置:不需要端口、不需要网络、不需要认证。Host 进程和 Server 进程在同一个机器上,通信走操作系统管道,延迟极低。

HTTP(Streamable HTTP)

适用于远程场景——MCP Server 部署在服务器上,多个客户端通过网络访问。ChatCrystal 目前使用 stdio 模式,因为它的定位是本地知识库工具。

工具注册:声明式定义

MCP Server 通过server.tool()注册工具,声明工具名称、描述和参数 schema:

constserver=newMcpServer({name:'chatcrystal',version:'0.2.0',});server.tool('search_knowledge','Semantic search across your AI conversation knowledge base.',{query:z.string().describe('Search query text'),limit:z.number().optional().default(10).describe('Maximum results'),},async({query,limit})=>{constresults=awaitclient.search(query,limit);return{content:[{type:'text',text:JSON.stringify(results,null,2)}],};},);

参数用 Zod schema 定义,MCP SDK 自动转换为 JSON Schema 发送给 Host。Host 的 LLM 看到工具描述和参数 schema,就能在对话中决定何时调用、传什么参数。

这个设计和 OpenAI 的 Function Calling 非常相似,但有一个关键区别:MCP 是跨进程、跨应用的标准协议,而 Function Calling 是单次 API 调用内的工具定义

MCP vs Function Calling

这是最常被问到的问题:MCP 和 Function Calling 有什么区别?

Function Calling

Function Calling 是 LLM API 的一部分。你在调用generateText时传入tools参数,LLM 在回复中决定是否调用工具:

constresult=awaitgenerateText({model,tools:{search:{description:'搜索知识库',parameters:z.object({query:z.string()}),execute:async({query})=>awaitsearch(query),},},prompt:'用户的问题',});

特点:

  • 工具定义和执行在同一个进程内
  • 每次 API 调用都需要重新声明工具
  • 工具的execute函数直接在应用代码中

MCP

MCP 是一个独立的协议层。工具定义在 MCP Server 中,Host 通过协议发现和调用:

特点:

  • 工具定义在独立进程中,可以跨应用复用
  • Server 启动时注册一次,Host 持续可用
  • 通信走 stdio 或 HTTP,天然支持远程部署

什么时候用哪个

场景选择
工具逻辑简单,在应用内完成Function Calling
工具需要访问外部服务(数据库、API)Function Calling + 服务封装
工具要被多个 AI 应用共享MCP
工具需要独立部署和更新MCP
用户想手动配置工具集MCP

ChatCrystal 选择 MCP 的原因是:它的知识库工具需要被 Claude Code、Cursor 等多个 AI 编程工具使用。如果用 Function Calling,每个工具都需要单独集成;用 MCP,一套 Server 代码,所有 Host 都能用。

ChatCrystal 的 7 个 MCP 工具

ChatCrystal 的 MCP Server 暴露了 7 个工具,分为两类:

只读知识工具

  1. search_knowledge— 语义搜索知识库,返回按相关性排序的笔记
  2. get_note— 获取单条笔记的完整内容(标题、摘要、结论、代码片段、标签)
  3. list_notes— 浏览笔记列表,支持按标签或关键词过滤
  4. get_relations— 获取笔记的关联关系(类型、置信度)

记忆循环工具

  1. recall_for_task— 为当前任务回忆相关知识,优先项目级记忆,补充全局记忆
  2. validate_task_memory— 预检任务记忆候选,不产生副作用,返回是否可接受
  3. write_task_memory— 持久化高质量的任务记忆,仅当内容满足质量门槛时写入

只读工具让 AI 编程助手能"回忆"你之前的经验——比如搜索"Fastify 插件注册",找到之前总结的最佳实践。记忆循环工具更进一步:AI 助手在完成任务后,可以把有价值的经验写回知识库,形成"用中学、学中用"的闭环。

write_task_memory有严格的质量门槛:它要求具体的标题、实质性的摘要、有意义的结论,以及可复用的经验教训(陷阱、修复、决策、模式)。模糊的进度日志、一次性环境检查、空洞的"健壮性"声明会被拒绝。

MCP SDK 的实现

ChatCrystal 使用@modelcontextprotocol/sdk官方 SDK。MCP Server 的核心代码非常精简——整个server.ts不到 150 行:

import{McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import{StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';constserver=newMcpServer({name:'chatcrystal',version:'0.2.0'});// 注册工具...server.tool('search_knowledge',...);server.tool('get_note',...);// ...// 连接 stdio 传输层consttransport=newStdioServerTransport();awaitserver.connect(transport);

SDK 封装了 JSON-RPC 协议细节、工具注册的 schema 转换、stdio 的消息分帧。你只需要关注工具的业务逻辑。

MCP 的生态现状

MCP 发布后迅速获得了生态支持:

  • Claude Code:原生支持 MCP Server 配置
  • Cursor:支持 MCP 工具集成
  • Windsurf / Cline:支持 MCP
  • VS Code Copilot:通过扩展支持 MCP

服务端方面,社区已经贡献了大量 MCP Server:GitHub、Slack、数据库、文件系统、搜索引擎……ChatCrystal 是其中一个——专注于 AI 对话知识管理。

MCP 的价值在于网络效应:每新增一个支持 MCP 的 Host,所有 MCP Server 都获得了新的分发渠道;每新增一个 MCP Server,所有 Host 都获得了新的能力。这是标准化协议的典型正反馈循环。

小结

MCP 解决的问题很简单:让 AI 工具能以标准化方式接入外部能力。它不是什么革命性的技术突破——本质上是把 Function Calling 从单次 API 调用扩展成了跨进程的协议。

但正是这个"简单的"标准化,让 ChatCrystal 的知识库能被所有支持 MCP 的 AI 编程工具访问。用户不需要为 Claude Code 写一个插件、为 Cursor 写另一个插件、为 Copilot 写第三个插件。一个crystal mcp命令,所有工具都能用。

对开发者而言,MCP Server 的开发成本也很低。ChatCrystal 的 MCP Server 核心代码不到 150 行,大部分工作量在工具背后的业务逻辑(搜索、检索、记忆写入),而不是协议适配。如果你有想要暴露给 AI 工具的能力,MCP 是目前最值得投入的集成方式。


项目地址:github.com/ZengLiangYi/ChatCrystal

如有疑问欢迎在 GitHub Issues 或私信交流,很乐意解答。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询