@j0hanz/fs-context-mcp 2.2.0 → 2.3.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.
- package/README.md +171 -417
- package/dist/assets/logo.svg +3766 -0
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/lib/constants.d.ts +0 -1
- package/dist/lib/constants.js +0 -1
- package/dist/lib/errors.d.ts +0 -1
- package/dist/lib/errors.js +0 -1
- package/dist/lib/file-operations/file-info.d.ts +0 -1
- package/dist/lib/file-operations/file-info.js +0 -1
- package/dist/lib/file-operations/gitignore.d.ts +0 -1
- package/dist/lib/file-operations/gitignore.js +0 -1
- package/dist/lib/file-operations/glob-engine.d.ts +0 -1
- package/dist/lib/file-operations/glob-engine.js +101 -84
- package/dist/lib/file-operations/list-directory.d.ts +0 -1
- package/dist/lib/file-operations/list-directory.js +91 -62
- package/dist/lib/file-operations/read-multiple-files.d.ts +0 -1
- package/dist/lib/file-operations/read-multiple-files.js +0 -1
- package/dist/lib/file-operations/search-content.d.ts +0 -1
- package/dist/lib/file-operations/search-content.js +68 -21
- package/dist/lib/file-operations/search-files.d.ts +0 -1
- package/dist/lib/file-operations/search-files.js +21 -11
- package/dist/lib/file-operations/search-worker.d.ts +0 -1
- package/dist/lib/file-operations/search-worker.js +0 -1
- package/dist/lib/file-operations/tree.d.ts +0 -1
- package/dist/lib/file-operations/tree.js +18 -8
- package/dist/lib/fs-helpers.d.ts +0 -1
- package/dist/lib/fs-helpers.js +19 -25
- package/dist/lib/observability.d.ts +0 -1
- package/dist/lib/observability.js +49 -43
- package/dist/lib/path-policy.d.ts +0 -1
- package/dist/lib/path-policy.js +0 -1
- package/dist/lib/path-validation.d.ts +0 -1
- package/dist/lib/path-validation.js +54 -38
- package/dist/lib/resource-store.d.ts +0 -1
- package/dist/lib/resource-store.js +0 -1
- package/dist/resources.d.ts +2 -3
- package/dist/resources.js +16 -3
- package/dist/schemas.d.ts +0 -1
- package/dist/schemas.js +35 -51
- package/dist/server.d.ts +0 -1
- package/dist/server.js +42 -11
- package/dist/tools/list-directory.d.ts +0 -1
- package/dist/tools/list-directory.js +14 -2
- package/dist/tools/read-multiple.d.ts +0 -1
- package/dist/tools/read-multiple.js +14 -2
- package/dist/tools/read.d.ts +0 -1
- package/dist/tools/read.js +14 -2
- package/dist/tools/roots.d.ts +0 -1
- package/dist/tools/roots.js +14 -2
- package/dist/tools/search-content.d.ts +0 -1
- package/dist/tools/search-content.js +29 -14
- package/dist/tools/search-files.d.ts +0 -1
- package/dist/tools/search-files.js +14 -2
- package/dist/tools/shared.d.ts +7 -1
- package/dist/tools/shared.js +7 -4
- package/dist/tools/stat-many.d.ts +0 -1
- package/dist/tools/stat-many.js +14 -2
- package/dist/tools/stat.d.ts +0 -1
- package/dist/tools/stat.js +14 -2
- package/dist/tools/tree.d.ts +0 -1
- package/dist/tools/tree.js +14 -2
- package/dist/tools.d.ts +0 -1
- package/dist/tools.js +0 -1
- package/package.json +22 -19
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/constants.d.ts.map +0 -1
- package/dist/lib/constants.js.map +0 -1
- package/dist/lib/errors.d.ts.map +0 -1
- package/dist/lib/errors.js.map +0 -1
- package/dist/lib/file-operations/file-info.d.ts.map +0 -1
- package/dist/lib/file-operations/file-info.js.map +0 -1
- package/dist/lib/file-operations/gitignore.d.ts.map +0 -1
- package/dist/lib/file-operations/gitignore.js.map +0 -1
- package/dist/lib/file-operations/glob-engine.d.ts.map +0 -1
- package/dist/lib/file-operations/glob-engine.js.map +0 -1
- package/dist/lib/file-operations/list-directory.d.ts.map +0 -1
- package/dist/lib/file-operations/list-directory.js.map +0 -1
- package/dist/lib/file-operations/read-multiple-files.d.ts.map +0 -1
- package/dist/lib/file-operations/read-multiple-files.js.map +0 -1
- package/dist/lib/file-operations/search-content.d.ts.map +0 -1
- package/dist/lib/file-operations/search-content.js.map +0 -1
- package/dist/lib/file-operations/search-files.d.ts.map +0 -1
- package/dist/lib/file-operations/search-files.js.map +0 -1
- package/dist/lib/file-operations/search-worker.d.ts.map +0 -1
- package/dist/lib/file-operations/search-worker.js.map +0 -1
- package/dist/lib/file-operations/tree.d.ts.map +0 -1
- package/dist/lib/file-operations/tree.js.map +0 -1
- package/dist/lib/fs-helpers.d.ts.map +0 -1
- package/dist/lib/fs-helpers.js.map +0 -1
- package/dist/lib/observability.d.ts.map +0 -1
- package/dist/lib/observability.js.map +0 -1
- package/dist/lib/path-policy.d.ts.map +0 -1
- package/dist/lib/path-policy.js.map +0 -1
- package/dist/lib/path-validation.d.ts.map +0 -1
- package/dist/lib/path-validation.js.map +0 -1
- package/dist/lib/resource-store.d.ts.map +0 -1
- package/dist/lib/resource-store.js.map +0 -1
- package/dist/resources.d.ts.map +0 -1
- package/dist/resources.js.map +0 -1
- package/dist/schemas.d.ts.map +0 -1
- package/dist/schemas.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/tools/list-directory.d.ts.map +0 -1
- package/dist/tools/list-directory.js.map +0 -1
- package/dist/tools/read-multiple.d.ts.map +0 -1
- package/dist/tools/read-multiple.js.map +0 -1
- package/dist/tools/read.d.ts.map +0 -1
- package/dist/tools/read.js.map +0 -1
- package/dist/tools/roots.d.ts.map +0 -1
- package/dist/tools/roots.js.map +0 -1
- package/dist/tools/search-content.d.ts.map +0 -1
- package/dist/tools/search-content.js.map +0 -1
- package/dist/tools/search-files.d.ts.map +0 -1
- package/dist/tools/search-files.js.map +0 -1
- package/dist/tools/shared.d.ts.map +0 -1
- package/dist/tools/shared.js.map +0 -1
- package/dist/tools/stat-many.d.ts.map +0 -1
- package/dist/tools/stat-many.js.map +0 -1
- package/dist/tools/stat.d.ts.map +0 -1
- package/dist/tools/stat.js.map +0 -1
- package/dist/tools/tree.d.ts.map +0 -1
- package/dist/tools/tree.js.map +0 -1
- package/dist/tools.d.ts.map +0 -1
- package/dist/tools.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,100 +1,66 @@
|
|
|
1
1
|
# FS Context MCP Server
|
|
2
2
|
|
|
3
|
-
<img src="
|
|
3
|
+
<img src="assets/logo.svg" alt="SuperFetch MCP Logo" width="300">
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[](https://www.npmjs.com/package/@j0hanz/fs-context-mcp)
|
|
8
|
-
[](LICENSE)
|
|
9
|
-
[](https://nodejs.org)
|
|
10
|
-
[](https://www.typescriptlang.org/)
|
|
11
|
-
[](https://modelcontextprotocol.io)
|
|
12
|
-
|
|
13
|
-
## One-Click Install
|
|
5
|
+
[](https://www.npmjs.com/package/@j0hanz/fs-context-mcp) [](LICENSE) [](https://nodejs.org) [](https://www.typescriptlang.org/) [](https://modelcontextprotocol.io)
|
|
14
6
|
|
|
15
7
|
[](https://insiders.vscode.dev/redirect/mcp/install?name=fs-context&inputs=%5B%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffs-context-mcp%40latest%22%2C%22%24%7BworkspaceFolder%7D%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=fs-context&inputs=%5B%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ffs-context-mcp%40latest%22%2C%22%24%7BworkspaceFolder%7D%22%5D%7D&quality=insiders)
|
|
16
8
|
|
|
17
|
-
|
|
9
|
+
Read-only Model Context Protocol (MCP) server for secure filesystem exploration, searching, and analysis.
|
|
18
10
|
|
|
19
11
|
## Overview
|
|
20
12
|
|
|
21
|
-
This server enables AI assistants to navigate your filesystem through a set of read-only tools
|
|
22
|
-
|
|
23
|
-
- Explore directory structures with `ls` and `tree`
|
|
24
|
-
- Find files using glob patterns with `find`
|
|
25
|
-
- Search file contents with `grep`
|
|
26
|
-
- Read files with options for previews, line ranges, and batch operations
|
|
27
|
-
- Access file metadata through `stat` and `stat_many`
|
|
28
|
-
|
|
29
|
-
All operations are restricted to explicitly approved directories, with no write or modification capabilities.
|
|
30
|
-
|
|
31
|
-
## Features
|
|
32
|
-
|
|
33
|
-
### Directory Operations
|
|
13
|
+
This server enables AI assistants to navigate your filesystem through a set of read-only tools. It provides capabilities to explore directory structures, find files using glob patterns, search file contents with grep, read files (including batch operations), and access file metadata—all restricted to explicitly approved directories.
|
|
34
14
|
|
|
35
|
-
|
|
36
|
-
- Render directory trees with configurable depth using `tree`
|
|
37
|
-
- Find files by glob patterns with `find`
|
|
15
|
+
## Key Features
|
|
38
16
|
|
|
39
|
-
|
|
17
|
+
- **Read-Only Security**: No write, delete, or modify permissions.
|
|
18
|
+
- **Allowed Roots**: Access is strictly limited to configured directories.
|
|
19
|
+
- **Directory Exploration**: List contents (`ls`) and visualize structures (`tree`).
|
|
20
|
+
- **File Search**: Find files by name or pattern (`find`) and search content (`grep`).
|
|
21
|
+
- **File Reading**: Read single (`read`) or multiple (`read_many`) files with line-range support.
|
|
22
|
+
- **Metadata**: Retrieve file stats (`stat`, `stat_many`) including size and timestamps.
|
|
23
|
+
- **Large File Handling**: Automatic truncation and pagination for large outputs.
|
|
24
|
+
- **Ignore Support**: Respects `.gitignore` and common ignore patterns by default.
|
|
40
25
|
|
|
41
|
-
|
|
42
|
-
- Batch read up to 100 files in a single operation
|
|
43
|
-
- Get file metadata (size, timestamps, permissions) with `stat` and `stat_many`
|
|
26
|
+
## Tech Stack
|
|
44
27
|
|
|
45
|
-
|
|
28
|
+
- **Runtime**: Node.js >= 22.19.8
|
|
29
|
+
- **Language**: TypeScript 5.9.3
|
|
30
|
+
- **MCP SDK**: @modelcontextprotocol/sdk 1.25.3
|
|
31
|
+
- **Libraries**: `zod` (validation), `re2` (safe regex), `ignore` (filtering)
|
|
46
32
|
|
|
47
|
-
|
|
48
|
-
- Respects root `.gitignore` patterns and common ignore directories
|
|
49
|
-
- Configurable search timeout and worker threads
|
|
33
|
+
## Repository Structure
|
|
50
34
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
35
|
+
```text
|
|
36
|
+
src/
|
|
37
|
+
├── tools/ # Tool implementations (read, find, grep, etc.)
|
|
38
|
+
├── lib/ # Core logic (filesystem, validation, errors)
|
|
39
|
+
├── index.ts # CLI entrypoint
|
|
40
|
+
├── server.ts # MCP server setup and roots management
|
|
41
|
+
├── tools.ts # Tool registration
|
|
42
|
+
├── resources.ts # Resource registration
|
|
43
|
+
├── schemas.ts # Zod schemas for inputs/outputs
|
|
44
|
+
└── config.ts # Shared configuration types
|
|
45
|
+
```
|
|
60
46
|
|
|
61
|
-
|
|
62
|
-
| ------------------------------- | ----------- |
|
|
63
|
-
| Explore project structure | `ls` |
|
|
64
|
-
| Render a directory tree | `tree` |
|
|
65
|
-
| Find files | `find` |
|
|
66
|
-
| Search for code patterns/text | `grep` |
|
|
67
|
-
| Read source code | `read` |
|
|
68
|
-
| Batch read multiple files | `read_many` |
|
|
69
|
-
| Get file metadata (size, dates) | `stat` |
|
|
70
|
-
| Batch get file metadata | `stat_many` |
|
|
71
|
-
| Check available directories | `roots` |
|
|
47
|
+
## Requirements
|
|
72
48
|
|
|
73
|
-
|
|
49
|
+
- Node.js >= 22.19.8
|
|
74
50
|
|
|
75
|
-
|
|
51
|
+
## Quickstart
|
|
76
52
|
|
|
77
|
-
|
|
53
|
+
Use `npx` to run the server directly.
|
|
78
54
|
|
|
79
55
|
```bash
|
|
80
56
|
npx -y @j0hanz/fs-context-mcp@latest --allow-cwd
|
|
81
57
|
```
|
|
82
58
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
npx -y @j0hanz/fs-context-mcp@latest /path/to/project /path/to/docs
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
> **Note:** If your MCP client supports the Roots protocol, you can omit directory arguments—the client will provide them automatically.
|
|
90
|
-
|
|
91
|
-
### VS Code
|
|
92
|
-
|
|
93
|
-
Add to `.vscode/mcp.json`:
|
|
59
|
+
### VS Code Configuration
|
|
94
60
|
|
|
95
61
|
```json
|
|
96
62
|
{
|
|
97
|
-
"
|
|
63
|
+
"mcpServers": {
|
|
98
64
|
"fs-context": {
|
|
99
65
|
"command": "npx",
|
|
100
66
|
"args": ["-y", "@j0hanz/fs-context-mcp@latest", "${workspaceFolder}"]
|
|
@@ -105,322 +71,181 @@ Add to `.vscode/mcp.json`:
|
|
|
105
71
|
|
|
106
72
|
## Installation
|
|
107
73
|
|
|
108
|
-
### NPX
|
|
109
|
-
|
|
110
|
-
Run without installation:
|
|
74
|
+
### NPX (Recommended)
|
|
111
75
|
|
|
112
76
|
```bash
|
|
113
|
-
npx -y @j0hanz/fs-context-mcp@latest /path/to/
|
|
77
|
+
npx -y @j0hanz/fs-context-mcp@latest /path/to/directory
|
|
114
78
|
```
|
|
115
79
|
|
|
116
80
|
### Global Installation
|
|
117
81
|
|
|
118
|
-
For permanent setup across all projects:
|
|
119
|
-
|
|
120
82
|
```bash
|
|
121
83
|
npm install -g @j0hanz/fs-context-mcp
|
|
122
|
-
fs-context-mcp /path/to/
|
|
84
|
+
fs-context-mcp /path/to/directory
|
|
123
85
|
```
|
|
124
86
|
|
|
125
87
|
### From Source
|
|
126
88
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
git clone https://github.com/j0hanz/fs-context-mcp-server.git
|
|
131
|
-
cd fs-context-mcp-server
|
|
132
|
-
npm install
|
|
133
|
-
npm run build
|
|
134
|
-
node dist/index.js /path/to/your/project
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Directory Access and Resolution
|
|
138
|
-
|
|
139
|
-
Access is always restricted to explicitly allowed directories.
|
|
140
|
-
|
|
141
|
-
1. CLI directories are validated and added first (if provided).
|
|
142
|
-
2. `--allow-cwd` optionally adds the current working directory.
|
|
143
|
-
3. MCP Roots from the client are used next:
|
|
144
|
-
- If CLI and/or `--allow-cwd` are provided, only roots inside those baseline directories are accepted.
|
|
145
|
-
- If no baseline is provided, roots become the allowed directories.
|
|
146
|
-
4. If nothing is configured and the client provides no roots, the server starts with no accessible directories and logs a warning until roots are provided.
|
|
147
|
-
|
|
148
|
-
Notes:
|
|
149
|
-
|
|
150
|
-
- Windows drive-relative paths like `C:path` are rejected. Use `C:\path` or `C:/path`.
|
|
151
|
-
- Reserved Windows device names (e.g., `CON`, `NUL`) are blocked.
|
|
152
|
-
- If multiple roots are configured, tools require an explicit `path` to disambiguate.
|
|
153
|
-
- When multiple roots are configured, relative paths are rejected; provide an absolute path within the desired root.
|
|
154
|
-
|
|
155
|
-
## Configuration
|
|
156
|
-
|
|
157
|
-
All configuration is optional. Sizes in bytes, timeouts in milliseconds.
|
|
158
|
-
|
|
159
|
-
### Environment Variables
|
|
160
|
-
|
|
161
|
-
| Variable | Default | Description |
|
|
162
|
-
| ---------------------------- | ----------------- | ----------------------------------------------------------------- |
|
|
163
|
-
| `MAX_FILE_SIZE` | 10MB | Max file size for read operations (range: 1MB-100MB) |
|
|
164
|
-
| `MAX_READ_MANY_TOTAL_SIZE` | 512KB | Max combined size for `read_many` (range: 10KB-100MB) |
|
|
165
|
-
| `MAX_SEARCH_SIZE` | 1MB | Max file size for content search (range: 100KB-10MB) |
|
|
166
|
-
| `DEFAULT_SEARCH_TIMEOUT` | 30000 | Timeout for search/list operations (range: 100-3600000ms) |
|
|
167
|
-
| `FS_CONTEXT_SEARCH_WORKERS` | min(cpu cores, 8) | Search worker threads (range: 0-16; 0 disables) |
|
|
168
|
-
| `FS_CONTEXT_ALLOW_SENSITIVE` | false | Allow reading sensitive files (set to `true` to disable denylist) |
|
|
169
|
-
| `FS_CONTEXT_DENYLIST` | (empty) | Additional denylist patterns (comma-separated globs) |
|
|
170
|
-
| `FS_CONTEXT_ALLOWLIST` | (empty) | Allowlist patterns that override denylist (comma-separated globs) |
|
|
171
|
-
| `FS_CONTEXT_TOOL_LOG_ERRORS` | false | Log tool failures to stderr with duration |
|
|
172
|
-
|
|
173
|
-
See [CONFIGURATION.md](CONFIGURATION.md) for examples and CLI usage.
|
|
174
|
-
|
|
175
|
-
### Sensitive File Policy
|
|
176
|
-
|
|
177
|
-
By default, reads and content searches are blocked for common secret filenames to reduce accidental leakage. The default denylist includes patterns like `.env`, `.npmrc`, `.aws/credentials`, `*.pem`, and `.mcpregistry_*_token`.
|
|
178
|
-
|
|
179
|
-
You can customize with:
|
|
180
|
-
|
|
181
|
-
- `FS_CONTEXT_ALLOW_SENSITIVE=true` to disable the default denylist.
|
|
182
|
-
- `FS_CONTEXT_DENYLIST` to add extra deny patterns (comma-separated globs using `*`).
|
|
183
|
-
- `FS_CONTEXT_ALLOWLIST` to allow specific paths even if they match the denylist.
|
|
184
|
-
|
|
185
|
-
Sensitive denylist patterns also filter `ls`, `find`, `tree`, and `stat` results by default to avoid revealing secret filenames.
|
|
186
|
-
|
|
187
|
-
## Resources
|
|
188
|
-
|
|
189
|
-
This server exposes standard MCP resources to provide static documentation and handle large content efficiently.
|
|
190
|
-
|
|
191
|
-
| Resource URI | Description |
|
|
192
|
-
| :------------------------- | :---------------------------------------------------------------------------------- |
|
|
193
|
-
| `internal://instructions` | Returns the detailed usage instructions (Markdown) for this server. |
|
|
194
|
-
| `fs-context://result/{id}` | Access to large file content or search results that were truncated in tool outputs. |
|
|
89
|
+
1. Clone the repository:
|
|
195
90
|
|
|
196
|
-
|
|
197
|
-
|
|
91
|
+
```bash
|
|
92
|
+
git clone https://github.com/j0hanz/fs-context-mcp-server.git
|
|
93
|
+
cd fs-context-mcp-server
|
|
94
|
+
```
|
|
198
95
|
|
|
199
|
-
|
|
96
|
+
2. Install dependencies:
|
|
200
97
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
98
|
+
```bash
|
|
99
|
+
npm ci
|
|
100
|
+
```
|
|
204
101
|
|
|
205
|
-
|
|
102
|
+
3. Build the project:
|
|
206
103
|
|
|
207
|
-
|
|
104
|
+
```bash
|
|
105
|
+
npm run build
|
|
106
|
+
```
|
|
208
107
|
|
|
209
|
-
|
|
210
|
-
| --------- | ---- | -------- | ------- | ----------- |
|
|
211
|
-
| (none) | - | - | - | - |
|
|
108
|
+
4. Run the server:
|
|
212
109
|
|
|
213
|
-
|
|
214
|
-
|
|
110
|
+
```bash
|
|
111
|
+
node dist/index.js /path/to/directory
|
|
112
|
+
```
|
|
215
113
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
### `ls`
|
|
219
|
-
|
|
220
|
-
List the immediate contents of a directory (non-recursive). Omit `path` to use
|
|
221
|
-
the sole allowed root (when only one root is configured).
|
|
222
|
-
|
|
223
|
-
| Parameter | Type | Required | Default | Description |
|
|
224
|
-
| --------------- | ------- | -------- | ----------- | ------------------------------------------------------- |
|
|
225
|
-
| `path` | string | No | `only root` | Directory path to list (omit when only one root exists) |
|
|
226
|
-
| `includeHidden` | boolean | No | `false` | Include hidden files and directories |
|
|
227
|
-
|
|
228
|
-
Returns: Entries with name, relativePath, type, size, and modified time.
|
|
229
|
-
Structured output includes `ok`, `path`, `entries`, and `totalEntries`.
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
### `find`
|
|
234
|
-
|
|
235
|
-
Search for files using glob patterns. Omit `path` to search from the sole
|
|
236
|
-
allowed root (when only one root is configured). By default, `find` excludes common dependency/build directories
|
|
237
|
-
(node_modules, dist, .git, etc.); set `includeIgnored: true` to include ignored
|
|
238
|
-
directories and disable built-in excludes.
|
|
239
|
-
|
|
240
|
-
| Parameter | Type | Required | Default | Description |
|
|
241
|
-
| ---------------- | ------- | -------- | ----------- | -------------------------------------------------------------- |
|
|
242
|
-
| `path` | string | No | `only root` | Base directory to search from (omit when only one root exists) |
|
|
243
|
-
| `pattern` | string | Yes | - | Glob pattern (e.g., `**/*.ts`, `src/**/*.js`) |
|
|
244
|
-
| `includeIgnored` | boolean | No | `false` | Include ignored dirs and disable built-in excludes |
|
|
245
|
-
| `maxResults` | number | No | `100` | Maximum matches to return (1-10000) |
|
|
246
|
-
|
|
247
|
-
Notes:
|
|
248
|
-
|
|
249
|
-
- When `includeIgnored=false`, results also respect a root `.gitignore` file (if present under the base `path`).
|
|
250
|
-
- Nested `.gitignore` files are not parsed.
|
|
251
|
-
|
|
252
|
-
Returns: Matching paths (relative) with size and modified date. Structured
|
|
253
|
-
output includes `ok`, `results`, `totalMatches`, and `truncated`.
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
### `tree`
|
|
258
|
-
|
|
259
|
-
Render a directory tree (bounded recursion). Omit `path` to use the sole
|
|
260
|
-
allowed root (when only one root is configured).
|
|
261
|
-
|
|
262
|
-
- `path` (string, optional; default: `only root`): Base directory to render
|
|
263
|
-
- `maxDepth` (number, optional; default: `5`): Maximum recursion depth (0 = just the root)
|
|
264
|
-
- `maxEntries` (number, optional; default: `1000`): Maximum number of entries before truncating
|
|
265
|
-
- `includeHidden` (boolean, optional; default: `false`): Include hidden files/directories
|
|
266
|
-
- `includeIgnored` (boolean, optional; default: `false`): Include ignored dirs and disable built-in + `.gitignore` filtering
|
|
267
|
-
|
|
268
|
-
Notes:
|
|
269
|
-
|
|
270
|
-
- When `includeIgnored=false`, the tree respects both built-in ignore rules (e.g., `node_modules`, `dist`, `.git`) and a root `.gitignore` file (if present).
|
|
271
|
-
|
|
272
|
-
Returns: ASCII tree output plus a structured JSON tree (`ok`, `root`, `tree`,
|
|
273
|
-
`ascii`, `truncated`, `totalEntries`).
|
|
274
|
-
|
|
275
|
-
---
|
|
276
|
-
|
|
277
|
-
### `read`
|
|
278
|
-
|
|
279
|
-
Read the contents of a text file.
|
|
280
|
-
|
|
281
|
-
| Parameter | Type | Required | Default | Description |
|
|
282
|
-
| ----------- | ------ | -------- | ------- | ------------------------------ |
|
|
283
|
-
| `path` | string | Yes | - | File path to read |
|
|
284
|
-
| `head` | number | No | - | Read only first N lines |
|
|
285
|
-
| `startLine` | number | No | - | 1-based start line (inclusive) |
|
|
286
|
-
| `endLine` | number | No | - | 1-based end line (inclusive) |
|
|
114
|
+
## Configuration
|
|
287
115
|
|
|
288
|
-
|
|
116
|
+
### Runtime Modes
|
|
289
117
|
|
|
290
|
-
|
|
291
|
-
- Full reads are capped by `MAX_FILE_SIZE` (default 10MB). When `head` is set,
|
|
292
|
-
output stops at the line limit or size budget, whichever comes first.
|
|
293
|
-
- `head` cannot be combined with `startLine`/`endLine`.
|
|
294
|
-
- If the content exceeds a size limit (default 20k chars), the tool returns a `resource_link` instead of inline content.
|
|
118
|
+
This server runs over **stdio** by default.
|
|
295
119
|
|
|
296
|
-
|
|
297
|
-
`truncated`, `totalLines`, and range metadata when applicable).
|
|
120
|
+
### CLI Arguments
|
|
298
121
|
|
|
299
|
-
|
|
122
|
+
| Argument | Description |
|
|
123
|
+
| :------------ | :-------------------------------------------------- |
|
|
124
|
+
| `[paths...]` | List of allowed root directories. |
|
|
125
|
+
| `--allow-cwd` | Add the current working directory to allowed roots. |
|
|
300
126
|
|
|
301
|
-
###
|
|
127
|
+
### Environment Variables
|
|
302
128
|
|
|
303
|
-
|
|
129
|
+
| Variable | Default | Description |
|
|
130
|
+
| :--------------------------- | :---------- | :------------------------------------------------- |
|
|
131
|
+
| `MAX_FILE_SIZE` | 10MB | Max file size for read operations. |
|
|
132
|
+
| `MAX_READ_MANY_TOTAL_SIZE` | 512KB | Max combined size for `read_many`. |
|
|
133
|
+
| `MAX_SEARCH_SIZE` | 1MB | Max file size for `grep`. |
|
|
134
|
+
| `DEFAULT_SEARCH_TIMEOUT` | 30000 | Timeout (ms) for search/list operations. |
|
|
135
|
+
| `FS_CONTEXT_SEARCH_WORKERS` | min(cpu, 8) | Number of worker threads for search. |
|
|
136
|
+
| `FS_CONTEXT_ALLOW_SENSITIVE` | false | Allow reading sensitive files (disables denylist). |
|
|
137
|
+
| `FS_CONTEXT_DENYLIST` | (empty) | Additional comma-separated glob patterns to block. |
|
|
138
|
+
| `FS_CONTEXT_ALLOWLIST` | (empty) | Comma-separated globs to allow despite denylist. |
|
|
139
|
+
| `FS_CONTEXT_TOOL_LOG_ERRORS` | false | Log tool failures to stderr. |
|
|
304
140
|
|
|
305
|
-
|
|
306
|
-
| ----------- | -------- | -------- | ------- | --------------------------------------- |
|
|
307
|
-
| `paths` | string[] | Yes | - | Array of file paths (max 100) |
|
|
308
|
-
| `head` | number | No | - | Read only first N lines of each file |
|
|
309
|
-
| `startLine` | number | No | - | 1-based start line (inclusive) per file |
|
|
310
|
-
| `endLine` | number | No | - | 1-based end line (inclusive) per file |
|
|
141
|
+
## MCP Surface
|
|
311
142
|
|
|
312
|
-
|
|
143
|
+
### Tools
|
|
313
144
|
|
|
314
|
-
|
|
315
|
-
is capped by `MAX_FILE_SIZE` (default 10MB).
|
|
316
|
-
- Total read budget across all files is capped by `MAX_READ_MANY_TOTAL_SIZE`.
|
|
317
|
-
- No binary detection is performed; use `read` for single-file safety checks.
|
|
318
|
-
- `head` cannot be combined with `startLine`/`endLine`.
|
|
319
|
-
- If any file content exceeds the inline limit, it is returned as a `resource_link`.
|
|
145
|
+
#### `roots`
|
|
320
146
|
|
|
321
|
-
|
|
322
|
-
`succeeded`, `failed`).
|
|
147
|
+
List the workspace roots this server can access.
|
|
323
148
|
|
|
324
|
-
|
|
149
|
+
- **Returns**: List of allowed directory paths.
|
|
325
150
|
|
|
326
|
-
|
|
151
|
+
#### `ls`
|
|
327
152
|
|
|
328
|
-
|
|
153
|
+
List the immediate contents of a directory.
|
|
329
154
|
|
|
330
|
-
| Parameter
|
|
331
|
-
|
|
|
332
|
-
| `path`
|
|
155
|
+
| Parameter | Type | Required | Default | Description |
|
|
156
|
+
| :--------------- | :------ | :------- | :------ | :----------------------------------------------- |
|
|
157
|
+
| `path` | string | No | (root) | Directory path to list. |
|
|
158
|
+
| `includeHidden` | boolean | No | false | Include hidden files. |
|
|
159
|
+
| `includeIgnored` | boolean | No | false | Include ignored directories (node_modules, etc). |
|
|
333
160
|
|
|
334
|
-
|
|
335
|
-
permissions, hidden status, MIME type (for files), and symlink target (if
|
|
336
|
-
applicable). Structured results may include `tokenEstimate` (rule of thumb:
|
|
337
|
-
ceil(size/4)).
|
|
161
|
+
#### `find`
|
|
338
162
|
|
|
339
|
-
|
|
163
|
+
Find files by glob pattern.
|
|
340
164
|
|
|
341
|
-
|
|
165
|
+
| Parameter | Type | Required | Default | Description |
|
|
166
|
+
| :--------------- | :------ | :------- | :------ | :------------------------------ |
|
|
167
|
+
| `pattern` | string | Yes | - | Glob pattern (e.g., `**/*.ts`). |
|
|
168
|
+
| `path` | string | No | (root) | Base directory to search from. |
|
|
169
|
+
| `includeIgnored` | boolean | No | false | Include ignored directories. |
|
|
170
|
+
| `maxResults` | number | No | 100 | Maximum matches to return. |
|
|
342
171
|
|
|
343
|
-
|
|
172
|
+
#### `tree`
|
|
344
173
|
|
|
345
|
-
|
|
346
|
-
| --------- | -------- | -------- | ------- | --------------------------------- |
|
|
347
|
-
| `paths` | string[] | Yes | - | Array of paths to query (max 100) |
|
|
174
|
+
Render a directory tree.
|
|
348
175
|
|
|
349
|
-
|
|
350
|
-
|
|
176
|
+
| Parameter | Type | Required | Default | Description |
|
|
177
|
+
| :--------------- | :------ | :------- | :------ | :----------------------------- |
|
|
178
|
+
| `path` | string | No | (root) | Base directory to render. |
|
|
179
|
+
| `maxDepth` | number | No | 5 | Maximum recursion depth. |
|
|
180
|
+
| `maxEntries` | number | No | 1000 | Max entries before truncating. |
|
|
181
|
+
| `includeHidden` | boolean | No | false | Include hidden files. |
|
|
182
|
+
| `includeIgnored` | boolean | No | false | Include ignored directories. |
|
|
351
183
|
|
|
352
|
-
|
|
184
|
+
#### `read`
|
|
353
185
|
|
|
354
|
-
|
|
186
|
+
Read the text contents of a file.
|
|
355
187
|
|
|
356
|
-
|
|
188
|
+
| Parameter | Type | Required | Default | Description |
|
|
189
|
+
| :---------- | :----- | :------- | :------ | :----------------------- |
|
|
190
|
+
| `path` | string | Yes | - | Path to the file. |
|
|
191
|
+
| `head` | number | No | - | Read only first N lines. |
|
|
192
|
+
| `startLine` | number | No | - | 1-based start line. |
|
|
193
|
+
| `endLine` | number | No | - | 1-based end line. |
|
|
357
194
|
|
|
358
|
-
|
|
359
|
-
- Pass a file path in `path` to search only that file.
|
|
195
|
+
#### `read_many`
|
|
360
196
|
|
|
361
|
-
|
|
197
|
+
Read multiple text files in a single request.
|
|
362
198
|
|
|
363
|
-
| Parameter
|
|
364
|
-
|
|
|
365
|
-
| `
|
|
366
|
-
| `
|
|
367
|
-
| `
|
|
199
|
+
| Parameter | Type | Required | Default | Description |
|
|
200
|
+
| :---------- | :------- | :------- | :------ | :------------------------------------- |
|
|
201
|
+
| `paths` | string[] | Yes | - | Array of file paths to read (max 100). |
|
|
202
|
+
| `head` | number | No | - | Read only first N lines of each file. |
|
|
203
|
+
| `startLine` | number | No | - | 1-based start line per file. |
|
|
204
|
+
| `endLine` | number | No | - | 1-based end line per file. |
|
|
368
205
|
|
|
369
|
-
|
|
206
|
+
#### `stat`
|
|
370
207
|
|
|
371
|
-
|
|
372
|
-
{ "path": "src/transform.ts", "pattern": "TODO" }
|
|
373
|
-
```
|
|
208
|
+
Get metadata for a file or directory.
|
|
374
209
|
|
|
375
|
-
|
|
376
|
-
|
|
210
|
+
| Parameter | Type | Required | Default | Description |
|
|
211
|
+
| :-------- | :----- | :------- | :------ | :------------------------- |
|
|
212
|
+
| `path` | string | Yes | - | Path to file or directory. |
|
|
377
213
|
|
|
378
|
-
|
|
214
|
+
#### `stat_many`
|
|
379
215
|
|
|
380
|
-
|
|
381
|
-
- Very large files are skipped based on `MAX_SEARCH_SIZE` (default 1MB).
|
|
382
|
-
“No matches” is not proof the text is absent from skipped files.
|
|
216
|
+
Get metadata for multiple files/directories.
|
|
383
217
|
|
|
384
|
-
|
|
385
|
-
|
|
218
|
+
| Parameter | Type | Required | Default | Description |
|
|
219
|
+
| :-------- | :------- | :------- | :------ | :----------------------- |
|
|
220
|
+
| `paths` | string[] | Yes | - | Array of paths to query. |
|
|
386
221
|
|
|
387
|
-
|
|
388
|
-
Matched line content is trimmed to 200 characters.
|
|
222
|
+
#### `grep`
|
|
389
223
|
|
|
390
|
-
|
|
224
|
+
Search for text within file contents.
|
|
391
225
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
226
|
+
| Parameter | Type | Required | Default | Description |
|
|
227
|
+
| :-------------- | :------ | :------- | :------ | :-------------------------------- |
|
|
228
|
+
| `pattern` | string | Yes | - | Text pattern to search for. |
|
|
229
|
+
| `path` | string | No | (root) | Base directory or file to search. |
|
|
230
|
+
| `includeHidden` | boolean | No | false | Include hidden files. |
|
|
397
231
|
|
|
398
|
-
|
|
232
|
+
### Resources
|
|
399
233
|
|
|
400
|
-
|
|
|
401
|
-
|
|
|
402
|
-
| `
|
|
403
|
-
| `
|
|
404
|
-
| `E_NOT_FILE` | Expected file, got directory |
|
|
405
|
-
| `E_NOT_DIRECTORY` | Expected directory, got file |
|
|
406
|
-
| `E_TOO_LARGE` | File exceeds size limits |
|
|
407
|
-
| `E_TIMEOUT` | Operation timed out |
|
|
408
|
-
| `E_INVALID_PATTERN` | Invalid glob/regex pattern |
|
|
409
|
-
| `E_INVALID_INPUT` | Invalid argument(s) |
|
|
410
|
-
| `E_PERMISSION_DENIED` | OS-level permission denied |
|
|
411
|
-
| `E_SYMLINK_NOT_ALLOWED` | Symlink escapes allowed roots |
|
|
412
|
-
| `E_UNKNOWN` | Unexpected error |
|
|
234
|
+
| Pattern | Description |
|
|
235
|
+
| :------------------------- | :-------------------------------------- |
|
|
236
|
+
| `internal://instructions` | Usage guidance and server instructions. |
|
|
237
|
+
| `fs-context://result/{id}` | Access to cached large tool outputs. |
|
|
413
238
|
|
|
414
|
-
## Client Configuration
|
|
239
|
+
## Client Configuration Examples
|
|
415
240
|
|
|
416
241
|
<details>
|
|
417
242
|
<summary><b>VS Code</b></summary>
|
|
418
243
|
|
|
419
|
-
Add to `.vscode/mcp.json
|
|
244
|
+
Add to `.vscode/mcp.json`:
|
|
420
245
|
|
|
421
246
|
```json
|
|
422
247
|
{
|
|
423
|
-
"
|
|
248
|
+
"mcpServers": {
|
|
424
249
|
"fs-context": {
|
|
425
250
|
"command": "npx",
|
|
426
251
|
"args": ["-y", "@j0hanz/fs-context-mcp@latest", "${workspaceFolder}"]
|
|
@@ -434,22 +259,23 @@ Add to `.vscode/mcp.json` (recommended) or `.vscode/settings.json`:
|
|
|
434
259
|
<details>
|
|
435
260
|
<summary><b>Claude Desktop</b></summary>
|
|
436
261
|
|
|
437
|
-
|
|
438
|
-
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
262
|
+
Add to `claude_desktop_config.json`:
|
|
439
263
|
|
|
440
264
|
```json
|
|
441
265
|
{
|
|
442
266
|
"mcpServers": {
|
|
443
267
|
"fs-context": {
|
|
444
268
|
"command": "npx",
|
|
445
|
-
"args": [
|
|
269
|
+
"args": [
|
|
270
|
+
"-y",
|
|
271
|
+
"@j0hanz/fs-context-mcp@latest",
|
|
272
|
+
"/absolute/path/to/project"
|
|
273
|
+
]
|
|
446
274
|
}
|
|
447
275
|
}
|
|
448
276
|
}
|
|
449
277
|
```
|
|
450
278
|
|
|
451
|
-
If your client supports MCP Roots, you can omit the path. Otherwise, pass a path or `--allow-cwd`.
|
|
452
|
-
|
|
453
279
|
</details>
|
|
454
280
|
|
|
455
281
|
<details>
|
|
@@ -470,21 +296,6 @@ Add to Cursor's MCP configuration:
|
|
|
470
296
|
|
|
471
297
|
</details>
|
|
472
298
|
|
|
473
|
-
<details>
|
|
474
|
-
<summary><b>Codex</b></summary>
|
|
475
|
-
|
|
476
|
-
Add to `~/.codex/config.toml`:
|
|
477
|
-
|
|
478
|
-
```toml
|
|
479
|
-
[mcp_servers.fs-context]
|
|
480
|
-
command = "npx"
|
|
481
|
-
args = ["-y", "@j0hanz/fs-context-mcp@latest", "/path/to/your/project"]
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
If your client supports MCP Roots, you can omit the path. Otherwise, pass a path or `--allow-cwd`.
|
|
485
|
-
|
|
486
|
-
</details>
|
|
487
|
-
|
|
488
299
|
<details>
|
|
489
300
|
<summary><b>Windsurf</b></summary>
|
|
490
301
|
|
|
@@ -503,86 +314,29 @@ Add to Windsurf's MCP configuration:
|
|
|
503
314
|
|
|
504
315
|
</details>
|
|
505
316
|
|
|
506
|
-
## Security
|
|
507
|
-
|
|
508
|
-
This server implements multiple layers of security:
|
|
509
|
-
|
|
510
|
-
| Protection | Description |
|
|
511
|
-
| ------------------------- | ------------------------------------------------------------- |
|
|
512
|
-
| Access control | Only explicitly allowed directories are accessible |
|
|
513
|
-
| Path validation | All paths are validated before any filesystem operation |
|
|
514
|
-
| Symlink protection | Symlinks that resolve outside allowed directories are blocked |
|
|
515
|
-
| Path traversal prevention | Attempts to escape via `..` are detected and blocked |
|
|
516
|
-
| Read-only operations | No writes, deletes, or modifications |
|
|
517
|
-
| Safe regex | Regex validation with RE2 prevents ReDoS |
|
|
518
|
-
| Size limits | Configurable limits prevent resource exhaustion |
|
|
519
|
-
|
|
520
|
-
## Development
|
|
521
|
-
|
|
522
|
-
### Prerequisites
|
|
317
|
+
## Security
|
|
523
318
|
|
|
524
|
-
-
|
|
525
|
-
-
|
|
319
|
+
- **Read-Only**: This server is designed to be read-only. It provides no tools for writing or modifying files.
|
|
320
|
+
- **Path Validation**: All file access is validated against the allowed root directories.
|
|
321
|
+
- **Path Traversal**: Attempts to access files outside allowed roots using `..` are blocked.
|
|
322
|
+
- **Symlinks**: Symlinks resolving outside allowed roots are blocked.
|
|
323
|
+
- **Sensitive Files**: Common sensitive files (e.g., `.env`, `.ssh/id_rsa`) are denied by default unless explicitly allowed via configuration.
|
|
324
|
+
- **Stdio**: The server communicates via stdio. Ensure your client does not pipe untrusted data into the server's input.
|
|
526
325
|
|
|
527
|
-
|
|
326
|
+
## Development Workflow
|
|
528
327
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
| `npm run test` | Run tests (node --test with tsx/esm) |
|
|
535
|
-
| `npm run test:watch` | Run tests in watch mode (node --test --watch) |
|
|
536
|
-
| `npm run test:coverage` | Run tests with coverage (node --test --experimental-test-coverage) |
|
|
537
|
-
| `npm run test:node` | Run node-tests (isolated checks) |
|
|
538
|
-
| `npm run lint` | Run ESLint |
|
|
539
|
-
| `npm run format` | Format code with Prettier |
|
|
540
|
-
| `npm run type-check` | TypeScript type checking |
|
|
541
|
-
| `npm run inspector` | Test with MCP Inspector |
|
|
328
|
+
1. **Install dependencies**: `npm ci`
|
|
329
|
+
2. **Run in dev mode**: `npm run dev` (watches for changes)
|
|
330
|
+
3. **Build**: `npm run build`
|
|
331
|
+
4. **Test**: `npm test`
|
|
332
|
+
5. **Lint**: `npm run lint`
|
|
542
333
|
|
|
543
|
-
|
|
334
|
+
## Troubleshooting
|
|
544
335
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
server.ts # MCP server wiring and roots handling
|
|
549
|
-
tools.ts # MCP tool registration + response helpers
|
|
550
|
-
schemas.ts # Zod input/output schemas
|
|
551
|
-
config.ts # Shared types and formatting helpers
|
|
552
|
-
instructions.md # Tool usage instructions (bundled in dist)
|
|
553
|
-
lib/ # Core logic and filesystem operations
|
|
554
|
-
__tests__/ # node:test + tsx tests
|
|
555
|
-
node-tests/ # Additional Node.js checks
|
|
556
|
-
docs/ # Static docs assets
|
|
557
|
-
dist/ # Build output (generated)
|
|
558
|
-
```
|
|
336
|
+
- **Access Denied**: Ensure the directory is included in the CLI arguments or client roots configuration.
|
|
337
|
+
- **File Too Large**: Large files are truncated. Use the `head` parameter or `startLine`/`endLine` to read specific sections, or follow the resource URI provided in the tool output.
|
|
338
|
+
- **Timeout**: Complex searches (`grep` or `find`) may timeout on large codebases. Try narrowing the search path.
|
|
559
339
|
|
|
560
|
-
##
|
|
340
|
+
## License
|
|
561
341
|
|
|
562
|
-
|
|
563
|
-
| ------------------------ | ---------------------------------------------------------------------------- |
|
|
564
|
-
| "Access denied" error | Ensure the path is within an allowed directory. Use `roots` to check. |
|
|
565
|
-
| "Path does not exist" | Verify the path exists. Use `ls` to explore available files. |
|
|
566
|
-
| "File too large" | Use `head` or increase `MAX_FILE_SIZE`. |
|
|
567
|
-
| "Binary file" warning | `read` only supports UTF-8 text and rejects binary files. |
|
|
568
|
-
| No directories available | Pass explicit paths, use `--allow-cwd`, or ensure the client provides Roots. |
|
|
569
|
-
| Symlink blocked | Symlinks that resolve outside allowed directories are blocked. |
|
|
570
|
-
| Invalid pattern | Simplify the pattern (note: `grep` treats `pattern` as literal text). |
|
|
571
|
-
|
|
572
|
-
## Contributing
|
|
573
|
-
|
|
574
|
-
Contributions are welcome! Please follow these steps:
|
|
575
|
-
|
|
576
|
-
1. Fork the repository
|
|
577
|
-
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
578
|
-
3. Run format, lint, type-check, build, and tests (`npm run format && npm run lint && npm run type-check && npm run build && npm run test`)
|
|
579
|
-
4. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
580
|
-
5. Push to the branch (`git push origin feature/amazing-feature`)
|
|
581
|
-
6. Open a Pull Request
|
|
582
|
-
|
|
583
|
-
### Code Style
|
|
584
|
-
|
|
585
|
-
- Use TypeScript with strict mode
|
|
586
|
-
- Follow ESLint configuration
|
|
587
|
-
- Use Prettier for formatting
|
|
588
|
-
- Write tests for new features
|
|
342
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|