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
A Node.js server implementing the Model Context Protocol (MCP) for filesystem operations. Published on npm as @modelcontextprotocol/server-filesystem.
Prerequisites
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/projectsby default. Add,roto make a mount read-only.
VS Code
Quick Install Buttons:
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:
initialize request with its capabilities.capabilities.roots):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.
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)
read_text_filepath (string), head (number, optional): first N lines, tail (number, optional): last N lines. Cannot specify both head and tail.read_media_filepath (string). Returns image/audio content or embedded resource.read_multiple_filespaths (string[]). Failed reads don't stop the operation.list_directory[FILE] or [DIR] prefixespath (string)list_directory_with_sizespath (string), sortBy (string, optional): "name" or "size" (default: "name"). Returns summary statistics.directory_treepath (string), excludePatterns (string[], optional): glob patterns. Returns JSON array with name, type ('file'/'directory'), and children (for directories).search_filespath (string), pattern (string), excludePatterns (string[], optional). Glob-style matching.get_file_infopath (string). Returns size, creation/modified/access times, type, permissions.list_allowed_directoriesWrite Operations
create_directorypath (string). Creates parent directories if needed. Succeeds silently if exists.write_filepath (string), content (string)edit_filepath (string), edits (array of {oldText, newText}), dryRun (boolean, default: false). Returns git-style diff.dryRun: true first.move_filesource (string), destination (string). Fails if destination exists.Tool Annotations (MCP Hints)
The server sets MCP ToolAnnotations to help clients understand tool behavior:
read_text_filetrueread_media_filetrueread_multiple_filestruelist_directorytruelist_directory_with_sizestruedirectory_treetruesearch_filestrueget_file_infotruelist_allowed_directoriestruecreate_directoryfalsetruefalsewrite_filefalsetruetrueedit_filefalsefalsetruemove_filefalsefalsetrueAll tools set openWorldHint: false – this server only accesses the local filesystem within allowed directories.
Dynamic Roots / Notes
notifications/roots/list_changed to update allowed directories without restarting the server./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 中文.