j0hanz/filesystem-context-mcp-server
If you are the rightful owner of filesystem-context-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
A secure Model Context Protocol (MCP) server designed for filesystem scanning, searching, and analysis, built with TypeScript and the official MCP SDK.
Filesystem Context MCP Server
A secure, read-only MCP server for filesystem scanning, searching, and analysis with comprehensive security validation.
One-Click Install
✨ Features
| Feature | Description |
|---|---|
| 📂 Directory Listing | List and explore directory contents with recursive support |
| 🔍 File Search | Find files using glob patterns like **/*.ts |
| 📝 Content Search | Search text within files using regex with context lines |
| 📊 Directory Analysis | Get statistics, file types, largest files, and recently modified files |
| 🌳 Directory Tree | JSON tree structure optimized for AI parsing |
| 📄 File Reading | Read single or multiple files with head/tail and line range support |
| 🖼️ Media File Support | Read binary files (images, audio, video) as base64 |
| 🔒 Security First | Path validation, symlink escape protection, and access control |
| ⚡ Parallel Operations | Efficient batch file reading with configurable concurrency |
🎯 When to Use
| Task | Tool |
|---|---|
| Explore project structure | list_directory |
| Find specific file types | search_files |
| Search for code patterns/text | search_content |
| Find code definitions | search_definitions |
| Understand codebase statistics | analyze_directory |
| Get AI-friendly project overview | directory_tree |
| Read source code | read_file |
| Batch read multiple files | read_multiple_files |
| Get file metadata (size, dates) | get_file_info |
| Batch get file metadata | get_multiple_file_info |
| Compute file checksums/hashes | compute_checksums |
| Read images or binary files | read_media_file |
| Check available directories | list_allowed_directories |
🚀 Quick Start
NPX (Recommended - Zero Config)
# Works in current directory automatically!
npx -y @j0hanz/filesystem-context-mcp@latest
Or specify directories explicitly:
npx -y @j0hanz/filesystem-context-mcp@latest /path/to/your/project
VS Code (with workspace folder)
Add to your VS Code settings (.vscode/mcp.json):
{
"servers": {
"filesystem-context": {
"command": "npx",
"args": [
"-y",
"@j0hanz/filesystem-context-mcp@latest",
"${workspaceFolder}"
]
}
}
}
Tip:
${workspaceFolder}automatically uses your current VS Code workspace. You can also omit it and the server will use its current working directory.
Claude Desktop
Add to your Claude Desktop configuration (claude_desktop_config.json):
{
"mcpServers": {
"filesystem-context": {
"command": "npx",
"args": ["-y", "@j0hanz/filesystem-context-mcp@latest"]
}
}
}
Note: Claude Desktop will use the current working directory automatically. No path arguments needed!
📦 Installation
NPX (No Installation)
npx -y @j0hanz/filesystem-context-mcp@latest /path/to/dir1 /path/to/dir2
Global Installation
npm install -g @j0hanz/filesystem-context-mcp
filesystem-context-mcp /path/to/your/project
From Source
git clone https://github.com/j0hanz/filesystem-context-mcp-server.git
cd filesystem-context-mcp-server
npm install
npm run build
node dist/index.js /path/to/your/project
⚙️ Configuration
Directory Resolution (Priority Order)
The server determines which directories to access in this order:
- CLI Arguments - Explicitly passed paths take highest priority
- MCP Roots Protocol - Directories provided by the MCP client
- Current Working Directory - Automatic fallback for plug-and-play experience
This means you can run the server with zero configuration and it will work!
Command Line Arguments
Optionally specify one or more directory paths as arguments:
filesystem-context-mcp /home/user/project /home/user/docs
MCP Roots Protocol
If no CLI arguments are provided, the server will use the MCP Roots protocol to receive allowed directories from the client (if supported).
Zero-Config Mode
If neither CLI arguments nor MCP Roots provide directories, the server automatically uses the current working directory. This makes it truly plug-and-play!
Environment Variables
All configuration values have sensible defaults and are optional. Only configure if you need to tune performance or resource usage.
| Variable | Default | Range | Description |
|---|---|---|---|
FILESYSTEM_CONTEXT_CONCURRENCY | Auto (2x cores) | 1-100 | Maximum parallel file operations |
TRAVERSAL_JOBS | 8 | 1-50 | Directory traversal concurrency |
REGEX_TIMEOUT | 100 | 50-1000 | Regex matching timeout (milliseconds) |
MAX_FILE_SIZE | 10MB | 1MB-100MB | Maximum text file size (bytes) |
MAX_MEDIA_SIZE | 50MB | 1MB-500MB | Maximum media file size (bytes) |
MAX_SEARCH_SIZE | 1MB | 100KB-10MB | Maximum file size for content search |
DEFAULT_DEPTH | 10 | 1-100 | Default maximum recursion depth |
DEFAULT_RESULTS | 100 | 10-10000 | Default maximum search results |
DEFAULT_LIST_MAX_ENTRIES | 10000 | 100-100000 | Default max entries for list_directory |
DEFAULT_SEARCH_MAX_FILES | 20000 | 100-100000 | Default max files to scan in searches |
DEFAULT_SEARCH_TIMEOUT | 30000 | 100-3600000 | Default search timeout (milliseconds) |
DEFAULT_TOP | 10 | 1-1000 | Default top N items in analysis |
DEFAULT_ANALYZE_MAX_ENTRIES | 20000 | 100-100000 | Default max entries in analyze_directory |
DEFAULT_TREE | 5 | 1-50 | Default directory tree depth |
DEFAULT_TREE_MAX_FILES | 5000 | 100-200000 | Default max files in directory tree |
💡 Tip: See for detailed environment variable usage examples, configuration profiles, and best practices for different use cases.
🔧 Tools
list_allowed_directories
List all directories that this server is allowed to access.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| (none) | - | - | - | No parameters required |
Returns: Array of allowed directory paths.
list_directory
List contents of a directory with optional recursive listing.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ? | - | Directory path to list |
recursive | boolean | ? | false | List recursively |
includeHidden | boolean | ? | false | Include hidden files |
excludePatterns | string[] | ? | [] | Patterns to exclude |
pattern | string | ? | - | Glob pattern to include |
maxDepth | number | ? | 10 | Maximum depth for recursive listing (0-100) |
maxEntries | number | ? | 10000 | Maximum entries to return (1-100,000) |
sortBy | string | ? | name | Sort by: name, size, modified, type |
includeSymlinkTargets | boolean | ? | false | Include symlink target paths |
Returns: List of entries with name, type, size, and modified date.
search_files
Search for files (not directories) using glob patterns.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ✅ | - | Base directory to search from |
pattern | string | ✅ | - | Glob pattern (e.g., **/*.ts, src/**/*.js) |
excludePatterns | string[] | ❌ | [] | Patterns to exclude |
maxResults | number | ❌ | 100 | Maximum matches to return (1-10,000) |
sortBy | string | ❌ | path | Sort by: name, size, modified, path |
maxDepth | number | ❌ | - | Maximum directory depth to search (1-100) |
maxFilesScanned | number | ❌ | 20000 | Maximum files to scan before stopping |
timeoutMs | number | ❌ | 30000 | Timeout in milliseconds (100-3,600,000) |
Returns: List of matching files with path, type, size, and modified date.
Example:
{
"path": "/project",
"pattern": "**/*.ts",
"excludePatterns": ["node_modules/**", "dist/**"]
}
read_file
Read the contents of a text file.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ? | - | File path to read |
encoding | string | ? | utf-8 | File encoding (utf-8, ascii, base64, etc.) |
maxSize | number | ? | 10MB | Maximum file size in bytes |
skipBinary | boolean | ? | false | Reject binary files (use read_media_file instead) |
lineStart | number | ? | - | Start line (1-indexed, min 1) for reading a range |
lineEnd | number | ? | - | End line (1-indexed, inclusive, min 1) for reading a range |
head | number | ? | - | Read only first N lines |
tail | number | ? | - | Read only last N lines |
Note: Cannot specify both
headandtailsimultaneously. UselineStart/lineEndfor range reading.
Returns: File contents as text.
read_multiple_files
Read multiple files in parallel for efficient batch operations.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
paths | string[] | ✅ | - | Array of file paths to read (max 100) |
encoding | string | ❌ | utf-8 | File encoding |
maxSize | number | ❌ | 10MB | Maximum size per file in bytes |
maxTotalSize | number | ❌ | 100MB | Maximum total size for all files combined |
head | number | ❌ | - | Read only first N lines of each file |
tail | number | ❌ | - | Read only last N lines of each file |
lineStart | number | ❌ | - | Start line (1-indexed) for reading a range |
lineEnd | number | ❌ | - | End line (inclusive) for reading a range |
Returns: Array of file contents with individual success/error status.
get_multiple_file_info
Get metadata for multiple files/directories in parallel.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
paths | string[] | ✅ | - | Array of paths to query (max 100) |
includeMimeType | boolean | ❌ | true | Include MIME type detection |
Returns: Array of file info (name, path, type, size, timestamps, permissions, mimeType) with individual success/error status, plus summary.
compute_checksums
Compute cryptographic checksums for files using memory-efficient streaming.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
paths | string[] | ✅ | - | Array of file paths (max 50) |
algorithm | string | ❌ | sha256 | Hash algorithm: md5, sha1, sha256, sha512 |
encoding | string | ❌ | hex | Output encoding: hex or base64 |
maxFileSize | number | ❌ | 100MB | Skip files larger than this |
Returns: Array of checksums with file sizes, plus summary (total, succeeded, failed).
Use cases:
- Verify file integrity after transfers
- Detect duplicate files by comparing hashes
- Generate checksums for release artifacts
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
paths | string[] | ✅ | - | Array of file paths (max 100) |
encoding | string | ❌ | utf-8 | File encoding |
maxSize | number | ❌ | 10MB | Maximum file size per file |
maxTotalSize | number | ❌ | 100MB | Maximum total size for all files combined |
head | number | ❌ | - | Read only first N lines of each file |
tail | number | ❌ | - | Read only last N lines of each file |
Note: Use
read_filefor single files with line ranges (lineStart/lineEnd). Useread_multiple_filesfor batch operations withhead/tailparameters. The batch API does not support line ranges per file.
Returns: Array of results with content or error for each file.
get_file_info
Get detailed metadata about a file or directory.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ✅ | - | Path to file or directory |
Returns: Metadata including name, type, size, created/modified/accessed timestamps, permissions, MIME type, and symlink target (if applicable).
search_content
Search for text content within files using regular expressions.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ✅ | - | Base directory to search in |
pattern | string | ✅ | - | Regex pattern to search for |
filePattern | string | ❌ | **/* | Glob pattern to filter files |
excludePatterns | string[] | ❌ | [] | Glob patterns to exclude |
caseSensitive | boolean | ❌ | false | Case-sensitive search |
maxResults | number | ❌ | 100 | Maximum number of results (1-10,000) |
maxFileSize | number | ❌ | 1MB | Maximum file size to scan |
maxFilesScanned | number | ❌ | 20000 | Maximum files to scan before stopping |
timeoutMs | number | ❌ | 30000 | Timeout in milliseconds (100-3,600,000) |
skipBinary | boolean | ❌ | true | Skip binary files |
includeHidden | boolean | ❌ | false | Include hidden files and directories |
contextLines | number | ❌ | 0 | Lines of context before/after match (0-10) |
wholeWord | boolean | ❌ | false | Match whole words only |
isLiteral | boolean | ❌ | false | Treat pattern as literal string (escape special) |
Returns: Matching lines with file path, line number, content, and optional context.
Example:
{
"path": "/project/src",
"pattern": "TODO|FIXME",
"filePattern": "**/*.ts",
"contextLines": 2
}
search_definitions
Find code definitions (classes, functions, interfaces, types, enums, variables) in TypeScript/JavaScript files without manual regex construction.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ❌ | - | Base directory to search in |
name | string | ❌ | - | Definition name to search for |
type | string | ❌ | - | Definition type to find: class, function, interface, type, enum, variable |
caseSensitive | boolean | ❌ | true | Case-sensitive name matching |
maxResults | number | ❌ | 100 | Maximum number of results (1-10,000) |
excludePatterns | string[] | ❌ | [] | Glob patterns to exclude |
includeHidden | boolean | ❌ | false | Include hidden files and directories |
contextLines | number | ❌ | 0 | Lines of context before/after match (0-10) |
Returns: List of definitions with name, type (class/function/interface/type/enum/variable), file path, line number, exported status, and code preview.
Use cases:
- Find by name: Search for a specific definition like
UserService - Discovery mode: Find all definitions of a type (e.g., all interfaces)
- Combined: Find definitions matching a name pattern and type
Examples:
{
"path": "/project/src",
"name": "UserService"
}
{
"path": "/project/src",
"type": "interface"
}
{
"path": "/project/src",
"name": "Handler",
"type": "class"
}
analyze_directory
Analyze a directory structure and return statistics.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ✅ | - | Directory to analyze |
maxDepth | number | ❌ | 10 | Maximum depth to analyze (0-100) |
topN | number | ❌ | 10 | Number of top items to return (max 1000) |
maxEntries | number | ? | 20000 | Maximum entries to scan (1-100,000) |
excludePatterns | string[] | ❌ | [] | Glob patterns to exclude |
includeHidden | boolean | ❌ | false | Include hidden files and directories |
Returns: Statistics including total files/directories, total size, file type distribution, largest files, and recently modified files.
directory_tree
Get a JSON tree structure of a directory, optimized for AI parsing.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ✅ | - | Directory path to build tree from |
maxDepth | number | ❌ | 5 | Maximum depth to traverse (0-50) |
excludePatterns | string[] | ❌ | [] | Glob patterns to exclude |
includeHidden | boolean | ❌ | false | Include hidden files and directories |
includeSize | boolean | ❌ | false | Include file sizes in the tree |
maxFiles | number | ❌ | - | Maximum total files to include (max 100,000) |
Returns: Hierarchical tree structure with file/directory nodes.
read_media_file
Read a binary/media file and return it as base64-encoded data.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | ✅ | - | Path to the media file |
maxSize | number | ❌ | 50MB | Maximum file size in bytes (max 500MB) |
Supported formats: Images (PNG, JPG, GIF, WebP, SVG, etc.), Audio (MP3, WAV, FLAC, etc.), Video (MP4, WebM, etc.), Fonts (TTF, WOFF, etc.), PDFs, and more.
Returns: Base64-encoded data with MIME type and size.
🔌 Client Configuration
VS Code
Add to .vscode/mcp.json (recommended) or .vscode/settings.json:
{
"servers": {
"filesystem-context": {
"command": "npx",
"args": [
"-y",
"@j0hanz/filesystem-context-mcp@latest",
"${workspaceFolder}"
]
}
}
}
Note:
${workspaceFolder}is expanded by VS Code to the current workspace path.
Claude Desktop
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"filesystem-context": {
"command": "npx",
"args": ["-y", "@j0hanz/filesystem-context-mcp@latest"]
}
}
}
Cursor
Add to Cursor's MCP configuration:
{
"mcpServers": {
"filesystem-context": {
"command": "npx",
"args": ["-y", "@j0hanz/filesystem-context-mcp@latest"]
}
}
}
Codex
Add to ~/.codex/config.toml:
Basic Configuration (auto-detects current directory):
[mcp_servers.filesystem-context]
command = "npx"
args = ["-y", "@j0hanz/filesystem-context-mcp@latest"]
Configuration with Explicit Directory:
[mcp_servers.filesystem-context]
command = "npx"
args = ["-y", "@j0hanz/filesystem-context-mcp@latest", "/path/to/your/project"]
Configuration with Multiple Directories:
[mcp_servers.filesystem-context]
command = "npx"
args = ["-y", "@j0hanz/filesystem-context-mcp@latest", "/path/to/project1", "/path/to/project2"]
Note: You can access the config file via Codex IDE by clicking the gear icon → "Codex Settings > Open config.toml". If no directories are specified, it will use the current working directory automatically.
Windsurf
Add to Windsurf's MCP configuration:
{
"mcpServers": {
"filesystem-context": {
"command": "npx",
"args": ["-y", "@j0hanz/filesystem-context-mcp@latest"]
}
}
}
🔒 Security
This server implements multiple layers of security:
| Protection | Description |
|---|---|
| Access Control | Only explicitly allowed directories are accessible |
| Path Validation | All paths are validated before any filesystem operation |
| Symlink Protection | Symlinks that resolve outside allowed directories are blocked |
| Path Traversal Prevention | Attempts to escape via ../ are detected and blocked |
| Read-Only Operations | Server only performs read operations—no writes, deletes, or modifications |
| Safe Regex | Regular expressions are validated to prevent ReDoS attacks |
| Size Limits | Configurable limits prevent resource exhaustion |
Security Model
┌─────────────────────────────────────────────────────────┐
│ MCP Client │
└─────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Filesystem Context MCP Server │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Path Validation Layer │ │
│ │ • Normalize paths │ │
│ │ • Check against allowed directories │ │
│ │ • Resolve and validate symlinks │ │
│ │ • Block traversal attempts │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Read-Only File Operations │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Allowed Directories Only │
│ /home/user/project ✅ │
│ /home/user/docs ✅ │
│ /etc/passwd ❌ (blocked) │
│ ../../../etc ❌ (blocked) │
└─────────────────────────────────────────────────────────┘
🛠️ Development
Prerequisites
- Node.js >= 20.0.0
- npm
Scripts
| Command | Description |
|---|---|
npm run build | Compile TypeScript to JavaScript |
npm run dev | Watch mode with tsx |
npm run start | Run compiled server |
npm run test | Run tests with Vitest |
npm run test:watch | Run tests in watch mode |
npm run test:coverage | Run tests with coverage report |
npm run lint | Run ESLint |
npm run format | Format code with Prettier |
npm run type-check | TypeScript type checking |
npm run inspector | Test with MCP Inspector |
Project Structure
src/
├── index.ts # Entry point, CLI argument parsing
├── server.ts # MCP server setup, roots protocol handling
├── instructions.md # AI instructions for tool usage (bundled with dist)
├── config/
│ └── types.ts # Shared TypeScript types
├── lib/
│ ├── constants.ts # Configuration constants and limits
│ ├── errors.ts # Error handling utilities
│ ├── file-operations.ts# Core filesystem operations (exports)
│ ├── path-utils.ts # Path manipulation utilities
│ ├── path-validation.ts# Security: path validation layer
│ ├── fs-helpers.ts # Low-level filesystem helpers (exports)
│ ├── file-operations/ # Core filesystem operations
│ │ ├── analyze-directory.ts
│ │ ├── directory-helpers.ts
│ │ ├── directory-tree.ts
│ │ ├── file-info.ts
│ │ ├── list-directory.ts
│ │ ├── pattern-validator.ts
│ │ ├── read-media-file.ts
│ │ ├── read-multiple-files.ts
│ │ ├── search-content.ts
│ │ ├── search-definitions.ts
│ │ ├── search-files.ts
│ │ └── sorting.ts
│ ├── fs-helpers/ # Low-level filesystem helpers
│ │ ├── binary-detect.ts
│ │ ├── concurrency.ts
│ │ ├── fs-utils.ts
│ │ ├── readers.ts
│ │ └── readers/ # File reading utilities
│ │ ├── head-file.ts
│ │ ├── line-range.ts
│ │ ├── read-file.ts
│ │ ├── tail-file.ts
│ │ └── utf8.ts
│ └── path-validation/ # Security: path validation
│ ├── allowed-directories.ts
│ ├── errors.ts
│ ├── roots.ts
│ └── validators.ts
├── schemas/
│ ├── common.ts # Shared Zod schemas
│ ├── input-helpers.ts # Input validation helpers
│ ├── inputs.ts # Input validation schemas
│ ├── output-helpers.ts # Output formatting helpers
│ ├── outputs.ts # Output validation schemas
│ └── index.ts # Schema exports
├── tools/
│ ├── analyze-directory.ts
│ ├── directory-tree.ts
│ ├── get-file-info.ts
│ ├── list-allowed-dirs.ts
│ ├── list-directory.ts
│ ├── read-file.ts
│ ├── read-media-file.ts
│ ├── read-multiple-files.ts
│ ├── search-content.ts
│ ├── search-definitions.ts
│ ├── search-files.ts
│ ├── tool-response.ts # Tool response formatting
│ └── index.ts # Tool registration
└── __tests__/ # Test files
├── lib/
│ ├── errors.test.ts
│ ├── file-operations.test.ts
│ ├── fs-helpers.test.ts
│ └── path-validation.test.ts
├── schemas/
│ └── validators.test.ts
└── security/
└── filesystem-boundary.test.ts
Testing with MCP Inspector
npm run inspector
This launches the MCP Inspector for interactive testing of all tools.
❓ Troubleshooting
| Issue | Solution |
|---|---|
| "Access denied" error | Ensure the path is within an allowed directory. Use list_allowed_directories to check. |
| "Path does not exist" error | Verify the path exists. Use list_directory to explore available files. |
| "File too large" error | Use head or tail parameters for partial reading, or increase maxSize. |
| "Binary file" warning | Use read_media_file for binary files, or set skipBinary=false in content search. |
| Unexpected directory access | Server defaults to CWD if no args/roots provided. Pass explicit paths to restrict. |
| Symlink blocked | Symlinks that resolve outside allowed directories are blocked for security. |
| Regex timeout | Simplify the regex pattern or use isLiteral=true for literal string search. |
🤝 Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Run tests and linting (
npm run lint && npm run test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Code Style
- Use TypeScript with strict mode
- Follow ESLint configuration
- Use Prettier for formatting
- Write tests for new features