关于 chisel
Chisel 是用于操作 Chisel MCP 服务文件系统工具的 Agent 技能。它指导 Agent 按需查看文件片段并进行定点编辑,同时说明命令与路径限制。
主要功能
- 01搜索文件和目录
- 02读取指定文件范围
- 03应用定点补丁
- 04写入或追加文件
- 05运行白名单命令
适用场景
- 01查找符号而不读取整个文件
- 02用补丁进行小幅修改
- 03探索不熟悉的代码库
- 04批量执行文件转换
MCP 相关
Chisel 提供使用 Chisel MCP 服务的说明。该服务提供 shell_exec、patch_apply 和 write_file 等文件系统工具。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ckanthony/ chisel --skill chisel安装后在 Claude Code 中输入/chisel确认已加载。
详细介绍
Chisel Agent 技能
你可以使用 Chisel MCP 服务。Chisel 提供精密的文件系统工具,旨在尽量降低令牌开销并最大限度地提高安全性。首要原则:只需要读取文件的一部分时,绝不读取整个文件;只需要修改文件的一部分时,绝不重写整个文件。
⚠️
shell_exec没有 shell 解释器。管道(|)、&&、||、$()以及所有 shell 元字符都会作为字面内容传递给进程,不会被解释。每次shell_exec调用只运行一条命令。多步逻辑需通过多个独立调用组合完成。
工具选择
Need to find something in a file or directory?
└─ shell_exec (grep / find / sed / awk / stat / ls)
Need to edit an existing file?
├─ Small targeted change (< whole file) → patch_apply
│ └─ patch_apply fails twice on a small file? → write_file (see below)
└─ Overwrite entirely / file is tiny → write_file
Need to add content to the end of a file?
└─ append
Need to create a directory?
└─ create_directory
Need to rename or relocate a file?
└─ move_file
读取——绝不读取不需要的内容
始终从所需的最小片段开始。只有首次调用未能提供足够上下文时,才逐步扩大范围。
| 目标 | 调用 |
|---|---|
| 查找包含某个符号的行 | shell_exec grep ["-n", "symbol", "/root/file"] |
| 搜索多个文件中的符号 | shell_exec grep ["-rn", "symbol", "/root"] |
| 列出 Markdown 文件中的所有标题 | shell_exec grep ["-n", "^#", "/root/file.md"] |
| 按标题提取一个章节 | shell_exec sed ["-n", "/^## Section/,/^## /p", "/root/file.md"] |
| 读取大型文件的第 40–60 行 | shell_exec sed ["-n", "40,60p", "/root/file"] |
| 显示小文件中的每一行及其行号 | shell_exec cat ["-n", "/root/file"] |
| 统计出现次数 | shell_exec grep ["-c", "pattern", "/root/file"] |
| 获取文件大小/行数 | shell_exec wc ["-l", "/root/file"] |
| 列出目录内容 | shell_exec ls ["-la", "/root/dir"] |
| 按名称查找文件 | shell_exec find ["/root", "-name", "*.rs"] |
| 查看文件类型/元数据 | shell_exec stat ["/root/file"] |
| 查看日志末尾 | shell_exec tail ["-n", "50", "/root/app.log"] |
**避免对超过约 50 行的文件调用 cat。**使用 sed -n 'M,Np' 按范围读取;或者对短文件使用 cat -n,在编写补丁前获取行号。
编辑——优先使用差异,而非完整重写
patch_apply——主要编辑工具
仅发送已更改的行。文件将以原子方式写入;若代码块不匹配,则返回 PatchFailed,并保持原文件不变。
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,7 +12,7 @@
fn main() {
- let port = 3000;
+ let port = 8080;
start_server(port);
}
有效补丁的规则:
- 上下文行(无前缀)必须与文件完全一致,包括空白字符。
@@ -L,N +L,N @@行号必须与当前文件状态完全一致,包括起始行和行数。标题中的行号错误会导致PatchFailed,即使内容行正确也不例外。编写代码块标题前,务必先运行grep -n或cat -n确认实际行号。- 创建新文件时,源文件标题使用
--- /dev/null;目标文件必须尚不存在。 - 一次调用中可以包含多个
@@代码块,所有代码块将以原子方式应用。
返回 PatchFailed 时:
- 使用
grep -n或sed -n 'L-3,L+3p'重新读取准确行内容。 - 根据实际内容重新生成补丁,包括上下文行和代码块标题。
- **如果一个不足约 100 行的文件两次出现
PatchFailed:**停止排查代码块问题。使用cat -n读取整个文件,完整修正后改用write_file。
write_file——完整覆盖
适用于以下情况:
- 创建包含大量初始内容的新文件。
- 修改涉及的内容太多,导致差异比整个文件还大。
- 文件较短(少于约 30 行),完整重写更简洁。
- 短文件上的
patch_apply已失败两次——使用write_file安全恢复。
append
用于添加日志条目、向配置文件追加行,或向逐步构建的文件添加内容。文件必须已存在。
使用 shell_exec sed -i 就地转换
对于批量替换(重命名符号、修复重复模式),sed 会直接修改文件,无需 diff。
⚠️ macOS(BSD sed)和 Linux(GNU sed)的
sed -i参数格式不同。请严格使用以下格式,不要自行尝试其他写法。
平台 参数数组 Linux(GNU sed) ["-i", "s/Old/New/g", "/abs/path/file"]macOS(BSD sed) ["-i", "", "s/Old/New/g", "/abs/path/file"]在 macOS 上,空字符串
""是备份后缀参数(表示不创建备份文件)。Chisel 会将其作为单独参数正确传递给 BSD sed——不要省略它,不要将其替换为-i.bak,也不要将它与-i合并成单个参数,例如"-i''"。 任何偏离都会导致难以理解的 BSD sed 解析错误(command a expects \…`),白白浪费操作轮次。**如果不确定当前使用的是哪个平台,**请使用
shell_exec stat ["/proc/version"](Linux)或shell_exec uname ["-s"]进行检查。也可以优先使用patch_apply或write_file编辑单个文件——它们不受平台影响。
# Linux
shell_exec sed ["-i", "s/OldName/NewName/g", "/root/src/lib.rs"]
# macOS — the "" is mandatory and is passed correctly; do not second-guess this
shell_exec sed ["-i", "", "s/OldName/NewName/g", "/root/src/lib.rs"]
成功的就地编辑会返回 exit_code: 0,且 stdout 为空。非零退出码或任何 stderr 输出都表示表达式或路径有误——请修正这些内容,不要更改 -i 格式。
工作流模式
定位 → 阅读片段 → 应用补丁
标准的低 token 编辑循环:
grep -n "target_symbol" /root/file— 查找行号。sed -n "L-5,L+10p" /root/file— 阅读相关位置附近的一小段内容。- 确认
@@ -L,N +L,N @@标题完全匹配。 patch_apply— 针对该确切内容提交 diff。
**仅适用于短文件:**在步骤 1 中使用 cat -n /root/file 一次查看所有行号——对于少于 50 行的文件,这比组合使用 grep 和 sed 更快。
探索不熟悉的代码库
ls -la /root— 查看顶层布局。find /root -name "*.rs" -not -path "*/target/*"— 列出源文件。grep -rn "struct MyStruct" /root/src— 定位定义。sed -n "L,L+30p" /root/src/file.rs— 阅读结构体主体。
相对路径会自动以根目录为基准。
.表示根目录本身,subdir/file表示root/subdir/file。 绝对路径也可使用。始终会阻止目录遍历(../escape)。
使用样板代码创建新文件
使用 write_file。文件创建后,所有后续编辑都通过 patch_apply 进行。
跨多个文件重命名符号
首选方式——通过 find -exec … {} + 一次调用:
find -exec cmd {} + 会将所有匹配路径批量传递给单次命令调用。无需 shell,无需循环,无论匹配多少个文件,都只需调用一次 shell_exec。
# macOS (BSD sed)
shell_exec find ["/root/src", "-name", "*.rs", "-exec", "sed", "-i", "", "s/OldName/NewName/g", "{}", "+"]
# Linux (GNU sed)
shell_exec find ["/root/src", "-name", "*.rs", "-exec", "sed", "-i", "s/OldName/NewName/g", "{}", "+"]
{} 占位符和 + 终止符会按原样传递给 find——它们不是 shell 元字符,无需转义。
备用方式——每个文件调用一次(仅当 find -exec 不可用或模式需要针对每个文件分别处理时):
grep -rl "OldName" /root/src— 获取文件列表。- 对每个文件:
- Linux:
sed ["-i", "s/OldName/NewName/g", "/root/src/file.rs"] - macOS:
sed ["-i", "", "s/OldName/NewName/g", "/root/src/file.rs"]
- Linux:
创建目录树样板
create_directory /root/src/handlers
write_file /root/src/handlers/mod.rs "..."
write_file /root/src/handlers/auth.rs "..."
错误处理
| 错误 | 含义 | 修复方法 |
|---|---|---|
PatchFailed | 上下文行或 hunk 标题与当前文件不匹配 | 使用 grep -n / cat -n 重新读取,修正标题行号和上下文,然后重新生成补丁。如果短文件连续失败两次,请使用 write_file。 |
OutsideRoot | 路径超出配置的根目录 | 仅使用服务器启动时指定根目录下的路径 |
NotFound | 文件不存在 | 使用 write_file 创建文件,或使用 find 检查路径 |
ReadOnly | 服务器处于只读模式 | 禁止写入;只能执行读取操作和 shell_exec |
CommandNotAllowed | 命令不在白名单中 | 仅使用:grep sed awk find cat head tail wc sort uniq cut tr diff file stat ls du |
不要这样做
| 反模式 | 原因 | 应该这样做 |
|---|---|---|
cat /root/large_file.rs | 会返回数千个你大多用不上的 token | 用 grep -n 定位,再用 sed -n 截取;仅对少于 50 行的文件使用 cat -n |
对 500 行文件中的 3 行改动使用 write_file | 会上传整个文件,还可能因幻觉而破坏无关行 | 使用带有针对性代码块的 patch_apply |
在一次 shell_exec 中使用 Shell 管道(cmd1 | cmd2) | 没有 Shell 解释器——|、&&、$() 都是字面内容,不是运算符 | 分别调用 shell_exec,在你的逻辑中组合结果 |
find / -name "*.env" | 路径会根据根目录进行验证;此命令会被阻止,或返回无用结果 | 始终将 find 的范围限定在 /root/... |
| 发送上下文行不准确或行号错误的补丁 | 会导致 PatchFailed——上下文和 @@ -L,N @@ 都必须准确 | 先运行 grep -n 或 cat -n,再与实际内容进行比对 |
批量替换时,每个文件都单独运行一次 sed | 明明一次就能完成,却要调用 N 次工具 | 使用 find ["/root", "-name", "*.ext", "-exec", "sed", "-i", "", "s/x/y/g", "{}", "+"]——将所有文件合并到一次 sed 调用中 |
在 macOS 上不带 "" 使用 sed -i "s/x/y/" file | BSD sed 要求显式指定后缀参数——省略后会悄悄错误解析参数 | macOS:["-i", "", "s/x/y/g", "/abs/file"];Linux:["-i", "s/x/y/g", "/abs/file"] |
使用 -i.bak 或 -i'',而不是 ["-i", ""] | Chisel 能正确传递空字符串,无需变通 | 坚持使用 ["-i", ""] 两参数形式;不要自行发明替代形式 |
BSD sed 解析出错后,换一种 -i 形式重试 | 出错的是表达式或路径,而不是 -i "" 形式 | 修正 sed 表达式或路径;保持 ["-i", ""] 不变 |
小文件上的 patch_apply 连续失败两次后仍继续重试 | 浪费轮次;上下文偏移会使问题不断加重 | 用 cat -n 查看文件,再用 write_file 正确重写 |