第 3 课
接入编程智能体:MCP 握手、Codex 和 Qwen Code 配置、CBM Lens 与干净卸载
用几十行 Python 按 MCP 协议完成握手、列出 17 个工具并调用 trace_path;用 install --dry-run 预览,再一键接入 Codex 和 Qwen Code,看清写入的 MCP 配置、指引、技能、子智能体和钩子,附 Claude Code 手动配置;通过 SSH 端口转发打开 CBM Lens 的架构图和热点页;最后停掉常驻进程,用 uninstall 干净撤回。
课程目录第 3 / 3 课
学习位置仅保存在当前浏览器,有效期 180 天。
图文教材
本课对照的官方资料:README 的 Manual MCP Configuration、Multi-Agent Support、CBM Lens Beta、Uninstall 部分(0.12.1 版) 。测试环境同课时 1:2026-11-14,Asia/Shanghai,Debian 13 x86_64,Python 3.13.5,
codebase-memory-mcp0.12.1。下面所有「对照结果」都是这台机器的真实输出,只做了节选。
前两课都是你自己在命令行里查。实际使用时,提问的往往是编程智能体:它通过 MCP 协议启动 codebase-memory-mcp,看到 17 个工具,再按需调用。这一课先用几十行 Python 亲手走一遍 MCP 握手,看清智能体那一侧拿到的是什么;再用官方安装器接入 Codex 和 Qwen Code,看它到底改了哪些文件;然后在浏览器里打开 CBM Lens;最后演示怎样干净地撤回。
第 1 步:用 Python 走一遍 MCP 握手
不带任何参数运行 codebase-memory-mcp,它就是一个走标准输入输出(stdio)的 MCP 服务器,每行一条 JSON-RPC 消息。编程智能体做的事情就三步:initialize 握手,tools/list 列出工具,tools/call 调用工具。把下面的内容保存为 ~/cbm-lab/mcp_probe.py,只用标准库:
#!/usr/bin/env python3
"""用 MCP 的 stdio 协议直接和 codebase-memory-mcp 对话(只用标准库)。"""
import json
import subprocess
import sys
import textwrap
project = sys.argv[1]
proc = subprocess.Popen(
["codebase-memory-mcp"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True,
)
def send(msg):
proc.stdin.write(json.dumps(msg) + "\n")
proc.stdin.flush()
def request(rid, method, params):
send({"jsonrpc": "2.0", "id": rid, "method": method, "params": params})
while True:
reply = json.loads(proc.stdout.readline())
if reply.get("id") == rid:
return reply
init = request(1, "initialize", {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "kun-probe", "version": "0.1"},
})
info = init["result"]["serverInfo"]
print("server:", info["name"], info["version"])
send({"jsonrpc": "2.0", "method": "notifications/initialized"})
tools = request(2, "tools/list", {})["result"]["tools"]
print("tools:", len(tools))
names = ", ".join(t["name"] for t in tools)
print(textwrap.indent(textwrap.fill(names, 76), " "))
call = request(3, "tools/call", {
"name": "trace_path",
"arguments": {"project": project, "function_name": "preprocess_request",
"direction": "inbound", "depth": 2},
})
for block in call["result"]["content"]:
print(block["text"])
proc.stdin.close()
proc.wait(timeout=10)
运行它,项目名填 flask:
cd ~/cbm-lab && python3 mcp_probe.py flask
对照结果:
server: codebase-memory-mcp 0.12.1
tools: 17
index_repository, search_graph, query_graph, trace_path, get_code_snippet,
get_file_outline, get_graph_schema, compare_graphs, get_architecture,
search_code, list_projects, delete_project, index_status,
check_index_coverage, detect_changes, manage_adr, ingest_traces
function: preprocess_request
direction: inbound
callers_total: 2
callers_total_relation: eq
callers: 2 (cols: qn hop)
flask.src.flask.app.Flask.full_dispatch_request 1
flask.src.flask.app.Flask.wsgi_app 2
智能体那一侧拿到的就是这些:17 个工具的名字和参数说明,以及和命令行里一模一样的紧凑文本结果。preprocess_request 的上游是 full_dispatch_request 和 wsgi_app,和第 2 课查到的一致。只要你的智能体能启动这个命令并完成握手,它就能用上这张图。
第 2 步:先预览安装器会改什么
第 1 课用 --skip-config 跳过了智能体配置。现在用 install 子命令接入,但先加 --dry-run 预览,不写任何文件。--clients 指定只配置哪几个智能体(codebase-memory-mcp install --clients 可以列出全部代号)。安装器靠检测配置目录来判断装了哪些智能体;测试机上没有装 Codex 和 Qwen Code,所以先建两个空的配置目录,看安装器会写些什么。你的电脑上如果已经装了它们,跳过 mkdir 这一行:
mkdir -p ~/.codex ~/.qwen
codebase-memory-mcp install --dry-run -y --clients=codex,qwen
find ~/.codex ~/.qwen -type f | wc -l
对照结果:
codebase-memory-mcp install 0.12.1
Found 2 existing index(es). Keeping them. After install, re-index to pick up ...
/home/kunlab/.cache/codebase-memory-mcp/flask.db
/home/kunlab/.cache/codebase-memory-mcp/activity.db
Detected agents: Codex Qwen-Code
Codex CLI:
mcp: /home/kunlab/.codex/config.toml
instructions: /home/kunlab/.codex/AGENTS.md (managed activation pointer)
skill: /home/kunlab/.codex/skills/codebase-memory/SKILL.md (1 installed)
agent: /home/kunlab/.codex/agents/codebase-memory-scout.toml
agent: /home/kunlab/.codex/agents/codebase-memory.toml
agent: /home/kunlab/.codex/agents/codebase-memory-auditor.toml
hooks: SessionStart + SubagentStart (dynamic graph context)
note: non-managed hooks require /hooks trust; definition changes require re-trust
Qwen Code:
mcp: /home/kunlab/.qwen/settings.json
instructions: /home/kunlab/.qwen/QWEN.md
skill: /home/kunlab/.qwen/skills/codebase-memory/SKILL.md (1 installed)
agent: /home/kunlab/.qwen/agents/codebase-memory-scout.md
agent: /home/kunlab/.qwen/agents/codebase-memory.md
agent: /home/kunlab/.qwen/agents/codebase-memory-auditor.md
...
(dry-run — no files were modified)
0
每个智能体会拿到五样东西:MCP 服务器配置、一段常驻指引(Codex 是 AGENTS.md,Qwen Code 是 QWEN.md)、一个技能文件、三个分工不同的子智能体(Scout 快速粗查、默认的 Verify 按任务核实、Auditor 做有边界的完整核查),以及会话开始时自动补充图谱上下文的钩子。最后一行的 0 说明预览确实没有写入文件。
第 3 步:正式接入 Codex 和 Qwen Code
去掉 --dry-run 正式执行,再看写进了什么:
codebase-memory-mcp install -y --clients=codex,qwen | tail -n 22
find ~/.codex ~/.qwen -type f | sort
jq ".mcpServers" ~/.qwen/settings.json
sed -n "1,6p" ~/.codex/config.toml
cat ~/.codex/AGENTS.md
对照结果:
...
hooks: SessionStart + SubagentStart + PostToolUse ReadFile
...
Install complete. Please restart your coding-agent sessions to properly take ...
/home/kunlab/.codex/AGENTS.md
/home/kunlab/.codex/agents/codebase-memory-auditor.toml
/home/kunlab/.codex/agents/codebase-memory-scout.toml
/home/kunlab/.codex/agents/codebase-memory.toml
/home/kunlab/.codex/config.toml
/home/kunlab/.codex/skills/codebase-memory/SKILL.md
/home/kunlab/.qwen/QWEN.md
/home/kunlab/.qwen/agents/codebase-memory-auditor.md
/home/kunlab/.qwen/agents/codebase-memory-scout.md
/home/kunlab/.qwen/agents/codebase-memory.md
/home/kunlab/.qwen/settings.json
/home/kunlab/.qwen/skills/codebase-memory/SKILL.md
{
"codebase-memory-mcp": {
"command": "/home/kunlab/.local/bin/codebase-memory-mcp",
"args": []
}
}
# >>> codebase-memory-mcp MCP >>>
[mcp_servers.codebase-memory-mcp]
command = "/home/kunlab/.local/bin/codebase-memory-mcp"
args = []
env_vars = ["CBM_CACHE_DIR", "CBM_RUNTIME_DIR"]
# <<< codebase-memory-mcp MCP <<<
<!-- codebase-memory-mcp:start -->
For structural codebase exploration, use the installed `codebase-memory` skill.
<!-- codebase-memory-mcp:end -->
MCP 配置就是让智能体执行 codebase-memory-mcp(不带参数),和第 1 步的 Python 脚本做的事一样。安装器写入的内容都包在 >>> ... <<< 或 start ... end 标记之间,你原有的配置不会被覆盖,卸载时也只删标记内的部分。Codex 用户第一次使用前要在 Codex 里用 /hooks 审核并信任新加的钩子。技能文件里写的是「什么问题该用哪个工具」:
sed -n "6,10p" ~/.qwen/skills/codebase-memory/SKILL.md
对照结果:
# Codebase Memory — Knowledge Graph Tools
Graph tools return precise structural results in ~500 tokens vs ~80K for grep.
## Quick Decision Matrix
接入之后重启智能体,进入一个已建索引的仓库,就可以直接用自然语言提问,比如「preprocess_request 被谁调用?」「我这次改动会影响哪些函数?」「src 里有哪些函数没有调用者?逐个说明是否真的没用」。智能体会自己选择第 2 课里的那些工具。官方 README 给的上手说法是对智能体说一句「Index this project」,让它先建索引。
用的是 Claude Code、又不想跑安装器的话,README 给了手动配置:在用户级的 ~/.claude.json 或项目里的 .mcp.json 加入下面这段(command 换成你的绝对路径,可以用 command -v codebase-memory-mcp 查),重启后用 /mcp 应该能看到 codebase-memory-mcp 和 17 个工具:
{
"mcpServers": {
"codebase-memory-mcp": {
"command": "/home/kunlab/.local/bin/codebase-memory-mcp",
"args": []
}
}
}
第 4 步:在浏览器里打开 CBM Lens
CBM Lens 是官方的可视化界面,目前是公开测试版(v0.0.1),已经编进 0.12.1 的程序里,由常驻进程在本机的 9749 端口提供。第 2 课已经启动过常驻进程,确认一下:
codebase-memory-mcp daemon status
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9749/
对照结果:
daemon: active (permanent)
pid: 3253981
build: 0.12.1 (77745491f0a9...)
committed clients: 0
ui: configured at http://127.0.0.1:9749 (readiness not checked; `daemon start ...
200
界面只监听 127.0.0.1,外网访问不到,这是有意的安全设计。代码在云主机上时,在自己电脑上开一条 SSH 端口转发(把用户名和主机换成你的):
ssh -N -L 9749:127.0.0.1:9749 kunlab@你的云主机IP
然后在自己电脑的浏览器里打开下面这个地址,project= 后面是项目名:
http://127.0.0.1:9749/?project=flask&workspace=architecture
第一次打开会弹出欢迎框,点「Start exploring」进入。Architecture 页的 Overview 把目录画成立体地图,src/flask、tests、docs、examples 各是一块;切到 Hotspots,能看到被引用最多的符号,第 2 课统计出的 url_for 和改过的 preprocess_request 都在里面。顶部还有 Explore(读源码)、Galaxy(三维关系图)、Coverage(索引缺口)、System(常驻进程和日志)几个页面。右上角的机器人图标可以下载一个小模型在浏览器里本地问答,需要浏览器支持 WebGPU,默认关闭,本课没有测试。
第 5 步:停止常驻进程,干净撤回
不用了就停掉常驻进程。想撤回第 3 步的接入,先预览再卸载:
codebase-memory-mcp daemon stop
codebase-memory-mcp uninstall --dry-run
codebase-memory-mcp uninstall -y | tail -n 12
find ~/.codex ~/.qwen -type f | sort
ls ~/.cache/codebase-memory-mcp/
对照结果:
daemon: stopping (pid 3253981)
Found 2 index(es):
/home/kunlab/.cache/codebase-memory-mcp/flask.db
/home/kunlab/.cache/codebase-memory-mcp/activity.db
Indexes kept in /home/kunlab/.cache/codebase-memory-mcp. To remove them, ...
Codex CLI: removed MCP config entry
...
(dry-run — no files were modified)
Removed /home/kunlab/.local/bin/codebase-memory-mcp
Left in place: /home/kunlab/.local/bin/install.sh
This is the updater; uninstall does not delete it because it cannot
prove it owns it. To remove it as well:
rm "/home/kunlab/.local/bin/install.sh"
Uninstall complete. Please restart your coding-agent sessions to properly take ...
/home/kunlab/.codex/AGENTS.md
/home/kunlab/.codex/config.toml
/home/kunlab/.qwen/QWEN.md
/home/kunlab/.qwen/settings.json
_config.db
activity.db
flask.db
logs
卸载删掉了程序、技能文件和三个子智能体,并把四个配置文件里属于它的部分清掉:测试机上 AGENTS.md、config.toml、QWEN.md 变成了空文件,settings.json 只剩空的 mcpServers 和 hooks。索引默认保留,要连索引一起删,用 uninstall -y --delete-indexes。更新器 install.sh 需要自己手动删。
常见坑
- 智能体里看不到这个 MCP 服务器:先用第 1 步的脚本确认服务器能正常握手,再检查配置里的
command是不是绝对路径,最后重启智能体。官方排错表也是这个顺序。 - 不确定安装器会改哪些文件:永远先跑
install --dry-run,再用--clients=只配置你需要的智能体。 - Codex 里钩子没生效:新加的钩子要在 Codex 里用
/hooks审核信任;安装器更新钩子定义后,需要重新信任。 - Lens 打不开:确认
daemon status是 active;云主机上要通过 SSH 端口转发访问,别把 9749 端口直接开到公网;?project=后面必须是list_projects里的项目名。 - 卸载后发现索引还在:这是默认行为。要删索引,加
--delete-indexes,或者删除~/.cache/codebase-memory-mcp/下对应的.db文件。
小结
这一课用几十行 Python 走完了 MCP 握手,看到智能体能用的 17 个工具;用 install --dry-run 预览、再用 install --clients=codex,qwen 一键接入,弄清了安装器写入的 MCP 配置、指引、技能、子智能体和钩子;通过 SSH 端口转发打开了 CBM Lens;最后停掉常驻进程,用 uninstall 干净撤回。整个系列课程从安装、建索引、查询、算影响面到接入智能体,都在一台没有显卡的云主机上完成,没有用到任何 API Key。
