Skip to main content
Glama
lofcz

MCP Smart Filesystem Server

by lofcz
README.md
# MCP Smart Filesystem Server

An LLM-optimized Model Context Protocol (MCP) filesystem server with intelligent features designed for effective AI agent interaction.

## Features

### 🚀 **Intelligent File Pagination**
- Automatically chunks large files (>500 lines) into manageable pieces
- Simple `start_line` parameter for easy navigation
- Clear indicators when more content is available
- Prevents context overflow in LLM conversations

### âš¡ **Ripgrep Integration**
- Lightning-fast code searching across entire codebase
- Regex pattern support with helpful examples
- File-specific searching (like Ctrl+F with regex)
- Flexible filtering by file type, path, and more

### 🔒 **Security Sandboxing**
- Strict directory access control
- Symlink attack prevention
- Path traversal protection
- Only accesses files within allowed directories

### 🎯 **LLM-Friendly Design**
- Helpful suggestions in responses
- Examples for common search patterns
- Reading strategy recommendations for large files
- Clear error messages with actionable guidance

## Tools

### 1. **list_directory**
List directory contents with metadata.

```json
{
  "path": "src"
}
```

**Returns:** Files, directories, sizes, line counts, and summary statistics.

### 2. **read_file**
Read file contents with automatic pagination for large files.

```json
{
  "path": "src/large-file.ts",
  "start_line": 0
}
```

For files >500 lines, returns first 500 lines with `hasMore: true` and `nextStartLine`.  
Read next chunk with `start_line: 500`, then `1000`, etc.

### 3. **search_code**
Search for code patterns using ripgrep (very fast).

**Examples:**

Find any type declaration (class/struct/interface/enum):
```json
{
  "pattern": "\\b(class|struct|interface|enum)\\s+ServiceName\\b",
  "filePattern": "*.ts"
}
```

Find method with any access modifier:
```json
{
  "pattern": "\\b(public|private|protected).*\\s+methodName\\s*\\(",
  "path": "src/directory"
}
```

Find all async functions:
```json
{
  "pattern": "async\\s+.*\\s*\\(",
  "caseInsensitive": true,
  "contextLines": 3
}
```

**Options:**
- `pattern` (required): Regex pattern
- `path`: Limit to specific directory
- `filePattern`: File glob (e.g., `*.js`, `*.{ts,tsx}`, `!*test*`)
- `caseInsensitive`: Ignore case
- `contextLines`: Lines of context (default: 2)
- `maxResults`: Max results (default: 50)
- `literalString`: Treat as literal, not regex
- `wordBoundary`: Match whole words only

### 4. **search_in_file**
Search within a specific file (like Ctrl+F with regex).

```json
{
  "path": "src/server.ts",
  "pattern": "app\\.use\\(",
  "contextLines": 3
}
```

### 5. **find_files**
Find files by name pattern.

```json
{
  "pattern": "*Handler*.ts"
}
```

**Pattern examples:**
- `config.json` - Exact name
- `*.config` - Wildcard
- `*Service*` - Contains "Service"
- `*.{ts,tsx,js}` - Multiple extensions

### 6. **get_file_info**
Get file metadata without reading contents.

```json
{
  "path": "src/large-file.ts"
}
```

**Returns:** Size, line count, language, binary status, and reading strategy for large files.

### 7. **list_allowed_directories**
Show accessible directories (security boundaries).

```json
{}
```

## Installation

### Docker (Recommended)

```bash
# Build image
docker build -t mcp-filesystem-smart .

# Run with workspace mounted
docker run -i --rm \
  -v /path/to/your/project:/workspace:ro \
  mcp-filesystem-smart
```

The `:ro` flag makes the directory read-only for extra security.

### Configuration via Environment Variables

Customize behavior with environment variables:

```bash
docker run -i --rm \
  -e MCP_LINES_PER_PAGE=1000 \
  -e MCP_MAX_SEARCH_RESULTS=200 \
  -v /path/to/your/project:/workspace:ro \
  mcp-filesystem-smart
```

**Available Variables:**
- `MCP_LINES_PER_PAGE` - Lines per page when reading files (default: 500)
- `MCP_MAX_SEARCH_RESULTS` - Search results per page (default: 100)

### Local Installation

```bash
npm install
npm run build
node dist/index.js /path/to/allowed/directory
```

## Usage with MCP Clients

### Configuration Example

```json
{
  "mcpServers": {
    "filesystem-smart": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-v", "/home/user/projects/myapp:/workspace:ro",
        "mcp-filesystem-smart"
      ]
    }
  }
}
```

### Multiple Allowed Directories

```bash
# Local
node dist/index.js /path/to/dir1 /path/to/dir2

# Docker (mount multiple volumes)
docker run -i --rm \
  -v /path/to/dir1:/workspace1:ro \
  -v /path/to/dir2:/workspace2:ro \
  mcp-filesystem-smart /workspace1 /workspace2
```

## LLM Usage Patterns

### Pattern 1: Find Type Declaration (Unknown Kind)
When you don't know if something is a class, struct, interface, or record:

```javascript
search_code({
  pattern: "\\b(class|struct|record|interface|enum)\\s+MyType\\b",
  filePattern: "*.cs"
})
```

### Pattern 2: Explore Then Read
1. Search for what you need: `search_code(pattern="functionName")`
2. Get file info: `get_file_info(path="src/module.ts")` 
3. Read strategically: `read_file(path="src/module.ts", start_line=0)`

### Pattern 3: Large File Navigation
1. Check size: `get_file_info(path="big-file.ts")` → "1500 lines"
2. Search within: `search_in_file(path="big-file.ts", pattern="export class")`
3. Read around matches: Use line numbers from search to read specific chunks

### Pattern 4: Find Files, Then Search
1. Find files: `find_files(pattern="*Service*.ts")`
2. Search within results: `search_code(pattern="constructor", path="src/services")`

## Common Search Patterns

### C# / .NET
```javascript
// Find any type
"\\b(class|struct|record|interface|enum)\\s+TypeName\\b"

// Find method
"\\b(public|private|protected|internal).*\\s+MethodName\\s*\\("

// Find async methods
"async\\s+(Task|ValueTask)<.*>\\s+\\w+\\s*\\("
```

### TypeScript / JavaScript
```javascript
// Find function/method
"(function|const|let|var)\\s+\\w+\\s*=.*=>|function\\s+\\w+\\s*\\("

// Find class/interface
"(class|interface)\\s+\\w+"

// Find async functions
"async\\s+(function|\\w+\\s*=>|\\(.*\\)\\s*=>)"
```

### Python
```javascript
// Find class
"class\\s+\\w+.*:"

// Find function
"def\\s+\\w+\\s*\\("

// Find async function
"async\\s+def\\s+\\w+"
```

## Requirements

- **Node.js**: 22 or higher
- **ripgrep**: Must be installed and available in PATH
  - Alpine Linux: `apk add ripgrep`
  - Ubuntu/Debian: `apt install ripgrep`
  - macOS: `brew install ripgrep`
  - Windows: `choco install ripgrep`

## Security

This server implements multiple security layers:

1. **Directory Sandboxing**: Only accesses files within allowed directories
2. **Symlink Resolution**: Prevents symlink attacks by checking real paths
3. **Path Validation**: Blocks path traversal attempts (../, etc.)
4. **Read-Only Docker**: Mount volumes as `:ro` for read-only access

## Development

```bash
# Install dependencies
npm install

# Build
npm run build

# Watch mode
npm run watch

# Test locally
node dist/index.js $(pwd)
```

## License

MIT

## Credits

Built on top of the Model Context Protocol (MCP) SDK and ripgrep.

TDQS

A3.7/5.0

Scored across 7 tools

Disambiguation4/5

Most tools have distinct purposes: find_files locates files by name, get_file_info provides metadata, list_allowed_directories shows accessible directories, list_directory enumerates directory contents, read_file reads file contents, search_code searches across files with regex, and search_in_file searches within a single file. However, search_code and search_in_file could be slightly confused as both involve regex-based searching, though their scopes differ (global vs. file-specific).

Naming Consistency5/5

All tool names follow a consistent snake_case pattern with clear verb_noun structures: find_files, get_file_info, list_allowed_directories, list_directory, read_file, search_code, and search_in_file. The naming is predictable and readable throughout the set.

Tool Count5/5

With 7 tools, the server is well-scoped for a filesystem domain, covering key operations like finding, listing, reading, and searching files. Each tool serves a specific function without redundancy, making the count appropriate for the intended purpose.

Completeness4/5

The toolset covers essential filesystem operations such as discovery, metadata retrieval, directory listing, reading, and searching, with good support for large files and regex patterns. A minor gap is the lack of write or modify operations (e.g., create, update, delete files), which might limit full lifecycle management, but the provided tools handle read-only workflows effectively.

Maintenance

ActivityInactive
ResponsivenessNo issues