CC-Monitor
写这个工具的目的
使用 CC 进行开发的时候经常不知道 Agent 对电脑操作的细节,很多时候配置被修改,也不知道是什么时候操作的。
CC-Monitor 提供了 Agent 操作审计功能,让 AI 对你电脑的操作一目了然,目前提供 Shell Log 和 Web UI 两种界面。
- 首页:概览统计——进行中的终端会话数、监测到的 Claude Code 会话总数、审计事件总数、拦截/疑似绕过次数、文件读/写/编辑/删除次数、日志类型与风险等级分布。"会话总数"、"审计事件总数"、"已拦截的高危操作"三张卡片可以点开查看下钻详情(分别是会话列表、按事件类型 + 所属 Session 的明细、被拦截操作的完整列表)。
- Log 审计:全宽的实时审计日志查看(按会话过滤,会话下拉框显示"文件夹 · 模型 · 短 ID",而不是一串看不出区别的 ID ),复用 CLI 那套人类可读的事件翻译逻辑。
- 终端会话:直接在浏览器里开启一个 Claude Code 终端对话(
node-pty起 PTY ),不用再切到本地终端软件;使用xterm.js+ WebGL 插件渲染,有 GPU 就使用 GPU 加速,没有则自动退化成 Canvas 。侧边栏可以切换到网格视图( herdr 风格),同屏显示所有进行中的会话,点击哪个面板就给哪个会话发送键盘输入。 - Claude Tap:查看某个会话发给/收到模型的完整对话内容(不只是"调用了哪个工具")——文本、思考、工具调用、工具结果、Token 用量,按字段分色渲染。数据来源是 Claude Code 自己写在本地的 transcript JSONL 文件( hook payload 里的
transcript_path),不是抓包/MITM 。CLI 等价命令:CC-Monitor tap [--session ID] [-f]。 - 状态信息:账号级额度(单次 5 小时窗口 / 周额度 / 分模型周额度 + 重置时间,跟 ccstatusline 读取同一份 Claude Code OAuth 凭证、查询同一个
api.anthropic.com/api/oauth/usage接口)+ 每个会话的模型、Token 用量、吞吐速率( tok/s ,由 transcript 估算)、CWD 、Git 分支、活跃时长、拦截情况。 - 中英文切换 + 多主题:右上角语言按钮(中文/EN )和主题下拉(标准配色/深色/浅色/Dracula/Nord/Midnight/Ocean/Forest/Sunset/Rose ,后 5 个移植自 AI_Web_Search 的配色方案),选择存入
localStorage。翻译范围是界面文案(导航、按钮、标题、空状态提示、风险/操作/状态标签),不翻译数据本身(命令文本、工具输出、transcript 对话原文)。审计日志的风险/操作类型/状态徽章使用固定的高饱和配色(不随主题变化),高危操作整行标红加粗。
GitHub
截图
图片使用
raw.githubusercontent.com直链,避免 GitHubblob页面导致 README 中图片无法正常渲染。
| 首页概览 | 会话列表下钻 |
|---|---|
![]() |
![]() |
| 事件类型明细 | 被拦截的高危操作 |
|---|---|
![]() |
![]() |
| 审计日志 |
|---|
![]() |
功能介绍
CC-Monitor 是双层监测架构:
- 应用层( Claude Code Hooks ):注册
PreToolUse/PostToolUsehook ,拿到每次工具调用的语义信息(工具名、命令、文件路径),按规则判定放行/拦截/需要确认。这是主力,成本低、覆盖面广。 - 系统层( eBPF 探针,Linux ):
CC-Monitor-probe使用bpftrace独立于 Claude Code 之外,直接在内核层跟踪claude进程派生出的整棵子孙进程树的execve/connect,交叉验证应用层 hooks 有没有被绕过或篡改——这是第二道防线,即使 hooks 配置被破坏也能兜底发现异常。
具体能力:
| 能力 | 说明 |
|---|---|
| 高危操作拦截 | 命中规则的 Bash/Write/Edit 等操作可以直接拒绝(如 rm -rf /、写 ~/.ssh/) |
| 人工确认 | 中风险操作在终端弹出确认提示 + 桌面通知,超时/无 TTY 默认拒绝 |
| 审计日志 | 所有事件落盘 SQLite ,tool_input/tool_response 全量留存 |
| 人类可读实时日志 | CC-Monitor tail 把原始 JSON 翻译成"事件类型 + 摘要 + 结果",终端自动彩色高亮,Bash 命令按语法(命令名/参数/字符串/变量/管道)着色 |
| 绕过检测 | CC-Monitor verify 比对系统层探针观测到的命令和 hook 记录,标出"探针看到了、但 hook 没记录"的可疑命令 |
| 网络层可视化 | eBPF 直接抓 connect() 目标 IP:port ,不解密 TLS 、不用装 CA 证书 |
实现原理
功能介绍是"能做什么",这里是"怎么做到的",每条机制都能在源码里直接对上号(完整版见 DESIGN.md):
- Hook 拦截:Claude Code 每次调用工具前后,会把一份 JSON payload 通过 stdin 传给
settings.json里配置的 hook 命令,同步等它退出。CC-Monitor-hook退出码是 2 就代表拒绝——stderr 里的原因会被 Claude Code 展示出来。它是每次调用都拉起的一次性子进程,不是常驻服务,所以也没有"进程挂了监控就失效"这种问题(但也意味着改完规则不用重启任何东西,下一次调用直接生效)。 - 规则引擎:
default_rules.json是一份有序规则表,policy.evaluate()按顺序逐条尝试,第一条命中就生效( first-match-wins ),所以更具体的规则要写在更通用的规则前面。每条规则声明tools(适用哪些工具)、field(从tool_input里取哪个字段,比如command/file_path/url)、pattern(正则)、risk/action。规则文件首次使用时从default_rules.json拷贝到~/.cc-monitor/rules.json,之后可以自行修改。 - 系统层 eBPF 探针:
probe_linux.bt挂在内核的execve/connect等 tracepoint 上,先用comm=="claude"认出 Claude Code 自己的进程,再监听sched_process_fork事件,把"正在被监控"这个标记沿着进程树一路传给它 fork 出来的所有子孙进程——不管子进程改名叫什么都跟得上。CC-Monitor verify拿探针观测到的命令去匹配同一时间窗口内 hook 记录的命令文本(做了引号归一化,兼容 zsh 快照包装命令时对引号的转义),标出"探针看到了、hook 却没记录"的可疑差异。 - Claude Tap:hook 的 JSON payload 里有个
transcript_path字段,指向 Claude Code 自己写在本地的对话 transcript JSONL 文件。直接读取这个文件、解析里面的user/assistant/tool_use/tool_result等条目,就能还原完整对话——不抓包、不用装 CA 证书、不需要中间人代理。 - 账号额度显示:读取
~/.claude/.credentials.json里 Claude Code 自己保存的 OAuth token ,使用它调用 Anthropic 官方的api.anthropic.com/api/oauth/usage接口(带上anthropic-beta: oauth-2025-04-20请求头)——跟 ccstatusline 读取的是同一份凭证、查询的是同一个接口,不是我们自己另外维护的一套用量统计。 - Web 终端:使用
node-pty起一个真正的伪终端( PTY ),跟你在本地开一个终端窗口没有本质区别;创建之后自动往这个 PTY 里输入claude\r帮你启动。Claude Code 第一次打开一个没信任过的目录时会弹出一个"是否信任这个文件夹"的确认框,默认高亮选项是"No, exit"——这里检测到这段提示文本后会自动按方向键 + 回车替你选择"Yes, I trust this folder",否则这个确认框没人处理的话,后续任何一次正常的回车操作都会把 Claude Code 意外退出,界面上却看起来"终端明明是好的"。 - 数据持久化/归档:首页"持久化归档"使用 SQLite 官方的
backup()API 给当前events.db做一次完整快照(不是简单复制文件——backup()会正确处理 WAL 模式下还没落盘的数据),存到~/.cc-monitor/archives/下;"清空当前数据"则是对同一个库执行DELETE并重置自增 ID 。
安装
依赖:Python 3 (标准库即可,无第三方包依赖)。系统层探针额外依赖 Linux 的 bpftrace。
有两种装法,效果一样,选一种就行:
方式一:直接在当前目录用(不动系统路径)
# 1. 把整个 CC-Monitor 目录放到你想要的位置(这里假设已经在 ~/Tools/CC-Monitor )
cd ~/Tools/CC-Monitor
# 2. 安装 hooks 到 Claude Code 配置(会自动 chmod +x bin/ 下的脚本)
python3 install.py # 全局安装:写入 ~/.claude/settings.json
python3 install.py --project /path/to/proj # 只对某个项目生效
python3 install.py --target /path/to/settings.json # 显式指定 settings.json (跨用户安装时用)
# 3.(可选)如果要用系统层探针,安装 bpftrace
sudo apt install bpftrace # Debian/Ubuntu
# 其它发行版参考 bpftrace 官方文档; macOS 暂不支持系统层探针
安装脚本按 command 字段去重合并写入 PreToolUse/PostToolUse hook 数组,不会覆盖你已有的其它 hooks 配置;遇到损坏的 settings.json 会自动备份成 .json.bak 再重建。安装后重启 Claude Code,新开的会话才会读取新配置。
方式二:make install 装到系统路径
想要有个全局命令、不用记着这份代码放在哪个目录,可以装到系统里:
sudo make install # 默认安装到 /usr/local/lib/cc-monitor + /usr/local/bin
sudo make install PREFIX=/opt/cc-monitor # 或者自定义前缀
# 安装完成后,任意目录都能直接用命令,再照方式一的第 2 步注册 hooks (使用安装后打印出来的路径):
CC-Monitor tail -v
python3 /usr/local/lib/cc-monitor/install.py
make install 只负责"把代码放到系统里、建好命令行链接",不会自动修改 ~/.claude/settings.json——注册 hooks 这一步需要自己手动运行 install.py(命令行结尾会打印出安装后的准确路径)。卸载使用 sudo make uninstall(同样只删除代码和命令链接,settings.json 里的 hooks 条目需要自己手动删除)。
编译方式
CC-Monitor 是纯 Python 实现(标准库 sqlite3/json/argparse/re 等,无第三方依赖),不需要编译:
bin/CC-Monitor、bin/CC-Monitor-hook、bin/CC-Monitor-probe都是带#!/usr/bin/env python3shebang 的可执行脚本,install.py会自动给它们添加执行权限。- 系统层探针依赖的
bpftrace是系统包管理器直接安装的现成二进制,不需要自己编译;cc_monitor/probe_linux.bt是 bpftrace 脚本,运行时由bpftrace解释执行,同样不需要编译。 Makefile里的make install不是编译,只是把文件拷贝到PREFIX下,再建立命令行链接,见上面的"安装"一节。- 目前没有打包成单文件可执行程序(比如使用 PyInstaller/Nuitka ),这属于待办事项,见下方"开发进展"。
使用方式
# 实时查看监测到的事件( Ctrl+C 退出)
./bin/CC-Monitor tail
./bin/CC-Monitor tail -v # 额外打印原始 JSON
# 查看当前生效的规则
./bin/CC-Monitor rules
# 查看统计(按风险等级/决策结果计数)
./bin/CC-Monitor stats
# 系统层探针(需要 root ,用于交叉验证 hooks 有没有被绕过)
sudo ./bin/CC-Monitor-probe
# 查看探针标记的"可能绕过监测"的记录
./bin/CC-Monitor verify
环境变量:
| 变量 | 作用 |
|---|---|
CC_MONITOR_HOME |
覆盖事件库/规则文件目录(默认 ~/.cc-monitor/) |
CC_MONITOR_COLOR |
always/never 强制开关终端配色(默认按是否为真终端自动判断) |
NO_COLOR |
设置后强制关闭配色(通用约定) |
事件与规则存放在 ~/.cc-monitor/:events.db( SQLite 审计日志)、rules.json(可编辑规则,修改后立即生效,无需重启)。
规则格式(rules.json 是规则数组):
{
"id": "规则名",
"risk": "high | medium | low",
"action": "block | confirm | log",
"tools": ["Bash"],
"field": "command | file_path | url",
"pattern": "正则表达式"
}
block:直接拦截,Claude Code 收到拒绝原因。confirm:终端弹出确认提示(等待 TTY 输入y才放行)+ 桌面通知,无 TTY/超时默认拒绝。log:放行但记录审计日志。
默认规则见 cc_monitor/default_rules.json,涵盖:危险删除、磁盘覆写命令、curl|bash、递归 777、sudo、git push --force、读写 SSH 密钥/凭据文件、写系统目录等。
功能开发进展
已实现
- 应用层 Hook 拦截器(
PreToolUse/PostToolUse),覆盖 Bash/Write/Edit/Read/WebFetch 等全部工具 - 策略引擎:正则规则匹配 + 三种动作( block/confirm/log )+ 三级风险分类
- SQLite 审计日志(
events.db),事件对 hook 输入/输出全量留存 - CLI:
CC-Monitor tail(实时查看)/rules(查看规则)/stats(查看规则)/verify(绕过检测) - 人类可读事件格式化:把原始 JSON 翻译成"事件类型 + 摘要 + 结果"
- 终端彩色输出:风险等级/决策结果/规则名独立配色,支持
NO_COLOR/CC_MONITOR_COLOR - Bash 命令语法高亮(命令名/参数/字符串/变量/管道重定向分色)
- 终端确认(
/dev/tty交互)+ 桌面通知(notify-send/osascript) - 安装脚本:安全合并 hooks 到
settings.json(全局/项目/自定义路径三种模式),不覆盖已有配置 - 系统层探针(
CC-Monitor-probe,仅 Linux ):eBPF 跟踪 Claude Code 进程树的execve/connect - 绕过检测:探针观测到的命令与 hook 记录模糊比对(进程树 + 时间窗口 + 去引号子串匹配),标记
hook_bypass_suspected - 网络层可视化:eBPF 直接抓
connect()目标 IP:port + 反向 DNS ,不用 MITM 代理
未实现 / 待办
- macOS 支持:设计文档里规划的 Endpoint Security Framework 方案完全未实现(需要签名的系统扩展 + 用户手动授权 Full Disk Access ),目前 CC-Monitor 只在 Linux 上验证过
- 强制沙箱( Phase 3 ):Landlock LSM / bubblewrap ( Linux )、
sandbox-exec/容器化( macOS ),目前只能拦截 + 告警,不能把 Claude Code 关进一个真正强制隔离的沙箱里 -
CC-Monitor-probe常驻化:目前需要手动sudo启动,没有 systemd unit / 开机自启,需要用户自己决定要不要安装成常驻服务 - 审计日志防篡改:日志和被监测进程同一用户权限,理论上可被同用户进程删除/篡改;异地转发、只追加权限(
chattr +a)等加固手段还没做 - 多机日志集中上报 / 规则库社区化( Phase 3 ):目前是纯本地单机工具
- 高危操作的图形化确认弹窗:目前只有终端 TTY 文本确认,没有可点击的 GUI 允许/拒绝对话框
- 规则语义化判断:目前纯正则匹配,没有轻量模型辅助判断命令意图(比如识别用自然语言描述的等价危险操作)
- 打包为单文件可执行程序:目前依赖系统 Python 环境直接运行,没有使用 PyInstaller/Nuitka 之类打包
已知限制
confirm依赖/dev/tty,无交互终端( CI/无头环境)时直接拒绝。- 探针的绕过检测是模糊匹配,不是精确语义分析;系统负载高、探针处理有延迟时,
CC-Monitor verify可能需要稍等片刻才能看到最新结果。 - 网络层只看 IP:port ,看不到真实域名(靠反向 DNS 尽力还原,不一定准)。




