Skip to main content
← Back to Articles
mcpcursorfilesystemlocal-filessetup2026

Filesystem MCP Server Cursor IDE Setup 2026: Allowed Directories & Roots

Set up the official @modelcontextprotocol/server-filesystem in Cursor IDE: the allowed-directories args pattern, why it's rarely needed alongside Cursor's own file tools, the Roots protocol, and the errors that show up when a path falls outside the allowlist.

By Web MCP GuideAugust 26, 20269 min read

How do you set up the Filesystem MCP server in Cursor? Add a filesystem entry under mcpServers in ~/.cursor/mcp.json running npx -y @modelcontextprotocol/server-filesystem followed by one or more absolute directory paths as additional args — each path becomes an allowed root the server can read, write, and search inside. Restart Cursor, then confirm with a prompt that lists files in one of those directories.

Read this first if you're using Cursor for everyday coding: Cursor's built-in file tools already read and edit files in your open workspace without any MCP server at all. This guide is for the cases that fall outside that — giving an agent access to directories outside the current workspace (a shared notes folder, a sibling repo, a Desktop folder of reference docs), or connecting a non-Cursor MCP client (Claude Desktop, a custom agent) to the same local files using the identical official package. If you only need Cursor editing the project you already have open, you likely don't need this server at all.

What the Filesystem Server Actually Adds

The official package is @modelcontextprotocol/server-filesystem, maintained in the modelcontextprotocol/servers reference repo. It exposes a defined tool set — read_text_file, write_file, edit_file, list_directory, search_files, move_file, directory_tree, get_file_info, and a few others — scoped strictly to the directories you pass as arguments. It cannot touch anything outside that allowlist, which is the entire security model: rather than trusting the client to behave, the server itself refuses paths outside its configured roots.

Prerequisites


  • Cursor IDE with MCP support enabled.

  • Node.js 18 or later.

  • The absolute paths of the directories you want to grant access to, decided in advance — don't default to your whole home directory.
  • Step 1: Decide Your Allowed Directories

    Pick specific, narrow paths. /Users/you/projects/client-notes is a reasonable allowed root; /Users/you is not, because it grants read/write access to your entire home directory, including SSH keys, browser profiles, and anything else that happens to live there. Multiple paths are fine — the server treats each one as an independent allowed root.

    Step 2: Add the Server to Cursor's mcp.json

    {
      "mcpServers": {
        "filesystem": {
          "command": "npx",
          "args": [
            "-y",
            "@modelcontextprotocol/server-filesystem",
            "/Users/you/projects/client-notes",
            "/Users/you/reference-docs"
          ]
        }
      }
    }
    

    Each path after the package name is a separate allowed root — add as many as you need, but keep the list to what you actually use. Restart Cursor completely for the new server to register.

    Step 3: Verify the Allowlist

    Once connected, ask directly:

    List the directories you're allowed to access via the filesystem MCP server.
    

    This maps to the list_allowed_directories tool and returns exactly what you configured — a useful sanity check before trusting the server with a write operation, especially if you're not 100% sure the JSON you pasted matches what you intended.

    Step 4: Test Read and Write

    List the files in /Users/you/reference-docs, then read the contents of whichever one looks like a README.
    

    Create a file called scratch.md in /Users/you/projects/client-notes with the text "test write" in it.
    

    If both work, the allowlist and permissions are correctly configured. If the write fails but the read succeeded, check that the directory itself is writable by the user Cursor runs as — a permissions issue at the OS level, not an MCP config issue.

    Step 5: Practical Workflows

    Cross-referencing a sibling repo without opening it as a second Cursor window

    Look in /Users/you/projects/shared-types for the User interface definition and tell me if the fields I'm using in this file match it exactly.
    

    Pulling context from a non-code folder

    Read every markdown file in /Users/you/reference-docs/meeting-notes from the last two weeks and summarize the decisions that affect the auth redesign.
    

    Bulk file operations outside the current workspace

    In /Users/you/projects/client-notes, find every file with "DRAFT" in the filename and list them with their last-modified dates.
    

    The Roots Protocol: Dynamic Access Without a Restart

    Beyond the static args-based allowlist, the server supports MCP's Roots protocol: a compliant client can send a roots/list_changed notification that updates the allowed directories at runtime, completely replacing whatever was set via args when the notification is received. In practice, most Cursor setups use the static args list rather than dynamic Roots — this matters more for MCP clients that expose a directory-picker UI and update the server's scope as the user changes it, without restarting the server process. If you're only using Cursor with a fixed set of folders, the static config in Step 2 is all you need.

    Troubleshooting

    "Access denied" or "Path not allowed" on a directory you're sure you configured
    Check for a trailing slash mismatch or a symlink. The server compares the resolved, absolute path — if you configured /Users/you/notes but the file is actually reached through a symlink that resolves elsewhere, the check can fail in a way that looks wrong at a glance. Use list_allowed_directories (Step 3) to see exactly what the server thinks is allowed, rather than trusting your memory of the config.

    Server works for read operations but every write silently fails
    This is almost always an OS-level file permission issue, not an MCP problem — the user account Cursor's background process runs as needs write access to that specific directory. Check with ls -la on the target directory rather than re-editing mcp.json.

    Tool calls are slow on a directory with thousands of files
    directory_tree and search_files walk the whole allowed root by default. Scope the allowed directory itself more narrowly (a specific subfolder rather than an entire large repo) rather than trying to filter after the fact, if you only ever need the server working in one part of a much larger tree.

    Config copied from a Claude Desktop tutorial doesn't work in Cursor
    The tool and package are identical — @modelcontextprotocol/server-filesystem isn't Cursor-specific — but Claude Desktop's config file uses claude_desktop_config.json with the same mcpServers schema Cursor uses, so a straight copy usually works. If it doesn't, check for a stray absolute-path assumption in the copied config (a Windows path pasted into a macOS config, for instance) rather than assuming the schema itself changed.

    You want Cursor to edit files in the currently open workspace and this doesn't seem to do anything
    That's expected — Cursor's built-in file tools already handle the open workspace without this server. This server is for directories outside what Cursor has open, or for connecting other MCP clients to the same local files.

    When Not to Use This

    Don't add your entire home directory or a directory containing credentials, SSH keys, or .env files with real secrets as an allowed root. The server's access control is directory-based, not file-type-based — if a directory is allowed, every file in it is fair game for both reads and writes by whatever the connected agent decides to do.

    Frequently Asked Questions

    Q: Do I need this if I'm just coding in the project Cursor already has open?
    A: No. Cursor's built-in file tools already read and edit files in your open workspace without any MCP server. This one is specifically for directories outside the current workspace, or for connecting a different MCP client to the same local files using the same official package.

    Q: Can I restrict the server to read-only, no writes?
    A: Not through a config flag on the official package — the tool set includes write_file, edit_file, move_file, and create_directory alongside the read tools, and access is controlled at the directory level, not the operation level. If you need a hard read-only boundary, run the directory itself with read-only OS permissions for the user Cursor runs as.

    Q: What happens if I pass a path that doesn't exist yet?
    A: The server needs the directory to already exist — it won't create a new allowed root out of thin air. create_directory can make subdirectories inside an already-allowed root once the server is running, but the top-level roots in args need to exist before you start the server.

    Q: Is this the same package Claude Desktop uses?
    A: Yes — @modelcontextprotocol/server-filesystem isn't Cursor-specific. The same package and the same allowed-directories argument pattern work in Claude Desktop's claude_desktop_config.json, which uses the identical mcpServers schema.

    Q: Can I add or remove allowed directories without restarting Cursor?
    A: Only if the connecting client implements MCP's Roots protocol and sends updates dynamically — most static Cursor setups don't do this and instead edit the args list and restart. For a fixed, small set of folders, editing and restarting is simpler than relying on Roots.

    Related Guides


  • How to Connect Claude to Local Files: Step by Step

  • Cursor IDE MCP Setup: Complete Guide (2026)

  • Local vs Remote MCP Servers

  • MCP Security Best Practices
  • Official docs cited


  • Filesystem MCP server (official repo)

  • Cursor MCP reference

  • Related guides