@j0hanz/filesystem-mcp 1.13.2 → 1.14.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 (43) hide show
  1. package/README.md +117 -100
  2. package/dist/config.d.ts +0 -1
  3. package/dist/lib/errors.js +5 -2
  4. package/dist/lib/file-operations/metadata.js +9 -3
  5. package/dist/lib/file-operations/search.d.ts +0 -1
  6. package/dist/lib/file-operations/search.js +5 -12
  7. package/dist/lib/fs-helpers.js +10 -11
  8. package/dist/lib/globs.d.ts +2 -0
  9. package/dist/lib/globs.js +19 -0
  10. package/dist/lib/zod-codecs.d.ts +2 -0
  11. package/dist/lib/zod-codecs.js +18 -0
  12. package/dist/pkg-info.d.ts +1 -0
  13. package/dist/pkg-info.js +2 -2
  14. package/dist/prompts.js +3 -3
  15. package/dist/resources/generated-instructions.js +3 -12
  16. package/dist/resources/tool-catalog.js +10 -41
  17. package/dist/resources/tool-info.d.ts +0 -1
  18. package/dist/resources/tool-info.js +11 -39
  19. package/dist/resources/workflows.js +8 -1
  20. package/dist/schemas.d.ts +179 -459
  21. package/dist/schemas.js +156 -165
  22. package/dist/server/roots-manager.js +1 -1
  23. package/dist/tools/apply-patch.js +19 -8
  24. package/dist/tools/calculate-hash.js +3 -5
  25. package/dist/tools/create-directory.js +1 -1
  26. package/dist/tools/delete-file.js +2 -4
  27. package/dist/tools/diff-files.js +1 -3
  28. package/dist/tools/edit-file.js +5 -2
  29. package/dist/tools/list-directory.js +10 -15
  30. package/dist/tools/move-file.js +14 -26
  31. package/dist/tools/read-multiple.js +12 -7
  32. package/dist/tools/read.js +1 -2
  33. package/dist/tools/replace-in-files.js +58 -94
  34. package/dist/tools/roots.js +2 -6
  35. package/dist/tools/search-content.js +150 -186
  36. package/dist/tools/search-files.js +5 -9
  37. package/dist/tools/shared.d.ts +7 -0
  38. package/dist/tools/shared.js +38 -11
  39. package/dist/tools/stat-many.js +6 -4
  40. package/dist/tools/stat.js +2 -2
  41. package/dist/tools/tree.js +1 -1
  42. package/dist/tools/write-file.js +1 -5
  43. package/package.json +2 -1
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/%40j0hanz%2Ffilesystem-mcp?style=flat-square&logo=npm)](https://www.npmjs.com/package/%40j0hanz%2Ffilesystem-mcp) [![License: MIT](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](#contributing-and-license)
4
4
 
5
- [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem-mcp&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D) [![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem-mcp&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D&quality=insiders) [![Install in Visual Studio](https://img.shields.io/badge/Visual_Studio-Install_Server-C16FDE?logo=visualstudio&logoColor=white)](https://vs-open.link/mcp-install?%7B%22filesystem-mcp%22%3A%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D%7D)
5
+ [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D) [![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D&quality=insiders) [![Install in Visual Studio](https://img.shields.io/badge/Visual_Studio-Install_Server-C16FDE?logo=visualstudio&logoColor=white)](https://vs-open.link/mcp-install?%7B%22filesystem-mcp%22%3A%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D%7D)
6
6
 
7
- [![Add to LM Studio](https://files.lmstudio.ai/deeplink/mcp-install-light.svg)](https://lmstudio.ai/install-mcp?name=filesystem-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19) [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=filesystem-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19) [![Install in Goose](https://block.github.io/goose/img/extension-install-dark.svg)](https://block.github.io/goose/extension?cmd=npx&arg=-y&arg=%40j0hanz%2Ffilesystem-mcp%40latest&id=%40j0hanz%2Ffilesystem-mcp&name=filesystem-mcp&description=MCP%20Server%20that%20enables%20LLMs%20to%20interact%20with%20the%20local%20filesystem.)
7
+ [![Add to LM Studio](https://files.lmstudio.ai/deeplink/mcp-install-light.svg)](https://lmstudio.ai/install-mcp?name=filesystem&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19) [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=filesystem&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19) [![Install in Goose](https://block.github.io/goose/img/extension-install-dark.svg)](https://block.github.io/goose/extension?cmd=npx&arg=-y&arg=%40j0hanz%2Ffilesystem-mcp%40latest&id=%40j0hanz%2Ffilesystem-mcp&name=filesystem&description=MCP%20Server%20that%20enables%20LLMs%20to%20interact%20with%20the%20local%20filesystem.)
8
8
 
9
9
  A local filesystem MCP server that lets LLMs and AI agents read, write, search, diff, patch, and manage files safely and efficiently. Built for reliable, structured, and controlled filesystem interaction.
10
10
 
@@ -12,7 +12,7 @@ A local filesystem MCP server that lets LLMs and AI agents read, write, search,
12
12
 
13
13
  A secure, production-ready [Model Context Protocol](https://modelcontextprotocol.io) server that gives AI assistants controlled access to the local filesystem. All operations are sandboxed to explicitly allowed directories with path traversal prevention, sensitive file blocking, and optional Bearer token authentication.
14
14
 
15
- Supports **stdio** (default) and **Streamable HTTP + SSE** transports with per-session isolation.
15
+ Supports stdio (default) and Streamable HTTP transport with SSE support. HTTP sessions are implemented with isolated per-session server state.
16
16
 
17
17
  ## Key Features
18
18
 
@@ -20,7 +20,7 @@ Supports **stdio** (default) and **Streamable HTTP + SSE** transports with per-s
20
20
  - **Security-first** — path validation, symlink escape prevention, sensitive file denylist, localhost-only CORS, optional API key auth
21
21
  - **Dual transport** — stdio for local use, Streamable HTTP with SSE for networked/multi-session deployments
22
22
  - **Structured output** — all tools return typed `outputSchema` / `structuredContent` for reliable LLM parsing
23
- - **Self-documenting** — 6 built-in resources (`internal://instructions`, `internal://tool-catalog`, etc.) and a `get-help` prompt
23
+ - **Self-documenting** — 6 built-in resources (`internal://instructions`, `internal://tool-catalog`, etc.) and 4 built-in prompts (`get-help`, `compare-files`, `analyze-path`, `get-tool-help`)
24
24
 
25
25
  ## Requirements
26
26
 
@@ -31,7 +31,7 @@ Supports **stdio** (default) and **Streamable HTTP + SSE** transports with per-s
31
31
  ```json
32
32
  {
33
33
  "mcpServers": {
34
- "filesystem-mcp": {
34
+ "filesystem": {
35
35
  "command": "npx",
36
36
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
37
37
  }
@@ -82,14 +82,14 @@ Examples:
82
82
  <details>
83
83
  <summary><b>Install in VS Code</b></summary>
84
84
 
85
- [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem-mcp&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D)
85
+ [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D)
86
86
 
87
87
  Add to `.vscode/mcp.json`:
88
88
 
89
89
  ```json
90
90
  {
91
91
  "servers": {
92
- "filesystem-mcp": {
92
+ "filesystem": {
93
93
  "command": "npx",
94
94
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
95
95
  }
@@ -100,7 +100,7 @@ Add to `.vscode/mcp.json`:
100
100
  Or install via CLI:
101
101
 
102
102
  ```sh
103
- code --add-mcp '{"name":"filesystem-mcp","command":"npx","args":["-y","@j0hanz/filesystem-mcp@latest"]}'
103
+ code --add-mcp '{"name":"filesystem","command":"npx","args":["-y","@j0hanz/filesystem-mcp@latest"]}'
104
104
  ```
105
105
 
106
106
  </details>
@@ -108,14 +108,14 @@ code --add-mcp '{"name":"filesystem-mcp","command":"npx","args":["-y","@j0hanz/f
108
108
  <details>
109
109
  <summary><b>Install in VS Code Insiders</b></summary>
110
110
 
111
- [![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem-mcp&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D&quality=insiders)
111
+ [![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D&quality=insiders)
112
112
 
113
113
  Add to `.vscode/mcp.json`:
114
114
 
115
115
  ```json
116
116
  {
117
117
  "servers": {
118
- "filesystem-mcp": {
118
+ "filesystem": {
119
119
  "command": "npx",
120
120
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
121
121
  }
@@ -126,7 +126,7 @@ Add to `.vscode/mcp.json`:
126
126
  Or install via CLI:
127
127
 
128
128
  ```sh
129
- code-insiders --add-mcp '{"name":"filesystem-mcp","command":"npx","args":["-y","@j0hanz/filesystem-mcp@latest"]}'
129
+ code-insiders --add-mcp '{"name":"filesystem","command":"npx","args":["-y","@j0hanz/filesystem-mcp@latest"]}'
130
130
  ```
131
131
 
132
132
  </details>
@@ -134,14 +134,14 @@ code-insiders --add-mcp '{"name":"filesystem-mcp","command":"npx","args":["-y","
134
134
  <details>
135
135
  <summary><b>Install in Cursor</b></summary>
136
136
 
137
- [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=filesystem-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19)
137
+ [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=filesystem&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19)
138
138
 
139
139
  Add to `~/.cursor/mcp.json`:
140
140
 
141
141
  ```json
142
142
  {
143
143
  "mcpServers": {
144
- "filesystem-mcp": {
144
+ "filesystem": {
145
145
  "command": "npx",
146
146
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
147
147
  }
@@ -156,10 +156,12 @@ Add to `~/.cursor/mcp.json`:
156
156
 
157
157
  [![Install in Visual Studio](https://img.shields.io/badge/Visual_Studio-Install_Server-C16FDE?logo=visualstudio&logoColor=white)](https://vs-open.link/mcp-install?%7B%22filesystem-mcp%22%3A%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D%7D)
158
158
 
159
+ Add to `<SOLUTIONDIR>.mcp.json` or `%USERPROFILE%\.mcp.json`:
160
+
159
161
  ```json
160
162
  {
161
- "mcpServers": {
162
- "filesystem-mcp": {
163
+ "servers": {
164
+ "filesystem": {
163
165
  "command": "npx",
164
166
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
165
167
  }
@@ -172,17 +174,20 @@ Add to `~/.cursor/mcp.json`:
172
174
  <details>
173
175
  <summary><b>Install in Goose</b></summary>
174
176
 
175
- [![Install in Goose](https://block.github.io/goose/img/extension-install-dark.svg)](https://block.github.io/goose/extension?cmd=npx&arg=-y&arg=%40j0hanz%2Ffilesystem-mcp%40latest&id=%40j0hanz%2Ffilesystem-mcp&name=filesystem-mcp&description=MCP%20Server%20that%20enables%20LLMs%20to%20interact%20with%20the%20local%20filesystem.)
177
+ [![Install in Goose](https://block.github.io/goose/img/extension-install-dark.svg)](https://block.github.io/goose/extension?cmd=npx&arg=-y&arg=%40j0hanz%2Ffilesystem-mcp%40latest&id=%40j0hanz%2Ffilesystem-mcp&name=filesystem&description=MCP%20Server%20that%20enables%20LLMs%20to%20interact%20with%20the%20local%20filesystem.)
176
178
 
177
- ```json
178
- {
179
- "mcpServers": {
180
- "filesystem-mcp": {
181
- "command": "npx",
182
- "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
183
- }
184
- }
185
- }
179
+ Add to `~/.config/goose/config.yaml`:
180
+
181
+ ```yaml
182
+ extensions:
183
+ filesystem:
184
+ name: Filesystem MCP
185
+ cmd: npx
186
+ args:
187
+ - -y
188
+ - '@j0hanz/filesystem-mcp@latest'
189
+ enabled: true
190
+ type: stdio
186
191
  ```
187
192
 
188
193
  </details>
@@ -190,12 +195,12 @@ Add to `~/.cursor/mcp.json`:
190
195
  <details>
191
196
  <summary><b>Add to LM Studio</b></summary>
192
197
 
193
- [![Add to LM Studio](https://files.lmstudio.ai/deeplink/mcp-install-light.svg)](https://lmstudio.ai/install-mcp?name=filesystem-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19)
198
+ [![Add to LM Studio](https://files.lmstudio.ai/deeplink/mcp-install-light.svg)](https://lmstudio.ai/install-mcp?name=filesystem&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19)
194
199
 
195
200
  ```json
196
201
  {
197
202
  "mcpServers": {
198
- "filesystem-mcp": {
203
+ "filesystem": {
199
204
  "command": "npx",
200
205
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
201
206
  }
@@ -213,7 +218,7 @@ Add to `claude_desktop_config.json`:
213
218
  ```json
214
219
  {
215
220
  "mcpServers": {
216
- "filesystem-mcp": {
221
+ "filesystem": {
217
222
  "command": "npx",
218
223
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
219
224
  }
@@ -230,12 +235,12 @@ Add to `claude_desktop_config.json`:
230
235
  claude mcp add filesystem-mcp -- npx -y @j0hanz/filesystem-mcp@latest
231
236
  ```
232
237
 
233
- Or add to config:
238
+ Or add a project-scoped `.mcp.json`:
234
239
 
235
240
  ```json
236
241
  {
237
242
  "mcpServers": {
238
- "filesystem-mcp": {
243
+ "filesystem": {
239
244
  "command": "npx",
240
245
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
241
246
  }
@@ -253,7 +258,7 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
253
258
  ```json
254
259
  {
255
260
  "mcpServers": {
256
- "filesystem-mcp": {
261
+ "filesystem": {
257
262
  "command": "npx",
258
263
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
259
264
  }
@@ -270,12 +275,12 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
270
275
  amp mcp add filesystem-mcp -- npx -y @j0hanz/filesystem-mcp@latest
271
276
  ```
272
277
 
273
- Or add to config:
278
+ Or add to `settings.json`:
274
279
 
275
280
  ```json
276
281
  {
277
- "mcpServers": {
278
- "filesystem-mcp": {
282
+ "amp.mcpServers": {
283
+ "filesystem": {
279
284
  "command": "npx",
280
285
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
281
286
  }
@@ -293,7 +298,7 @@ Add to `cline_mcp_settings.json`:
293
298
  ```json
294
299
  {
295
300
  "mcpServers": {
296
- "filesystem-mcp": {
301
+ "filesystem": {
297
302
  "command": "npx",
298
303
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
299
304
  }
@@ -304,32 +309,35 @@ Add to `cline_mcp_settings.json`:
304
309
  </details>
305
310
 
306
311
  <details>
307
- <summary><b>Install in Codex CLI</b></summary>
312
+ <summary><b>Install in Codex</b></summary>
308
313
 
309
- ```json
310
- {
311
- "mcpServers": {
312
- "filesystem-mcp": {
313
- "command": "npx",
314
- "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
315
- }
316
- }
317
- }
314
+ ```sh
315
+ codex mcp add filesystem -- npx -y @j0hanz/filesystem-mcp@latest
316
+ ```
317
+
318
+ Or add to `~/.codex/config.toml` (or `.codex/config.toml` in a trusted project):
319
+
320
+ ```toml
321
+ [mcp_servers.filesystem]
322
+ command = "npx"
323
+ args = ["-y", "@j0hanz/filesystem-mcp@latest"]
318
324
  ```
319
325
 
320
326
  </details>
321
327
 
322
328
  <details>
323
- <summary><b>Install in GitHub Copilot</b></summary>
329
+ <summary><b>Install in GitHub Copilot Coding Agent</b></summary>
324
330
 
325
- Add to `.vscode/mcp.json`:
331
+ Add this JSON in your repository's GitHub Copilot coding agent MCP configuration:
326
332
 
327
333
  ```json
328
334
  {
329
- "servers": {
330
- "filesystem-mcp": {
335
+ "mcpServers": {
336
+ "filesystem": {
337
+ "type": "local",
331
338
  "command": "npx",
332
- "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
339
+ "args": ["-y", "@j0hanz/filesystem-mcp@latest"],
340
+ "tools": ["*"]
333
341
  }
334
342
  }
335
343
  }
@@ -343,7 +351,7 @@ Add to `.vscode/mcp.json`:
343
351
  ```json
344
352
  {
345
353
  "mcpServers": {
346
- "filesystem-mcp": {
354
+ "filesystem": {
347
355
  "command": "npx",
348
356
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
349
357
  }
@@ -361,7 +369,7 @@ Add to `.kiro/settings/mcp.json`:
361
369
  ```json
362
370
  {
363
371
  "mcpServers": {
364
- "filesystem-mcp": {
372
+ "filesystem": {
365
373
  "command": "npx",
366
374
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
367
375
  }
@@ -379,7 +387,7 @@ Add to `~/.gemini/settings.json`:
379
387
  ```json
380
388
  {
381
389
  "mcpServers": {
382
- "filesystem-mcp": {
390
+ "filesystem": {
383
391
  "command": "npx",
384
392
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
385
393
  }
@@ -397,11 +405,10 @@ Add to `~/.config/zed/settings.json`:
397
405
  ```json
398
406
  {
399
407
  "context_servers": {
400
- "filesystem-mcp": {
401
- "settings": {
402
- "command": "npx",
403
- "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
404
- }
408
+ "filesystem": {
409
+ "command": "npx",
410
+ "args": ["-y", "@j0hanz/filesystem-mcp@latest"],
411
+ "env": {}
405
412
  }
406
413
  }
407
414
  }
@@ -419,7 +426,7 @@ Add to VS Code `settings.json` under `augment.advanced`:
419
426
  "augment.advanced": {
420
427
  "mcpServers": [
421
428
  {
422
- "id": "filesystem-mcp",
429
+ "id": "filesystem",
423
430
  "command": "npx",
424
431
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
425
432
  }
@@ -436,7 +443,7 @@ Add to VS Code `settings.json` under `augment.advanced`:
436
443
  ```json
437
444
  {
438
445
  "mcpServers": {
439
- "filesystem-mcp": {
446
+ "filesystem": {
440
447
  "command": "npx",
441
448
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
442
449
  }
@@ -452,7 +459,7 @@ Add to VS Code `settings.json` under `augment.advanced`:
452
459
  ```json
453
460
  {
454
461
  "mcpServers": {
455
- "filesystem-mcp": {
462
+ "filesystem": {
456
463
  "command": "npx",
457
464
  "args": ["-y", "@j0hanz/filesystem-mcp@latest"]
458
465
  }
@@ -536,6 +543,9 @@ Create directories, move/rename files, delete files, and verify file integrity v
536
543
  |
537
544
  +-- prompts/get ─────────────────────────────────────────
538
545
  | +-- get-help (optional topic argument)
546
+ | +-- compare-files (original, modified)
547
+ | +-- analyze-path (path)
548
+ | +-- get-tool-help (name)
539
549
  |
540
550
  +-- Capabilities: logging, resources, tools, prompts, completions, tasks
541
551
  ```
@@ -602,26 +612,29 @@ Find files by glob pattern. Returns matching files with metadata.
602
612
 
603
613
  Render a directory tree with bounded recursion. Returns ASCII tree + structured JSON.
604
614
 
605
- | Parameter | Type | Required | Description |
606
- | ---------------- | ------- | -------- | ------------------------------------------------- |
607
- | `path` | string | no | Base directory (default: root) |
608
- | `maxDepth` | integer | no | Depth (0 = root node only). Default: 10, Max: 100 |
609
- | `maxEntries` | integer | no | Max entries. Default: 5000, Max: 100000 |
610
- | `includeHidden` | boolean | no | Include dotfiles. Default: `false` |
611
- | `includeIgnored` | boolean | no | Include ignored items. Default: `false` |
615
+ | Parameter | Type | Required | Description |
616
+ | ---------------- | ------- | -------- | ---------------------------------------------------- |
617
+ | `path` | string | no | Base directory (default: root) |
618
+ | `maxDepth` | integer | no | Depth (0 = root node only). Default: 10, Max: 100 |
619
+ | `maxEntries` | integer | no | Max entries. Default: 5000, Max: 100000 |
620
+ | `includeHidden` | boolean | no | Include dotfiles. Default: `false` |
621
+ | `includeIgnored` | boolean | no | Include ignored items. Default: `false` |
622
+ | `includeSizes` | boolean | no | Include file sizes in tree entries. Default: `false` |
612
623
 
613
624
  ---
614
625
 
615
626
  #### `read`
616
627
 
617
- Read text file contents. Use `head` to preview first N lines of large files.
628
+ Read text file contents. Use `head`/`tail` to preview first/last N lines of large files.
618
629
 
619
- | Parameter | Type | Required | Description |
620
- | ----------- | ------- | -------- | --------------------------------------------------- |
621
- | `path` | string | **yes** | Absolute path to file |
622
- | `head` | integer | no | Read first N lines (1-100000) |
623
- | `startLine` | integer | no | Start line (1-based, inclusive) |
624
- | `endLine` | integer | no | End line (1-based, inclusive). Requires `startLine` |
630
+ | Parameter | Type | Required | Description |
631
+ | ------------- | ------- | -------- | ----------------------------------------------------------- |
632
+ | `path` | string | **yes** | Absolute path to file |
633
+ | `head` | integer | no | Read first N lines (1-100000) |
634
+ | `tail` | integer | no | Read last N lines (1-100000) |
635
+ | `startLine` | integer | no | Start line (1-based, inclusive) |
636
+ | `endLine` | integer | no | End line (1-based, inclusive). Requires `startLine` |
637
+ | `includeHash` | boolean | no | Include SHA-256 hash of full file content. Default: `false` |
625
638
 
626
639
  ---
627
640
 
@@ -633,6 +646,7 @@ Read multiple text files in one request.
633
646
  | ----------- | -------- | -------- | ------------------------------- |
634
647
  | `paths` | string[] | **yes** | Files to read (1-100 paths) |
635
648
  | `head` | integer | no | Read first N lines of each file |
649
+ | `tail` | integer | no | Read last N lines of each file |
636
650
  | `startLine` | integer | no | Start line (1-based) per file |
637
651
  | `endLine` | integer | no | End line (1-based) per file |
638
652
 
@@ -789,23 +803,28 @@ Bulk search-and-replace across files matching a glob. Replaces **all** occurrenc
789
803
  | `includeHidden` | boolean | no | Include dotfiles. Default: `false` |
790
804
  | `includeIgnored` | boolean | no | Include ignored items. Default: `false` |
791
805
  | `returnDiff` | boolean | no | Return diff even when not dry-run. Default: `false` |
806
+ | `maxFiles` | integer | no | Max files to process before stopping (1-10000) |
807
+ | `caseSensitive` | boolean | no | Case-sensitive matching. Default: `true` |
792
808
 
793
809
  ### Resources
794
810
 
795
- | Resource | URI | MIME Type | Description |
796
- | ------------ | ------------------------------ | ------------- | ------------------------------------------------------------------ |
797
- | Instructions | `internal://instructions` | text/markdown | Comprehensive usage rules and guidelines |
798
- | Tool Catalog | `internal://tool-catalog` | text/markdown | Tool selection guide and data flow map |
799
- | Workflows | `internal://workflows` | text/markdown | Standard operating procedures for exploration, search, edit, patch |
800
- | Tool Info | `internal://tool-info/{name}` | text/markdown | Per-tool contract details, nuances, gotchas |
801
- | Result Cache | `filesystem-mcp://result/{id}` | text/markdown | Ephemeral cached tool output (large results externalized here) |
802
- | Metrics | `filesystem-mcp://metrics` | text/markdown | Live per-tool call/error/avgDurationMs snapshot |
811
+ | Resource | URI | MIME Type | Description |
812
+ | ------------ | ------------------------------ | ---------------- | ------------------------------------------------------------------ |
813
+ | Instructions | `internal://instructions` | text/markdown | Comprehensive usage rules and guidelines |
814
+ | Tool Catalog | `internal://tool-catalog` | text/markdown | Tool selection guide and data flow map |
815
+ | Workflows | `internal://workflows` | text/markdown | Standard operating procedures for exploration, search, edit, patch |
816
+ | Tool Info | `internal://tool-info/{name}` | text/markdown | Per-tool contract details, nuances, gotchas |
817
+ | Result Cache | `filesystem-mcp://result/{id}` | text/plain | Ephemeral cached tool output (large results externalized here) |
818
+ | Metrics | `filesystem-mcp://metrics` | application/json | Live per-tool call/error/avgDurationMs snapshot |
803
819
 
804
820
  ### Prompts
805
821
 
806
- | Prompt | Arguments | Description |
807
- | ---------- | ------------------ | ---------------------------------------------------------------------- |
808
- | `get-help` | `topic` (optional) | Return usage instructions. Optionally filter by section heading prefix |
822
+ | Prompt | Arguments | Description |
823
+ | --------------- | ---------------------- | ---------------------------------------------------------------------- |
824
+ | `get-help` | `topic` (optional) | Return usage instructions. Optionally filter by section heading prefix |
825
+ | `compare-files` | `original`, `modified` | Generate a workflow for comparing two files using `diff_files` |
826
+ | `analyze-path` | `path` | Generate a workflow for analyzing a file or directory |
827
+ | `get-tool-help` | `name` | Return a prompt with the authoritative contract for a specific tool |
809
828
 
810
829
  ## MCP Capabilities
811
830
 
@@ -814,8 +833,8 @@ Bulk search-and-replace across files matching a glob. Replaces **all** occurrenc
814
833
  | `logging` | confirmed | `src/server/bootstrap.ts` — registered in capabilities |
815
834
  | `resources` | confirmed | `src/server/bootstrap.ts` — 6 resources registered |
816
835
  | `tools` | confirmed | `src/server/bootstrap.ts` — 18 tools registered |
817
- | `prompts` | confirmed | `src/server/bootstrap.ts` — `get-help` prompt registered |
818
- | `completions` | confirmed | `src/completions.ts` — path + topic auto-completion |
836
+ | `prompts` | confirmed | `src/server/bootstrap.ts` — 4 prompts registered |
837
+ | `completions` | confirmed | `src/completions.ts` — path, topic, and tool-name auto-completion |
819
838
  | `tasks` | confirmed | `src/server/bootstrap.ts` — optional task support (list, cancel, requests) |
820
839
 
821
840
  ### Tool Annotations
@@ -881,18 +900,16 @@ When started with `--port <number>`, the server exposes a single MCP endpoint:
881
900
 
882
901
  ## Development
883
902
 
884
- | Script | Command | Purpose |
885
- | ------------ | --------------------------------------------------------- | --------------------------------- |
886
- | `dev` | `tsc --watch` | Watch mode TypeScript compilation |
887
- | `dev:run` | `node --env-file=.env --watch dist/index.js` | Run server with auto-reload |
888
- | `start` | `node dist/index.js` | Run production server |
889
- | `build` | `node scripts/tasks.mjs build` | Clean build |
890
- | `test` | `node scripts/tasks.mjs test` | Build + run all tests |
891
- | `test:fast` | `node --test --import tsx/esm src/__tests__/**/*.test.ts` | Run tests without build |
892
- | `lint` | `eslint .` | Lint source |
893
- | `type-check` | `node scripts/tasks.mjs type-check` | Type-check src + tests |
894
- | `format` | `prettier --write .` | Format code |
895
- | `inspector` | `npm run build && npx @modelcontextprotocol/inspector` | Launch MCP Inspector |
903
+ - `dev` `tsc --watch --preserveWatchOutput` — Watch mode TypeScript compilation
904
+ - `dev:run` `node --env-file=.env --watch dist/index.js` — Run server with auto-reload
905
+ - `start` `node dist/index.js` Run production server
906
+ - `build` `node scripts/tasks.mjs build` Clean build
907
+ - `test` `node scripts/tasks.mjs test` Build + run all tests
908
+ - `test:fast` `node --test --import tsx/esm src/__tests__/**/*.test.ts node-tests/**/*.test.ts` Run tests without build
909
+ - `lint` `eslint .` Lint source
910
+ - `type-check` `node scripts/tasks.mjs type-check` Type-check src + tests
911
+ - `format` `prettier --write .` Format code
912
+ - `inspector` `npm run build && npx -y @modelcontextprotocol/inspector node dist/index.js ${workspaceFolder}` Launch MCP Inspector
896
913
 
897
914
  ## Build and Release
898
915
 
package/dist/config.d.ts CHANGED
@@ -77,7 +77,6 @@ export interface SearchContentResult {
77
77
  readonly skippedTooLarge: number;
78
78
  readonly skippedBinary: number;
79
79
  readonly skippedInaccessible: number;
80
- readonly linesSkippedDueToRegexTimeout: number;
81
80
  readonly stoppedReason?: 'maxResults' | 'maxFiles' | 'timeout';
82
81
  };
83
82
  }
@@ -188,7 +188,10 @@ const ERROR_SUGGESTIONS = {
188
188
  [ErrorCode.E_SYMLINK_NOT_ALLOWED]: 'Symbolic links that escape allowed directories are not permitted for security reasons.',
189
189
  [ErrorCode.E_UNKNOWN]: 'An unexpected error occurred. Check the error message for details.',
190
190
  };
191
- const NOT_FOUND_PATTERNS = ['enoent', 'no such file or directory'];
191
+ const NOT_FOUND_PATTERNS = [
192
+ 'no such file or directory',
193
+ 'does not exist',
194
+ ];
192
195
  const PERMISSION_DENIED_PATTERNS = [
193
196
  'permission denied',
194
197
  'not permitted',
@@ -234,7 +237,7 @@ function classifyError(error) {
234
237
  return terminalCode ?? timeoutCode ?? fallbackCode ?? ErrorCode.E_UNKNOWN;
235
238
  }
236
239
  export function createDetailedError(error, path, additionalDetails) {
237
- const message = error instanceof Error ? error.message : String(error);
240
+ const message = formatUnknownErrorMessage(error);
238
241
  const code = classifyError(error);
239
242
  const suggestion = ERROR_SUGGESTIONS[code];
240
243
  const resolvedPath = resolveErrorPath(error, path);
@@ -3,6 +3,7 @@ import * as path from 'node:path';
3
3
  import { DEFAULT_EXCLUDE_PATTERNS, DEFAULT_LIST_MAX_ENTRIES, DEFAULT_MAX_DEPTH, DEFAULT_READ_MANY_MAX_TOTAL_SIZE, DEFAULT_SEARCH_TIMEOUT_MS, getMimeType, MAX_TEXT_FILE_SIZE, PARALLEL_CONCURRENCY, } from '../constants.js';
4
4
  import { isAbortError } from '../errors.js';
5
5
  import { assertNotAborted, getFileType, isHidden, processInParallel, readFile, readFileWithStats, withAbort, withTimedAbortSignal, } from '../fs-helpers.js';
6
+ import { assertSafeGlobPattern } from '../globs.js';
6
7
  import { assertAllowedFileAccess, isPathWithinDirectories, isSensitivePath, normalizePath, toPosixPath, validateExistingDirectory, validateExistingPath, validateExistingPathDetailed, } from '../paths.js';
7
8
  import { applyIndexedErrors, applyIndexedValues, isEntryAccessibleByType, isIgnoredByGitignore, loadRootGitignore, needsStatsForSort, resolveEntryType, resolveStopReason, withOptionalStoppedReason, } from './core.js';
8
9
  import { globEntries } from './traversal.js';
@@ -149,6 +150,7 @@ function normalizeListOptions(options) {
149
150
  timeoutMs: options.timeoutMs ?? DEFAULT_SEARCH_TIMEOUT_MS,
150
151
  };
151
152
  if (options.pattern && options.pattern.length > 0) {
153
+ assertSafeGlobPattern(options.pattern);
152
154
  normalized.pattern = options.pattern;
153
155
  }
154
156
  return normalized;
@@ -590,6 +592,7 @@ function buildReadOptions(options) {
590
592
  const readOptions = {
591
593
  encoding: options.encoding,
592
594
  maxSize: options.maxSize,
595
+ skipBinary: true,
593
596
  };
594
597
  applyLineSelection(readOptions, options);
595
598
  return readOptions;
@@ -653,10 +656,13 @@ function applyLineSelection(target, source) {
653
656
  target.head = source.head;
654
657
  if (source.tail !== undefined)
655
658
  target.tail = source.tail;
656
- if (source.startLine !== undefined)
657
- target.startLine = source.startLine;
658
- if (source.endLine !== undefined)
659
+ if (source.endLine !== undefined) {
660
+ target.startLine = source.startLine ?? 1;
659
661
  target.endLine = source.endLine;
662
+ }
663
+ else if (source.startLine !== undefined) {
664
+ target.startLine = source.startLine;
665
+ }
660
666
  }
661
667
  function resolveNormalizedReadOptions(options) {
662
668
  const { signal, ...rest } = options;
@@ -12,7 +12,6 @@ declare const SearchOptionsSchema: z.ZodObject<{
12
12
  contextLines: z.ZodInt;
13
13
  wholeWord: z.ZodBoolean;
14
14
  isLiteral: z.ZodBoolean;
15
- multiline: z.ZodBoolean;
16
15
  includeHidden: z.ZodBoolean;
17
16
  baseNameMatch: z.ZodBoolean;
18
17
  caseSensitiveFileMatch: z.ZodBoolean;
@@ -117,10 +117,8 @@ function buildLiteralMatcher(pattern, options) {
117
117
  return count;
118
118
  };
119
119
  }
120
- function buildRegexMatcher(final, caseSensitive, multiline) {
121
- let flags = caseSensitive ? 'g' : 'gi';
122
- if (multiline)
123
- flags += 'm';
120
+ function buildRegexMatcher(final, caseSensitive) {
121
+ const flags = caseSensitive ? 'g' : 'gi';
124
122
  const regex = new RE2(final, flags);
125
123
  return (line) => countRegexLineMatches(regex, line);
126
124
  }
@@ -133,7 +131,7 @@ function buildMatcher(pattern, options) {
133
131
  }
134
132
  const final = buildRegexPattern(pattern, options);
135
133
  validatePattern(pattern, options); // Re-validate to be safe
136
- return buildRegexMatcher(final, options.caseSensitive, options.multiline);
134
+ return buildRegexMatcher(final, options.caseSensitive);
137
135
  }
138
136
  // --- Configuration & Schemas ---
139
137
  const SEARCH_CONTENT_MAX_RESULTS = 500;
@@ -149,7 +147,6 @@ const SearchOptionsSchema = z.strictObject({
149
147
  contextLines: z.int().min(0),
150
148
  wholeWord: z.boolean(),
151
149
  isLiteral: z.boolean(),
152
- multiline: z.boolean(),
153
150
  includeHidden: z.boolean(),
154
151
  baseNameMatch: z.boolean(),
155
152
  caseSensitiveFileMatch: z.boolean(),
@@ -166,7 +163,6 @@ const DEFAULTS = {
166
163
  contextLines: 0,
167
164
  wholeWord: false,
168
165
  isLiteral: true,
169
- multiline: false,
170
166
  includeHidden: false,
171
167
  baseNameMatch: false,
172
168
  caseSensitiveFileMatch: true,
@@ -182,7 +178,7 @@ function resolveOptions(options) {
182
178
  const merged = mergeOptions(DEFAULTS, normalizedOptions);
183
179
  const result = SearchOptionsSchema.safeParse(merged);
184
180
  if (!result.success) {
185
- throw new McpError(ErrorCode.E_INVALID_INPUT, `Invalid search options: ${result.error.message}`, undefined, { errors: z.treeifyError(result.error) });
181
+ throw new McpError(ErrorCode.E_INVALID_INPUT, `Invalid search options:\n${z.prettifyError(result.error)}`, undefined, { errors: z.treeifyError(result.error) });
186
182
  }
187
183
  return result.data;
188
184
  }
@@ -370,7 +366,6 @@ function buildMatcherOptions(opts) {
370
366
  caseSensitive: opts.caseSensitive,
371
367
  wholeWord: opts.wholeWord,
372
368
  isLiteral: opts.isLiteral,
373
- multiline: opts.multiline,
374
369
  };
375
370
  }
376
371
  function applyScanOutcome(summary, outcome) {
@@ -405,7 +400,6 @@ function buildSearchContentResult(root, pattern, filePattern, matches, summary)
405
400
  skippedTooLarge: summary.skippedTooLarge,
406
401
  skippedBinary: summary.skippedBinary,
407
402
  skippedInaccessible: summary.skippedInaccessible,
408
- linesSkippedDueToRegexTimeout: 0,
409
403
  };
410
404
  return {
411
405
  basePath: root,
@@ -1080,8 +1074,7 @@ function getMatcherCacheKey(pattern, options) {
1080
1074
  const cs = options.caseSensitive ? '1' : '0';
1081
1075
  const ww = options.wholeWord ? '1' : '0';
1082
1076
  const lit = options.isLiteral ? '1' : '0';
1083
- const ml = options.multiline ? '1' : '0';
1084
- return `${pattern}|${cs}|${ww}|${lit}|${ml}`;
1077
+ return `${pattern}|${cs}|${ww}|${lit}`;
1085
1078
  }
1086
1079
  function getCachedMatcher(pattern, options) {
1087
1080
  const key = getMatcherCacheKey(pattern, options);