@j0hanz/filesystem-mcp 1.0.0 → 1.0.1

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.
package/README.md CHANGED
@@ -1,64 +1,82 @@
1
1
  # Filesystem MCP
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/%40j0hanz%2Ffilesystem-mcp)](https://www.npmjs.com/package/@j0hanz/filesystem-mcp) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D24-brightgreen)](https://nodejs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-1.26+-purple)](https://modelcontextprotocol.io/)
3
+ ![npm version](https://img.shields.io/npm/v/@j0hanz/filesystem-mcp) ![License](https://img.shields.io/npm/l/@j0hanz/filesystem-mcp) ![Node.js Version](https://img.shields.io/node/v/@j0hanz/filesystem-mcp) ![Docker Image](https://ghcr-badge.egpl.dev/j0hanz/filesystem-mcp/latest_tag?trim=major&label=docker)
4
4
 
5
5
  [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0078d7?logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%7B%22name%22%3A%22filesystem-mcp%22%2C%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-24bfa5?logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%7B%22name%22%3A%22filesystem-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffilesystem-mcp%40latest%22%5D%7D) [![Install in Claude Desktop](https://img.shields.io/badge/Claude_Desktop-Install-f79a2e?logo=claude&logoColor=white)](https://modelcontextprotocol.io/quickstart/user#2-add-the-filesystem-server) [![Install in Cursor](https://img.shields.io/badge/Cursor-Install-000000?logo=cursor&logoColor=white)](https://cursor.com/deeplink/mcp-install?name=filesystem-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19)
6
6
 
7
- MCP server that provides a secure interface for language models to perform filesystem operations.
8
-
9
- ## Overview
10
-
11
- The `filesystem-mcp` server provides a secure interface for language models to perform filesystem operations. By defining a set of tools that map to common file and directory actions, it allows LLMs to read, write, search, and manipulate files within specified allowed directories. This can be used for tasks like code analysis, content generation, data processing, and more, all while ensuring that the model's access is safely confined.
7
+ MCP Server that enables LLMs to interact with the local filesystem. Provides tools for navigation, file management, searching, and analysis, all within a secure, allowed set of directories. Ideal for agents needing to read/write files, explore directory structures, or perform file operations as part of their tasks.
12
8
 
13
9
  ## Key Features
14
10
 
15
- - **Filesystem Navigation**: List directories (`ls`), visualize structures (`tree`), and list allowed roots (`roots`).
16
- - **File Operations**: Read (`read`, `read_many`), write (`write`), edit (`edit`), move (`mv`), and delete (`rm`) files.
17
- - **Advanced Search**: Find files by glob pattern (`find`) or search file contents (`grep`) with regex support.
18
- - **Diff & Patch**: Hash files (`calculate_hash`), generate unified diffs (`diff_files`), apply patches (`apply_patch`), and bulk replace (`search_and_replace`).
19
- - **Batch Processing**: Efficiently read or stat multiple files in a single request (`read_many`, `stat_many`).
20
- - **Security**: Operations are strictly confined to allowed directories specified at startup.
11
+ - **Navigation**: List directories (`ls`), view trees (`tree`), and discover workspace roots (`roots`).
12
+ - **File Management**: Create (`mkdir`), write (`write`), edit (`edit`), move (`mv`), and delete (`rm`) files/directories.
13
+ - **Search**: Find files by glob pattern (`find`) or search content using regex (`grep`).
14
+ - **Analysis**: Inspect metadata (`stat`), calculate hashes (`calculate_hash`), and compare files (`diff_files`).
15
+ - **Batch Operations**: Read multiple files (`read_many`) or replace text across many files (`search_and_replace`).
16
+ - **Security**: Strictly scoped to allowed directories provided at startup.
21
17
 
22
18
  ## Tech Stack
23
19
 
24
- - **Runtime**: Node.js >=24
25
- - **Language**: TypeScript 5.9
26
- - **MCP SDK**: @modelcontextprotocol/sdk 1.26
27
- - **Validation**: Zod
28
- - **Regex**: re2 (safe regex execution)
20
+ - **Runtime**: Node.js >= 24
21
+ - **Language**: TypeScript
22
+ - **SDK**: `@modelcontextprotocol/sdk`
23
+ - **Libraries**: `zod`, `commander`, `re2`, `diff`
24
+
25
+ ## Repository Structure
26
+
27
+ ```text
28
+ .
29
+ ├── src/
30
+ │ ├── index.ts # Entry point
31
+ │ ├── server.ts # MCP Server implementation
32
+ │ ├── tools/ # Individual tool implementations
33
+ │ └── lib/ # Shared utilities
34
+ ├── assets/ # Images and static resources
35
+ ├── scripts/ # Build and maintenance scripts
36
+ └── package.json
37
+ ```
38
+
39
+ ## Requirements
40
+
41
+ - Node.js >= 24
29
42
 
30
43
  ## Quickstart
31
44
 
32
- To run the server with access to your current directory:
45
+ Run directly with `npx`:
33
46
 
34
47
  ```bash
35
- npx -y @j0hanz/filesystem-mcp .
48
+ npx -y @j0hanz/filesystem-mcp@latest "C:\path\to\allowed\directory"
36
49
  ```
37
50
 
38
51
  ## Installation
39
52
 
40
- ### Using npx (Recommended)
53
+ ### NPX (Recommended)
41
54
 
42
55
  ```bash
43
- npx -y @j0hanz/filesystem-mcp <allowed-directory>
56
+ npx -y @j0hanz/filesystem-mcp@latest [options] [directories...]
44
57
  ```
45
58
 
46
- ### From Source
59
+ ### Docker
47
60
 
48
- 1. Clone the repository:
61
+ ```bash
62
+ docker run -i --rm \
63
+ -v /path/to/your/project:/projects/workspace:ro \
64
+ ghcr.io/j0hanz/filesystem-mcp:latest \
65
+ /projects/workspace
66
+ ```
49
67
 
50
- ```bash
51
- git clone https://github.com/j0hanz/filesystem-mcp.git
52
- cd filesystem-mcp
53
- ```
68
+ > Mount host directories as volumes to `/projects/` and pass the container paths as arguments.
54
69
 
70
+ ### From Source
71
+
72
+ 1. Clone the repository
55
73
  2. Install dependencies:
56
74
 
57
75
  ```bash
58
76
  npm ci
59
77
  ```
60
78
 
61
- 3. Build the server:
79
+ 3. Build the project:
62
80
 
63
81
  ```bash
64
82
  npm run build
@@ -67,286 +85,122 @@ npx -y @j0hanz/filesystem-mcp <allowed-directory>
67
85
  4. Run:
68
86
 
69
87
  ```bash
70
- node dist/index.js <allowed-directory>
88
+ node dist/index.js [options] [directories...]
71
89
  ```
72
90
 
73
91
  ## Configuration
74
92
 
75
- The server is configured primarily via command-line arguments.
76
-
77
- ### CLI Arguments
78
-
79
- | Argument | Description |
80
- | :--------------------------- | :--------------------------------------------------------------------------- |
81
- | `allowedDirs` | Positional arguments specifying which directories the server can access. |
82
- | `--allow-cwd`, `--allow_cwd` | Flag to automatically add the current working directory to the allowed list. |
83
- | `-h`, `--help` | Show CLI usage and exit. |
84
- | `-v`, `--version` | Show server version and exit. |
85
-
86
- ### Environment Variables
87
-
88
- | Variable | Default | Description |
89
- | :-------------------------------- | :-------------- | :---------------------------------------------------------------------- |
90
- | `MAX_SEARCH_SIZE` | `1048576` | Max file size (bytes) for `grep`/search content. Min 100 KB, max 10 MB. |
91
- | `MAX_FILE_SIZE` | `10485760` | Max file size (bytes) for `read`/`read_many`. Min 1 MB, max 100 MB. |
92
- | `MAX_READ_MANY_TOTAL_SIZE` | `524288` | Max total bytes returned by `read_many`. Min 10 KB, max 100 MB. |
93
- | `DEFAULT_SEARCH_TIMEOUT` | `5000` | Timeout (ms) for search operations. Min 100 ms, max 60 s. |
94
- | `FS_CONTEXT_ALLOW_SENSITIVE` | `false` | Allow access to sensitive files (set to `1`/`true` to allow). |
95
- | `FS_CONTEXT_DENYLIST` | (empty) | Additional denylist patterns (comma or newline separated). |
96
- | `FS_CONTEXT_ALLOWLIST` | (empty) | Allowlist patterns that override the denylist. |
97
- | `FS_CONTEXT_SEARCH_WORKERS` | `min(cores, 8)` | Worker threads for content search (0-16). |
98
- | `FS_CONTEXT_SEARCH_WORKERS_DEBUG` | `0` | Log worker debug details when set to `1`. |
99
- | `FS_CONTEXT_DIAGNOSTICS` | `0` | Enable diagnostics channels when set to `1`. |
100
- | `FS_CONTEXT_DIAGNOSTICS_DETAIL` | `0` | Diagnostics detail level: 0=off, 1=hashed paths, 2=full paths. |
101
- | `FS_CONTEXT_TOOL_LOG_ERRORS` | `0` | Emit tool error diagnostics when enabled. |
102
-
103
- ## MCP Surface
104
-
105
- ### Tools
106
-
107
- #### `roots`
108
-
109
- List the workspace roots this server can access.
110
-
111
- | Parameter | Type | Required | Default | Description |
112
- | :-------- | :--- | :------- | :------ | :---------- |
113
- | (none) | - | - | - | - |
114
-
115
- #### `ls`
116
-
117
- List the immediate contents of a directory (non-recursive).
118
-
119
- | Parameter | Type | Required | Default | Description |
120
- | :---------------------- | :------ | :------- | :------ | :-------------------------------------------------------------- |
121
- | `path` | string | No | (root) | Base directory for the operation. |
122
- | `includeHidden` | boolean | No | `false` | Include hidden files and directories (starting with .). |
123
- | `includeIgnored` | boolean | No | `false` | Include normally ignored directories (node_modules, dist, etc). |
124
- | `sortBy` | string | No | `name` | Sort by `name`, `size`, `modified`, or `type`. |
125
- | `maxDepth` | number | No | - | Max recursion depth when `pattern` is provided. |
126
- | `maxEntries` | number | No | - | Max entries before truncation. |
127
- | `pattern` | string | No | - | Optional glob filter (for recursive listing). |
128
- | `includeSymlinkTargets` | boolean | No | `false` | Include resolved symlink targets in output. |
129
-
130
- #### `find`
131
-
132
- Find files by glob pattern.
133
-
134
- | Parameter | Type | Required | Default | Description |
135
- | :---------------- | :------ | :------- | :------ | :--------------------------------------------- |
136
- | `pattern` | string | Yes | - | Glob pattern to match files (e.g., `**/*.ts`). |
137
- | `path` | string | No | (root) | Base directory for the operation. |
138
- | `maxResults` | number | No | `100` | Maximum matches to return. |
139
- | `includeIgnored` | boolean | No | `false` | Include normally ignored directories. |
140
- | `includeHidden` | boolean | No | `false` | Include hidden files and directories. |
141
- | `sortBy` | string | No | `path` | Sort by `path`, `name`, `size`, or `modified`. |
142
- | `maxDepth` | number | No | - | Maximum directory depth to scan. |
143
- | `maxFilesScanned` | number | No | - | Hard cap on scanned files. |
144
-
145
- #### `tree`
146
-
147
- Render a directory tree.
148
-
149
- | Parameter | Type | Required | Default | Description |
150
- | :--------------- | :------ | :------- | :------ | :------------------------------------------- |
151
- | `path` | string | No | (root) | Base directory for the operation. |
152
- | `maxDepth` | number | No | `5` | Maximum depth to recurse. |
153
- | `maxEntries` | number | No | `1000` | Maximum number of entries before truncating. |
154
- | `includeHidden` | boolean | No | `false` | Include hidden files. |
155
- | `includeIgnored` | boolean | No | `false` | Include ignored directories. |
156
-
157
- #### `read`
158
-
159
- Read the text contents of a file.
160
-
161
- | Parameter | Type | Required | Default | Description |
162
- | :---------- | :----- | :------- | :------ | :-------------------------------------- |
163
- | `path` | string | Yes | - | Absolute path to file. |
164
- | `head` | number | No | - | Read only the first N lines. |
165
- | `startLine` | number | No | - | Start reading from this line (1-based). |
166
- | `endLine` | number | No | - | Stop reading at this line (inclusive). |
167
-
168
- #### `read_many`
169
-
170
- Read multiple text files in a single request.
171
-
172
- | Parameter | Type | Required | Default | Description |
173
- | :---------- | :----- | :------- | :------ | :---------------------------------------- |
174
- | `paths` | array | Yes | - | Array of file paths to read. |
175
- | `head` | number | No | - | Read only the first N lines of each file. |
176
- | `startLine` | number | No | - | Start line for each file. |
177
- | `endLine` | number | No | - | End line for each file. |
178
-
179
- #### `stat`
180
-
181
- Get metadata for a file or directory.
182
-
183
- | Parameter | Type | Required | Default | Description |
184
- | :-------- | :----- | :------- | :------ | :---------------------------------- |
185
- | `path` | string | Yes | - | Absolute path to file or directory. |
186
-
187
- #### `stat_many`
188
-
189
- Get metadata for multiple files or directories.
190
-
191
- | Parameter | Type | Required | Default | Description |
192
- | :-------- | :---- | :------- | :------ | :-------------------------------- |
193
- | `paths` | array | Yes | - | Array of file or directory paths. |
194
-
195
- #### `grep`
196
-
197
- Search for text within file contents.
198
-
199
- | Parameter | Type | Required | Default | Description |
200
- | :---------------- | :------ | :------- | :------ | :--------------------------------------- |
201
- | `pattern` | string | Yes | - | Text to search for. |
202
- | `path` | string | No | (root) | Base directory or file for the search. |
203
- | `isRegex` | boolean | No | `false` | Treat pattern as a regular expression. |
204
- | `caseSensitive` | boolean | No | `false` | Enable case-sensitive matching. |
205
- | `wholeWord` | boolean | No | `false` | Match whole words only. |
206
- | `contextLines` | number | No | `0` | Include N lines before/after each match. |
207
- | `maxResults` | number | No | `500` | Maximum match rows to return. |
208
- | `maxFilesScanned` | number | No | `20000` | Hard cap on scanned files. |
209
- | `filePattern` | string | No | `**/*` | Glob filter for candidate files. |
210
- | `includeHidden` | boolean | No | `false` | Include hidden files. |
211
- | `includeIgnored` | boolean | No | `false` | Include ignored directories. |
212
-
213
- #### `calculate_hash`
214
-
215
- Compute a SHA-256 hash for a file.
216
-
217
- | Parameter | Type | Required | Default | Description |
218
- | :-------- | :----- | :------- | :------ | :--------------------- |
219
- | `path` | string | Yes | - | Absolute path to file. |
220
-
221
- #### `diff_files`
222
-
223
- Generate a unified diff between two files.
224
-
225
- | Parameter | Type | Required | Default | Description |
226
- | :----------------- | :------ | :------- | :------ | :------------------------------------------------- |
227
- | `original` | string | Yes | - | Path to original file. |
228
- | `modified` | string | Yes | - | Path to modified file. |
229
- | `context` | number | No | - | Lines of context to include in the diff. |
230
- | `ignoreWhitespace` | boolean | No | `false` | Ignore leading/trailing whitespace in comparisons. |
231
- | `stripTrailingCr` | boolean | No | `false` | Strip trailing carriage returns before diffing. |
232
-
233
- #### `apply_patch`
93
+ The server requires specifying allowed directories via command-line arguments.
234
94
 
235
- Apply a unified patch to a file.
95
+ ### Arguments
236
96
 
237
- | Parameter | Type | Required | Default | Description |
238
- | :----------------------- | :------ | :------- | :------ | :--------------------------------------------- |
239
- | `path` | string | Yes | - | Path to file to patch. |
240
- | `patch` | string | Yes | - | Unified diff content. |
241
- | `fuzzy` | boolean | No | `false` | Allow fuzzy patching (compatibility flag). |
242
- | `fuzzFactor` | number | No | - | Maximum fuzzy mismatches per hunk. |
243
- | `autoConvertLineEndings` | boolean | No | `true` | Auto-convert patch line endings to match file. |
244
- | `dryRun` | boolean | No | `false` | Check only, no writes. |
97
+ | Argument | Description |
98
+ | :----------------- | :-------------------------------------------------------------------------- |
99
+ | `[allowedDirs...]` | Positional arguments specifying the root directories the server can access. |
245
100
 
246
- #### `search_and_replace`
101
+ ### Options
247
102
 
248
- Search and replace text across multiple files.
103
+ | Option | Description |
104
+ | :-------------- | :--------------------------------------------------------- |
105
+ | `--allow-cwd` | Allow the current working directory as an additional root. |
106
+ | `-v, --version` | Display server version. |
107
+ | `-h, --help` | Display command help. |
249
108
 
250
- Response includes `processedFiles`, `failedFiles`, and a sample `failures`
251
- list when some files cannot be processed.
109
+ ## Usage
252
110
 
253
- | Parameter | Type | Required | Default | Description |
254
- | :---------------- | :------ | :------- | :------ | :-------------------------------- |
255
- | `path` | string | No | (root) | Base directory for the operation. |
256
- | `filePattern` | string | Yes | - | Glob pattern (e.g., `**/*.ts`). |
257
- | `excludePatterns` | array | No | `[]` | Glob patterns to exclude. |
258
- | `searchPattern` | string | Yes | - | Text or regex pattern to replace. |
259
- | `replacement` | string | Yes | - | Replacement text. |
260
- | `isRegex` | boolean | No | `false` | Treat search pattern as regex. |
261
- | `dryRun` | boolean | No | `false` | Check only, no writes. |
111
+ ### Stdio Transport
262
112
 
263
- #### `mkdir`
113
+ The server communicates via `stdio`. Ensure your MCP client is configured to run the server command and capture standard input/output.
264
114
 
265
- Create a new directory (recursive).
266
-
267
- | Parameter | Type | Required | Default | Description |
268
- | :-------- | :----- | :------- | :------ | :-------------- |
269
- | `path` | string | Yes | - | Path to create. |
270
-
271
- #### `write`
272
-
273
- Write content to a file.
274
-
275
- | Parameter | Type | Required | Default | Description |
276
- | :-------- | :----- | :------- | :------ | :---------------- |
277
- | `path` | string | Yes | - | Path to file. |
278
- | `content` | string | Yes | - | Content to write. |
279
-
280
- #### `edit`
281
-
282
- Edit a file by replacing text.
115
+ ## MCP Surface
283
116
 
284
- | Parameter | Type | Required | Default | Description |
285
- | :-------- | :------ | :------- | :------ | :--------------------------------------------- |
286
- | `path` | string | Yes | - | Path to file. |
287
- | `edits` | array | Yes | - | Array of objects with `oldText` and `newText`. |
288
- | `dryRun` | boolean | No | `false` | Only check if edits would succeed. |
117
+ ### Tools
289
118
 
290
- #### `mv`
119
+ | Tool | Description | Key Parameters |
120
+ | :------------------- | :---------------------------------- | :-------------------------------------------- |
121
+ | `roots` | List allowed workspace roots | None |
122
+ | `ls` | List directory contents | `path`, `includeHidden` |
123
+ | `find` | Find files by glob pattern | `pattern`, `path`, `maxDepth` |
124
+ | `tree` | Generate directory tree | `path`, `maxDepth` |
125
+ | `read` | Read file content | `path`, `head` |
126
+ | `read_many` | Read multiple files | `paths` |
127
+ | `grep` | Search file content (regex/literal) | `pattern`, `path`, `isRegex` |
128
+ | `stat` | Get file metadata | `path` |
129
+ | `stat_many` | Get metadata for multiple files | `paths` |
130
+ | `calculate_hash` | Calculate SHA-256 hash | `path` |
131
+ | `mkdir` | Create directory (recursive) | `path` |
132
+ | `write` | Write file (create/overwrite) | `path`, `content` |
133
+ | `edit` | Edit file (string replacement) | `path`, `edits` |
134
+ | `mv` | Move or rename file/directory | `source`, `destination` |
135
+ | `rm` | Delete file or directory | `path`, `recursive` |
136
+ | `diff_files` | Generate unified diff | `original`, `modified` |
137
+ | `apply_patch` | Apply unified patch | `path`, `patch` |
138
+ | `search_and_replace` | Search & replace across files | `filePattern`, `searchPattern`, `replacement` |
291
139
 
292
- Move or rename a file or directory.
140
+ ### Resources
293
141
 
294
- | Parameter | Type | Required | Default | Description |
295
- | :------------ | :----- | :------- | :------ | :------------ |
296
- | `source` | string | Yes | - | Current path. |
297
- | `destination` | string | Yes | - | New path. |
142
+ | URI Pattern | Description |
143
+ | :----------------------------- | :----------------------------------------------- |
144
+ | `internal://instructions` | Usage guidance and documentation |
145
+ | `filesystem-mcp://result/{id}` | Ephemeral cached tool output (for large results) |
298
146
 
299
- #### `rm`
147
+ ### Prompts
300
148
 
301
- Delete a file or directory.
149
+ | Prompt | Description |
150
+ | :--------- | :---------------------------------------- |
151
+ | `get-help` | Returns usage instructions for the server |
302
152
 
303
- | Parameter | Type | Required | Default | Description |
304
- | :------------------ | :------ | :------- | :------ | :------------------------------------ |
305
- | `path` | string | Yes | - | Path to delete. |
306
- | `recursive` | boolean | No | `false` | Allow deleting non-empty directories. |
307
- | `ignoreIfNotExists` | boolean | No | `false` | Do not fail if path missing. |
153
+ ## Client Configuration Examples
308
154
 
309
- ### Resources
155
+ <details>
156
+ <summary><strong>Claude Desktop</strong></summary>
310
157
 
311
- | Pattern | Description |
312
- | :----------------------------- | :------------------ |
313
- | `internal://instructions` | Server Instructions |
314
- | `filesystem-mcp://result/{id}` | Cached Tool Result |
158
+ Add to your `claude_desktop_config.json`:
315
159
 
316
- Tool responses may include a `resource_link` or a `resourceUri` when output is too large to inline. Fetch the full payload with `resources/read` using the provided URI. Cached results are ephemeral and may not appear in `resources/list`.
160
+ ```json
161
+ {
162
+ "mcpServers": {
163
+ "filesystem": {
164
+ "command": "npx",
165
+ "args": [
166
+ "-y",
167
+ "@j0hanz/filesystem-mcp@latest",
168
+ "C:\\path\\to\\allowed\\directory"
169
+ ]
170
+ }
171
+ }
172
+ }
173
+ ```
317
174
 
318
- ### Prompts
175
+ </details>
319
176
 
320
- | Prompt | Description |
321
- | :--------- | :--------------------------------------------------- |
322
- | `get-help` | Returns the server instructions for quick reference. |
177
+ <details>
178
+ <summary><strong>Cursor</strong></summary>
323
179
 
324
- ### Tasks
180
+ Add to your `.cursor/mcp.json` or configure via UI:
325
181
 
326
- Long-running tools (`grep`, `find`, `search_and_replace`, `tree`, `read_many`,
327
- `stat_many`) support task-augmented calls. When `task` is provided to
328
- `tools/call`, the server returns a task id that can be polled with `tasks/get`
329
- and resolved via `tasks/result`. Include `_meta.progressToken` on requests to
330
- receive `notifications/progress` updates. Task data is stored in memory and is
331
- cleared when the server restarts.
182
+ ```json
183
+ {
184
+ "id": "filesystem",
185
+ "name": "filesystem",
186
+ "command": "npx",
187
+ "args": ["-y", "@j0hanz/filesystem-mcp@latest", "${workspaceFolder}"]
188
+ }
189
+ ```
332
190
 
333
- ## Client Configuration Examples
191
+ </details>
334
192
 
335
193
  <details>
336
- <summary><strong>VS Code (Claude Dev / Cline)</strong></summary>
194
+ <summary><strong>VS Code</strong></summary>
337
195
 
338
- Add to your `~/AppData/Roaming/Code/User/globalStorage/mcp-settings.json` (Windows) or `~/Library/Application Support/Code/User/globalStorage/mcp-settings.json` (macOS):
196
+ Add to your `.vscode/mcp.json`:
339
197
 
340
198
  ```json
341
199
  {
342
200
  "mcpServers": {
343
- "filesystem-mcp": {
201
+ "filesystem": {
344
202
  "command": "npx",
345
- "args": [
346
- "-y",
347
- "@j0hanz/filesystem-mcp",
348
- "c:\\path\\to\\allowed\\directory"
349
- ]
203
+ "args": ["-y", "@j0hanz/filesystem-mcp@latest", "${workspaceFolder}"]
350
204
  }
351
205
  }
352
206
  }
@@ -355,19 +209,20 @@ Add to your `~/AppData/Roaming/Code/User/globalStorage/mcp-settings.json` (Windo
355
209
  </details>
356
210
 
357
211
  <details>
358
- <summary><strong>Claude Desktop</strong></summary>
212
+ <summary><strong>Docker (any MCP client)</strong></summary>
359
213
 
360
- Add to your `claude_desktop_config.json`:
214
+ Use the Docker image with any MCP client that supports stdio transport:
361
215
 
362
216
  ```json
363
217
  {
364
218
  "mcpServers": {
365
- "filesystem-mcp": {
366
- "command": "npx",
219
+ "filesystem": {
220
+ "command": "docker",
367
221
  "args": [
368
- "-y",
369
- "@j0hanz/filesystem-mcp",
370
- "c:\\path\\to\\allowed\\directory"
222
+ "run", "-i", "--rm",
223
+ "-v", "/path/to/project:/projects/workspace:ro",
224
+ "ghcr.io/j0hanz/filesystem-mcp:latest",
225
+ "/projects/workspace"
371
226
  ]
372
227
  }
373
228
  }
@@ -377,52 +232,57 @@ Add to your `claude_desktop_config.json`:
377
232
  </details>
378
233
 
379
234
  <details>
380
- <summary><strong>Cursor</strong></summary>
235
+ <summary><strong>Codex</strong></summary>
381
236
 
382
- Configure via the MCP settings panel:
237
+ Add to your configuration:
383
238
 
384
- - Name: `filesystem-mcp`
385
- - Type: `command`
386
- - Command: `npx -y @j0hanz/filesystem-mcp c:\path\to\allowed\directory`
239
+ ```toml
240
+ [mcp_servers.filesystem-mcp]
241
+ command = "npx"
242
+ args = ["-y", "@j0hanz/filesystem-mcp@latest", "${workspaceFolder}"]
243
+ ```
387
244
 
388
245
  </details>
389
246
 
390
247
  ## Security
391
248
 
392
- - **Path Scope**: Operations are restricted to the directories specified in `allowedDirs` or the current working directory if `--allow-cwd` is used.
393
- - **Path Validation**:
394
- - Null bytes are rejected.
395
- - Windows drive-relative paths (e.g., `C:path`) are rejected.
396
- - Windows reserved device names are rejected.
397
- - **Symlinks**: Symlink targets are reported but not implicitly followed during recursion in some operations to prevent loops or escaping scope (specific behavior varies by tool).
249
+ - **Path Restrictions**: All file operations are strictly validated against the allowed root directories provided at startup.
250
+ - **Path Validation**: Uses `isPathWithinDirectories` to prevent path traversal attacks.
251
+ - **Hidden Files**: Hidden files (starting with `.`) are excluded by default in listings and searches unless explicitly requested.
398
252
 
399
253
  ## Development Workflow
400
254
 
401
- 1. **Install dependencies**:
255
+ 1. **Install Dependencies**:
402
256
 
403
257
  ```bash
404
- npm ci
258
+ npm install
405
259
  ```
406
260
 
407
- 2. **Run in development mode** (rebuilds on change):
261
+ 2. **Development Mode** (watch):
408
262
 
409
263
  ```bash
410
264
  npm run dev
411
265
  ```
412
266
 
413
- 3. **Run tests**:
267
+ 3. **Run Locally**:
268
+
269
+ ```bash
270
+ npm start -- --allow-cwd
271
+ ```
272
+
273
+ 4. **Test**:
414
274
 
415
275
  ```bash
416
276
  npm run test
417
277
  ```
418
278
 
419
- 4. **Lint and Format**:
279
+ 5. **Lint & Format**:
420
280
 
421
281
  ```bash
422
282
  npm run lint
423
283
  npm run format
424
284
  ```
425
285
 
426
- ## Contributing & License
286
+ ## License
427
287
 
428
- This project is licensed under the [MIT License](LICENSE).
288
+ MIT
@@ -1,20 +1,20 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
- <style>
3
- path {
4
- fill: none;
5
- stroke: #000000;
6
- stroke-width: 1.3;
7
- stroke-linecap: round;
8
- stroke-linejoin: round
9
- }
10
-
11
- @media (prefers-color-scheme: dark) {
12
- path {
13
- stroke: #FFFFFF
14
- }
15
- }
16
- </style>
17
- <path d="M3 8H21V20H3Z" />
18
- <path d="M3 8L5 4H11L13 8" />
19
- <path d="M3 12H21" />
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <style>
3
+ path {
4
+ fill: none;
5
+ stroke: #000000;
6
+ stroke-width: 1.3;
7
+ stroke-linecap: round;
8
+ stroke-linejoin: round
9
+ }
10
+
11
+ @media (prefers-color-scheme: dark) {
12
+ path {
13
+ stroke: #FFFFFF
14
+ }
15
+ }
16
+ </style>
17
+ <path d="M3 8H21V20H3Z" />
18
+ <path d="M3 8L5 4H11L13 8" />
19
+ <path d="M3 12H21" />
20
20
  </svg>
package/dist/index.js CHANGED
File without changes
@@ -1,4 +1,4 @@
1
- # FILESYSTEM-OPS-MCP INSTRUCTIONS
1
+ # FILESYSTEM-MCP INSTRUCTIONS
2
2
 
3
3
  These instructions are available as a resource (internal://instructions) or prompt (get-help). Load them when unsure about tool usage.
4
4
 
@@ -6,9 +6,9 @@ These instructions are available as a resource (internal://instructions) or prom
6
6
 
7
7
  ## CORE CAPABILITY
8
8
 
9
- - Domain: Filesystem operations via an MCP server, enabling LLMs to interact with the filesystem securely and efficiently.
9
+ - Domain: Filesystem operations via an MCP server, enabling LLMs to interact with the local filesystem read, write, search, diff, patch, and manage files/directories securely.
10
10
  - Primary Resources: Files, Directories, Search Results, File Metadata.
11
- - Tools: `ls`, `roots`, `find`, `tree`, `read`, `read_many`, `stat`, `stat_many`, `grep`, `calculate_hash`, `diff_files` (READ); `mkdir`, `write`, `edit`, `mv`, `rm`, `apply_patch`, `search_and_replace` (WRITE).
11
+ - Tools: `roots`, `ls`, `find`, `tree`, `read`, `read_many`, `stat`, `stat_many`, `grep`, `calculate_hash`, `diff_files` (READ); `mkdir`, `write`, `edit`, `mv`, `rm`, `apply_patch`, `search_and_replace` (WRITE).
12
12
 
13
13
  ---
14
14
 
@@ -51,7 +51,7 @@ These instructions are available as a resource (internal://instructions) or prom
51
51
  ### WORKFLOW B: SEARCH & RETRIEVAL
52
52
 
53
53
  - Call `find` to locate files by glob (e.g., `**/*.ts`).
54
- - Call `grep` to search contents by regex (e.g., `function.*test`).
54
+ - Call `grep` to search contents by regex or literal text.
55
55
  - Call `read` or `read_many` to inspect files.
56
56
  - If content is truncated, use `resourceUri` from response or paginated `read` with `startLine`.
57
57
 
@@ -63,21 +63,28 @@ These instructions are available as a resource (internal://instructions) or prom
63
63
  - Call `mv` or `rm` for organization.
64
64
  NOTE: Always confirm destructive actions (delete/overwrite) with the user first.
65
65
 
66
+ ### WORKFLOW D: DIFF, PATCH & BULK REPLACE
67
+
68
+ - Call `diff_files` to compare two files (unified diff).
69
+ - Call `apply_patch` to apply a unified patch to a file. Use `dryRun: true` first.
70
+ - Call `search_and_replace` for bulk text replacement across files matching a glob. Use `dryRun: true` first.
71
+ NOTE: Always dry-run before applying patches or bulk replacements.
72
+
66
73
  ---
67
74
 
68
75
  ## TOOL NUANCES & GOTCHAS
69
76
 
77
+ `roots`
78
+
79
+ - Purpose: List allowed workspace roots. Call this first in every session.
80
+ - Output: Includes `rootsCount` and `hasMultipleRoots`.
81
+
70
82
  `ls`
71
83
 
72
84
  - Purpose: List directory contents (non-recursive).
73
85
  - Input: `path` (optional, default root), `includeIgnored`, `includeHidden`, optional `pattern`, `maxDepth`, `maxEntries`, `sortBy`, `includeSymlinkTargets`.
74
86
  - Limits: Use `tree` for recursion (depth limited).
75
87
 
76
- `roots`
77
-
78
- - Purpose: List allowed workspace roots.
79
- - Output: Includes `rootsCount` and `hasMultipleRoots`.
80
-
81
88
  `find`
82
89
 
83
90
  - Purpose: Search file paths by glob.
@@ -85,19 +92,37 @@ These instructions are available as a resource (internal://instructions) or prom
85
92
  - Output: Includes `root` and `pattern` for traceability.
86
93
  - Nuance: Respects `.gitignore` unless `includeIgnored=true`.
87
94
 
88
- `grep`
95
+ `tree`
89
96
 
90
- - Purpose: Search file content.
91
- - Input: `pattern` (string/regex), optional `isRegex`, `caseSensitive`, `wholeWord`, `contextLines`, `filePattern`, `maxResults`, `maxFilesScanned`, `includeHidden`, `includeIgnored`.
92
- - Output: Includes `patternType` and `caseSensitive`.
93
- - Limits: Skips binaries/large files. Returns max 50 inline matches.
97
+ - Purpose: Render a bounded directory tree (ASCII + JSON).
98
+ - Input: `path`, `maxDepth` (0–50, default 5), `maxEntries` (default 1000).
99
+ - Gotcha: `maxDepth=0` returns only the root node with empty children array.
94
100
 
95
- `read` / `read_many`
101
+ `read`
96
102
 
97
103
  - Purpose: Read file text.
98
- - Input: `path`, `head` (lines), `startLine`/`endLine`.
99
- - Output: `read_many` includes per-file `maxTotalSize` and `truncationReason` when truncated.
100
- - Gotcha: Large files return `resourceUri`; read it or use pagination.
104
+ - Input: `path`, `head` (first N lines), `startLine`/`endLine` (range).
105
+ - Gotcha: `head` is mutually exclusive with `startLine`/`endLine`. Large files return `resourceUri`; read it or use pagination.
106
+
107
+ `read_many`
108
+
109
+ - Purpose: Read multiple files in one call.
110
+ - Input: `paths` (max 100), `head`, `startLine`/`endLine`.
111
+ - Output: per-file `truncationReason` when truncated.
112
+ - Limits: Total budget capped by `MAX_READ_MANY_TOTAL_SIZE` (default 512 KB).
113
+
114
+ `stat` / `stat_many`
115
+
116
+ - Purpose: Get file/directory metadata (size, modified, permissions, MIME type).
117
+ - Output: Includes `tokenEstimate` (≈ size/4) for LLM context budgeting.
118
+
119
+ `grep`
120
+
121
+ - Purpose: Search file content (grep-like).
122
+ - Input: `pattern` (literal by default), `isRegex` (opt-in), `caseSensitive`, `wholeWord`, `contextLines`, `filePattern`, `maxResults`, `maxFilesScanned`.
123
+ - Output: Includes `patternType` and `caseSensitive`.
124
+ - Limits: Skips binaries and files larger than `MAX_SEARCH_SIZE` (default 1 MB). Returns max results per `maxResults` (default 500).
125
+ - Gotcha: Regex uses RE2 engine — no backreferences or lookahead/lookbehind.
101
126
 
102
127
  `calculate_hash`
103
128
 
@@ -106,7 +131,6 @@ These instructions are available as a resource (internal://instructions) or prom
106
131
  - Behavior: Auto-detects file vs directory using `fs.stat`.
107
132
  - **Files**: Returns `{ hash, isDirectory: false }`.
108
133
  - **Directories**: Returns `{ hash, isDirectory: true, fileCount }`. Uses deterministic hash-of-hashes pattern (lexicographically sorted paths, respects `.gitignore`).
109
- - Example: File → `979043bb...`, Directory with 20 files → `ace111aa...` (same hash on repeated calls).
110
134
 
111
135
  `diff_files`
112
136
 
@@ -115,6 +139,13 @@ These instructions are available as a resource (internal://instructions) or prom
115
139
  - Output: Includes `isIdentical` (diff may be empty when true).
116
140
  - Gotcha: Large diffs may be returned via `resourceUri`.
117
141
 
142
+ `edit`
143
+
144
+ - Purpose: Sequential string replacement in a file.
145
+ - Input: `path`, `edits` (array of `{oldText, newText}`), `dryRun`.
146
+ - Output: `unmatchedEdits` lists any `oldText` values not found.
147
+ - Gotcha: `oldText` must match exactly. First occurrence only per edit.
148
+
118
149
  `apply_patch`
119
150
 
120
151
  - Purpose: Apply a unified diff patch to a file.
@@ -127,12 +158,16 @@ These instructions are available as a resource (internal://instructions) or prom
127
158
  - Output: Includes `changedFiles` with per-file match counts (may be truncated).
128
159
  - Gotcha: Review `processedFiles`, `failedFiles`, and `failures` for partial errors.
129
160
 
130
- `edit`
161
+ `write`
131
162
 
132
- - Purpose: Sequential string replacement.
133
- - Input: `edits` (array of {oldText, newText}).
134
- - Output: `unmatchedEdits` lists any `oldText` values not found.
135
- - Gotcha: `oldText` must match exactly. First occurrence only per edit.
163
+ - Purpose: Create or overwrite a file.
164
+ - Side effects: Destructive overwrites existing content without confirmation.
165
+
166
+ `rm`
167
+
168
+ - Purpose: Delete a file or directory.
169
+ - Input: `path`, `recursive` (for non-empty dirs), `ignoreIfNotExists`.
170
+ - Side effects: Destructive and irreversible.
136
171
 
137
172
  ---
138
173
 
@@ -140,7 +175,14 @@ These instructions are available as a resource (internal://instructions) or prom
140
175
 
141
176
  - `E_NOT_FOUND`: Check path with `ls` or `find`.
142
177
  - `E_ACCESS_DENIED`: Path outside allowed `roots`.
143
- - `E_TIMEOUT`: Reduce scope (e.g., specific subdir) or batch size.
178
+ - `E_NOT_FILE`: Path is a directory. Use `ls` to explore its contents.
179
+ - `E_NOT_DIRECTORY`: Path is a file. Use `read` to read file contents.
180
+ - `E_TOO_LARGE`: File exceeds size limit. Use `head` to preview, or narrow scope.
181
+ - `E_TIMEOUT`: Reduce scope (narrower path), fewer results (`maxResults`), or search fewer files.
144
182
  - `E_INVALID_PATTERN`: Fix glob/regex syntax.
183
+ - `E_INVALID_INPUT`: Check tool documentation for correct parameter usage.
184
+ - `E_PERMISSION_DENIED`: OS-level permission denied. Check file permissions.
185
+ - `E_SYMLINK_NOT_ALLOWED`: Symlinks escaping allowed directories are blocked for security.
186
+ - `E_UNKNOWN`: Unexpected error. Check the error message for details.
145
187
 
146
188
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@j0hanz/filesystem-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "mcpName": "io.github.j0hanz/filesystem-mcp",
5
5
  "description": "MCP Server that enables LLMs to interact with the local filesystem.",
6
6
  "type": "module",