@j0hanz/filesystem-mcp 2.7.5 → 2.7.6

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 (67) hide show
  1. package/README.md +290 -394
  2. package/dist/cli-help.d.ts.map +1 -1
  3. package/dist/cli-help.js +15 -7
  4. package/dist/cli-help.js.map +1 -1
  5. package/dist/core/concurrency.d.ts +7 -0
  6. package/dist/core/concurrency.d.ts.map +1 -1
  7. package/dist/core/concurrency.js +19 -0
  8. package/dist/core/concurrency.js.map +1 -1
  9. package/dist/core/fs.d.ts +8 -0
  10. package/dist/core/fs.d.ts.map +1 -1
  11. package/dist/core/fs.js +62 -12
  12. package/dist/core/fs.js.map +1 -1
  13. package/dist/core/path.d.ts +7 -16
  14. package/dist/core/path.d.ts.map +1 -1
  15. package/dist/core/path.js +10 -26
  16. package/dist/core/path.js.map +1 -1
  17. package/dist/core/read.d.ts +4 -1
  18. package/dist/core/read.d.ts.map +1 -1
  19. package/dist/core/read.js +13 -3
  20. package/dist/core/read.js.map +1 -1
  21. package/dist/core/search.d.ts +7 -0
  22. package/dist/core/search.d.ts.map +1 -1
  23. package/dist/core/search.js +50 -15
  24. package/dist/core/search.js.map +1 -1
  25. package/dist/core/util.d.ts +8 -0
  26. package/dist/core/util.d.ts.map +1 -1
  27. package/dist/core/util.js +8 -0
  28. package/dist/core/util.js.map +1 -1
  29. package/dist/server.d.ts +2 -0
  30. package/dist/server.d.ts.map +1 -1
  31. package/dist/server.js +1 -0
  32. package/dist/server.js.map +1 -1
  33. package/dist/tools/create.d.ts.map +1 -1
  34. package/dist/tools/create.js +98 -84
  35. package/dist/tools/create.js.map +1 -1
  36. package/dist/tools/define.d.ts +3 -0
  37. package/dist/tools/define.d.ts.map +1 -1
  38. package/dist/tools/define.js +1 -0
  39. package/dist/tools/define.js.map +1 -1
  40. package/dist/tools/edit.d.ts.map +1 -1
  41. package/dist/tools/edit.js +18 -5
  42. package/dist/tools/edit.js.map +1 -1
  43. package/dist/tools/index.d.ts +1 -0
  44. package/dist/tools/index.d.ts.map +1 -1
  45. package/dist/tools/index.js +1 -0
  46. package/dist/tools/index.js.map +1 -1
  47. package/dist/tools/list.js +1 -1
  48. package/dist/tools/list.js.map +1 -1
  49. package/dist/tools/move.d.ts.map +1 -1
  50. package/dist/tools/move.js +35 -5
  51. package/dist/tools/move.js.map +1 -1
  52. package/dist/tools/patch.d.ts.map +1 -1
  53. package/dist/tools/patch.js +91 -86
  54. package/dist/tools/patch.js.map +1 -1
  55. package/dist/tools/read.d.ts.map +1 -1
  56. package/dist/tools/read.js +16 -1
  57. package/dist/tools/read.js.map +1 -1
  58. package/dist/tools/replace-text.d.ts.map +1 -1
  59. package/dist/tools/replace-text.js +38 -15
  60. package/dist/tools/replace-text.js.map +1 -1
  61. package/dist/transport/http.d.ts.map +1 -1
  62. package/dist/transport/http.js +1 -0
  63. package/dist/transport/http.js.map +1 -1
  64. package/dist/transport/stdio.d.ts.map +1 -1
  65. package/dist/transport/stdio.js +1 -0
  66. package/dist/transport/stdio.js.map +1 -1
  67. package/package.json +1 -1
package/README.md CHANGED
@@ -1,109 +1,95 @@
1
- # Filesystem MCP Server
2
-
3
- [![License](https://img.shields.io/github/license/j0hanz/filesystem-mcp?style=for-the-badge)](https://github.com/j0hanz/filesystem-mcp/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/%40j0hanz%2Ffilesystem-mcp?style=for-the-badge&logo=npm&logoColor=white)](https://www.npmjs.com/package/@j0hanz/filesystem-mcp) [![Build](https://img.shields.io/github/actions/workflow/status/j0hanz/filesystem-mcp/release.yml?style=for-the-badge&logo=githubactions&logoColor=white&label=build)](https://github.com/j0hanz/filesystem-mcp/actions) [![GitHub stars](https://img.shields.io/github/stars/j0hanz/filesystem-mcp?style=for-the-badge&logo=github)](https://github.com/j0hanz/filesystem-mcp/stargazers)
4
-
5
- [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://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-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-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) [![Install in Cursor](https://img.shields.io/badge/Cursor-Install-000000?style=flat-square&logo=cursor&logoColor=white)](cursor://anysphere.cursor-deeplink/mcp/install?name=filesystem&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19)
6
-
7
- ## Overview
8
-
9
- Filesystem-MCP is a [Model Context Protocol](https://modelcontextprotocol.io) server that lets AI assistants read and write files within explicitly allowed directories. Sensitive file patterns (`.env`, `*.pem`, `*id_rsa*`) are blocked by default. It exposes filesystem tools, resources, and prompts over stdio or Streamable HTTP transport.
10
-
11
- | Aspect | Details |
12
- | :----------- | :--------------------------------------------- |
13
- | **Status** | Active (see npm badge for the current version) |
14
- | **Language** | TypeScript (strict) |
15
- | **Runtime** | Node.js >= 24 |
16
- | **Package** | npm |
17
- | **License** | MIT |
18
-
19
- ## Features
20
-
21
- | Feature | Description |
22
- | :--------------------- | :--------------------------------------------------------------------------------------------------------- |
23
- | **Path guarding** | Every path is validated against allowed roots; `.env`, `*.pem`, `*id_rsa*` and similar patterns are denied |
24
- | **Filesystem tools** | Navigate, inspect, read, and write across all major file operations |
25
- | **Batch operations** | Most tools accept `path`, `paths[]`, or `files[]` for parallel execution |
26
- | **Dual transport** | stdio by default; `--port` enables Streamable HTTP for both 2025-era and 2026-07-28 clients |
27
- | **File subscriptions** | Resource subscriptions push change notifications when watched files update |
28
- | **Regex safety** | RE2 in all search tools: linear-time matching, so no pattern can ReDoS the server |
29
-
30
- ## Compared with the reference server
31
-
32
- How this server differs from [`@modelcontextprotocol/server-filesystem`](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem), checked against its README and source on 2026-09-24:
33
-
34
- | Capability | filesystem-mcp | Reference server |
35
- | :------------------------ | :----------------------------------------------- | :-------------------------------------- |
36
- | Search inside files | `search_text`: RE2 regex or literal, linear time | None; `search_files` matches names only |
37
- | Secret files | `.env`, `*.pem`, `*id_rsa*` denied by default | Not blocked |
38
- | Read-only mode | `--read-only` removes every mutating tool | Docker `ro` mounts only |
39
- | Apply a unified diff | `patch` | None |
40
- | Compare two files | `diff` | None |
41
- | Replace across many files | `replace_text` over a glob | None |
42
- | Watch files | Resource subscriptions push change notifications | No resources |
43
- | Transport | stdio, or Streamable HTTP with `--port` | stdio |
44
-
45
- ## Built with
46
-
47
- [![Node.js](https://img.shields.io/badge/node-%3E%3D24-339933?style=for-the-badge&logo=node.js&logoColor=white)](https://nodejs.org) [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org) [![Docker](https://img.shields.io/badge/Docker-ready-2496ED?style=for-the-badge&logo=docker&logoColor=white)](https://www.docker.com)
48
-
49
- | Layer | Technology |
50
- | :-------- | :--------------------------------------------------------------------- |
51
- | Protocol | MCP SDK v2 (`@modelcontextprotocol/server`) |
52
- | Runtime | Node.js >= 24 · TypeScript 6 · ESM |
53
- | Transport | stdio (default) · Streamable HTTP (`--port`) |
54
- | Regex | RE2 (`re2-wasm`) — linear time, no lookahead/lookbehind/backreferences |
55
- | Container | Docker alpine · multi-stage build · non-root user |
56
-
57
- ## Table of Contents
58
-
59
- - [Quick start](#quick-start)
60
- - [Usage](#usage)
61
- - [Project structure](#project-structure)
62
- - [Configuration](#configuration)
63
- - [Scripts](#scripts)
64
- - [Security](#security)
65
- - [Contributing](#contributing)
66
- - [Privacy Policy](#privacy-policy)
67
- - [License](#license)
1
+ <img src="assets/logo.png" alt="Filesystem MCP logo" width="96" height="96">
2
+
3
+ # Filesystem MCP
4
+
5
+ **Let your AI assistant work with your files, safely.**
6
+
7
+ Read, search, edit, and patch files in the folders you choose.<br>
8
+ Secret files stay hidden, and risky changes wait for your OK.
9
+
10
+ [![npm version](https://img.shields.io/npm/v/%40j0hanz%2Ffilesystem-mcp?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@j0hanz/filesystem-mcp) [![CI](https://img.shields.io/github/actions/workflow/status/j0hanz/filesystem-mcp/ci.yml?branch=main&style=flat-square&logo=githubactions&logoColor=white&label=CI)](https://github.com/j0hanz/filesystem-mcp/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/github/license/j0hanz/filesystem-mcp?style=flat-square)](LICENSE) [![GitHub stars](https://img.shields.io/github/stars/j0hanz/filesystem-mcp?style=flat-square&logo=github)](https://github.com/j0hanz/filesystem-mcp/stargazers)
11
+
12
+ [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://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-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-C16FDE?style=flat-square&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) [![Install in Cursor](https://img.shields.io/badge/Cursor-Install-000000?style=flat-square&logo=cursor&logoColor=white)](https://cursor.com/en/install-mcp?name=filesystem&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovZmlsZXN5c3RlbS1tY3BAbGF0ZXN0Il19) [![Install in Claude Desktop](https://img.shields.io/badge/Claude_Desktop-Install-D97757?style=flat-square&logo=claude&logoColor=white)](https://github.com/j0hanz/filesystem-mcp/releases/latest/download/filesystem-mcp.mcpb)
13
+
14
+ ## What is this?
15
+
16
+ [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is how AI apps
17
+ such as Claude, GitHub Copilot in VS Code, and Cursor connect to tools.
18
+ Filesystem MCP is an MCP server: a small program that runs on your computer
19
+ and gives the AI 13 tools for working with files. You choose which folders it
20
+ can use, and everything outside them is off limits.
21
+
22
+ Once it is connected, you can ask things like:
23
+
24
+ - _"Find every TODO in this repo and group them by file."_
25
+ - _"Rename `getUser` to `fetchUser` in all `.ts` files. Show me the diff first."_
26
+ - _"What changed between `config.dev.json` and `config.prod.json`?"_
27
+ - _"Read the last 50 lines of `server.log` and explain the error."_
28
+ - _"Move the old screenshots into `archive/2025/`."_
29
+
30
+ ## Why Filesystem MCP?
31
+
32
+ - It is safe by default. The AI can use only the folders you allow, and
33
+ `.env` files, private keys, and cloud credentials are blocked. The server
34
+ asks you before the AI deletes a non-empty folder, opens a folder you did
35
+ not allow, or writes over a file with `create` or `move`. Only `create` and
36
+ copies can skip that question, by passing `overwrite: true`. Edits made with
37
+ `edit`, `patch`, and `replace_text` apply without asking, but the AI can
38
+ show you the diff first with `dryRun`. If the AI should never change
39
+ anything, `--read-only` removes every tool that writes.
40
+ - Search and editing are made for code. The AI can search inside files like
41
+ `grep`, with a regex engine (RE2) that cannot hang, and by default the
42
+ server skips `.gitignore`d files and folders like `node_modules`. Edits are
43
+ exact-match replacements that fail loudly instead of guessing, and you can
44
+ preview them as a diff first.
45
+ - It goes easy on the AI's context. The AI can read many files in one call or
46
+ only the lines it needs, and it can check a file's size and token estimate
47
+ before reading it.
48
+ - It works with any MCP client, over stdio or HTTP, on macOS, Linux, and
49
+ Windows. You can install it with npx, Docker, or a one-click Claude Desktop
50
+ extension, or [build your own client](#build-your-own-client) on it.
51
+ - It is private: it runs on your machine, has no telemetry, and makes no
52
+ network calls.
53
+
54
+ ### Compared with the reference server
55
+
56
+ How this server differs from the official
57
+ [`@modelcontextprotocol/server-filesystem`](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem),
58
+ checked against its README on 2026-10-11:
59
+
60
+ | Capability | Filesystem MCP | Reference server |
61
+ | :------------------------ | :------------------------------------------------- | :-------------------------------------- |
62
+ | Search inside files | `search_text`: literal text or RE2 regex | None; `search_files` matches names only |
63
+ | Secret files | `.env`, keys, and credentials blocked by default | Not blocked |
64
+ | Overwriting a file | `create` asks you first (unless `overwrite: true`) | `write_file` overwrites without asking |
65
+ | Delete files | `delete`; asks before deleting a non-empty folder | None |
66
+ | `.gitignore` | Respected by listing and search tools | Not supported |
67
+ | Read-only mode | `--read-only` removes every tool that writes | Docker `ro` mounts only |
68
+ | Apply a unified diff | `patch` | None |
69
+ | Compare two files | `diff` | None |
70
+ | Replace across many files | `replace_text` over a folder or glob | None |
71
+ | Watch files | Subscribe to a file and get change notifications | None |
72
+ | Transport | stdio, or Streamable HTTP with `--port` | stdio |
68
73
 
69
74
  ## Quick start
70
75
 
71
76
  > [!NOTE]
72
- > Requires Node.js ≥ 24.
77
+ > You need Node.js 24 or later. Check with `node --version`.
73
78
 
74
- ### Prerequisites
79
+ 1. Add the server to your AI app. Pick yours below.
80
+ 2. Replace `/path/to/project` with the folder the AI may use. You can list
81
+ several folders.
82
+ 3. Restart the app and ask: _"Which folders can you access?"_
75
83
 
76
- | Requirement | Version / Notes |
77
- | :---------- | :--------------------------- |
78
- | Node.js | ≥ 24 |
79
- | npm | Bundled with Node.js |
80
- | Docker | Optional — for container use |
84
+ > [!TIP]
85
+ > VS Code currently shares the folders you have open with the server, so the
86
+ > one-click VS Code install works without a path. In other apps, or over HTTP,
87
+ > put the folder in `args`. If the AI says it has no folders, that is the fix.
81
88
 
82
- ### Install via npx
89
+ <details>
90
+ <summary><b>VS Code</b></summary>
83
91
 
84
- ```bash
85
- npx -y @j0hanz/filesystem-mcp /path/to/allowed/dir
86
- ```
87
-
88
- Or install globally:
89
-
90
- ```bash
91
- npm install -g @j0hanz/filesystem-mcp
92
- filesystem-mcp /path/to/allowed/dir
93
- ```
94
-
95
- ### Install via Docker
96
-
97
- ```bash
98
- docker run -i --rm \
99
- -v /path/to/project:/workspace:ro \
100
- ghcr.io/j0hanz/filesystem-mcp:latest \
101
- --read-only /workspace
102
- ```
103
-
104
- ### Configure in VS Code
105
-
106
- Add to `.vscode/mcp.json`:
92
+ Click **Install in VS Code** above, or add this to `.vscode/mcp.json`:
107
93
 
108
94
  ```json
109
95
  {
@@ -116,19 +102,24 @@ Add to `.vscode/mcp.json`:
116
102
  }
117
103
  ```
118
104
 
119
- Or install via CLI:
105
+ Or from a terminal:
120
106
 
121
107
  ```sh
122
108
  code --add-mcp '{"name":"filesystem","command":"npx","args":["-y","@j0hanz/filesystem-mcp@latest","/path/to/project"]}'
123
109
  ```
124
110
 
125
- ### Configure in Visual Studio
111
+ </details>
112
+
113
+ <details>
114
+ <summary><b>Cursor</b></summary>
126
115
 
127
- Add to `.vs\mcp.json` in your solution directory, or `%USERPROFILE%\.mcp.json` for a global configuration:
116
+ Click **Install in Cursor** above, then add your folder to `args`. Or add this
117
+ to `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` for all
118
+ projects:
128
119
 
129
120
  ```json
130
121
  {
131
- "servers": {
122
+ "mcpServers": {
132
123
  "filesystem": {
133
124
  "command": "npx",
134
125
  "args": ["-y", "@j0hanz/filesystem-mcp@latest", "/path/to/project"]
@@ -137,11 +128,18 @@ Add to `.vs\mcp.json` in your solution directory, or `%USERPROFILE%\.mcp.json` f
137
128
  }
138
129
  ```
139
130
 
140
- ### Configure in Claude Desktop
131
+ </details>
132
+
133
+ <details>
134
+ <summary><b>Claude Desktop</b></summary>
141
135
 
142
- One click: download [`filesystem-mcp.mcpb`](https://github.com/j0hanz/filesystem-mcp/releases/latest/download/filesystem-mcp.mcpb), open it with Claude Desktop, and pick the directories to allow. Claude Desktop's built-in Node.js runs it.
136
+ For a one-click install, download
137
+ [`filesystem-mcp.mcpb`](https://github.com/j0hanz/filesystem-mcp/releases/latest/download/filesystem-mcp.mcpb),
138
+ open it with Claude Desktop, and pick the folders to allow. Claude Desktop's
139
+ built-in Node.js runs it.
143
140
 
144
- Or configure it by hand. Add to your `claude_desktop_config.json`:
141
+ To set it up by hand, add this to `claude_desktop_config.json`
142
+ (Settings → Developer → Edit Config):
145
143
 
146
144
  ```json
147
145
  {
@@ -154,57 +152,61 @@ Or configure it by hand. Add to your `claude_desktop_config.json`:
154
152
  }
155
153
  ```
156
154
 
157
- ### Install in Cursor
155
+ </details>
158
156
 
159
- Add to `.cursor/mcp.json` in your project root (project-scoped), or `~/.cursor/mcp.json` for a global configuration:
157
+ <details>
158
+ <summary><b>Claude Code</b></summary>
159
+
160
+ ```sh
161
+ claude mcp add filesystem -- npx -y @j0hanz/filesystem-mcp@latest /path/to/project
162
+ ```
163
+
164
+ Or install the plugin, which points the server at your current project:
165
+
166
+ ```text
167
+ /plugin marketplace add j0hanz/j0hanz-marketplace
168
+ /plugin install filesystem-mcp@j0hanz-marketplace
169
+ ```
170
+
171
+ </details>
172
+
173
+ <details>
174
+ <summary><b>Visual Studio</b></summary>
175
+
176
+ Add this to `.vs\mcp.json` in your solution folder, or `%USERPROFILE%\.mcp.json`
177
+ for all solutions:
160
178
 
161
179
  ```json
162
180
  {
163
- "mcpServers": {
181
+ "servers": {
164
182
  "filesystem": {
165
183
  "command": "npx",
166
- "args": ["-y", "@j0hanz/filesystem-mcp@latest", "/path/to/project"]
184
+ "args": ["-y", "@j0hanz/filesystem-mcp@latest", "C:/path/to/project"]
167
185
  }
168
186
  }
169
187
  }
170
188
  ```
171
189
 
172
- ### Install as a plugin
190
+ </details>
173
191
 
174
- The [filesystem-mcp plugin](https://github.com/j0hanz/j0hanz-marketplace/tree/main/plugins/filesystem-mcp) wires the server up with project-scoped defaults:
192
+ <details>
193
+ <summary><b>GitHub Copilot CLI and Antigravity CLI (plugin)</b></summary>
194
+
195
+ The [filesystem-mcp plugin](https://github.com/j0hanz/j0hanz-marketplace/tree/main/plugins/filesystem-mcp)
196
+ sets the server up for your current project:
175
197
 
176
198
  | Client | Install |
177
199
  | :-------------- | :------------------------------------------------------------------------------------------------------------------------------ |
178
- | Claude Code | `/plugin marketplace add j0hanz/j0hanz-marketplace`, then `/plugin install filesystem-mcp@j0hanz-marketplace` |
179
200
  | Copilot CLI | `copilot plugin marketplace add j0hanz/j0hanz-marketplace`, then `copilot plugin install filesystem-mcp@j0hanz-marketplace` |
180
201
  | Antigravity CLI | `git clone https://github.com/j0hanz/j0hanz-marketplace`, then `agy plugin install ./j0hanz-marketplace/plugins/filesystem-mcp` |
181
202
 
182
- The plugin README covers the defaults and how each client picks the project directory.
183
-
184
- ### Docker configuration
203
+ </details>
185
204
 
186
- VS Code (`.vscode/mcp.json`) and Visual Studio (`.vs\mcp.json`):
187
-
188
- ```json
189
- {
190
- "servers": {
191
- "filesystem": {
192
- "command": "docker",
193
- "args": [
194
- "run",
195
- "-i",
196
- "--rm",
197
- "-v",
198
- "/path/to/project:/workspace",
199
- "ghcr.io/j0hanz/filesystem-mcp:latest",
200
- "/workspace"
201
- ]
202
- }
203
- }
204
- }
205
- ```
205
+ <details>
206
+ <summary><b>Docker</b></summary>
206
207
 
207
- Claude Desktop (`claude_desktop_config.json`) and Cursor (`mcp.json`):
208
+ The container can only see the folders you mount. This setup is read-only
209
+ twice over: the `:ro` mount and the `--read-only` flag.
208
210
 
209
211
  ```json
210
212
  {
@@ -216,8 +218,9 @@ Claude Desktop (`claude_desktop_config.json`) and Cursor (`mcp.json`):
216
218
  "-i",
217
219
  "--rm",
218
220
  "-v",
219
- "/path/to/project:/workspace",
221
+ "/path/to/project:/workspace:ro",
220
222
  "ghcr.io/j0hanz/filesystem-mcp:latest",
223
+ "--read-only",
221
224
  "/workspace"
222
225
  ]
223
226
  }
@@ -225,291 +228,184 @@ Claude Desktop (`claude_desktop_config.json`) and Cursor (`mcp.json`):
225
228
  }
226
229
  ```
227
230
 
228
- > [!NOTE]
229
- > For least privilege, use both controls: `:ro` makes the container mount
230
- > read-only at the operating-system boundary, while the server's `--read-only`
231
- > flag removes mutating tools (`create`, `edit`, `move`, `delete`, `patch`,
232
- > `replace_text`) from `tools/list`.
233
-
234
- ## Usage
235
-
236
- ### Tools
237
-
238
- All tools are scoped to the configured roots. Call `list_roots` first to discover what is allowed.
239
-
240
- #### Navigate
241
-
242
- | Tool | Description |
243
- | :----------- | :------------------------------------------------------------------------------------- |
244
- | `list_roots` | List allowed workspace roots. Call this first — all other tools scope to these. |
245
- | `list` | List directory contents. Returns entries (dirs-first, alphabetical) and an ASCII tree. |
246
- | `find_files` | Find files by glob pattern (e.g. `**/*.ts`). Returns matching files with metadata. |
231
+ Drop `:ro` and `--read-only` to let the AI make changes. VS Code and Visual
232
+ Studio use `"servers"` instead of `"mcpServers"`. See
233
+ [Running in Docker](docs/configuration.md#running-in-docker) for more.
247
234
 
248
- #### Inspect
235
+ </details>
249
236
 
250
- | Tool | Description |
251
- | :------------ | :---------------------------------------------------------------------------------------- |
252
- | `stat` | Get file/directory metadata: size, modified time, permissions, MIME type, token estimate. |
253
- | `search_text` | Search file contents for text (grep-like). Returns matching lines with context. |
254
- | `diff` | Compare two files and return a unified diff with added/removed line counts. |
237
+ <details>
238
+ <summary><b>Other MCP clients</b></summary>
255
239
 
256
- #### Read
240
+ Windsurf, Cline, and most other clients use the same `mcpServers` JSON as
241
+ Claude Desktop above. In any client, the server is:
257
242
 
258
- | Tool | Description |
259
- | :----- | :----------------------------------------------------------------------------------- |
260
- | `read` | Read a text file. Supports head/tail and line ranges. Accepts `paths[]` for batches. |
243
+ - **command:** `npx`
244
+ - **args:** `-y`, `@j0hanz/filesystem-mcp@latest`, then one or more folders
261
245
 
262
- #### Write
246
+ You can also install it globally and run `filesystem-mcp /path/to/project`:
263
247
 
264
- | Tool | Description |
265
- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
266
- | `create` | Create one or more files, creating parent directories as needed. An existing file prompts the user to confirm the overwrite; `overwrite: true` on an entry skips the prompt, `append: true` adds to the end instead. |
267
- | `edit` | Apply sequential literal string replacements to one or more files (up to 5 files per call, 100 edits per file). |
268
- | `move` | Move, rename, or copy (`copy: true`) one or more files/directories to explicit destinations. |
269
- | `delete` | Permanently delete one or more files or directories. This action is irreversible. |
270
- | `replace_text` | Bulk search-and-replace across files matching a glob pattern. |
271
- | `patch` | Apply a single-file unified diff and write the result. |
272
-
273
- ### Resources
274
-
275
- | URI | Description |
276
- | :------------------------------ | :------------------------------------------------------------------------------------ |
277
- | `internal://instructions` | Server navigation guide — tools overview, constraints, and error recovery. |
278
- | `filesystem-mcp://file/{+path}` | Read a workspace file. Subscribe to receive push notifications on change. |
279
- | `filesystem-mcp://result/{id}` | Ephemeral cached tool output. Expires after ~60 seconds, eviction, or server restart. |
280
-
281
- ### Prompts
282
-
283
- | Prompt | Description |
284
- | :--------- | :-------------------------------------------------------------------- |
285
- | `get-help` | Return usage instructions, optionally filtered to a specific section. |
286
-
287
- ## Project structure
288
-
289
- ```text
290
- filesystem-mcp/
291
- ├── __tests__/ Test suites (node --test) and shared helpers
292
- ├── docs/adr/ Architecture decision records
293
- ├── mcpb/manifest.json Claude Desktop extension manifest
294
- ├── scripts/ Release-path scripts (MCPB pack, Smithery publish)
295
- ├── src/
296
- │ ├── core/ Path guarding, filesystem facade, search, stores, watchers
297
- │ ├── tools/ One file per tool, plus define.ts (registration) and batch.ts
298
- │ ├── transport/ stdio.ts, http.ts, http-policy.ts (auth, Origin, rate limit), shared.ts
299
- │ ├── cli.ts Argument parsing and --print-config
300
- │ ├── cli-help.ts --help / --version text
301
- │ ├── index.ts Process entrypoint, shutdown, transport selection
302
- │ ├── instructions.ts Server instructions sent to every client
303
- │ ├── prompts.ts Prompt definitions and registration
304
- │ ├── resources.ts Resource definitions, subscriptions, completion
305
- │ ├── server.ts Server factory and registrar composition
306
- │ └── transport.ts Facade re-exporting startServer / startHttpServer
307
- └── Dockerfile Multi-stage alpine build, non-root user
248
+ ```sh
249
+ npm install -g @j0hanz/filesystem-mcp
308
250
  ```
309
251
 
310
- Runtime composition flows from `src/index.ts` to `src/transport/` (stdio or HTTP), then to
311
- `src/server.ts`, the registrars, and finally `src/core/`. Each registrar owns
312
- the narrow dependency contract it consumes.
313
-
314
- Tools use Zod for runtime input validation and named TypeScript types for results;
315
- output schemas are neither validated nor published. `defineTool` derives wire
316
- annotations from each tool's required `readOnlyHint`. Every server supplies a
317
- result store, while file-resource links point directly to guarded reads from disk.
318
-
319
- | Path | Purpose |
320
- | :-------------------- | :------------------------------------------------------------------------------ |
321
- | `src/core/path.ts` | `PathGuard` — validates every path against allowed roots |
322
- | `src/core/fs.ts` | `GuardedFileSystem` — guarded filesystem facade |
323
- | `src/tools/define.ts` | Tool registration and execution framework |
324
- | `src/tools/batch.ts` | Batch helpers (runOverPaths, summarize, isTotalFailure) |
325
- | `src/server.ts` | Builds shared dependencies and invokes the three registrars |
326
- | `src/transport/` | stdio (`stdio.ts`), Streamable HTTP (`http.ts`), HTTP policy (`http-policy.ts`) |
327
-
328
- ## Configuration
329
-
330
- The server starts with allowed directories from explicit startup configuration:
331
-
332
- 1. **Positional directories** passed to `filesystem-mcp`.
333
- 2. **Environment variable** `FS_ALLOWED_DIRS` (separated by `:` on POSIX or `;` on Windows).
334
- 3. **Current working directory** when `--allow-cwd` is enabled.
335
-
336
- When `--root-boundary` / `FS_ROOT_BOUNDARY` is set, a configured root that
337
- does not fall under it is skipped at startup with a warning; only roots under
338
- the boundary (and later grants under it) are allowed.
339
-
340
- Legacy MCP connections may additionally seed roots through the deprecated
341
- `roots/list` flow. Modern 2026-07-28 connections do not automatically send
342
- workspace roots. They can add access after startup by calling a tool with a
343
- concrete path and approving the elicitation-backed grant. `list_roots` reports
344
- the roots already configured or accepted; it cannot discover an unknown
345
- workspace by itself.
346
-
347
- Over HTTP, 2025-era clients are served statelessly: tools, resources and
348
- prompts work. Confirmations (recursive delete, overwrite, access grants) need a
349
- 2026-07-28 client or stdio and answer with a tool error saying so; file
350
- subscriptions are not advertised on that leg, and a `resources/subscribe` sent
351
- anyway is refused with method-not-found.
352
-
353
- ### Recommended global recipes
354
-
355
- #### VS Code / Cursor / Claude Code (primary recipe)
252
+ </details>
356
253
 
357
- Configure the project directory explicitly:
254
+ ## Tools
358
255
 
359
- Add to your global or project-scoped configuration:
360
-
361
- ```json
362
- {
363
- "mcpServers": {
364
- "filesystem": {
365
- "command": "npx",
366
- "args": ["-y", "@j0hanz/filesystem-mcp@latest", "/path/to/project"]
367
- }
368
- }
369
- }
370
- ```
256
+ | Tool | What it does |
257
+ | :--------------- | :------------------------------------------------------------------------------------------------------------ |
258
+ | `list_roots` | Shows the folders the server may use. |
259
+ | `list` | Lists a folder as a tree, like `ls` or `tree`. |
260
+ | `find_files` | Finds files by name or glob, such as `**/*.test.ts`. |
261
+ | `search_text` | Searches inside files for text or a regex, like `grep`, with optional context lines. |
262
+ | `stat` | Gets size, dates, type, permissions, and a token estimate without reading the file. |
263
+ | `read` | Reads one or many text files, whole or by line range, head, or tail. Images and audio come back as media. |
264
+ | `diff` | Compares two files and returns a unified diff. |
265
+ | `create` ✎ | Writes new files, or appends to them. Asks before replacing an existing file, unless `overwrite: true`. |
266
+ | `edit` ✎ | Replaces exact text in files. All edits to a file apply, or none do. `dryRun` shows the diff first. |
267
+ | `patch` ✎ | Applies a unified diff to a file. All hunks apply, or none do. |
268
+ | `replace_text` ✎ | Finds and replaces text or a regex across many files. `dryRun` shows what would change. |
269
+ | `move` ✎ | Moves, renames, or copies files and folders. Asks before overwriting, unless a copy passes `overwrite: true`. |
270
+ | `delete` ✎ | Deletes files and folders. Asks before deleting a non-empty folder. |
371
271
 
372
- #### Claude Desktop (fallback recipe via environment variable)
272
+ ✎ changes files. `--read-only` removes these tools.
373
273
 
374
- Claude Desktop and similar clients don't support the MCP Roots protocol. Use the `FS_ALLOWED_DIRS` environment variable to configure allowed folders.
274
+ Search and listing tools skip hidden files, `.gitignore`d files, and folders
275
+ like `node_modules`, `dist`, and `.git` unless the AI asks for them.
375
276
 
376
- Add to your `claude_desktop_config.json`:
277
+ ## Configuration
377
278
 
378
- ```json
379
- {
380
- "mcpServers": {
381
- "filesystem": {
382
- "command": "npx",
383
- "args": ["-y", "@j0hanz/filesystem-mcp@latest"],
384
- "env": {
385
- "FS_ALLOWED_DIRS": "/path/to/project1:/path/to/project2"
386
- }
387
- }
388
- }
389
- }
390
- ```
279
+ Most people only need the folder argument. These options cover the common
280
+ cases:
391
281
 
392
- _(On Windows, separate directories with a semicolon `;` instead of a colon `:`)._
282
+ | Option | What it does |
283
+ | :-------------------- | :--------------------------------------------------------------------------- |
284
+ | `--read-only` | Removes every tool that changes files. |
285
+ | `--deny '<pattern>'` | Blocks more files, for example `--deny 'private/**'` or `--deny '*.sqlite'`. |
286
+ | `--allow '<pattern>'` | Unblocks one built-in secret pattern, for example `--allow '.env.example'`. |
287
+ | `--allow-cwd` | Also allows the folder the server was started from. |
288
+ | `--max-file-size <n>` | Largest file `read` will load, in bytes. Default 10 MiB. |
289
+ | `--port <n>` | Serves over HTTP at `http://127.0.0.1:<n>/mcp` instead of stdio. |
290
+ | `--print-config` | Prints the settings the server would use, then exits. |
393
291
 
394
- ### Advanced / per-project positional arguments
292
+ Flags go in `args` after the package name, for example
293
+ `["-y", "@j0hanz/filesystem-mcp@latest", "--read-only", "/path/to/project"]`.
395
294
 
396
- You can also restrict access to specific directories by passing positional arguments directly:
295
+ The [full configuration reference](docs/configuration.md) covers every flag
296
+ and environment variable, the complete secret-file list, limits, HTTP setup
297
+ with API keys, Docker, and troubleshooting.
397
298
 
398
- ```bash
399
- # Start with explicit positional paths
400
- filesystem-mcp /path/to/project1 /path/to/project2
401
- ```
299
+ ## Security
402
300
 
403
- ---
404
-
405
- ### Configuration reference
406
-
407
- #### CLI flags
408
-
409
- | Flag | Default | Purpose |
410
- | :------------------------ | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
411
- | `[dirs...]` | — | One or more allowed root directories (positional). A whole argument `${NAME}` is read from the environment and dropped when unset |
412
- | `--allow-cwd` | `false` | Also allow the current working directory as a root |
413
- | `--walk-cwd` | `false` | Walk up from CWD to find a project root; implies `--allow-cwd` |
414
- | `--allow-missing-roots` | `false` | Start even if configured allowed directories do not exist |
415
- | `--port <n>` | — | Enable Streamable HTTP transport on the given port (env: `FS_PORT`) |
416
- | `--http-host <host>` | — | HTTP server bind address (env: `FS_HTTP_HOST`) |
417
- | `--api-key <key>` | — | Require this API key on HTTP requests (env: `FS_API_KEY`) |
418
- | `--read-only` | `false` | Disable write tools: `create`, `edit`, `delete`, `move`, `patch`, `replace_text` |
419
- | `--deny <pattern>` | — | Block paths matching this pattern; repeatable |
420
- | `--allow <pattern>` | — | Exempt a pattern from the built-in sensitive denylist; repeatable (env: `FS_ALLOWLIST`). Does not lift `--deny`/`FS_DENYLIST` entries |
421
- | `--allow-sensitive` | `false` | Allow access to sensitive system paths (env: `FS_ALLOW_SENSITIVE`) |
422
- | `--root-boundary <path>` | — | Require all allowed roots to fall under this path (env: `FS_ROOT_BOUNDARY`) |
423
- | `--max-file-size <bytes>` | — | Maximum file size for reads and the combined content of one create call, in bytes (env: `FS_MAX_FILE_SIZE`). Each transport accepts one message of up to 3 × this + 1 MiB |
424
- | `--log-level <level>` | `info` | RFC 5424 log level, `debug` through `emergency` (env: `FS_LOG_LEVEL`) |
425
- | `--print-config` | `false` | Print the active configuration as JSON (roots, tools, limits, policy, supported protocol revisions, SDK pins) and exit |
426
-
427
- `--deny` and `--allow` patterns support `*` (any run within a segment),
428
- `**` (any run of segments), `?`, `[...]` classes, and `{a,b}` alternation.
429
- Dot-leading (hidden) names match like any other — `secrets/**` denies
430
- `secrets/.env`, `*id_rsa*` denies `.id_rsa`.
431
-
432
- #### Environment variables
433
-
434
- All boolean variables accept `true` or `1` to enable and `false`, `0`, or
435
- unset to disable; any other value logs a warning and reads as disabled.
436
- Flags take precedence when both are set.
437
-
438
- | Variable | Purpose |
439
- | :---------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
440
- | `FS_ALLOWED_DIRS` | Colon-separated (POSIX) or semicolon-separated (Windows) list of directories to allow. |
441
- | `FS_ROOT_BOUNDARY` | Path prefix all allowed roots must fall under (mirrors `--root-boundary`). |
442
- | `FS_ALLOW_CWD_WALK` | Walk up from CWD to find a project root (mirrors `--walk-cwd`). |
443
- | `FS_ALLOW_MISSING_ROOTS` | Start even if configured directories do not exist (mirrors `--allow-missing-roots`). |
444
- | `FS_ALLOW_SENSITIVE` | Allow access to sensitive system paths (mirrors `--allow-sensitive`). |
445
- | `FS_DENYLIST` | Comma-separated list of paths or patterns to block (mirrors `--deny`). |
446
- | `FS_ALLOWLIST` | Comma-separated patterns exempted from the built-in sensitive denylist (mirrors `--allow`). Never lifts `FS_DENYLIST`/`--deny` entries. |
447
- | `FS_MAX_FILE_SIZE` | Maximum file size for reads and for one create call's combined content, in bytes (mirrors `--max-file-size`). Also sizes the per-message wire limit: 3 × this + 1 MiB. |
448
- | `FS_LOG_LEVEL` | RFC 5424 log level: `debug`, `info`, `notice`, `warn`/`warning`, `error`, `critical`, `alert`, or `emergency` (mirrors `--log-level`). |
449
- | `FS_PORT` | Start the Streamable HTTP transport on this port; unset = stdio (mirrors `--port`). |
450
- | `FS_HTTP_HOST` | HTTP server bind address (mirrors `--http-host`). |
451
- | `FS_API_KEY` | API key required on HTTP requests (mirrors `--api-key`). |
452
- | `FS_TRUST_PROXY` | Express `trust proxy` setting: hop count or expression. Unset = do not trust `X-Forwarded-*`. |
453
- | `FS_ALLOWED_HOSTS` | Comma-separated Host header values to accept (HTTP transport). |
454
- | `FS_ALLOWED_ORIGINS` | Comma-separated origin hostnames allowed to call `/mcp` from a browser. Replaces the localhost default, so also list `localhost`, `127.0.0.1` or `[::1]` if local browser clients still need access. For browser-extension clients, list the extension ID (the hostname of a `chrome-extension://` origin) or a lowercase `<scheme>://*` entry such as `moz-extension://*` to admit every extension of that scheme; `http://*` and `https://*` are not honoured. |
455
- | `FS_ALLOW_UNRESTRICTED_HOSTS` | Bind a wildcard host with no Host validation (accepts the risk). |
456
- | `FS_PUBLIC_URL` | Resource identifier URL for RFC 9728 discovery. |
457
- | `FS_RATE_LIMIT_RPM` | Per-client-IP requests/minute (default 120 with API-key authentication, 6,000 for keyless loopback; range 1–100000). |
458
- | `FS_MAX_WATCHERS` | Max concurrent file watchers (default 256, 1–4096). |
459
- | `NO_COLOR` | Any value disables ANSI color output. |
460
- | `FS_REQUEST_STATE_KEY` | HMAC key sealing `input_required` requestState across retry rounds. Optional (random per boot if unset); set it, at >=32 bytes UTF-8, to keep in-flight rounds alive across a restart. |
461
-
462
- ### Examples
463
-
464
- ```bash
465
- # Allow current working directory
466
- filesystem-mcp --allow-cwd
467
-
468
- # HTTP transport on port 3000
469
- filesystem-mcp --port 3000
301
+ | Protection | How it works |
302
+ | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
303
+ | Folder sandbox | The server resolves every path, including symlinks, and the resolved path must stay inside an allowed folder. |
304
+ | Secret files | `.env`, `*.pem`, `*.key`, SSH keys, `.npmrc`, cloud credentials, and [more](docs/configuration.md#secret-files) are blocked and hidden from listings. |
305
+ | You stay in charge | The server asks you before the AI deletes a non-empty folder, gets access to a new folder, or writes over a file with `create` or `move`. Only `create` and copies skip that question, when the AI passes `overwrite: true`. In-place edits (`edit`, `patch`, `replace_text`) do not ask, but `dryRun` previews them. A client that cannot ask gets a clear error instead. |
306
+ | Off-limits folders | Neither the AI nor the client can ever add your home folder itself, system folders, or `~/.ssh`, `~/.aws`, and similar folders. |
307
+ | Safe writes | New content goes to a temporary file that is then renamed into place, so a crash never leaves a half-written file. Writes keep the file's permissions. |
308
+ | No regex hangs | RE2 runs in linear time, so no search pattern can freeze the server. |
309
+ | HTTP | The server listens only on localhost by default. Any other address requires an API key. |
310
+ | Container | The Docker image runs as a non-root user. |
311
+
312
+ If you find a vulnerability, please report it privately.
313
+ [SECURITY.md](SECURITY.md) explains how.
314
+
315
+ ## Build your own client
316
+
317
+ You can also call Filesystem MCP from your own code: an agent, an editor
318
+ plugin, a web app, a CI job, or a script. The same rules apply as for an AI
319
+ app, so your code cannot reach outside the allowed folders or read secret
320
+ files.
321
+
322
+ ```ts
323
+ import { Client } from '@modelcontextprotocol/client';
324
+ import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';
325
+
326
+ const dir = '/path/to/project';
327
+ const client = new Client(
328
+ { name: 'my-app', version: '1.0.0' },
329
+ { capabilities: { elicitation: { form: {} } }, versionNegotiation: { mode: 'auto' } },
330
+ );
331
+ client.setRequestHandler('elicitation/create', async () => ({ action: 'decline' }));
332
+ await client.connect(
333
+ new StdioClientTransport({
334
+ command: 'npx',
335
+ args: ['-y', '@j0hanz/filesystem-mcp', dir],
336
+ cwd: dir,
337
+ }),
338
+ );
339
+
340
+ const result = await client.callTool({ name: 'search_text', arguments: { searchPattern: 'TODO' } });
341
+ const { matches } = (result.structuredContent ?? result._meta) as { matches: unknown[] };
342
+ console.log(matches);
343
+ await client.close(); // stops the server process; without it the script never exits
470
344
  ```
471
345
 
472
- ## Scripts
473
-
474
- | Mode | Command | Description |
475
- | :--------------- | :--------------------- | :--------------------------------------------------- |
476
- | Full check | `npm run check` | Run build, type check, lint, format, knip, and tests |
477
- | Auto-fix + check | `npm run fix` | Auto-fix formatting/linting and run the full check |
478
- | Static only | `npm run check:static` | Run static analysis without tests |
479
- | Tests only | `npm test` | Run tests; accepts native `node --test` options |
480
-
481
- ## Security
346
+ The basics:
347
+
348
+ - **Where the data is.** The text block is written for a model. The same data
349
+ as JSON is in `_meta` for tools that write their own text (`list`,
350
+ `search_text`, `edit`, ...) and in `structuredContent` for `stat`,
351
+ `create`, and `list_roots`. `read` is the exception: the file's text is
352
+ only in the text block, and `_meta` holds metadata about it.
353
+ - **Paths.** Relative paths resolve against the server's working directory,
354
+ not its root: set `cwd` over stdio, and send absolute paths over HTTP.
355
+ - **Confirmations.** Overwrites, recursive deletes, and paths outside the
356
+ roots are questions for the user. Declare the `elicitation` capability and
357
+ answer them in a handler, or, on the 2026-07-28 protocol, take them as data
358
+ (`input_required`) and answer later.
359
+ - **Protocol versions.** The server speaks the 2025 protocol and 2026-07-28,
360
+ over stdio and Streamable HTTP. Over HTTP, 2025-era clients get no
361
+ confirmations or change notifications.
362
+ - **Resources.** Read and subscribe to any file as
363
+ `filesystem-mcp://file/{+path}`; `internal://instructions` and the
364
+ `get-help` prompt hold the server's guide for models.
365
+
366
+ The [client guide](docs/client-guide.md) has the details, tested with the
367
+ TypeScript and Python SDKs, and [`examples/`](examples/) has six runnable
368
+ clients:
369
+
370
+ | Example | What it is |
371
+ | :----------------------------------------- | :------------------------------------------------------------------ |
372
+ | [fsq](examples/clients/fsq/) | Any tool from your shell, over stdio or HTTP; `--json` for scripts |
373
+ | [browser](examples/clients/browser/) | A local web UI where the server's questions appear in the page |
374
+ | [tail](examples/clients/tail/) | `tail -f` through file subscriptions, locally or on a remote server |
375
+ | [gatekeeper](examples/clients/gatekeeper/) | A coding agent that shows each change's diff and waits for your y/N |
376
+ | [hooks](examples/clients/hooks/) | Runs a task through a model whenever the workspace changes |
377
+ | [python](examples/clients/python/) | A TODO report for a workspace, with the Python SDK |
482
378
 
483
- > [!IMPORTANT]
484
- > Report vulnerabilities privately via [GitHub Security Advisories](https://github.com/j0hanz/filesystem-mcp/security/advisories). Do not open public issues for security reports.
379
+ ## Privacy Policy
485
380
 
486
- | Topic | Detail |
487
- | :-------------- | :------------------------------------------------------------------------------ |
488
- | Path traversal | Every path is resolved and validated against allowed roots before any operation |
489
- | Sensitive files | `.env`, `*.pem`, `*id_rsa*`, and similar patterns are denied by default |
490
- | Regex safety | RE2 cannot backtrack, so a hostile pattern cannot hang the server (ReDoS) |
491
- | Container | Runs as non-root `mcp` user; bind mounts control what is exposed |
381
+ Filesystem MCP runs entirely on your machine. This policy covers the npm
382
+ package, the Docker image, and the `.mcpb` desktop extension.
383
+
384
+ - **Data collection:** none. The server has no telemetry, analytics, or crash
385
+ reporting, and makes no outbound network requests.
386
+ - **Use and storage:** files are read and written only inside the folders you
387
+ allow, and only when your MCP client calls a tool. Tool results go to that
388
+ client and nowhere else. Short-lived result caches live in memory and
389
+ disappear when the server exits.
390
+ - **Third-party sharing:** none by this server. Your MCP client may send tool
391
+ results to its model provider under that client's own privacy policy.
392
+ - **Retention:** nothing is kept after the process exits. Diagnostic logs go to
393
+ stderr on your machine; your MCP client may save them in its own log files.
394
+ - **Contact:** open an issue at
395
+ <https://github.com/j0hanz/filesystem-mcp/issues>, or report security
396
+ problems privately through
397
+ [GitHub Security Advisories](https://github.com/j0hanz/filesystem-mcp/security/advisories).
492
398
 
493
399
  ## Contributing
494
400
 
495
- 1. Fork the repository.
496
- 2. Create a feature branch: `git checkout -b feat/your-feature`.
497
- 3. Commit your changes with a clear message.
498
- 4. Run `npm run check` to confirm tests, types, lint, formatting, and knip all pass.
499
- 5. Open a pull request.
500
-
501
- [![Contributors](https://contrib.rocks/image?repo=j0hanz/filesystem-mcp)](https://github.com/j0hanz/filesystem-mcp/graphs/contributors)
502
-
503
- ## Privacy Policy
401
+ Bug reports, ideas, and pull requests are welcome. Start with
402
+ [CONTRIBUTING.md](CONTRIBUTING.md): it covers setup, running the server from
403
+ source, and the checks a pull request needs.
504
404
 
505
- filesystem-mcp runs entirely on your machine. This policy covers the npm package, the Docker image, and the `.mcpb` desktop extension.
405
+ If Filesystem MCP is useful to you, a star on GitHub helps other people find it.
506
406
 
507
- - **Data collection:** none. The server has no telemetry, analytics, or crash reporting, and makes no outbound network requests.
508
- - **Use and storage:** files are read and written only inside the directories you allow, and only when your MCP client calls a tool. Tool results go to that client and nowhere else. Short-lived result caches live in memory and disappear when the server exits.
509
- - **Third-party sharing:** none by this server. Your MCP client may send tool results to its model provider under that client's own privacy policy.
510
- - **Retention:** nothing is kept after the process exits. Diagnostic logs go to stderr on your machine; your MCP client may save them in its own log files.
511
- - **Contact:** open an issue at <https://github.com/j0hanz/filesystem-mcp/issues>, or report security problems privately through [GitHub Security Advisories](https://github.com/j0hanz/filesystem-mcp/security/advisories).
407
+ [![Contributors](https://contrib.rocks/image?repo=j0hanz/filesystem-mcp)](https://github.com/j0hanz/filesystem-mcp/graphs/contributors)
512
408
 
513
409
  ## License
514
410
 
515
- Released under the MIT License. See [LICENSE](LICENSE) for details.
411
+ [MIT](LICENSE)