Filesystem MCP Server: Giving an Agent Folder Access Safely

The reference Filesystem MCP server lets an AI assistant read, write, move and search files in folders you name. How allowed directories and Roots work, the tools it exposes, setup in Claude Desktop, how to keep it read-only, and why coding agents such as Claude Code do not need it.

7 min read

The Filesystem MCP server is the Model Context Protocol project’s reference server for local files, published as @modelcontextprotocol/server-filesystem. You start it with a list of folders, and it gives the assistant tools to read, write, edit, move and search files inside those folders and nowhere else. It is the usual way to let Claude Desktop, or any chat app without file tools of its own, work with documents on your computer. To use it safely, name the narrowest folders that do the job, never your home directory; mount them read-only through Docker if the assistant should only read, since the server has no read-only switch; keep the package current, because two path-check bypasses were fixed in July 2025; and approve write tools one at a time. Coding agents such as Claude Code already have file tools and folder permissions built in, so they do not need it.

What the server can do

The Filesystem server README (opens in a new tab) lists its tools. Each carries MCP annotations that tell the client whether it only reads:

  • Read-only: read_text_file (with optional head or tail lines), read_media_file, read_multiple_files, list_directory, list_directory_with_sizes, directory_tree, search_files, get_file_info and list_allowed_directories.
  • Write: create_directory, write_file, which creates a file or overwrites an existing one, edit_file, which replaces matched text and has a dryRun option that returns a diff without saving, and move_file, which moves or renames and fails if the destination exists.

There is no delete tool, but that is less comforting than it sounds. write_file can replace a file’s contents with nothing, and move_file can take a file out of the folder where you expect it. The README marks all three as destructive. Ask for dryRun first whenever you want an edit, and read the diff before you let it save.

Allowed directories

Every operation is limited to the allowed directories. The simplest way to set them is as arguments when the server starts: every path after the package name is a folder it may open, including everything below it. The server refuses to start with none. The assistant can call list_allowed_directories to see the current list, and so can you, which is the quickest check that the configuration did what you meant.

Pick folders by what the job needs. A folder of meeting notes, a project’s docs directory or a scratch folder for drafts are good choices. Your home directory, your whole Desktop, a folder synced to a shared drive, or anywhere that holds .ssh, .env files, password exports or tax documents are not. The server runs as your user, so inside an allowed folder it can do anything you can.

Roots, and why they are fading

The README also supports MCP Roots and calls them the recommended method: a client that supports Roots tells the server which folders are relevant, and can update the list while the server runs. Note one detail. When a client provides roots, they completely replace the folders you passed as arguments, so the list you wrote in the config file may not be the list in force. Ask the assistant to call list_allowed_directories after connecting.

The protocol is moving the other way. The Roots page of the MCP specification (opens in a new tab) marks the feature deprecated as of protocol version 2026-07-28, to remain for at least twelve months, and asks new implementations not to adopt it and existing ones to pass directories through tool parameters or server configuration instead. It also says roots are informational guidance, not an access-control mechanism, and the protocol does not enforce them. In this server, the path checks are the server’s own code. For a setup you can reason about, pass the folders as arguments and treat Roots as an extra. What else changed in that revision is in MCP specification changes.

Setup in Claude Desktop

The MCP project’s guide to connecting local servers (opens in a new tab) uses this server as its example. Open Claude Desktop’s Settings from the menu bar, choose Developer, then Edit Config, and add an entry to claude_desktop_config.json with the folders you want:

claude_desktop_config.json (macOS)
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/you/Documents/Meeting Notes",
        "/Users/you/Drafts"
      ]
    }
  }
}

On Windows the file lives at %APPDATA%\Claude\claude_desktop_config.json, paths use doubled backslashes, and the README wraps npx in cmd /c. The server needs Node.js. Quit Claude Desktop completely and restart it, then find the server under connectors and read its tool list. The guide says Claude asks for your approval before it acts. Allow the read tools for the session if you like; keep asking on write_file, edit_file and move_file. More on this file’s format is in the Claude Desktop MCP config guide.

Claude Desktop also installs local servers as desktop extensions, one-click packages from Settings, Extensions, according to Anthropic’s guide to local MCP servers on Claude Desktop (opens in a new tab). On Team and Enterprise plans, Owners can limit which extensions members may install. Whichever route you use, the folder list is the part to get right.

Read-only use

The server has no read-only flag. The dependable way to make it read-only is to run it in Docker and mount your folder with the ro option, so the operating system refuses writes whatever the assistant asks for. The README’s Docker setup mounts folders under /projects:

claude_desktop_config.json (read-only mount)
{
  "mcpServers": {
    "filesystem-readonly": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "--mount", "type=bind,src=/Users/you/Documents/Meeting Notes,dst=/projects/notes,ro",
        "mcp/filesystem",
        "/projects"
      ]
    }
  }
}

The write tools still appear in the tool list, but every write fails. Two lighter options, if Docker is not available: point the server at a copy of the folder rather than the original, or deny the write tools in your client’s approval prompt every time. The copy is safer; a prompt you click through out of habit is not a control.

The risks to check first

  • Path-check bugs. In July 2025 the maintainers published two high-severity advisories for this server: a symlink handling bypass (opens in a new tab) and a colliding-prefix bypass, where a path that merely began with an allowed folder’s name could reach files outside it. The advisories name 2025.7.1 as a fixed release; if you pinned an older version, update it.
  • Instructions inside files. A document someone sent you can hold text aimed at the assistant. Reading it is how the instruction arrives, and a write tool is how it would act, so read-only mounts matter most for folders that hold other people’s files. The pattern is covered in indirect prompt injection.
  • Your own permissions. The server runs as you. A symlink or a sync folder inside an allowed directory can reach further than the folder name suggests.
  • Reference code. The MCP servers repository describes its servers as reference implementations for learning, not production-ready solutions, and asks you to judge your own threat model.

The wider list, from tool poisoning to over-broad tokens, is in MCP security risks.

Why Claude Code does not need it

Coding agents ship their own file tools. Claude Code reads, edits and writes files with built-in tools, and its permissions documentation (opens in a new tab) sets the boundary: by default Claude can reach the directory where you launched it, you add others with --add-dir or /add-dir, and Read and Edit deny rules such as Read(./.env) keep specific files out. Permission modes decide whether edits need approval. Adding the Filesystem server on top gives the agent a second, overlapping set of file tools with different rules, which is harder to reason about, not safer. What a Claude Code session can see by default is covered in what Claude Code can read.

The server earns its place in chat apps: Claude Desktop, other desktop clients, and hosts you build yourself. That is also where the folder list does all the work, because there is no project directory to fall back on.

From a folder of notes to a task list

A common first job for the server is reading a folder of meeting notes and pulling out what was agreed. The actions in those notes are work someone has to do, and a folder is a poor place to track them. Connect fenbs as a second server at https://fenbs.ai/api/mcp, and a read-only filesystem mount is enough: the assistant reads the notes, searches the board so nothing is filed twice, and creates each action as a feature, enhancement or bug with a note naming the file it came from. The files stay untouched, and History records each task under the assistant’s name. If you would rather review first, ask for the list as plain lines and paste it into Add many yourself.

Related

The same server in a real workflow: MCP examples. Running servers in containers: Docker MCP Toolkit. Habits for any connection: MCP security best practices. Connecting fenbs: the MCP docs and Claude integration.

Questions people ask.

How do I limit which folders the Filesystem MCP server can access?

List the folders as arguments after the package name when the server starts. Every operation is limited to those folders and everything below them. If your client supports MCP Roots, the roots it sends replace that list, so call list_allowed_directories to see what is actually in force.

Can the Filesystem MCP server be read-only?

Not with a flag. Run it in Docker and mount your folder with the ro option, so the operating system refuses every write, or point it at a copy of the folder. The write tools still appear, but they fail.

Does Claude Code need the Filesystem MCP server?

No. Claude Code has built-in tools to read, edit and write files, and it limits them to the directory you launch it in plus any you add with --add-dir, with deny rules for files it must not read.

Can the Filesystem MCP server delete files?

It has no delete tool, but write_file can overwrite a file and move_file can move one out of place, and both are marked destructive. Approve those tools one at a time, or mount the folder read-only.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.