第 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 干净撤回。

图文20 分钟

课程目录第 3 / 3 课

学习位置仅保存在当前浏览器,有效期 180 天。

01 / 图文教材

图文教材

本课对照的官方资料: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-mcp 0.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。