fs-mcp
by quincydelp
README.md
# fs-mcp
Hosted filesystem MCP server over HTTP. Read, write, edit, grep, glob, and tree — deployable to Railway with a persistent volume.
## Gap this fills
Every existing filesystem MCP server (including the official `@modelcontextprotocol/server-filesystem` with 248k weekly downloads) is **stdio-only** — it runs as a local subprocess. There is no hosted, HTTP-accessible filesystem MCP with auth. This fills that gap.
## Tools
| Tool | Description |
|------|-------------|
| `read_file` | Read file with line numbers, pagination (offset/limit) |
| `write_file` | Write/overwrite a file, creates parent dirs |
| `edit_file` | Search-and-replace patch (safe: errors if >1 match unless replace_all) |
| `grep` | Regex search across files with context lines |
| `glob` | Find files by glob pattern, sorted by mtime |
| `tree` | Directory tree (max_depth up to 6) |
| `list_dir` | List directory with sizes and timestamps |
| `delete_file` | Delete a single file |
## Auth
All requests require `Authorization: Bearer <MCP_AUTH_TOKEN>`.
## Environment variables
| Var | Default | Description |
|-----|---------|-------------|
| `MCP_AUTH_TOKEN` | *(required)* | Bearer token for auth |
| `FS_ROOT` | `/data` | Filesystem root. Mount a Railway volume here. |
| `PORT` | `8000` | HTTP port |
## Deploy to Railway
```bash
# 1. Create project
railway login
railway init
# 2. Set env vars
railway variables set MCP_AUTH_TOKEN=$(openssl rand -hex 32)
railway variables set FS_ROOT=/data
# 3. Add a volume mounted at /data in Railway dashboard
# 4. Deploy
railway up
```
## Connect from Claude Desktop / any MCP client
```json
{
"mcpServers": {
"fs-mcp": {
"transport": "http",
"url": "https://your-app.up.railway.app/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
```
## Local dev
```bash
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
MCP_AUTH_TOKEN=dev FS_ROOT=./data PORT=8000 .venv/bin/python3 server.py
```