SafetyCard Request a review

MCP Filesystem server

Reference MCP server for read/write filesystem access within allowed dirs

github.com/modelcontextprotocol/servers › src/filesystem · 2026-10-03 · f46d957

Defense-in-depth score

5.3 / 10

A small, well-fenced file server: every path is resolved through symlinks and checked against the directories you allow, and it never runs code, touches the network or holds credentials. The main risk is what it hands a hijacked model inside those directories: write, edit and move tools are always on with no read-only switch and no undo, and file contents (including any .env or key files there) go to the model unmarked. It keeps no log of what it did and puts no limits on file sizes or recursive listings, so allow only the narrowest directories you need and rely on the host to approve writes.

Safest setup

The filesystem server holds no credentials, runs no code and makes no network calls, and every path it touches is checked against the directories you allow. Write tools are always on, nothing is logged and nothing is limited, so the safest setup narrows what the process can reach and adds approval, backups and a record around it.

SetupHowWhat it gives you
A dedicated non-root userRun the server, or its container, as an OS user whose own permissions reach only the directories it servesThe operating system itself keeps the rest of your files out of reach, whatever the server is asked to do C1
Read-only mountsRun the Docker image with each directory mounted under /projects, adding the ro flag to every directory the task only readsThose directories cannot be changed, even though the write tools stay registered C3
Only the directories neededPass just the task's directories as the allowed-directory argumentsThe server's path check measures every call against just the folders you named C3
Matching client rootsSet the host's roots to the same narrow directories, since client roots replace the command-line listThe allowed directories stay the ones you chose for the whole session C1
Secrets kept elsewhereKeep .env files, private keys and credential files outside every allowed directoryFile contents sent to the model hold no secrets to leak C8
Version control or backupsKeep the allowed directories under version control or a regular backupAny overwrite, edit or move can be rolled back C2
A memory ceilingRun the server with a memory limit set by the container or the OSA large file or deep directory walk stops at the limit you set, not at the machine's memory C10
A host-side call logKeep the host application's record of MCP tool calls, stored outside the allowed directoriesA trace of every read, write and move that the server does not keep itself C9

Approving with confidence

  • Read each prompt and approve write, edit and move calls one at a time; every tool is labelled read-only or destructive for the host to act on.
  • Ask for an edit preview with dryRun before approving the edit itself; whole-file writes and moves have no preview.

Handling data

  • File contents go to the model verbatim and unmarked, so treat the conversation like the files it read.
  • The server's stderr output holds directory paths and errors, never file contents.

Criteria

C1 Identity & least privilege

0.38 / 1.00

The server holds no credentials, reads no environment variables, starts no other programs and makes no network calls, so there is no token to steal or forward. It does, however, run with the full file permissions of whoever launched it (or as root inside the shipped Docker image), and the only thing narrowing that is the allowed-directories check, which is scored under tool scoping. If that check failed, the server could read and write anything the user can, including SSH keys, cloud credential files and shell startup files.

C2 Approval gates

0.57 / 1.00

As a tool server, this project cannot ask the user for approval itself; it gives the host the information to do so. Reading tools and writing tools are separate, and every tool carries accurate hints: all ten read tools are marked read-only and the write, edit and move tools are marked destructive. The edit tool offers a dry-run preview, but overwriting a whole file and moving files have no preview, and the server has no read-only mode of its own. Overwrites are immediate and keep no backup, so a wrongly approved write cannot be undone by the server.

C3 Tool & action scoping

0.60 / 1.00

This is the server's strongest area. Every tool takes a path and every path goes through one validation function that resolves symlinks with realpath, checks containment against the allowed directories with a separator-aware comparison, rejects null bytes, and for new files walks each existing parent component checking it stays inside. Writes avoid following pre-existing symlinks by using exclusive creation and atomic rename. The tools are narrow (no shell, no network), but all of them, including write, edit and move, are always on, there is no read-only switch, and nothing bounds file sizes or result counts. Path containment is not a complete boundary.

C4 Code-execution isolation

N/A · full credit 1.00 / 1.00

The server never runs code: there is no shell, no process spawning and no dynamic evaluation anywhere in its source. It can write files that some other program might later execute, but that execution happens outside this server and is not counted here.

C5 Untrusted input blast radius

0.13 / 1.00

The server's job is to hand file contents to the model, so any file in the allowed directories can carry a prompt injection. Contents are returned as plain text with no marker that they are untrusted and no source path attached (except in the multi-file read), so the host gets nothing it could act on. The server has no network access of its own, so it cannot itself send data out, but a hijacked model can use it to overwrite or rearrange files without any check from the server, and paired with any egress-capable tool on the same host the full leak-plus-damage chain is open.

C6 Memory, context & configuration integrity

N/A · full credit 1.00 / 1.00

Nothing the model does can change how the server behaves later. There is no memory, cache or database, no settings file is read from the allowed directories, and configuration comes only from command-line arguments and the client's roots list.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

The server loads no third-party code at runtime: no plugins, no dynamic imports, no package installs and no other MCP servers. How the host installs this server (the README's npx -y line fetches the latest version) is the host's supply-chain concern and is not scored here.

C8 Secrets & sensitive-data protection

0.45 / 1.00

The server holds no keys or tokens and reads no environment variables, so there is nothing of its own to leak, and its stderr log lines contain directory paths and error messages but never file contents. It has no telemetry. But it does nothing to protect secrets that sit in the allowed directories: a .env file, private key or credentials file is returned to the model verbatim, with no denylist or redaction.

C9 Audit & traceability

0.00 / 1.00

The server keeps no record of what it did. Tool calls, their arguments and results are not logged anywhere; the only output is a handful of startup and roots-change messages on stderr. Reconstructing an incident depends entirely on whatever the host application chose to log.

C10 Limits & kill switch

0.20 / 1.00

The server puts no limits on its own work. Whole files are read into memory regardless of size, the multi-file read takes any number of paths at once, and the directory tree and search tools walk the entire directory with no depth or result limit. The only bounds are the optional head and tail line counts the caller may pass. Requests cannot be cancelled mid-way, though stopping the server process ends everything because it starts no background work or child processes.