Skip to main content

A secure MCP filesystem server with Stdio and Web UI modes.

Project description

fs-mcp 📂

Universal, Provider-Agnostic Filesystem MCP Server

Works with Claude, Gemini, GPT — zero configuration required.


https://github.com/user-attachments/assets/132acdd9-014c-4ba0-845a-7db74644e655

💡 Why This Exists

MCP (Model Context Protocol) is incredible, but connecting AI agents to filesystems hits real-world walls:

Problem fs-mcp Solution
Container Gap — Stdio doesn't work across Docker boundaries HTTP server by default — connect from anywhere
Token Waste — Agents dump entire files to find one function Smart grep → read pattern with section hints
Schema Hell — Gemini silently corrupts nested object schemas Auto-transforms schemas at runtime — just works
Blind Overwrites — One hallucination wipes your main.py Human-in-the-loop review with VS Code diff

fs-mcp is a Python-based server built on fastmcp that treats efficiency, safety, and universal compatibility as first-class citizens.


🚀 Core Value

1. Agent-First Efficiency

Tools are designed to minimize token usage and maximize context quality:

flowchart LR
    A["grep_content('def calculate')"] --> B["Returns: Line 142<br/>(hint: function ends L158)"]
    B --> C["read_files(start=142, end=158)"]
    C --> D["17 lines instead of 5000"]
    
    style D fill:#90EE90
  • Section Hints: grep_content tells you where functions/classes end
  • Pattern Reading: read_files with read_to_next_pattern extracts complete blocks
  • Token-Efficient Errors: Fuzzy match suggestions instead of file dumps (90% savings)

2. Human-in-the-Loop Safety

The propose_and_review tool opens a VS Code diff for every edit:

sequenceDiagram
    participant Agent
    participant Server
    participant Human

    Agent->>Server: propose_and_review(edits)
    Server->>Human: Opens VS Code diff
    
    alt Approve
        Human->>Server: Add double newline + Save
        Server->>Agent: "APPROVE"
        Agent->>Server: commit_review()
    else Modify
        Human->>Server: Edit directly + Save
        Server->>Agent: "REVIEW" + your changes
        Agent->>Agent: Incorporate feedback
    end

Safety features:

  • Full overwrites require explicit OVERWRITE_FILE sentinel
  • Batch edits with edits=[] for multiple changes in one call
  • Session-based workflow prevents race conditions
  • Optional dangerous mode: create FS_MCP_FLAG in the workspace root to bypass path restrictions and auto-commit propose_and_review edits without human review until the file is deleted

3. Universal Provider Compatibility

The problem: Gemini silently corrupts JSON Schema $ref references — nested objects like FileReadRequest degrade to STRING, breaking tool calls.

The fix: fs-mcp automatically transforms all schemas to Gemini-compatible format at startup. No configuration needed.

Before (broken):     "items": {"$ref": "#/$defs/FileReadRequest"}
                              ↓ Gemini sees this as ↓
                     "items": {"type": "STRING"}  ❌

After (fs-mcp):      "items": {"type": "object", "properties": {...}}  ✅

This "lowest common denominator" approach means the same server works with Claude, Gemini, and GPT without any provider-specific code.


⚡ Quick Start

Run Instantly

# One command — launches Web UI (8123) + HTTP Server (8124)
uvx fs-mcp .

Selective Launch

# HTTP only (headless / Docker / CI)
fs-mcp --no-ui .

# UI only (local testing)
fs-mcp --no-http .

Docker

# In your Dockerfile or entrypoint
uvx fs-mcp --no-ui --http-host 0.0.0.0 --http-port 8124 /app

🔌 Configuration

Claude Desktop (Stdio)

{
  "mcpServers": {
    "fs-mcp": {
      "command": "uvx",
      "args": ["fs-mcp", "/path/to/your/project"]
    }
  }
}

OpenCode / Other HTTP Clients

Point your MCP client to http://localhost:8124/mcp/ (SSE transport).


🧰 The Toolbox

Discovery & Reading

Tool Purpose
grep_content Regex search with section hints — knows where functions end
read_files Multi-file read with head/tail, line ranges, read_to_next_pattern, or per-file reads arrays for multi-slice requests
directory_tree Recursive tree explorer: compact text by default (compact=True), legacy JSON with compact=False
search_files Glob pattern file discovery
get_file_info Metadata + token estimate + chunking recommendations

Editing (Human-in-the-Loop)

Tool Purpose
propose_and_review Safe editing — VS Code diff, batch edits, fuzzy match suggestions
commit_review Finalize approved changes

Structured Data

Tool Purpose
query_jq JQ queries on large JSON files (bounded output)
query_yq YQ queries on structured data files (YAML, XML, TOML, CSV, TSV, INI, HCL)

Utilities

Tool Purpose
list_directory_with_sizes Detailed listing with formatted sizes
list_allowed_directories Show security-approved paths
create_directory Create directories
read_media_file Base64 encode images/audio for vision models

Analysis

Tool Purpose
analyze_gsd_work_log Semantic analysis of GSD-Lite project logs

🏗️ Architecture

src/fs_mcp/
├── server.py          # Tool definitions + schema transforms
├── gemini_compat.py   # JSON Schema → Gemini-compatible
├── edit_tool.py       # propose_and_review logic
├── web_ui.py          # Streamlit dashboard
└── gsd_lite_analyzer.py

scripts/schema_compat/ # CLI for schema validation
tests/                 # pytest suite (including Gemini compat CI guard)

Required CLI tools (fs-mcp exits with install instructions if missing):

  • ripgrep (rg) — powers grep_content
  • jq — powers query_jq
  • yq — powers query_yq (also handles XML, TOML, CSV, TSV, INI, HCL)
# macOS
brew install ripgrep jq yq

# Ubuntu/Debian
sudo apt-get install ripgrep jq
# yq: download from https://github.com/mikefarah/yq/releases

📊 Why Token Efficiency Matters

Scenario Without fs-mcp With fs-mcp
Find a function Read entire file (5000 tokens) grep + targeted read (200 tokens)
Edit mismatch error Dump file + error (6000 tokens) Fuzzy suggestions (500 tokens)
Explore large JSON Load entire file (10000 tokens) JQ query (100 tokens)

Result: 10-50x reduction in context usage for common operations.


🧪 Testing

# Run all tests
uv run pytest

# Run Gemini compatibility guard (fails if schemas break)
uv run pytest tests/test_gemini_schema_compat.py

📜 License & Credits

Built with ❤️ for the MCP community by luutuankiet.

Powered by FastMCP, Pydantic, and Streamlit.

Now go build some agents. 🚀

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fs_mcp-1.33.1.tar.gz (670.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fs_mcp-1.33.1-py3-none-any.whl (59.6 kB view details)

Uploaded Python 3

File details

Details for the file fs_mcp-1.33.1.tar.gz.

File metadata

  • Download URL: fs_mcp-1.33.1.tar.gz
  • Upload date:
  • Size: 670.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fs_mcp-1.33.1.tar.gz
Algorithm Hash digest
SHA256 902b2f38ff413b77b6a45c4690645feb1bfd691ed1a262fc7d8ee2d7bf071ef2
MD5 adfbe98ca98c18ae0112526bef93b7d3
BLAKE2b-256 fa6b5e80525b4f74530bc38b0eaee7814bea1a8bfbc9c37712f4b2f02db5c870

See more details on using hashes here.

File details

Details for the file fs_mcp-1.33.1-py3-none-any.whl.

File metadata

  • Download URL: fs_mcp-1.33.1-py3-none-any.whl
  • Upload date:
  • Size: 59.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fs_mcp-1.33.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d8e109fc278d82ebd051f069ff57bb3b31757a210526fec80492784e71901d99
MD5 a1cbee7565ff02923f2acad9acc6c186
BLAKE2b-256 5294690ca863c95da4a491bfd90b0f66e9778e6b983691e02ce3c4bb371a10f0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page