mcp-read-file-server 1.3.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +37 -33
  2. package/SKILL.md +35 -12
  3. package/index.js +860 -107
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
 
9
9
  电脑安装了文件加密软件(如天锐绿盾、IP-Guard、亿赛通、深信服等),磁盘上的文件是密文。AI Agent(Claude Code、Cursor、Windsurf、Cline 等)是独立进程,内置文件工具不在白名单内,只能读到密文。而 Node.js 进程在白名单内,通过 MCP Server 提供的替代工具可以正常读写明文。
10
10
 
11
+
11
12
  **前提条件:Node.js 进程已被加密软件列为白名单(受信任进程)。**
12
13
 
13
14
  ## 支持的 AI Agent
@@ -38,8 +39,7 @@ mcp-read-file-server/
38
39
  ├── SKILL.md # 配套 Skill(可选,让 AI 学会自动选用本工具)
39
40
  ├── index.js # MCP Server 主程序(含 shebang,可作可执行入口)
40
41
  ├── package.json # 包配置(bin/files/依赖声明,可 npm publish)
41
- ├── smithery.yaml # Smithery 市场上架配置
42
- ├── .gitignore # Git 忽略规则
42
+ ├── .gitignore # Git 忽略规则
43
43
  └── node_modules/ # 依赖(@modelcontextprotocol/sdk、zod,不随包发布)
44
44
  ```
45
45
 
@@ -178,15 +178,20 @@ claude mcp list
178
178
 
179
179
  | 工具名 | 替代内置 | 功能 | 参数 |
180
180
  |--------|---------|------|------|
181
- | `read_file` | Read | 读取单个文件明文 | `path`: 文件路径 |
182
- | `read_files` | 多次 Read | 批量读取多个文件明文 | `paths`: 逗号分隔的路径 |
181
+ | `read_file` | Read | 读取单个文件明文(超大文件自动截断) | `path` |
182
+ | `read_files` | 多次 Read | 批量读取多个文件明文(数组或逗号分隔字符串) | `paths` |
183
183
  | `read_file_partial` | Read(局部) | 局部读取文件(前N字符 / 指定行范围) | `path`、`mode`、`charCount`、`startLine`、`endLine` |
184
- | `write_file` | Write | 写入文件(自动加密落盘) | `path`、`content` |
185
- | `edit_file` | Edit/MultiEdit | 精确字符串/正则替换后写回 | `path`、`oldString`、`newString`、`useRegex`、`replaceAll`、`ignoreCase` |
186
- | `search_files` | Grep | 递归搜索文件内容 | `pattern`、`path`、`include`、`ignoreCase`、`onlyMatching`、`maxResults` |
184
+ | `write_file` | Write | 写入文件(支持追加模式 / 行尾风格 / BOM 保留) | `path`、`content`、`mode`、`eol` |
185
+ | `edit_file` | Edit/MultiEdit | 精确替换后写回(CRLF/LF 自动兼容、BOM 保留、正则多行模式、`edits` 批量原子编辑、失败附相似行诊断) | `path`、`oldString`、`newString`、`edits`、`useRegex`、`replaceAll`、`ignoreCase` |
186
+ | `search_files` | Grep | 递归搜索文件内容(支持 `**` 目录通配、跳过二进制/超大文件) | `pattern`、`path`、`include`、`exclude`、`ignoreCase`、`onlyMatching`、`maxResults` |
187
+ | `find_files` | Glob | 按文件名 glob 递归查找(如 `**/*.test.js`) | `pattern`、`path`、`maxResults` |
188
+ | `list_directory` | LS | 列出目录内容(类型/大小/时间) | `path`、`showHidden` |
189
+ | `copy_path` | bash cp | 复制文件/目录(递归;加密环境必须经白名单进程) | `source`、`destination` |
190
+ | `move_path` | bash mv | 移动/重命名(跨盘符自动回退复制+删除) | `source`、`destination` |
191
+ | `remove_path` | bash rm | 删除文件/目录(默认递归,谨慎使用) | `path`、`recursive` |
187
192
  | `create_directory` | - | 递归创建目录 | `path` |
188
- | `file_info` | - | 查询文件/目录信息 | `path` |
189
- | `check_status` | - | 检查工具运行状态 | |
193
+ | `file_info` | - | 查询文件/目录信息(含明文大小、符号链接) | `path` |
194
+ | `check_status` | - | 检查运行状态(可实测解密能力) | `path`(可选) |
190
195
 
191
196
  ### `read_file_partial` 参数详解
192
197
 
@@ -206,6 +211,29 @@ claude mcp list
206
211
 
207
212
  > 返回内容会带文件名、读取范围、总字符数/总行数的头部信息,行模式下每行带行号前缀。超出文件范围时自动截断并提示。
208
213
 
214
+ ### `edit_file` 换行符自动兼容
215
+
216
+ Windows 下文件多为 CRLF 换行,而 AI Agent 生成的多行 `oldString` 通常是 LF 换行,字节级比对会直接失败(报"未找到匹配内容")。本工具已内置兼容逻辑:
217
+
218
+ - **匹配阶段**:先按字节原样精确匹配;未命中时自动将文件与 `oldString` 的换行符统一归一(`\r\n` / `\r` / `\n` 均视为换行)后再匹配,两种风格任意组合均可命中
219
+ - **写入阶段**:`newString` 的行尾会自动转换为文件本身的主导换行风格,不会把 CRLF 文件改写为 LF 混行
220
+ - **提示信息**:触发换行适配时,返回结果会附 `ℹ️ 换行符已自动适配` 说明,方便排查
221
+ - **BOM 自动处理**:UTF-8 BOM 读取时自动剥离、写回时自动补回,`oldString` 无需关心 BOM
222
+ - **正则模式默认多行**:`useRegex=true` 时自动附加 `m` 标志,`^xxx` / `xxx$` 按行锚定
223
+ - **批量原子编辑(edits 数组)**:一次调用完成多处修改,按序应用;**任一条目失败则整体不写盘**,不会产生「半改状态」。条目按文件现状顺序构造(前面条目的结果参与后续条目匹配)
224
+ - **失败附相似行诊断**:字符串匹配失败时返回「可能相关的行」及相似度,直接对照排查空白/缩进差异,无需盲目重试
225
+
226
+ 注意:该兼容仅针对换行符差异,空格、缩进等其他空白字符仍需与原文完全一致。含反引号 `` ` `` 与 `${}` 的内容直接原样传参(JSON 传输无 JS 模板字面量转义问题)。
227
+
228
+ ### 其他内置保护
229
+
230
+ - **预算读取(性能)**:`read_file` / `read_files` / `read_file_partial`(chars 模式) 只读取需要的字节数而非整个文件。读取 100MB 大文件的前 40 万字符从 ~160ms/100MB 内存降到 ~3ms/1.5MB 内存
231
+ - **编码防损坏**:UTF-16 文件(BOM/字节特征检测)直接拒绝读取并提示转换;疑似非 UTF-8(GBK 等,含大量乱码替换字符)的文件 `edit_file` 拒绝编辑写回,防止不可逆损坏
232
+ - **大文件截断**:`read_file` / `read_files` 单文件超过 40 万字符自动截断,提示改用 `read_file_partial` 分页读取,避免撑爆上下文
233
+ - **二进制/超大文件跳过**:`search_files` 只预读首 8KB 判定二进制(图片/exe 含 NUL 字节)后即跳过,超过 5MB 的文件也跳过,并在结果中说明跳过数量
234
+ - **隐藏文件默认跳过**:`search_files` / `find_files` 默认跳过 `.` 开头的文件与目录(避免把 `.env` 等敏感内容灌入上下文),忽略目录还包含 `node_modules`、`.git`、`target`、`build`、`dist`、`vendor` 等;`list_directory` 可用 `showHidden=true` 显示
235
+ - **glob 支持 `{a,b}` 花括号**:`find_files` / `search_files` 的 include 支持 `src/**/*.{ts,tsx}` 这类 Agent 高频写法
236
+
209
237
  ## 使用
210
238
 
211
239
  配置好后,在 Agent 中直接说需求即可。Agent 会自动调用 MCP 工具读写文件明文。
@@ -285,30 +313,6 @@ cp SKILL.md ~/.openclaw/skills/encryption-file-ops/SKILL.md
285
313
 
286
314
  > 若需离线使用或二次开发,再按「安装 -> 方式二」从源码克隆运行。
287
315
 
288
- ## 上架 MCP 市场
289
-
290
- 本包已具备 `npx` 直接运行能力,可上架到各 MCP 市场:
291
-
292
- | 市场 | 上架方式 |
293
- |------|---------|
294
- | npm | `npm publish`(包名 `mcp-read-file-server`,已配置 `bin` 与 `files`) |
295
- | Smithery | 在 https://smithery.ai 提交包名,仓库根已提供 `smithery.yaml`(上架前以官方文档核对) |
296
- | mcp.so | 在 https://mcp.so 提交 npm 包名与启动命令 `npx -y mcp-read-file-server` |
297
- | PulseMCP | 在 https://www.pulsemcp.com 提交包名 |
298
-
299
- 发布到 npm 前建议本地预检:
300
-
301
- ```bash
302
- # 预览将发布到 npm 的文件清单(应只有 index.js / README.md / SKILL.md / LICENSE / package.json)
303
- npm pack --dry-run
304
-
305
- # 登录并发布
306
- npm login
307
- npm publish
308
- ```
309
-
310
- 发布后,他人即可通过 `npx -y mcp-read-file-server` 一行命令运行,无需手动 `npm install`。
311
-
312
316
  ## 故障排查
313
317
 
314
318
  ### 读取到的仍是密文
package/SKILL.md CHANGED
@@ -32,11 +32,16 @@ description: 在文件加密软件(天锐绿盾 / IP-Guard / 亿赛通 / 深
32
32
  | 写文件 | `Write` | `mcp__read-file-server__write_file` |
33
33
  | 精确编辑 | `Edit` / `MultiEdit` | `mcp__read-file-server__edit_file` |
34
34
  | 搜索内容 | `Grep` | `mcp__read-file-server__search_files` |
35
+ | 按文件名查找 | `Glob` | `mcp__read-file-server__find_files` |
36
+ | 列目录内容 | `LS` | `mcp__read-file-server__list_directory` |
37
+ | 复制文件/目录 | `Bash cp` | `mcp__read-file-server__copy_path` |
38
+ | 移动/重命名 | `Bash mv` | `mcp__read-file-server__move_path` |
39
+ | 删除文件/目录 | `Bash rm` | `mcp__read-file-server__remove_path` |
35
40
  | 创建目录 | (无) | `mcp__read-file-server__create_directory` |
36
41
  | 查文件信息 | (无) | `mcp__read-file-server__file_info` |
37
42
  | 健康检查 | (无) | `mcp__read-file-server__check_status` |
38
43
 
39
- > **强约束**:在加密环境下,**禁止使用** `Read/Write/Edit/MultiEdit/Grep` 内置工具--它们会读到密文或破坏加密结构。
44
+ > **强约束**:在加密环境下,**禁止使用** `Read/Write/Edit/MultiEdit/Grep/Glob/LS` 内置工具与 `Bash` 的 `cp/mv/rm` 文件操作--它们会读到密文、写出密文或破坏加密结构。
40
45
 
41
46
  ---
42
47
 
@@ -80,8 +85,10 @@ description: 在文件加密软件(天锐绿盾 / IP-Guard / 亿赛通 / 深
80
85
  ```
81
86
  1. mcp__read-file-server__read_file 读取明文
82
87
  2. 分析内容
83
- 3. mcp__read-file-server__edit_file 修改
84
- - oldString 必须从第 1 步读到的内容里**原样复制**(含空格、缩进、换行)
88
+ 3. 修改:
89
+ - 单处修改 -> mcp__read-file-server__edit_file(oldString/newString)
90
+ - 多处修改 -> mcp__read-file-server__edit_file 的 edits 数组(原子:失败整体不写盘)
91
+ - oldString 从第 1 步读到的内容里**原样复制**(含空格、缩进;换行风格差异会自动兼容)
85
92
  4. 必要时再 read_file 验证修改结果
86
93
  ```
87
94
 
@@ -115,28 +122,40 @@ description: 在文件加密软件(天锐绿盾 / IP-Guard / 亿赛通 / 深
115
122
  | 参数 | 类型 | 必填 | 默认 | 说明 |
116
123
  |------|------|------|------|------|
117
124
  | `path` | string | ✅ | - | 文件绝对路径 |
118
- | `oldString` | string | | - | 要替换的原内容,必须**精确匹配** |
119
- | `newString` | string | | - | 替换后的新内容 |
120
- | `useRegex` | boolean | | false | true 时 oldString 当正则,可用 `$1 $2` 引用捕获组 |
125
+ | `oldString` | string | 单次模式✅ | - | 要替换的原内容,必须**精确匹配**(换行风格差异已自动兼容) |
126
+ | `newString` | string | 单次模式✅ | - | 替换后的新内容 |
127
+ | `edits` | array | 批量模式✅ | - | 批量原子编辑:`[{oldString, newString, replaceAll?}]` 按序应用,**任一条目失败则整体不写盘**(不会产生半改状态)。一次完成多处修改必须用它,不要逐条调用 |
128
+ | `useRegex` | boolean | ❌ | false | true 时 oldString 当正则(单次模式),可用 `$1 $2` 引用捕获组;默认启用多行模式(`^`/`$` 按行锚定) |
121
129
  | `replaceAll` | boolean | ❌ | false | true 时替换所有匹配项;false 时仅替换第一处 |
122
130
  | `ignoreCase` | boolean | ❌ | false | 是否忽略大小写(仅字符串模式生效) |
123
131
 
124
132
  ### 常见用法
125
133
  - **单点替换**:`useRegex=false, replaceAll=false`(默认)
126
134
  - **批量替换**:`useRegex=true, replaceAll=true`(如改命名)
135
+ - **多处修改**:`edits` 数组(如重命名+改值+删行一次完成,失败自动整体回滚)
127
136
  - **正则提取后重组**:`useRegex=true, newString` 里用 `$1` `$2`
128
137
 
138
+ ### 实战避坑(来自真实使用反馈)
139
+
140
+ 1. **换行差异已自动兼容,无需关心 CRLF/LF**:oldString 用 LF 匹配 CRLF 文件(或相反)均可命中,newString 行尾自动跟随文件风格。**不要**再为此绕道写 Node 补丁脚本手工归一
141
+ 2. **oldString 含反引号 `` ` `` 与 `${}` 直接原样传入**:MCP 参数走 JSON 传输,无 JS 模板字面量的转义层级问题;同样不要绕道脚本(脚本里转义极易写错)
142
+ 3. **多处修改必须用 `edits` 批量模式**:逐条调用时若中途失败,前面条目已写盘会产生「半改状态」,后续按原内容构造的 oldString 必然失配;`edits` 原子模式要么全成要么不动。**批量条目按序应用**:前面条目的 newString 会成为后续条目的匹配环境,请按文件现状顺序构造(如 A 改为 B 后,后条可用 B 做锚点)
143
+ 4. **oldString 带足上下文保证唯一**:短 oldString 命中多处时工具会警告(如 `替换 1/2 处`),此时加长上下文(含前后行)唯一定位;超长行(如记忆表格行)优先选行内独有片段做锚点
144
+ 5. **匹配失败看诊断**:失败信息会附「可能相关的行」及相似度,直接对照检查空白/缩进/字符差异,不要盲目重试;正则模式报错时注意 oldString 正则里 `$` 需写成 `\$`(如匹配字面 `$1`),而 newString 里的 `$1` 是捕获组引用原样保留
145
+
129
146
  ---
130
147
 
131
148
  ## 六、注意事项
132
149
 
133
150
  1. **路径**:用**绝对路径**最稳(如 `D:/AiJiamiToolsPlugins/...`),相对路径以 MCP Server 启动目录为基准
134
151
  2. **`edit_file` 前必读**:必须先 `read_file` 拿到明文,再从原文里**原样复制** `oldString`,否则会因为空格/缩进不匹配而失败
135
- 3. **不要在 `oldString` 里漏换行**:多行替换时,行末换行符也要复制完整
152
+ 3. **换行风格无需担心**:文件是 CRLF 而 `oldString` 是 LF(或相反)时,`edit_file` 会自动归一换行后匹配;`newString` 行尾也会自动跟随文件主导风格,不会产生混行
136
153
  4. **`write_file` 是覆盖写**:会清空原文件再写入,重要文件修改前建议先 `read_file` 备份内容
137
- 5. **`search_files` 自动跳过**:`node_modules`、`.git`、`target`、`build`、`dist`、`.idea`、`.vscode`
154
+ 5. **`search_files` / `find_files` 自动跳过**:`node_modules`、`.git`、`target`、`build`、`dist`、`.svn`、`bin`、`obj`、`out`、`vendor` 与 `.` 开头的隐藏文件/目录;`search_files` 另跳过二进制与超过 5MB 的文件
138
155
  6. **大批量搜索**:用 `maxResults` 控制返回数量,避免一次性返回过多结果
139
- 7. **工具调用顺序**:复杂任务先 `check_status` 确认 MCP 正常,再正式操作
156
+ 7. **工具调用顺序**:复杂任务先 `check_status`(可传 path 实测解密)确认 MCP 正常,再正式操作
157
+ 8. **`remove_path` 不可恢复**:递归删除前建议先 `list_directory` 确认内容
158
+ 9. **`read_files` 路径含逗号时必须传数组**:Windows 路径可合法包含英文逗号,逗号分隔字符串形式会被错误切分
140
159
 
141
160
  ---
142
161
 
@@ -146,7 +165,11 @@ description: 在文件加密软件(天锐绿盾 / IP-Guard / 亿赛通 / 深
146
165
  |------|----------|----------|
147
166
  | 读到的还是密文/乱码 | Node.js 不在加密软件白名单 | 联系管理员把 `node.exe` 加入白名单 |
148
167
  | `mcp__read-file-server__*` 工具全部不可见 | MCP Server 未配置或未启动 | 见 `README.md` 配置 `.mcp.json` |
149
- | `edit_file` 报"未找到匹配内容" | `oldString` 拼写、缩进、换行不对 | 重新 `read_file` 复制原文,**不要凭记忆写** |
168
+ | `edit_file` 报"未找到匹配内容" | `oldString` 拼写、缩进不对(换行 CRLF/LF 差异与 BOM 已自动兼容) | 重新 `read_file` 复制原文,**不要凭记忆写**;重点检查空格与缩进 |
169
+ | 读取被拒:文件疑似 UTF-16 | 工具仅支持 UTF-8 | 先转换为 UTF-8 再操作(防乱码与写回损坏) |
170
+ | `edit_file` 拒绝编辑:疑似非 UTF-8(GBK 等) | 按 UTF-8 读出大量乱码替换字符 | 继续写回会不可逆损坏文件;先转码再编辑 |
171
+ | 大文件读取不完整 | 超过 40 万字符自动截断 | 用 `read_file_partial` 分页读取 |
172
+ | `search_files` 搜不到某些文件 | 二进制/超大(>5MB)文件被跳过,或隐藏文件/忽略目录被排除 | 看返回尾部的跳过统计;必要时用 `include` 限定范围 |
150
173
  | `edit_file` 报"匹配到 N 处" | 文件中存在重复内容 | 加更长/更唯一的 `oldString` 唯一定位,或 `replaceAll=true` |
151
174
  | `search_files` 报"正则表达式无效" | 正则语法错误 | 检查 `pattern` 是否需要转义特殊字符 |
152
175
  | `write_file` 报权限错误 | 文件被占用或目录无写权限 | 关闭占用进程 / 检查目录权限 |
@@ -158,8 +181,8 @@ description: 在文件加密软件(天锐绿盾 / IP-Guard / 亿赛通 / 深
158
181
 
159
182
  | 工具类型 | 在加密环境下 | 备注 |
160
183
  |----------|--------------|------|
161
- | 内置 `Read/Write/Edit/Grep` | ❌ 禁用 | 会读到密文或破坏加密 |
162
- | 内置 `Bash` | ⚠️ 慎用 | Bash 进程通常不在白名单,`cat`/`sed` 也会读到密文 |
184
+ | 内置 `Read/Write/Edit/Grep/Glob/LS` | ❌ 禁用 | 会读到密文或破坏加密 |
185
+ | 内置 `Bash` | ⚠️ 慎用 | Bash 进程通常不在白名单,`cat`/`sed`/`cp`/`mv`/`rm` 也会读到密文或产出密文文件;文件操作一律改用 MCP 工具 |
163
186
  | 内置 `Glob` | ✅ 可用 | 只列文件名,不读内容 |
164
187
  | 内置 `NotebookEdit` | ⚠️ 慎用 | 同 Edit |
165
188
  | `mcp__read-file-server__*` | ✅ 主用 | 本 Skill 推广的工具集 |