中文
← Back to tutorials

Filesystem MCP Server: Complete Setup and Usage Guide 2026

Give AI agents access to your local files - step-by-step guide to Filesystem MCP Server

By AI Skill Navigation Editorial TeamPublished January 1, 2026

A Node.js server implementing the Model Context Protocol (MCP) for filesystem operations. Published on npm as @modelcontextprotocol/server-filesystem.

Prerequisites

  • Node.js 18+ (for npx usage)
  • Docker (optional, for containerized deployment)
  • An MCP client (Claude Desktop, VS Code, or any MCP-compatible application)
  • Installation

    NPX (No Installation Required)

    Run directly without installing:

    bash
    npx -y @modelcontextprotocol/server-filesystem /path/to/allowed/dir1 /path/to/allowed/dir2
    

    Docker

    Build the image:

    bash
    docker build -t mcp/filesystem -f src/filesystem/Dockerfile .
    

    Or pull from a registry (if published).

    Configuration

    Claude Desktop

    Add to claude_desktop_config.json:

    NPX (macOS/Linux):

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

    NPX (Windows):

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

    Docker:

    json
    {
      "mcpServers": {
        "filesystem": {
          "command": "docker",
          "args": [
            "run",
            "-i",
            "--rm",
            "--mount", "type=bind,src=/Users/username/Desktop,dst=/projects/Desktop",
            "--mount", "type=bind,src=/path/to/other/allowed/dir,dst=/projects/other/allowed/dir,ro",
            "--mount", "type=bind,src=/path/to/file.txt,dst=/projects/path/to/file.txt",
            "mcp/filesystem",
            "/projects"
          ]
        }
      }
    }
    

    Note: In Docker, all directories must be mounted to /projects by default. Add ,ro to make a mount read-only.

    VS Code

    Quick Install Buttons:

  • Install with NPX
  • Install with Docker
  • Manual Configuration:

    Add to .vscode/mcp.json (workspace) or user MCP config (Command Palette → MCP: Open User Configuration):

    NPX (macOS/Linux):

    json
    {
      "servers": {
        "filesystem": {
          "command": "npx",
          "args": [
            "-y",
            "@modelcontextprotocol/server-filesystem",
            "${workspaceFolder}"
          ]
        }
      }
    }
    

    NPX (Windows):

    json
    {
      "servers": {
        "filesystem": {
          "command": "cmd",
          "args": [
            "/c",
            "npx",
            "-y",
            "@modelcontextprotocol/server-filesystem",
            "${workspaceFolder}"
          ]
        }
      }
    }
    

    Docker:

    json
    {
      "servers": {
        "filesystem": {
          "command": "docker",
          "args": [
            "run",
            "-i",
            "--rm",
            "--mount", "type=bind,src=${workspaceFolder},dst=/projects/workspace",
            "mcp/filesystem",
            "/projects"
          ]
        }
      }
    }
    

    Directory Access Control

    The server restricts all filesystem operations to explicitly allowed directories. Two methods are available:

    Method 1: Command-Line Arguments

    Pass directories when starting the server:

    bash
    mcp-server-filesystem /path/to/dir1 /path/to/dir2
    

    These directories are fixed for the session unless the client supports Roots.

    Method 2: MCP Roots (Recommended)

    MCP clients that support Roots can dynamically update allowed directories at runtime without restarting the server.

    How it works:

  • Server Startup – Starts with directories from command-line args (if provided). If no args are given, starts with an empty allowed list.
  • Client Connection – The client sends an initialize request with its capabilities.
  • Roots Protocol Handling (if client supports capabilities.roots):
  • - On initialization: Server requests roots via roots/list. Client responds with its configured roots. Server replaces all allowed directories with the client's roots. - On runtime updates: Client sends notifications/roots/list_changed. Server requests updated roots and replaces allowed directories again.
  • Fallback (if client doesn't support roots): Server uses command-line directories only. No dynamic updates.
  • Access Control – All operations are restricted to allowed directories. Use list_allowed_directories to see current directories.
  • Important: If the server starts without command-line arguments AND the client doesn't support roots (or provides empty roots), the server will throw an error during initialization. At least one allowed directory is required.

    Available Tools

    Read Operations (Read-Only)

    ToolDescriptionInputs

    read_text_fileRead complete file contents as UTF-8 textpath (string), head (number, optional): first N lines, tail (number, optional): last N lines. Cannot specify both head and tail. read_media_fileRead file as base64 with MIME typepath (string). Returns image/audio content or embedded resource. read_multiple_filesRead multiple files simultaneouslypaths (string[]). Failed reads don't stop the operation. list_directoryList directory contents with [FILE] or [DIR] prefixespath (string) list_directory_with_sizesList directory contents with file sizespath (string), sortBy (string, optional): "name" or "size" (default: "name"). Returns summary statistics. directory_treeRecursive JSON tree of directory contentspath (string), excludePatterns (string[], optional): glob patterns. Returns JSON array with name, type ('file'/'directory'), and children (for directories). search_filesRecursively search files/directories by patternpath (string), pattern (string), excludePatterns (string[], optional). Glob-style matching. get_file_infoGet detailed file/directory metadatapath (string). Returns size, creation/modified/access times, type, permissions. list_allowed_directoriesList all directories the server can accessNo input. Returns the current allowed directories.

    Write Operations

    ToolDescriptionInputsNotes

    create_directoryCreate new directory or ensure it existspath (string). Creates parent directories if needed. Succeeds silently if exists.Idempotent write_fileCreate new file or overwrite existingpath (string), content (string)Destructive – overwrites existing files edit_fileMake selective edits with pattern matchingpath (string), edits (array of {oldText, newText}), dryRun (boolean, default: false). Returns git-style diff.Not idempotent. Always use dryRun: true first. move_fileMove or rename files/directoriessource (string), destination (string). Fails if destination exists.Destructive – deletes source

    Tool Annotations (MCP Hints)

    The server sets MCP ToolAnnotations to help clients understand tool behavior:

    ToolreadOnlyHintidempotentHintdestructiveHint

    read_text_filetrue–– read_media_filetrue–– read_multiple_filestrue–– list_directorytrue–– list_directory_with_sizestrue–– directory_treetrue–– search_filestrue–– get_file_infotrue–– list_allowed_directoriestrue–– create_directoryfalsetruefalse write_filefalsetruetrue edit_filefalsefalsetrue move_filefalsefalsetrue

    All tools set openWorldHint: false – this server only accesses the local filesystem within allowed directories.

    Dynamic Roots / Notes

  • Roots replace, not merge: When a client provides roots via the MCP Roots protocol, they completely replace any directories specified via command-line arguments.
  • Runtime updates: Clients can send notifications/roots/list_changed to update allowed directories without restarting the server.
  • Minimum requirement: The server requires at least one allowed directory to operate. If none are provided (no args and no roots), initialization fails.
  • Docker mounts: In Docker, all directories must be mounted to /projects by default. Use ,ro for read-only mounts.
  • FAQ

    1. Why does the server fail to initialize with "no allowed directories"?

    This happens when you start the server without command-line arguments and your MCP client either doesn't support the Roots protocol or provides an empty roots list. The server requires at least one allowed directory. Either provide directories via command-line args or configure roots in your client.

    2. Can I use both command-line directories and Roots simultaneously?

    No. When a client supports Roots, the roots completely replace any directories specified via command-line arguments. The server does not merge them. If you need both sets of directories, configure all of them as roots in your client.

    3. How do I make a directory read-only in Docker?

    Add ,ro to the mount flag. For example:

    json
    "--mount", "type=bind,src=/path/to/dir,dst=/projects/dir,ro"
    

    4. What happens if I use edit_file without a dry run?

    The changes are applied immediately. Since edit_file is not idempotent, re-applying the same edits can fail (if the old text no longer exists) or double-apply (if the pattern matches again). Always use dryRun: true first to preview changes.

    5. Can I read binary files like images or audio?

    Yes, use read_media_file. It streams the file and returns base64-encoded content with the correct MIME type. Images and audio files are returned as image/audio content blocks; other file types are returned as embedded resource blocks.


    *Last updated: July 2026. Authoritative source: @modelcontextprotocol/server-filesystem.*

    Also available in 中文.