fs-mcp
# fs-mcp
A tiny MCP server exposing six tools:
1. **`explore_filesystem(subpath?, glob?)`** — lists files/folders under the
root directory, optionally filtered by a glob (`**/*.js`, etc).
2. **`edit_file(path, edits[], createIfMissing?)`** — applies git-style line
edits (replace / insert / delete a line range) to a file under the root.
3. **`create_file(path, content?, overwrite?)`** — creates a new file with
optional content, creating parent directories as needed.
4. **`delete_file(path, recursive?)`** — deletes a file or directory under
the root (optionally recursive for non-empty directories).
5. **`read_file(path, startLine?, endLine?)`** — reads file content, optionally
scoped to a line range, with line numbers prefixed.
6. **`grep(pattern, glob?, useRegex?, caseInsensitive?)`** — searches for text
patterns in files, with optional regex support and glob filtering.
Root = wherever the process's working directory is when it starts.
## Install as a global CLI
```bash
npm install
npm link # or: npm install -g .
```
This gives you a global `fs-mcp` command (wired up via the `bin` field in
`package.json`).
## Running it
```bash
fs-mcp # stdio mode (default) — for Claude Desktop/Code,
# which spawn the process themselves
fs-mcp --http # HTTP mode on http://localhost:4823/mcp — for
# curl, the MCP Inspector, or the on-demand
# Claude Desktop setup below
fs-mcp --http -p 5000 # custom port
fs-mcp --help
```
Whichever folder you're standing in when you run it becomes the exposed
root.
## Connecting to Claude Desktop
Claude Desktop spawns MCP servers itself and talks over stdio — it does
**not** inherit your terminal's current directory. That gives you two
setup options depending on how you want to work:
### Option A — on-demand from any folder (recommended if you want the CLI feel)
Configure Desktop **once**, pointed at a fixed local port rather than a
fixed folder. See `claude_desktop_config.example.json` — merge its
`"fs-mcp"` entry into your existing `mcpServers` object at:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`
Restart Claude Desktop once. From then on:
```bash
cd ~/whatever/project
fs-mcp --http
```
That folder is now what Claude can see, for as long as the server is
running. `Ctrl+C` it and start it again from a different folder to switch
context — no further Desktop config changes needed.
Note: `--allow-http` is required because `mcp-remote` (the stdio↔HTTP
bridge) defaults to expecting HTTPS + OAuth for real remote servers; this
flag tells it plain unauthenticated `localhost` traffic is fine.
### Option B — one fixed folder, always available
If you'd rather Desktop always expose the same project without having to
manually start anything:
```json
{
"mcpServers": {
"fs-mcp": {
"command": "fs-mcp",
"cwd": "/absolute/path/to/the/folder/you/want/exposed"
}
}
}
```
Restart Desktop. This uses stdio mode directly — no proxy, no manual
`fs-mcp --http` step — but changing the exposed folder means editing this
config and restarting Desktop again.
## Security notes
- Every path is resolved against the root and rejected if it would escape
it (e.g. `../../etc/passwd`) — verified with a path-traversal test.
- There's no authentication. Anything that can reach the server (any local
process, in `--http` mode) can read and write any file under the root.
Fine for trusted local dev use; don't run it somewhere sensitive, and
don't bind it beyond `localhost`.
## Edit semantics (`edit_file`)
Edits are `{startLine, endLine, newLines}`, 1-indexed and inclusive:
- Replace lines 3–5: `{startLine: 3, endLine: 5, newLines: ["new content"]}`
- Delete lines 3–5: `{startLine: 3, endLine: 5, newLines: []}`
- Insert before line 6 (no deletion): `{startLine: 6, endLine: 5, newLines: ["inserted"]}`
Multiple edits in one call are applied bottom-to-top internally, so line
numbers in your edit list don't shift as earlier edits are applied.
TDQS
Scored across 6 tools
Each tool targets a distinct filesystem operation: listing, reading, creating, editing, deleting, and searching. There is no meaningful overlap between grep and read_file, or between create_file and edit_file, so an agent can reliably select the right tool.
Most tools follow a consistent verb_noun snake_case pattern: explore_filesystem, edit_file, create_file, delete_file, read_file. The one exception is 'grep', which is a conventional command name but slightly breaks the verb_noun pattern.
Six tools is a well-scoped set for a filesystem server. Each tool covers a distinct core operation without redundancy or bloat, fitting comfortably within the ideal 3-15 tool range.
The server covers the full basic lifecycle: list, read, create, edit, delete, and search. Minor gaps exist such as rename/move and file metadata/stat operations, but these can be worked around with existing tools.