Skip to main content
Glama
donliggett

mcp-filesystem

by donliggett

mcp-filesystem

Ein gehärteter Dateisystem-MCP-Server. Gibt einem lokalen Modell Lese- und Schreibzugriff auf eine Auswahl von Verzeichnissen – und sonst nichts.

Basiert auf dem MCP TypeScript SDK v2 gegen die Protokollrevision 2026-07-28, mit Abwärtskompatibilität für Clients aus der 2025-Ära auf demselben Endpunkt. Läuft über stdio (für LM Studio, Claude Desktop und alles andere, das einen lokalen Prozess startet) oder Streamable HTTP (für einen containerisierten gemeinsamen Endpunkt).


Warum dieser

Die meisten Dateisystem-MCP-Server prüfen, ob ein Pfad mit einem erlaubten Präfix beginnt, und gut ist. Dabei übersehen sie drei Dinge, die zählen:

  • Symlinks. Ein Link, der innerhalb der Sandbox platziert wurde und auf /etc zeigt, macht eine Präfixprüfung komplett wirkungslos.

  • Schreibvorgänge durch symlinkierte Verzeichnisse. realpath wirft bei Pfaden, die noch nicht existieren, einen Fehler. Server, die nur bestehende Dateien auflösen, legen also bereitwillig sandbox/linkdir/payload.sh außerhalb der Sandbox an.

  • Präfix-Kollisionen. /data-secrets beginnt mit /data.

Dieser Server löst jeden Pfad vor der Entscheidung zu seinem physischen Speicherort auf – und geht dabei bis zum tiefsten existierenden Vorfahren hoch, wenn das Ziel noch nicht existiert – und vergleicht mit per realpath aufgelösten Wurzeln unter Berücksichtigung von Trennzeichen. Die Testsuite prüft, dass jeder dieser Fluchtversuche fehlschlägt.


Related MCP server: MCP Filesystem Server

Tools

Tool

Zweck

read_file

Textdatei lesen, mit Zeilennummern, Seitenumbruch (offset/limit) und tail

read_multiple_files

Bis zu 50 Dateien in einem Aufruf lesen, mit gemeinsamem Byte-Budget

get_file_info

Größe, Typ, Zeitstempel, Berechtigungen, Text-/Binärerkennung

list_allowed_directories

Was erreichbar ist und die aktiven Limits

list_directory

Eine Ebene, Verzeichnisse zuerst, optionale Größen und Zeitstempel

directory_tree

Eingerückter rekursiver Baum, überspringt node_modules/.git/dist/…

search_files

Nach Glob suchen (**/*.ts)

grep_files

Dateiinhalte per Regex durchsuchen, mit Kontextzeilen

write_file

Atomarer Ganzdatei-Schreibvorgang

append_file

Anhängen, mit optionaler Zeilenumbruch-Normalisierung

edit_file

Exakte-String-Ersetzung, gibt ein Unified-Diff zurück, unterstützt dry_run

create_directory

mkdir -p

move_file

Verschieben/Umbenennen, dateisystemübergreifend sicher

copy_file

Datei oder Baum kopieren

delete_file

Löschen, mit explizitem recursive-Gate

Schreibvorgänge sind atomar: Der Inhalt geht in eine temporäre Datei im selben Verzeichnis, wird fsync'd und dann über das Ziel umbenannt. Ein Absturz oder eine volle Festplatte lässt das Original intakt statt abgeschnitten.


Schnellstart

npm install
npm run build
npm test

Dann einen Client darauf ausrichten:

node dist/index.js --root ./workspace

Oder interaktiv ausprobieren, ohne einen Client zu konfigurieren:

npx @modelcontextprotocol/inspector node dist/index.js --root ./workspace

LM Studio

LM Studio liest ~/.lmstudio/mcp.json (unter Windows C:\Users\<du>\.lmstudio\mcp.json). Öffnen Sie es über Programm → Installieren → mcp.json bearbeiten, fügen Sie einen Eintrag unter mcpServers hinzu und laden Sie dann LM Studio neu.

Nativ ausführen

Die Option mit dem geringsten Reibungsverlust – und die, mit der man beginnen sollte.

{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": [
        "/absolute/path/to/mcp-file-system/dist/index.js",
        "--root", "/absolute/path/to/your/project",
        "--read-only"
      ]
    }
  }
}

Fügen Sie --read-only hinzu, sobald Sie ihm vertrauen. Fügen Sie weitere --root-Flags für weitere Verzeichnisse hinzu.

Diese beiden Pfade müssen absolut sein. Der Host startet den Server als Kindprozess mit einem unvorhersehbaren Arbeitsverzeichnis, ein relativer Pfad würde also nicht aufgelöst. Auf der Kommandozeile, wo Sie das Arbeitsverzeichnis kontrollieren, sind relative Pfade wie --root ./workspace in Ordnung.

Unter Windows schreiben Sie entweder Schrägstriche (C:/Users/du/projects) oder verdoppeln die Backslashes, da ein einzelnes \ ein Escape-Zeichen innerhalb eines JSON-Strings ist.

In Docker ausführen

Docker gibt Ihnen eine vom Kernel erzwungene Grenze unterhalb der eigenen Prüfungen des Servers – das ist das eigentliche Argument dafür: Selbst ein Bug im Sandbox-Code kann nichts erreichen, das Sie nicht gemountet haben.

docker build -t mcp-filesystem:latest .
{
  "mcpServers": {
    "filesystem": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm", "--init",
        "--network", "none",
        "-v", "/absolute/path/to/your/project:/data:ro",
        "mcp-filesystem:latest",
        "--stdio", "--read-only"
      ]
    }
  }
}

Hinweise:

  • -i ist erforderlich. Ohne sie bekommt der Container kein stdin und der JSON-RPC-Handshake findet nie statt – das ist die mit Abstand häufigste Fehlkonfiguration.

  • --network none lohnt sich: Dieser Server hat keinen Grund, das Netzwerk zu erreichen, und das Entfernen der Schnittstelle entfernt eine ganze Klasse von Exfiltration.

  • :ro am Mount macht die Schreibschutz-Durchsetzung zur Aufgabe des Kernels. Um Schreibvorgänge zu erlauben, entfernen Sie :ro und entfernen Sie --read-only.

  • Docker verlangt, dass die Host-Seite von -v ein absoluter Pfad ist.

  • Auf Docker Desktop für Windows muss das Laufwerk, von dem Sie mounten, unter Einstellungen → Ressourcen → Dateifreigabe freigegeben sein.

  • Auf einem Linux-Host fügen Sie --user "$(id -u):$(id -g)" hinzu, damit geschriebene Dateien Ihnen gehören und nicht uid 1000.

Mounten Sie mehrere Verzeichnisse, indem Sie -v wiederholen und passende --root-Flags übergeben:

"-v", "/absolute/path/to/your/code:/data/code:ro",
"-v", "/absolute/path/to/your/notes:/data/notes",
"mcp-filesystem:latest",
"--stdio", "--root", "/data/code", "--root", "/data/notes"

HTTP-Transport

Für einen langlebigen Container, den mehrere Clients gemeinsam nutzen:

docker compose up -d
curl http://127.0.0.1:3000/health

Zeigen Sie einen Client auf http://127.0.0.1:3000/.

Dieser Server hat keine Authentifizierung. Jeder, der den Port erreichen kann, hat den Dateisystemzugriff, den der Server hat. docker-compose.yml veröffentlicht nur auf 127.0.0.1. Wenn Sie ihn woanders binden, setzen Sie einen authentifizierenden Reverse-Proxy davor und erwarten Sie, dass das Startprotokoll Sie warnt.

Wenn er an Loopback gebunden ist, validiert der Server Host- und Origin-Header, um DNS-Rebinding zu blockieren – eine Webseite, die Sie besuchen, löst eine angreiferkontrollierte Domain zu 127.0.0.1 auf und POSTet an diesen Port.


Konfiguration

Jedes Flag hat ein Umgebungsvariablen-Pendant, das der Container verwendet. CLI-Flags gewinnen.

Flag

Env

Standard

Bedeutung

--root <dir>

FS_ALLOWED_ROOTS (kommagetrennt)

erforderlich

Erlaubtes Verzeichnis. Wiederholbar.

--read-only

FS_READ_ONLY

false

Alle mutierenden Tools ablehnen

--deny <glob>

FS_DENY_PATTERNS

siehe unten

Zusätzliche blockierte Muster

--allow-default-denied

FS_ALLOW_DEFAULT_DENIED

false

Die eingebaute Deny-Liste entfernen

--follow-symlinks

FS_FOLLOW_SYMLINKS

false

Symlinks erlauben, die im Sandbox bleiben

--max-read-bytes <n>

FS_MAX_READ_BYTES

10485760

Pro-Datei-Leselimit

--max-write-bytes <n>

FS_MAX_WRITE_BYTES

10485760

Pro-Datei-Schreiblmit

--max-results <n>

FS_MAX_RESULTS

1000

Limit für Liste/Suche/Grep-Ergebnisse

--max-depth <n>

FS_MAX_DEPTH

20

Rekursionstiefe

--stdio / --http

FS_TRANSPORT

stdio

Transport

--host / --port

FS_HTTP_HOST / FS_HTTP_PORT

127.0.0.1 / 3000

HTTP-Bindung

--audit / --no-audit

FS_AUDIT

true

JSON-Auditzeile pro Aufruf auf stderr

Der Server weigert sich, ohne konfigurierte Roots zu starten. Ein Dateisystem-Server ohne Sandbox ist kein sicheres Standardverhalten, und das Standardverhalten auf das Arbeitsverzeichnis zu setzen, macht den Fehler nur still.

Standard-Deny-Liste

Blockiert, es sei denn, Sie übergeben --allow-default-denied: .env und .env.*, *.pem, *.key, *.p12, *.pfx, *.keystore, id_rsa/id_dsa/id_ecdsa/id_ed25519, .ssh/, .aws/, .gnupg/, .kube/config, .npmrc, .netrc, .pypirc, .docker/config.json, .git/, .svn/, .hg/, shadow.

Das existiert, damit ein unachtsames -v $HOME:/data überlebbar ist. Es ist ein Sicherheitsnetz, kein Ersatz für das Mounten des richtigen Verzeichnisses.


Sicherheitsmodell

Was durchgesetzt wird

  • Physische Pfadauflösung (realpath) vor jeder Containment-Entscheidung, auch für Pfade, die noch nicht existieren

  • Trennzeichenbewusste Root-Übereinstimmung (/data matcht nie /data-secrets)

  • Symlinks standardmäßig abgelehnt, in jeder Pfadposition – nicht nur am Blatt

  • NUL-Byte-Ablehnung (safe.txt\0/../../etc/passwd wird im Syscall abgeschnitten)

  • Windows: alternative Datenströme (file:stream), reservierte Gerätenamen (CON, NUL, COM1…), Geräte-Namespace-Pfade (\\?\, \\.\) und case-insensitive Containment

  • Read-only-Modus sperrt mutierende Tools, bevor der Handler läuft

  • Beide Operanden werden bei move/copy geprüft – eine Nur-Quelle-Prüfung ist ein Schreib-Primitiv für den gesamten Host

  • Erlaubte Roots können selbst nicht gelöscht oder verschoben werden

  • Größenlimits werden vor der Zuweisung per stat geprüft

  • Binärerkennung, damit Binärdateien nicht als Token-verbrennender Müll zurückgegeben werden

  • Regex-Screening und eine Wanduhr-Frist für grep_files

  • Fehlermeldungen geben nie Host-Pfade wieder; SecurityError gibt eine vage Meldung an das Modell zurück und protokolliert den echten Grund im Audit-Stream, damit die Sandbox kein Orakel für die Kartierung Ihres Dateisystems ist

Was nicht

  • TOCTOU. Zwischen dem Auflösen eines Pfads und dem Öffnen könnte ein lokaler Angreifer, der in Ihre erlaubten Roots schreiben kann, eine Datei gegen einen Symlink tauschen. Das zu schließen erfordert openat2(RESOLVE_BENEATH) unter Linux, das Node nicht exponiert. Die praktische Abmilderung ist die Container-Grenze – mounten Sie nur, was Sie wirklich exponieren wollen.

  • Authentifizierung. Kein Transport authentifiziert. stdio erbt das Vertrauen dessen, der den Prozess gestartet hat; HTTP ist aus diesem Grund nur Loopback.

  • Ressourcenerschöpfung. Limits und Fristen begrenzen das Meiste, aber ein pathologischer Regex kann trotzdem eine 15-Sekunden-Frist an CPU verbrennen. Die Compose-Datei setzt Speicher- und CPU-Limits.

  • Prompt-Injection. Wenn eine Datei in Ihrer Sandbox Anweisungen enthält und Ihr Modell ihnen folgt, wird dieser Server treu ausführen, welche Tools das Modell als Nächstes aufruft. Der Read-only-Modus ist die Mitigation, die tatsächlich funktioniert.

Container-Härtung (in docker-compose.yml): Nicht-Root-Benutzer, read_only-Root-Dateisystem, alle Capabilities entfernt, no-new-privileges, tmpfs /tmp, Speicher- und CPU-Limits.


Audit-Protokoll

Ein JSON-Objekt pro Zeile auf stderr – nie stdout, das ist der JSON-RPC-Kanal unter stdio. console.log wird beim Start monkey-gepatcht, um auf stderr umzuleiten, damit eine verirrte Debug-Anweisung den Protokollstrom nicht korrumpieren kann.

{"ts":"2026-08-21T19:12:03.441Z","tool":"read_file","outcome":"ok","durationMs":3,"paths":["src/index.ts"],"bytes":4821}
{"ts":"2026-08-21T19:12:07.882Z","tool":"read_file","outcome":"denied","durationMs":1,"detail":"physical containment failed: /data/../etc/passwd -> /etc/passwd"}

Protokollierte Pfade sind sandbox-relativ. Das Feld detail trägt den vollständigen Grund und wird nur hier geschrieben, nie an das Modell zurückgegeben.

docker compose logs -f filesystem | jq 'select(.outcome=="denied")'

Tests

npm run build && npm test

test/sandbox.test.ts ist die Suite, die zählt – jeder Fall ist ein Versuch, eine Datei außerhalb des Roots zu erreichen. Wenn einer von ihnen zu bestehen beginnt, wo er werfen sollte, ist der Server auf die einzige Weise kaputt, die wirklich gefährlich ist.

Symlink-Tests überspringen sich unter Windows, es sei denn, der Entwicklermodus ist aktiviert, da das Erstellen von Symlinks sonst Admin-Rechte erfordert.


Projektstruktur

src/
  index.ts              entrypoint, transport selection, shutdown
  config.ts             CLI + env parsing, root resolution
  security/
    sandbox.ts          path resolution and containment — the security core
    audit.ts            structured stderr logging, stdout protection
  tools/
    context.ts          registration wrapper: read-only gate, errors, audit
    read.ts             read_file, read_multiple_files, get_file_info, ...
    write.ts            write_file, append_file, edit_file
    listing.ts          list_directory, directory_tree
    manage.ts           create_directory, move_file, copy_file, delete_file
    search.ts           search_files, grep_files
  util/
    walk.ts             sandbox-aware directory traversal with cycle guard
    binary.ts           binary detection, BOM handling
    errors.ts           error taxonomy and fs error translation
    format.ts           output formatting for model consumption

Lizenz

MIT

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables secure filesystem operations with directory sandboxing and optional read-only mode. Supports file reading/writing, directory management, file searching, and text operations while restricting access to specified directories.
    12
  • A
    license
    A
    quality
    D
    maintenance
    Provides secure filesystem access for AI models through the Model Context Protocol with strict path validation, file operations, directory management, and system command execution within predefined directories.
    16
    7
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides sandboxed access to local filesystem operations including directory and file management, content search with glob and regex patterns, and binary file support with configurable safety limits.
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides a secure, constrained filesystem workspace for LLM agents to manage files, notes, and code artifacts via stdio or remote HTTP. It features granular access controls, including extension whitelisting, storage quotas, and immutable paths for safe automated file operations.
    BSD 3-Clause

View all related MCP servers

Related MCP Connectors

  • Securely search and manage workspace context files for AI agents and teams.

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

  • Cross-agent artifact workspace with provenance across Claude Code, Codex, Cursor, LangGraph.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/donliggett/mcp-file-system'

If you have feedback or need assistance with the MCP directory API, please join our Discord server