@pajecawav/fs-mcp
v0.0.2
Published
MCP Server for file system
Readme
fs-mcp
An MCP (Model Context Protocol) server that gives LLMs read-only access to a file system directory.
All file operations are sandboxed to a configured root directory — path traversal and symlink escapes are blocked.
Features
- 7 read-only tools — list, read, stat, tree, glob, search, and grep
- Path traversal protection —
..and absolute paths outside root are rejected - Symlink escape protection —
realpathverification prevents following symlinks outside root - Two transports — stdio (default) and HTTP (Streamable HTTP)
- Configurable tool prefix — namespace tools to avoid conflicts with other MCP servers
Installation
pnpm add @pajecawav/fs-mcp
# or
npm install @pajecawav/fs-mcpRequires Node.js >= 22.18.0.
Usage
CLI
fs-mcp <root> [options]Arguments:
| Argument | Required | Description |
| -------- | -------- | ---------------------------------------------------------------- |
| <root> | Yes | Root directory to serve (all file operations are sandboxed here) |
Options:
| Option | Default | Description |
| ---------------- | ----------- | ------------------------------------------------------------- |
| --transport | stdio | Transport type: stdio or http |
| --host | localhost | HTTP server host (only used with --transport http) |
| --port | 3000 | HTTP server port (only used with --transport http) |
| --tools-prefix | (none) | Prefix added to all tool names (e.g. my_ → my_fs_listdir) |
Examples
# Stdio transport (for MCP clients that spawn the server)
fs-mcp /path/to/project
# HTTP transport (for remote MCP clients)
fs-mcp /path/to/project --transport http --host 0.0.0.0 --port 3000
# With a tool prefix
fs-mcp /path/to/project --tools-prefix my_Claude Desktop / Claude Code
Add to your MCP client configuration:
{
"mcpServers": {
"fs": {
"command": "npx",
"args": ["fs-mcp", "/path/to/your/project"]
}
}
}HTTP Health Check
When using HTTP transport, a /health endpoint is available:
curl http://localhost:3000/health
# {"status":"ok"}The MCP endpoint is at /mcp.
Tools
All tools are read-only (readOnlyHint: true, destructiveHint: false).
fs_listdir
List directory entries within the root directory.
| Parameter | Type | Required | Description |
| --------- | ------ | -------- | ------------------------------ |
| path | string | Yes | Relative path to the directory |
Returns entries with name and type (directory | file | symlink | other), sorted with directories first.
fs_read
Read a text file within the root directory.
| Parameter | Type | Required | Description |
| --------- | ------ | -------- | ------------------------- |
| path | string | Yes | Relative path to the file |
Returns raw file content as text. Files larger than 10 MB and binary files (detected via null bytes) are rejected.
fs_stat
Get metadata for a file or directory.
| Parameter | Type | Required | Description |
| --------- | ------ | -------- | -------------------------------------- |
| path | string | Yes | Relative path to the file or directory |
Returns type, size, mode, isSymbolicLink, modifiedAt, createdAt, and accessedAt.
fs_tree
Recursively list a directory as a nested tree structure.
| Parameter | Type | Required | Default | Description |
| ---------- | ------ | -------- | ------- | ---------------------------------- |
| path | string | Yes | — | Relative path to the directory |
| maxDepth | number | No | 3 | Maximum recursion depth (max 10) |
Returns a nested structure of nodes with name, path, type, and children. Symlinks are skipped.
fs_glob
Find files matching a glob pattern within the root directory.
| Parameter | Type | Required | Default | Description |
| --------- | ------ | -------- | ------- | ----------------------------- |
| pattern | string | Yes | — | Glob pattern (e.g. **/*.ts) |
| path | string | No | . | Relative path to search in |
Returns matching file paths relative to root. Paths that escape root via .. are filtered out.
fs_search
Search for a literal string across files within the root directory.
| Parameter | Type | Required | Default | Description |
| ------------ | ------- | -------- | ------- | -------------------------- |
| query | string | Yes | — | String to search for |
| path | string | No | . | Relative path to search in |
| ignoreCase | boolean | No | false | Case-insensitive matching |
Returns matches with file, line (1-based), and content. Results are capped at 100 matches. node_modules/ and .git/ are excluded. Binary files are skipped.
fs_grep
Search file contents using a regular expression.
| Parameter | Type | Required | Default | Description |
| --------- | ------ | -------- | ------- | ------------------------------------------- |
| pattern | string | Yes | — | Regular expression pattern |
| path | string | No | . | Relative path to search in |
| flags | string | No | "" | Regex flags (e.g. i for case-insensitive) |
Returns matches with file, line (1-based), and content. Same limits and exclusions as fs_search.
Security
All tools enforce that file operations stay within the configured root directory:
Path resolution —
path.resolve(root, relativePath)normalizes the path, then astartsWithcheck ensures it stays within root. This blocks../traversal attacks.Symlink verification — operations that read file contents or list directories (
fs_listdir,fs_read,fs_tree) usefs.realpath()to resolve symlinks and re-verify the real path is within root.Glob filtering —
fs_globuses absolute paths internally and filters results through the root boundary check.Tree symlink skipping —
fs_treeskips all symlinks to avoid traversing outside root via symlinked directories.
Development
# Install dependencies
pnpm install
# Run in dev mode (stdio, with watch)
pnpm dev -- /path/to/project
# Run with MCP inspector
pnpm inspect -- /path/to/project
# Lint
pnpm lint
# Run tests
pnpm test
# Build
pnpm buildLicense
MIT
