FS-Context MCP Server


Filesystem MCP Server that enables LLMs to interact with the local filesystem.
Overview
The fs-context-mcp server provides a secure interface for language models to perform filesystem operations. By defining a set of tools that map to common file and directory actions, it allows LLMs to read, write, search, and manipulate files within specified allowed directories. This can be used for tasks like code analysis, content generation, data processing, and more, all while ensuring that the model's access is safely confined.
Key Features
- Filesystem Navigation: List directories (
ls), visualize structures (tree), and list allowed roots (roots).
- File Operations: Read (
read, read_many), write (write), edit (edit), move (mv), and delete (rm) files.
- Advanced Search: Find files by glob pattern (
find) or search file contents (grep) with regex support.
- Diff & Patch: Hash files (
calculate_hash), generate unified diffs (diff_files), apply patches (apply_patch), and bulk replace (search_and_replace).
- Batch Processing: Efficiently read or stat multiple files in a single request (
read_many, stat_many).
- Security: Operations are strictly confined to allowed directories specified at startup.
Tech Stack
- Runtime: Node.js >=24
- Language: TypeScript 5.9
- MCP SDK: @modelcontextprotocol/sdk 1.26
- Validation: Zod
- Regex: re2 (safe regex execution)
Quickstart
To run the server with access to your current directory:
npx -y @j0hanz/fs-context-mcp .
Installation
Using npx (Recommended)
npx -y @j0hanz/fs-context-mcp <allowed-directory>
From Source
Configuration
The server is configured primarily via command-line arguments.
CLI Arguments
allowedDirs | Positional arguments specifying which directories the server can access. |
--allow-cwd, --allow_cwd | Flag to automatically add the current working directory to the allowed list. |
-h, --help | Show CLI usage and exit. |
-v, --version | Show server version and exit. |
Environment Variables
MAX_SEARCH_SIZE | 1048576 | Max file size (bytes) for grep/search content. Min 100 KB, max 10 MB. |
MAX_FILE_SIZE | 10485760 | Max file size (bytes) for read/read_many. Min 1 MB, max 100 MB. |
MAX_READ_MANY_TOTAL_SIZE | 524288 | Max total bytes returned by read_many. Min 10 KB, max 100 MB. |
DEFAULT_SEARCH_TIMEOUT | 5000 | Timeout (ms) for search operations. Min 100 ms, max 60 s. |
FS_CONTEXT_ALLOW_SENSITIVE | false | Allow access to sensitive files (set to 1/true to allow). |
FS_CONTEXT_DENYLIST | (empty) | Additional denylist patterns (comma or newline separated). |
FS_CONTEXT_ALLOWLIST | (empty) | Allowlist patterns that override the denylist. |
FS_CONTEXT_SEARCH_WORKERS | min(cores, 8) | Worker threads for content search (0-16). |
FS_CONTEXT_SEARCH_WORKERS_DEBUG | 0 | Log worker debug details when set to 1. |
FS_CONTEXT_DIAGNOSTICS | 0 | Enable diagnostics channels when set to 1. |
FS_CONTEXT_DIAGNOSTICS_DETAIL | 0 | Diagnostics detail level: 0=off, 1=hashed paths, 2=full paths. |
FS_CONTEXT_TOOL_LOG_ERRORS | 0 | Emit tool error diagnostics when enabled. |
MCP Surface
Tools
roots
List the workspace roots this server can access.
ls
List the immediate contents of a directory (non-recursive).
path | string | No | (root) | Base directory for the operation. |
includeHidden | boolean | No | false | Include hidden files and directories (starting with .). |
includeIgnored | boolean | No | false | Include normally ignored directories (node_modules, dist, etc). |
sortBy | string | No | name | Sort by name, size, modified, or type. |
maxDepth | number | No | - | Max recursion depth when pattern is provided. |
maxEntries | number | No | - | Max entries before truncation. |
pattern | string | No | - | Optional glob filter (for recursive listing). |
includeSymlinkTargets | boolean | No | false | Include resolved symlink targets in output. |
find
Find files by glob pattern.
pattern | string | Yes | - | Glob pattern to match files (e.g., **/*.ts). |
path | string | No | (root) | Base directory for the operation. |
maxResults | number | No | 100 | Maximum matches to return. |
includeIgnored | boolean | No | false | Include normally ignored directories. |
includeHidden | boolean | No | false | Include hidden files and directories. |
sortBy | string | No | path | Sort by path, name, size, or modified. |
maxDepth | number | No | - | Maximum directory depth to scan. |
maxFilesScanned | number | No | - | Hard cap on scanned files. |
tree
Render a directory tree.
path | string | No | (root) | Base directory for the operation. |
maxDepth | number | No | 5 | Maximum depth to recurse. |
maxEntries | number | No | 1000 | Maximum number of entries before truncating. |
includeHidden | boolean | No | false | Include hidden files. |
includeIgnored | boolean | No | false | Include ignored directories. |
read
Read the text contents of a file.
path | string | Yes | - | Absolute path to file. |
head | number | No | - | Read only the first N lines. |
startLine | number | No | - | Start reading from this line (1-based). |
endLine | number | No | - | Stop reading at this line (inclusive). |
read_many
Read multiple text files in a single request.
paths | array | Yes | - | Array of file paths to read. |
head | number | No | - | Read only the first N lines of each file. |
startLine | number | No | - | Start line for each file. |
endLine | number | No | - | End line for each file. |
stat
Get metadata for a file or directory.
path | string | Yes | - | Absolute path to file or directory. |
stat_many
Get metadata for multiple files or directories.
paths | array | Yes | - | Array of file or directory paths. |
grep
Search for text within file contents.
pattern | string | Yes | - | Text to search for. |
path | string | No | (root) | Base directory or file for the search. |
isRegex | boolean | No | false | Treat pattern as a regular expression. |
caseSensitive | boolean | No | false | Enable case-sensitive matching. |
wholeWord | boolean | No | false | Match whole words only. |
contextLines | number | No | 0 | Include N lines before/after each match. |
maxResults | number | No | 500 | Maximum match rows to return. |
maxFilesScanned | number | No | 20000 | Hard cap on scanned files. |
filePattern | string | No | **/* | Glob filter for candidate files. |
includeHidden | boolean | No | false | Include hidden files. |
includeIgnored | boolean | No | false | Include ignored directories. |
calculate_hash
Compute a SHA-256 hash for a file.
path | string | Yes | - | Absolute path to file. |
diff_files
Generate a unified diff between two files.
original | string | Yes | - | Path to original file. |
modified | string | Yes | - | Path to modified file. |
context | number | No | - | Lines of context to include in the diff. |
ignoreWhitespace | boolean | No | false | Ignore leading/trailing whitespace in comparisons. |
stripTrailingCr | boolean | No | false | Strip trailing carriage returns before diffing. |
apply_patch
Apply a unified patch to a file.
path | string | Yes | - | Path to file to patch. |
patch | string | Yes | - | Unified diff content. |
fuzzy | boolean | No | false | Allow fuzzy patching (compatibility flag). |
fuzzFactor | number | No | - | Maximum fuzzy mismatches per hunk. |
autoConvertLineEndings | boolean | No | true | Auto-convert patch line endings to match file. |
dryRun | boolean | No | false | Check only, no writes. |
search_and_replace
Search and replace text across multiple files.
Response includes processedFiles, failedFiles, and a sample failures
list when some files cannot be processed.
path | string | No | (root) | Base directory for the operation. |
filePattern | string | Yes | - | Glob pattern (e.g., **/*.ts). |
excludePatterns | array | No | [] | Glob patterns to exclude. |
searchPattern | string | Yes | - | Text or regex pattern to replace. |
replacement | string | Yes | - | Replacement text. |
isRegex | boolean | No | false | Treat search pattern as regex. |
dryRun | boolean | No | false | Check only, no writes. |
mkdir
Create a new directory (recursive).
path | string | Yes | - | Path to create. |
write
Write content to a file.
path | string | Yes | - | Path to file. |
content | string | Yes | - | Content to write. |
edit
Edit a file by replacing text.
path | string | Yes | - | Path to file. |
edits | array | Yes | - | Array of objects with oldText and newText. |
dryRun | boolean | No | false | Only check if edits would succeed. |
mv
Move or rename a file or directory.
source | string | Yes | - | Current path. |
destination | string | Yes | - | New path. |
rm
Delete a file or directory.
path | string | Yes | - | Path to delete. |
recursive | boolean | No | false | Allow deleting non-empty directories. |
ignoreIfNotExists | boolean | No | false | Do not fail if path missing. |
Resources
internal://instructions | Server Instructions |
fs-context://result/{id} | Cached Tool Result |
Tool responses may include a resource_link or a resourceUri when output is too large to inline. Fetch the full payload with resources/read using the provided URI. Cached results are ephemeral and may not appear in resources/list.
Prompts
get-help | Returns the server instructions for quick reference. |
Tasks
Long-running tools (grep, find, search_and_replace, tree, read_many,
stat_many) support task-augmented calls. When task is provided to
tools/call, the server returns a task id that can be polled with tasks/get
and resolved via tasks/result. Include _meta.progressToken on requests to
receive notifications/progress updates. Task data is stored in memory and is
cleared when the server restarts.
Client Configuration Examples
VS Code (Claude Dev / Cline)
Add to your ~/AppData/Roaming/Code/User/globalStorage/mcp-settings.json (Windows) or ~/Library/Application Support/Code/User/globalStorage/mcp-settings.json (macOS):
{
"mcpServers": {
"fs-context": {
"command": "npx",
"args": [
"-y",
"@j0hanz/fs-context-mcp",
"c:\\path\\to\\allowed\\directory"
]
}
}
}
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"fs-context": {
"command": "npx",
"args": [
"-y",
"@j0hanz/fs-context-mcp",
"c:\\path\\to\\allowed\\directory"
]
}
}
}
Cursor
Configure via the MCP settings panel:
- Name:
fs-context
- Type:
command
- Command:
npx -y @j0hanz/fs-context-mcp c:\path\to\allowed\directory
Security
- Path Scope: Operations are restricted to the directories specified in
allowedDirs or the current working directory if --allow-cwd is used.
- Path Validation:
- Null bytes are rejected.
- Windows drive-relative paths (e.g.,
C:path) are rejected.
- Windows reserved device names are rejected.
- Symlinks: Symlink targets are reported but not implicitly followed during recursion in some operations to prevent loops or escaping scope (specific behavior varies by tool).
Development Workflow
Contributing & License
This project is licensed under the MIT License.