Model Context Protocol · 以 codegraph 为例

把 AI 接上外挂的标准插座

MCP 是让 AI 助手即插即用地接入外部工具的一套协议。像 USB 统一了电脑外设一样,MCP 统一了「AI 如何调用工具」。这页用你电脑上真实安装的 codegraph,从概念到字节,把一次 MCP 连接彻底拆开讲透。

codegraph v0.9.8 feishu-mcp-pro chrome-devtools playwright baidu-netdisk zeus-devx-database

第一课 · 三个角色

一次 MCP 连接里,有三个东西在配合

点下面三个盒子,看清每个角色是谁、负责什么。理解这一点,后面的一切都顺了。

使用工具
Host · 宿主
Claude Code
负责发起调用的一方。它读配置、启动 server、把能力变成「我能用的函数」。
干活
MCP Server · 服务器
codegraph 程序
真正实现能力的独立进程。它做代码索引查询,并把自己会什么上报给宿主。
连接对象
MCP Client · 客户端
Host 内部的连接
不是独立程序,而是 Host 内部维护的那条「通往 server 的连接」。

第二课 · 谁真的懂 MCP

模型不认识 MCP,懂它的是宿主程序

最容易搞混的一点:MCP 协议没有被「训练」进模型。模型只学会了「工具调用」这个通用能力;真正懂 MCP 协议、负责翻译消息的,是 Claude Code 这个宿主程序。点下面三层看各自懂什么、不懂什么。

训练而来
大模型 · Claude
会下指令的老板
只会说「帮我查状态」这种意图,不碰协议。
代码写死
宿主程序 · Claude Code
翻译官
把人话意图翻译成 MCP 消息,再翻回结果。
代码写死
MCP Server · codegraph
打印机
只懂 MCP 协议和自己的业务,不懂模型是谁。
一次调用的翻译过程
# 1. 模型输出「工具调用意图」(不是 MCP,是模型的原生能力)
Claude 决定调用 codegraph_status,参数 {}

# 2. Claude Code 把意图翻译成 MCP 协议消息
{ "method": "tools/call", "params": { "name": "codegraph_status" } }

# 3. codegraph 执行,结果再被 Claude Code 翻译回给模型

第三课 · 完整一生

一次 MCP 连接,走完这 6 步

点圆点或「下一步」逐格推进。每一步都配了你电脑上的真实数据,看它每一步到底发生了什么。

第四课 · 方法 vs 工具

tools/list 是「方法」,由协议统一规定

MCP 底层是 JSON-RPC 2.0,每条消息里都有个 method 字段。协议规范定义了一组标准方法,所有 server 都实现同一套——这就是 Claude Code 能用一套代码连任何 server 的原因。点下面的方法,看它是什么、对应哪条消息。

方法(method)

协议层的「动词」,统一的通信动作。由 MCP 规范定义,所有 server 相同。例子:tools/list、tools/call、initialize。

工具(tool)

业务层的「名词」,具体能做什么事。由每个 server 自己定义,通过 tools/list 上报。例子:codegraph_search、doc_read。

第五课 · 工具的结构

一个「工具」,就是这三样东西

每个通过 tools/list 上报的工具,都是同一个模子:name + description + inputSchema。模型完全没见过 codegraph 的代码,就靠这三样学会用它。点每一段看含义。

一个真实工具的完整定义(codegraph_trace)
{
  "name": "codegraph_trace",
  "description": "Call path between two symbols — how does <from> reach <to>?",
  "inputSchema": {
    "type": "object",
    "properties": {
      "from": { "type": "string" },
      "to":   { "type": "string" }
    },
    "required": ["from", "to"]
  }
}

第六课 · 配置

那段配置,逐字拆开看

这是写在你 ~/.claude.json 里的真实登记信息。点每一行,看它是什么意思。

第七课 · 命名

工具名为什么这么长

点名字的每一段,看它由什么拼成。

第八课 · 底层

一次调用,消息到底怎么跑

MCP 的底层是 JSON-RPC 2.0 消息,走标准输入输出(stdin/stdout)管道。点「发送请求」,看一条消息往返的完整旅程。

Claude Code
Host 进程
codegraph
Server 进程
↔ stdin(请求进去) · stdout(结果出来)
→ Claude Code 写进 codegraph 的 stdin(请求)
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "codegraph_status", "arguments": {} } }
← codegraph 从 stdout 写回(响应)
{ "jsonrpc": "2.0", "id": 2, "result": { "content": [ { "type": "text", "text": "Index ready: 1,234 files · 8,901 symbols" } ] } }

第九课 · 传输方式

数据走哪条路:stdio、HTTP、SSE 还是 WebSocket

MCP 的「传输层」是可插拔的。点下面每个传输方式,看它是什么、底层跑在什么之上。

本机 · stdio(不进网络)

MCP工具调用语义
stdio 管道操作系统进程间通信

字节只在两个进程的内存里流动,没碰过网卡、没碰过 IP/TCP。

远程 · Streamable HTTP(进网络)

MCP工具调用语义
HTTP应用层
TCP传输层
IP网络层
物理 / 链路光纤、网卡

MCP 是「叠在 HTTP 之上的应用层协议」——HTTP 本身也是应用层,所以是应用层里再叠一层。

一句话:MCP 是应用层协议,而且是应用层里叠在 HTTP(或 stdio)之上的那一层。它规定「说什么」,不关心字节怎么传;字节怎么传,由可插拔的传输层决定。用 stdio 就根本不进网络,用 Streamable HTTP 才坐上 TCP/IP 这趟车。

第十课 · 微服务互调

真实世界里:两个 Java 微服务怎么调

你问的 OpenFeign 调用,底层就是最普通的 HTTP + JSON。看一次调用怎么从 A 服务的代码走到 B 服务的代码。

业务代码 getOrder(1)↓ OpenFeign→ HTTP 报文(JSON)→ TCP→ 服务B Tomcat→ Spring MVC 反序列化
OpenFeign 自动生成的请求
GET /orders/1 HTTP/1.1
Host: order-service
Content-Type: application/json

# body 里装的是 JSON(Jackson 把 Java 对象序列化成的文本)

OpenFeign 调用

Java 对象 → JSON → HTTP → TCP → IP

MCP 远程调用

JSON-RPC → HTTP → TCP → IP

同一个地基(HTTP over TCP),区别只在 body 里装什么:OpenFeign 装业务 JSON,MCP 装 JSON-RPC 工具调用消息。

微服务互调的三大流派

调用方式是什么底层协议数据格式
OpenFeignHTTP 客户端框架HTTP/1.1 → TCPJSON(文本)
RestTemplate / WebClientHTTP 客户端库HTTP/1.1 → TCPJSON
DubboRPC 框架自定义二进制 → TCP二进制
gRPCRPC 框架HTTP/2 → TCPProtobuf(二进制)
RabbitMQ / Kafka消息队列AMQP 等 → TCP各格式

第十一课 · RPC 与 JSON-RPC

JSON-RPC = JSON + RPC

RPC 是「远程过程调用」这个思想;JSON-RPC 就是用 JSON 来编码这种调用的协议。点下面消息的字段,看它对应 RPC 的哪个要素。

一条 JSON-RPC 请求
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": { "name": "codegraph_status" }
}

本地调用

int sum = add(1,2); 直接执行,立刻拿到结果。

远程调用(RPC)

把「调 add、参数 1 和 2」打包成消息发过去,对方执行后把结果发回来,看起来像本地调用。

拆词:JSON-RPC = JSON(用什么格式说话)+ RPC(本质是远程过程调用)。同族还有 XML-RPC / SOAP(用 XML)、gRPC(用 Protobuf 二进制)——都是 RPC,只是编码格式不同。

附录 · 分类尺子

概念 / 协议 / 框架 / 格式,一眼分清

拿不准一个名词属于哪类?记住这把尺子:协议是「规则」,框架是「代码」,格式是「文字」,概念是「想法」。点下面每类看判断标准。

类别名词怎么记
概念RPC「远程调函数」这个想法
协议TCP、IP、UDP、HTTP、WebSocket、SSE、JSON-RPC、AMQP、MCP规定「怎么说话」的规则
框架 / 库OpenFeign、RestTemplate、WebClient、Spring MVC、Dubbo、gRPC、RabbitMQ、Kafka帮你干活的代码
格式JSON、XML、Protobuf、Hessian数据「怎么写」
机制stdio、Unix domain socket操作系统底层能力
易混点:gRPC 和 Dubbo「一词两义」——指代码是框架,指规则是协议。RabbitMQ 是产品,AMQP 才是协议。Protobuf 是格式不是协议。

第十三课 · CLI 与 MCP

同一个程序的两张脸:给人用 CLI,给 AI 用 MCP

CLI 和 MCP 工具不是二选一,而是同一个程序的两种接口。看 codegraph 自己的命令行长什么样——答案就藏在里面(这是你电脑上真实的 codegraph --help 输出)。

codegraph --help(真实输出,已精简)
# 这些命令,人直接在终端里敲:
  codegraph query   AuthService     # 搜索符号
  codegraph context "实现登录"        # 构建任务上下文
  codegraph callers AuthService     # 谁调它
  codegraph impact  AuthService     # 影响分析
  codegraph status                  # 索引状态

# 而这两条,揭示了全部秘密:
  codegraph serve --mcp             ★ 作为 MCP server 启动(给 AI 用)
  codegraph install                 ★ 把 codegraph 装成各 agent 的 MCP server
秘密一:你配置里的 "args": ["serve", "--mcp"],就是让 codegraph 这个 CLI 程序以 MCP 模式跑起来。MCP server 不是另一个程序,它就是 CLI 的 serve 子命令。

秘密二:CLI 命令和 MCP 工具,几乎一一对应

CLI 命令(给人敲)MCP 工具(给 AI 调)干的事
codegraph querycodegraph_search搜索符号
codegraph contextcodegraph_context任务上下文
codegraph callerscodegraph_callers谁调它
codegraph calleescodegraph_callees它调谁
codegraph impactcodegraph_impact影响分析
codegraph filescodegraph_files文件结构
codegraph statuscodegraph_status索引状态

CLI vs MCP,接口上的区别

维度CLI(给人)MCP 工具(给 AI)
调用者人AI / 程序
怎么知道有啥能力人看 --helpAI 靠 tools/list 自动发现
怎么知道传参人读 help 文本AI 靠 inputSchema
输出格式人类可读文本结构化数据
进程一次跑完就退出常驻(连接期间)
总结:CLI 是「为人优化的接口」,MCP 是「为 AI 优化的接口」。同一个程序、同一套能力,两张脸——你敲 codegraph query,我调 codegraph_search,背后是同一份代码。

第十四课 · skill 为什么不够

用 skill 教 CLI,为什么替代不了 MCP

你可能会想:把 CLI 操作指南封装进 skill,教 agent 用,不就跟 MCP 一样了吗?答案:能覆盖七八成,但有 5 个结构性硬伤——MCP 就是为治这 5 个伤而生的。

Skill

一份知识 / 说明书(文本),告诉 agent「遇到什么情况该做什么」。加载进上下文,靠 agent 理解。

MCP 工具

一个能力 / 插座(协议 + 代码),运行时自动发现,靠协议结构化调用。

skill + CLI 的 5 个硬伤(点开看详情)

一个真实例子:找 AuthService 在哪

skill + CLI 方案

  1. agent 读 skill 说明书
  2. 决定运行 codegraph query AuthService
  3. Bash 吐出 40 行带格式文本
  4. agent 自己在这堆文本里抽取结果

MCP 方案

  1. 发现工具 codegraph_search(带 description + inputSchema)
  2. 调用,传 {"query":"AuthService"}
  3. 返回结构化 JSON
  4. 直接读字段,完事
公平地说:当程序没有 MCP server、命令简单、输出稳定时,skill + CLI 完全够用甚至更好——尤其 skill 擅长教「流程和判断」。所以两者常配合:MCP 给可靠的能力插座,skill 给「怎么组合用」的专家知识。

三者的定位

层次解决什么问题类比
CLI让人手动执行程序柜台点餐
Skill给 agent 装「知识 / 流程」说明书 / 老员工经验
MCP给 agent 装「可靠的能力接口」标准插座(USB)
终结论:说明书能教你接线,但(1)你每次都要照着书手动接、自己认哪根线是哪根,(2)书会过时,(3)接错了没人拦你,(4)换个电工还得重写一本。MCP 把这四件事全自动化了——所以 MCP 不是「另一种说明书」,而是「插座」。