Skip to content
CodeLifter
Search/ Browse prompts
CodeLifter Forum

How do you sandbox the Filesystem MCP server?

Staff answerWritten by CodeLifter editors · MCP and tools2 repliesupdated

Short answer

Give it one project folder and nothing more. Pass that folder as the only allowed directory, or run the Docker image with the folder bind-mounted under /projects, read-only where reads are enough, and with networking switched off. Keep secrets out of that folder, and confirm what the server can see before you let an assistant write.

Written by CodeLifter editors · Staff, CodeLifter ·
CiteCodeLifter Forum, "How do you sandbox the Filesystem MCP server?", https://codelifter.com/forum/posts/how-do-you-sandbox-the-filesystem-mcp-server/, accessed 2026-11-12.
  1. Staff, CodeLifter ·

    What the server can reach by default

    The reference Filesystem server restricts every operation to its allowed directories. Its README says "All filesystem operations are restricted to allowed directories" and that the server "requires at least ONE allowed directory to operate." Inside those directories it can read any file, write new files, overwrite existing ones with write_file, edit with edit_file, and move or rename with move_file, which the README's annotation table marks as destructive ("Deletes source file"). The README documents no undo or trash.

    There are two ways the allowed list gets set, and the difference matters for sandboxing:

    1. Command-line arguments. The paths after the package name in your config.
    2. MCP Roots. If your client supports Roots, the README says roots sent by the client "completely replace any server-side Allowed directories". The README recommends this method because the list can change at runtime without a restart.

    So if your client sends roots, the folders you typed in the config are not the ones in force. Check which applies before you rely on either.

    Step 1: narrow the allowed directories

    Point the server at the project you are working on, not your home folder or Desktop. With npx, the config in claude_desktop_config.json (or your client's equivalent) looks like this:

    {
      "mcpServers": {
        "filesystem": {
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/code/my-app"]
        }
      }
    }
    

    In VS Code, the README's example uses ${workspaceFolder} as the path, which limits the server to the open workspace. On Windows the README says to launch npx through cmd /c, so the command becomes cmd and the arguments start with "/c", "npx".

    Step 2: run it in a container with read-only mounts

    The npx route runs the server as you, with your user's file permissions. A container adds a second boundary: the server can only see what you mount. The README's Docker example mounts host folders under /projects and notes that "Adding the ro flag will make the directory readonly by the server." Docker's own bind mount documentation says bind mounts "have write access to files on the host by default" and that you can use the readonly or ro option to prevent writes.

    {
      "mcpServers": {
        "filesystem": {
          "command": "docker",
          "args": [
            "run", "-i", "--rm", "--network", "none",
            "--mount", "type=bind,src=/Users/you/code/my-app,dst=/projects/my-app",
            "--mount", "type=bind,src=/Users/you/code/shared-docs,dst=/projects/docs,ro",
            "mcp/filesystem",
            "/projects"
          ]
        }
      }
    }
    

    The --network none flag is our addition, not part of the README's example. Docker's none network driver page says it will "completely isolate the networking stack of a container" so that "only the loopback device is created." The README states that every tool sets openWorldHint: false and that the server "only accesses the local filesystem," and stdio needs no network, so the flag should not change how it works. Test it with your client before you depend on it.

    Step 3: keep secrets out of the allowed folders

    The server's read_text_file tool "Always treats the file as UTF-8 text regardless of extension", so an .env file, an SSH key or a cloud credentials file inside an allowed folder can be read like any other file. Before you start:

    1. Move secrets out of the project folder, or mount only the subfolders the assistant needs (for example src/ and docs/, not the repository root).
    2. Do not allow your home directory. It usually contains ~/.ssh, shell history and tool configs.
    3. If a token has to sit in the project, assume the assistant can read it, and scope that token tightly. The thread on GitHub MCP token scopes covers that for GitHub.

    Step 4: keep a human on the write tools

    Sandboxing limits where damage can happen. It does not stop damage inside the folder. Turn on your client's per-call approval for write_file, edit_file and move_file. The README advises using edit_file with dryRun first, which returns a diff without applying it. The MCP tools specification also says clients "MUST consider tool annotations to be untrusted unless they come from trusted servers", so treat a read-only hint as a label, not a lock. A read-only mount is the lock. Commit your work to git before a session so a bad overwrite can be reverted.

    Which control limits what

    Control Limits Does not limit
    One allowed directory (args) Paths the server will touch Anything inside that folder; replaced if the client sends Roots
    Roots from the client Paths, and they can change at runtime Same as above; you rely on the client's choice of roots
    Docker bind mounts What the process can see at all Writes to mounts without ro
    ro on a mount Writes to that folder Reads, including secrets in it
    --network none Network access from the container File access inside the mounts
    Client approval prompts Which calls run Calls you approve without reading

    Check the sandbox before you work

    1. Ask the assistant to call list_allowed_directories and read the result yourself. With Docker it should show only paths under /projects.
    2. Ask it to read a file outside those paths. The call should fail.
    3. Ask it to create a file in a folder you mounted with ro. The call should fail.
    4. Repeat after any client update, because Roots behaviour depends on the client.

    The CodeLifter page on the Filesystem MCP server lists every tool and its annotation. If you are choosing between local and hosted servers more generally, see remote or local GitHub MCP server, which walks through the same trade-off for GitHub.

    0
    ReplyLink

Plain text or simple Markdown. Links are nofollow. Your email is never shown.

  1. CodeLifter editorsStaffStaff, CodeLifter ·

    Is the Filesystem MCP server meant for production use? Its maintainers say no. The modelcontextprotocol/servers README describes the Filesystem server as one of a small number of reference servers maintained by the MCP steering group, and says they are meant to serve as educational examples, not as production-ready solutions. That does not make it unsafe to use on your own machine; it means nobody has promised the hardening or support a production component needs, which is one more reason for the container and read-only mounts in the opening post. Some facts worth recording if you depend on it, as checked on 15 October 2026: the npm package is @modelcontextprotocol/server-filesystem, its latest version was 1.0.0, published on 11 October 2026, and the server's own README says it is MIT licensed. The repository's LICENSE adds that new contributions are licensed under Apache-2.0, while earlier MIT contributions stay MIT. Pin the version in your config rather than taking whatever npx -y fetches, for example @modelcontextprotocol/server-filesystem@1.0.0, so an update does not change tool behaviour in the middle of a project. Then re-run the four sandbox checks whenever you change the version.

  2. CodeLifter editorsStaffStaff, CodeLifter ·

    Does a local MCP server run with my permissions? Yes. The MCP project's security best practices describe local servers as binaries downloaded and executed on the same machine as the client, and tell clients to warn that MCP servers run with the same privileges as the client. The same section lists the attacks that follow without sandboxing and consent: a malicious startup command hidden in a client configuration, a malicious payload inside the server package, and an insecure server left listening on localhost being reached through DNS rebinding. Its examples include a command that installs a package and then uploads ~/.ssh/id_rsa. For clients that offer one-click setup, the page says they must show the exact command, without truncation, and require explicit approval. It recommends running servers in a sandbox with minimal default privileges, using containers, chroot or application sandboxes, and granting directory or network access only when needed. For servers, it recommends the stdio transport, which limits access to the client that started it. The Docker setup in the opening post follows that advice. Before you paste anyone's config, read the command and args lines as you would read a shell script.

CodeLifter

Reviewed vibe coding prompts, the JavaScript each one should produce, and sourced answers on AI-generated code: who wrote it, who owns it, and whether you can ship it. Free since 1999.

Browse the Prompt Shelf

Popular topics

© 1999 to 2026 CodeLifter

Independent. No ties to any software vendor.
Code MIT Text CC-BY-4.0 Back to top