Skip to main content

Filesystem MCP Guide 2026: Secure AI File Operations

Set up the official Filesystem MCP server for Claude Code: install options, Roots vs. command-line paths, its file tools, and security best practices.

When using AI coding assistants, have you wished they could:

  • Directly read files: No manual copy-pasting of file contents
  • Batch process files: Operate on multiple files or directories at once
  • Safe file writing: Modify files within controlled boundaries
  • Dynamically explore project structure: Automatically discover and analyze files

Filesystem MCP is an official Model Context Protocol server from Anthropic that provides AI assistants with secure, controlled file system operation capabilities.

Updated November 4, 2026: Corrected against the server’s current README and Claude Code v2.1.318: --scope user replaces the nonexistent --scope global; user- and local-scope servers live in ~/.claude.json, not ~/.claude/.mcp.json; command-line directories are now the recommended access control, because Roots is deprecated as of MCP protocol revision 2026-07-28; and the Docker setup, tool names (read_text_file, search_files), and the ${VAR} example now match the server and the Claude Code docs.

What is Filesystem MCP?

Filesystem MCP is a Node.js-based MCP server that implements the Model Context Protocol’s file system operation interface, allowing AI assistants to read and write local files under strict permission controls.

Core Features

  1. Flexible Permission Control 🔒

    • Specify allowed directories via command-line arguments
    • Roots-based runtime updates for 2025-era clients (deprecated as of MCP protocol revision 2026-07-28)
    • Default deny-all for unauthorized directory access
  2. Rich File Operations 📁

    • read_text_file() - Read file contents as text (read_file is a deprecated alias)
    • read_media_file() - Read images, audio, and other binary files as base64
    • write_file() - Write or overwrite files
    • edit_file() - Line-level editing (search and replace)
    • list_directory() - List directory contents
    • create_directory() - Create directories
    • move_file() - Move or rename files
    • search_files() - Search files using glob patterns
    • get_file_info() - Get file metadata
  3. Security First 🛡️

    • Sandbox mechanism prevents unauthorized directory access
    • Read-only mode support (Docker ro flag)
    • Environment variable configuration to avoid hardcoded paths
  4. Modern Integration ⚡

    • Serves both MCP protocol eras on stdio (2026-07-28 and 2025-era clients)
    • Roots for 2025-era clients only (deprecated; command-line directories are recommended)
    • Seamless integration with all MCP-compatible clients

Why Filesystem MCP?

The Problem: Inefficiency of Manual File Operations

Before Filesystem MCP, AI assistants handled files by:

  1. Manual copy-paste by users → AI can’t proactively explore projects
  2. Limited content visibility → Only sees user-provided snippets
  3. No batch operations → Each file needs manual handling
  4. Modifications require human intervention → AI can only suggest, not execute

The Solution: Safe Autonomous File Operations

Filesystem MCP enables AI to:

  • ✅ Proactively read related files, understand complete context
  • ✅ Batch process multiple files (refactoring, formatting, migration)
  • ✅ Directly write modifications, reducing manual copy-paste
  • ✅ Explore project structure, automatically discover related files

While maintaining security: Only access directories you explicitly authorize.

Installation & Setup

The server needs Node.js 24 or later when it runs through npx.

# Install for project, allow access to current directory
claude mcp add \
  --scope project \
  filesystem \
  -- npx -y @modelcontextprotocol/server-filesystem \
  "$(pwd)"

# Install for all your projects (user scope), allow access to multiple directories
claude mcp add \
  --scope user \
  filesystem \
  -- npx -y @modelcontextprotocol/server-filesystem \
  /Users/username/projects \
  /Users/username/documents

Method 2: Manual Configuration

Edit .mcp.json in the project root (project scope). User- and local-scope servers are stored in ~/.claude.json, which Claude Code manages for you, so add those with claude mcp add instead:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/Desktop",
        "/path/to/other/allowed/dir"
      ]
    }
  }
}

Method 3: Docker Sandbox Mode

Use Docker for stricter isolation:

{
  "mcpServers": {
    "filesystem": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "--mount", "type=bind,src=/path/to/project,dst=/projects/project,ro",
        "mcp/filesystem",
        "/projects"
      ]
    }
  }
}

Tip: Mount each directory under /projects and pass /projects as the allowed directory. The ro option makes that mount read-only, so AI can read but not modify it.

Roots vs. Command-Line Arguments

{
  "command": "npx",
  "args": [
    "-y",
    "@modelcontextprotocol/server-filesystem",
    "/allowed/dir1",
    "/allowed/dir2"
  ]
}

This is the only method that works on every MCP protocol version, which is why the server’s README recommends it.

Limitation: Changing permissions requires server restart.

Deprecated: Roots Protocol (2025-era Clients Only)

Roots is MCP’s mechanism for clients to dynamically expose filesystem boundaries to servers. A client that connects with a 2025-era protocol version and supports Roots can replace the allowed directories at runtime:

  • ✅ Runtime permission updates (no restart needed)
  • ✅ Auto-sync via roots/list_changed notifications

Roots is deprecated as of MCP protocol revision 2026-07-28, and a 2026-07-28 connection can’t use it. Claude Code’s v2 MCP runtime asks stdio servers whether they support that revision and uses it with those that do, and this server does, so in Claude Code pass the allowed directories on the command line.

Don’t start the server without directories and count on Roots: if a 2025-era client doesn’t support Roots, the server exits at startup, and on a 2026-07-28 connection every tool call returns an error.

Real-World Examples

Example 1: Project Refactoring

You: "Replace all var with const in .js files"

Filesystem MCP automatically:
1. search_files("/Users/username/project", "**/*.js") → Find all JS files
2. Execute read_text_file() on each file
3. Analyze and generate modification suggestions
4. Use edit_file() to batch replace var → const
5. Report modification results

Result: 50 files refactored in 5 minutes

Example 2: Project Structure Analysis

You: "Analyze this project's architecture and draw a module dependency diagram"

Filesystem MCP automatically:
1. list_directory("/Users/username/project") → Get root directory structure
2. search_files("/Users/username/project", "**/*.ts") → Find all TypeScript files
3. read_text_file() to read import statements in each file
4. Analyze dependencies
5. Generate Mermaid diagram

Result: Automatically generated complete project architecture diagram

Example 3: Batch File Processing

You: "Add copyright headers to all TypeScript files under src/components"

Filesystem MCP automatically:
1. list_directory("/Users/username/project/src/components")
2. search_files("/Users/username/project/src/components", "**/*.ts")
3. Execute read_text_file() on each file
4. Insert copyright header at file beginning
5. Use write_file() to write back

Result: 30 files automatically updated with headers

Available Tools Explained

1. read_text_file(path: string) 📖

Read file contents as text; the optional head or tail returns only the first or last N lines. read_file still works as a deprecated alias.

// AI internal call
read_text_file("/Users/username/project/src/index.ts")

// Returns the file's text
"import React from 'react'..."

2. write_file(path: string, content: string) ✍️

Write or overwrite file.

write_file("/Users/username/project/README.md", "# My Project\n...")

⚠️ Warning: Overwrites existing files, use with caution.

3. edit_file(path: string, edits: Edit[]) ✂️

Line-level editing with search and replace.

edit_file("/path/to/file.ts", [
  {
    oldText: "const foo = 'bar'",
    newText: "const foo = 'baz'"
  }
])

4. list_directory(path: string) 📂

List directory contents.

list_directory("/Users/username/project/src")

// Returns
// [FILE] index.ts
// [FILE] App.tsx
// [DIR] components
// [DIR] utils

5. create_directory(path: string) 🆕

Create new directory (supports nested creation).

create_directory("/Users/username/project/src/new/nested/dir")

6. move_file(source: string, destination: string) 🔀

Move or rename file.

move_file(
  "/Users/username/project/old-name.ts",
  "/Users/username/project/new-name.ts"
)

7. search_files(path: string, pattern: string, excludePatterns?: string[]) 🔍

Recursively search from path using glob patterns.

// Find all TypeScript test files
search_files("/Users/username/project", "**/*.test.ts")

// Find all React components in src
search_files("/Users/username/project/src", "**/*.tsx")

Supported glob patterns:

  • *.ts - All TS files in the starting directory
  • **/*.ts - All TS files in all subdirectories
  • src/**/*.{ts,tsx} - TS and TSX files under src

8. get_file_info(path: string) ℹ️

Get file metadata.

get_file_info("/Users/username/project/package.json")

// Returns
{
  size: 1024,
  created: "2024-01-01T00:00:00Z",
  modified: "2024-06-15T12:30:00Z",
  accessed: "2024-06-18T06:00:00Z",
  isDirectory: false,
  isFile: true,
  permissions: "rw-r--r--"
}

Security Best Practices

  1. Principle of Least Privilege

    # ❌ Don't give entire home directory permission
    npx @modelcontextprotocol/server-filesystem ~
    
    # ✅ Only give project directory permission
    npx @modelcontextprotocol/server-filesystem ~/projects/my-app
  2. Protect Sensitive Data

    # ✅ Exclude sensitive directories (similar to .gitignore logic)
    # Don't authorize .env, secrets/, credentials/ directories
  3. Use Read-Only Mode

    # Docker read-only mount
    docker run -i --rm --mount type=bind,src=/path,dst=/projects/path,ro mcp/filesystem /projects
  4. Regular Permission Audits

    # Check current Filesystem MCP authorized directories
    cat .mcp.json | jq '.mcpServers.filesystem.args'

❌ Avoid

  1. Authorizing root directory / - Never do this
  2. Authorizing system directories /etc, /usr, /System - Dangerous
  3. Authorizing home directory ~ - Too broad
  4. Hardcoded absolute paths - Use relative paths or environment variables

Synergy with Other MCP Servers

Filesystem MCP works perfectly with other MCP servers:

1. Filesystem + Memory MCP

You: "Remember this project's architecture: src/ is source code, tests/ is tests"

Collaboration:
1. Filesystem explores directory structure
2. Memory stores project knowledge in knowledge graph
3. Next time you ask, AI automatically remembers project structure

2. Filesystem + Context7 MCP

You: "Refactor this component using latest React"

Collaboration:
1. Context7 fetches latest React documentation
2. Filesystem reads current component code
3. AI refactors code based on latest docs
4. Filesystem writes back modifications

3. Filesystem + Sequential Thinking MCP

You: "Help me with a complex project migration"

Collaboration:
1. Sequential Thinking breaks task into steps
2. Filesystem executes file operations for each step
3. Ensures migration process is orderly and traceable

Advanced Tips

1. Environment Variable Configuration

Avoid hardcoded paths with ${VAR} expansion, which Claude Code applies to command, args, env, url, and headers in .mcp.json. The values come from the environment you start Claude Code in, not from the server’s own env block (that block only sets variables for the server process), so export the variable in your shell:

export PROJECT_ROOT=/Users/username/my-project
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "${PROJECT_ROOT}/src",
        "${PROJECT_ROOT}/tests"
      ]
    }
  }
}

If PROJECT_ROOT isn’t set, claude mcp list warns about it and the server receives the literal ${PROJECT_ROOT}/src. Write ${PROJECT_ROOT:-/Users/username/my-project} to supply a default.

2. Multi-Project Permission Management

Set different permissions for different projects:

{
  "mcpServers": {
    "filesystem-work": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/work"
      ]
    },
    "filesystem-personal": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/personal"
      ]
    }
  }
}

Manually switch: Tell Claude which MCP to use.

3. Mixed Read-Only + Writable Mode

{
  "mcpServers": {
    "filesystem-readonly": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "--mount", "type=bind,src=/reference-code,dst=/projects/reference-code,ro",
        "mcp/filesystem",
        "/projects"
      ]
    },
    "filesystem-writable": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/work-in-progress"
      ]
    }
  }
}

AI can read reference code (read-only) but only modify work directory (writable).

Troubleshooting

Issue 1: Permission Denied

Error: Access denied to /Users/username/unauthorized/path

Cause: Attempting to access unauthorized directory.

Solution:

  1. Check authorized directories in MCP configuration
  2. Verify path spelling
  3. Use absolute paths instead of relative paths

Issue 2: File Not Found

Error: ENOENT: no such file or directory

Cause: File or directory doesn’t exist.

Solution:

  1. Use list_directory() to confirm directory contents
  2. Check if file path is correct
  3. Use get_file_info() to confirm file exists

Issue 3: Roots Not Working

Server cannot operate: No allowed directories available. ...

Cause: The server was started without directory arguments, and the connection can’t supply Roots: either a 2025-era client doesn’t support Roots (the server then exits at startup), or the client connected with MCP protocol revision 2026-07-28, which has no Roots.

Solution: Pass the allowed directories as command-line arguments. That works on every protocol version.

Limitations

Unsupported Features

  1. Symlinks that lead outside the allowed directories - Refused: every path is resolved and checked against the allowed directories
  2. File Permission Modification - No chmod, chown operations
  3. File Watching - No watch/monitor file changes
  4. Writing Binary Files - write_file and edit_file take text; binary files can only be read (as base64) with read_media_file

Performance Limitations

  1. Large File Reading - Files over 10MB may be slow
  2. Mass File Operations - Processing hundreds of files may timeout
  3. Deep Directory Scanning - Nested directories over 5 levels may affect performance

Recommendations:

  • Large files: Process in segments or use streaming
  • Mass files: Process in batches (e.g., 10 at a time)
  • Deep directories: Specify exact paths instead of global search

Difference from Claude Code Built-in Tools

Claude Code has built-in file operation tools (Read, Write, Edit), so why need Filesystem MCP?

FeatureClaude Code Built-inFilesystem MCP
SetupBuilt-in, no setupManual configuration needed
Permission ControlAuto-managedManually specify directories
FunctionalityBasic read/write/editComplete filesystem operations
Advanced FeaturesNoneGlob search, metadata queries
Cross-Project UseLimited to current projectCan authorize multiple directories
Roots Support✅✅

Conclusion:

  • Daily use: Built-in tools sufficient
  • Advanced needs: Filesystem MCP provides more control and features

Conclusion

Filesystem MCP is a secure bridge for AI assistants to operate the file system. It provides powerful file operation capabilities while ensuring system security through strict permission controls.

Is It Right for You?

Use CaseRecommendation
Batch file refactoring⭐⭐⭐⭐⭐
Project structure analysis⭐⭐⭐⭐⭐
Automated file processing⭐⭐⭐⭐⭐
Multi-project management⭐⭐⭐⭐
Sensitive data handling⭐⭐ (requires careful permission setup)

Get Started Now

  1. Install: claude mcp add --scope project filesystem -- npx -y @modelcontextprotocol/server-filesystem "$(pwd)"
  2. Authorize project directory
  3. Start enjoying AI-driven file operations

Further Reading