Skip to main content
Glama
Polarts

fs-mcp

by Polarts
README.md
# 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

A4.3/5.0

Scored across 6 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues