Skip to main content
Glama
MCP Filesystem Server

MCP Filesystem Server

by alex-furrier

MCP Filesystem Server

WARNING

Archived. Do not use this project for new work.

This was built before modern coding-agent harnesses had good filesystem tools, shell access, scoped editing, and context management. Those harnesses now provide the useful parts of this server directly, without adding another MCP layer.

This repository is kept only as a historical reference. I do not recommend installing it, depending on it, or using it as the starting point for a new filesystem integration.

MCP Filesystem Server let an MCP client read, search, and edit files inside explicitly allowed directories. It was designed for early MCP clients that needed path sandboxing, line-range reads, grep-style search, and edit previews.

The server does not grant whole-disk access. At startup you pass one or more allowed directories; every tool call is validated against those roots.

Historical setup

The remaining documentation records how the project worked. These commands are not maintained or recommended for new setups. Published-package installation is not verified.

git clone https://github.com/safurrier/mcp-filesystem.git
cd mcp-filesystem
uv sync --frozen
uv run run_server.py --version

Success signal:

MCP Filesystem Server v0.2.0
A Model Context Protocol server for filesystem operations

uv sync --frozen installs the locked dependencies into .venv in the checkout.

To see the command-line options without starting an MCP session:

uv run run_server.py --help

The main entry points in this repo are:

  • uv run run_server.py ... — direct script used by tests and the Claude Desktop examples below.

  • uv run mcp-filesystem ... — installed console script with the same Typer CLI.

Related MCP server: Filesystem MCP Server

Connect it to Claude Desktop

Use absolute paths for both the repository and the directories you want the server to access:

REPO_PATH=$(pwd)
PROJECTS_PATH=$(cd ~/Projects && pwd)
DOCUMENTS_PATH=$(cd ~/Documents && pwd)
printf 'repo=%s\nprojects=%s\ndocuments=%s\n' "$REPO_PATH" "$PROJECTS_PATH" "$DOCUMENTS_PATH"

Edit Claude Desktop's config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add one server entry, replacing the example paths with your own absolute paths:

{
  "mcpServers": {
    "mcp-filesystem": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/mcp-filesystem",
        "run",
        "run_server.py",
        "/absolute/path/to/allowed-dir-1",
        "/absolute/path/to/allowed-dir-2"
      ]
    }
  }
}

Restart Claude Desktop after saving the file.

Claude-side success signals:

  • The MCP server named mcp-filesystem appears in Claude Desktop's MCP tools.

  • The tool list includes list_allowed_directories, read_file, grep_files, and edit_file_at_line.

  • Calling list_allowed_directories returns only the directories you passed in the config.

If the server does not appear, watch the Claude Desktop MCP log:

# macOS
tail -n 50 -f ~/Library/Logs/Claude/mcp-server-mcp-filesystem.log

# Windows PowerShell
Get-Content -Path "$env:APPDATA\Claude\Logs\mcp-server-mcp-filesystem.log" -Tail 50 -Wait

Run the server manually

The server uses stdio by default, which is what MCP clients such as Claude Desktop expect:

uv run run_server.py /absolute/path/to/dir1 /absolute/path/to/dir2

If you do not pass directories, the server allows the current working directory.

Options verified from the CLI:

Option

Meaning

--transport, -t

Transport protocol. Default: stdio. Use sse for SSE.

--port, -p

Port for SSE transport. Default: 8000.

--debug, -d

Enable debug logging through FASTMCP_LOG_LEVEL=DEBUG.

--version, -v

Print version information and exit.

--help

Print CLI help and exit.

For MCP Inspector testing, run from a checkout:

npx @modelcontextprotocol/inspector uv run run_server.py /absolute/path/to/test-dir

The Inspector command may download Node packages through npx if they are not already installed.

How access control works

  • Allowed roots come from positional CLI arguments, or from MCP_ALLOWED_DIRS when the CLI sets it.

  • If neither is set, the current working directory is the only allowed root.

  • Paths are validated before filesystem operations run.

  • Symlinks are checked so a path inside an allowed root cannot point outside it.

  • The server runs with the operating-system permissions of the user that started it.

Practical rule: pass the narrowest directory that contains the files you want Claude to work with. Do not pass /, your full home directory, or a secrets directory unless you mean to expose it to the MCP client.

MCP tools

Tool names below are taken from mcp_filesystem/server.py.

Discovery and read-only file access

Tool

Use it for

list_allowed_directories

Show the sandbox roots available to this server process.

list_directory

List files and directories, with optional hidden-file and pattern filtering.

get_file_info

Return file or directory metadata.

read_file

Read one complete file.

read_multiple_files

Read several complete files in one tool call.

read_file_lines

Read a line range with offset and limit.

head_file

Read the first N lines of a text file.

tail_file

Read the last N lines of a text file.

directory_tree

Return a recursive directory tree with depth and pattern controls.

Tool

Use it for

grep_files

Search file contents with literal or regex matching, context lines, pagination, size limits, and optional JSON output. Uses ripgrep when available and falls back to Python.

search_files

Find files or directories by glob pattern, optionally requiring content matches.

Mutating filesystem operations

Tool

Use it for

write_file

Create or overwrite a file. Can create parent directories when requested.

create_directory

Create a directory, optionally including parents.

move_file

Move or rename a file or directory.

edit_file

Apply old-text/new-text edits and return a git-style diff. Supports dry_run.

edit_file_at_line

Apply line-targeted edits. Supports verification, relative line numbers, abort-on-verification-failure, and dry_run.

Start mutating work with dry_run: true where the tool supports it. For write_file, create_directory, and move_file, choose a temporary test directory first if you are checking behavior.

Analysis and cleanup helpers

Tool

Use it for

calculate_directory_size

Calculate directory size as human-readable text, bytes, or JSON.

find_duplicate_files

Find duplicate files by size and content hash.

compare_files

Compare two text files and return similarity plus diff output.

find_large_files

Find files above a size threshold.

find_empty_directories

Find empty directories.

These helpers can scan many files. Use narrow allowed directories and result limits for large trees.

Common workflows

Read a specific part of a large file

Use grep_files to find a match, then read_file_lines to inspect the surrounding range. read_file_lines uses a 0-based offset and a maximum limit.

{
  "path": "/absolute/path/to/file.log",
  "offset": 1200,
  "limit": 80,
  "encoding": "utf-8"
}

Search with context and pagination

{
  "path": "/absolute/path/to/project",
  "pattern": "def main",
  "is_regex": false,
  "context_before": 2,
  "context_after": 4,
  "include_patterns": ["*.py"],
  "results_offset": 0,
  "results_limit": 20
}

Preview a line-targeted edit

{
  "path": "/absolute/path/to/file.txt",
  "line_edits": [
    {
      "line_number": 15,
      "action": "replace",
      "content": "replacement text\n",
      "expected_content": "old text\n"
    }
  ],
  "abort_on_verification_failure": true,
  "dry_run": true
}

Then repeat with dry_run: false only after the preview is correct.

Development

Set up the checkout:

uv sync --frozen --all-extras

Run focused checks while editing:

uv run -m pytest tests/test_cli.py
uv run -m pytest tests/test_server_unit.py
uv run -m ruff check mcp_filesystem tests
uv run -m mypy mcp_filesystem

The Makefile also provides maintainer workflows:

make setup   # compiles requirements, creates .venv, syncs deps, installs pre-commit hooks
make check   # setup, lint with --fix, format, tests with coverage, mypy

make check mutates local files because it may update requirements, install hooks, apply Ruff fixes, and write coverage data.

Troubleshooting

Claude Desktop cannot start the server

Do this:

  1. Run uv run run_server.py --version from the checkout.

  2. Confirm the Claude config uses an absolute path after --directory.

  3. Confirm every allowed directory path is absolute and exists.

  4. Check the Claude MCP log shown above.

Do not use relative paths in the Claude config; they may be resolved relative to the client process, not this repository.

A file outside the allowed directory is rejected

That is expected. Restart the MCP server with the narrowest additional allowed root that contains the file.

Search is slower than expected

Install ripgrep (rg). The server uses ripgrep when it is available and falls back to Python search otherwise.

A mutating tool changed the wrong file

Prefer edit_file_at_line with expected_content, abort_on_verification_failure: true, and dry_run: true before applying changes. For whole-file replacement, use read_file or get_file_info first so the client has the current path and content.

Further reading

Available Tools

21 tools
calculate_directory_sizeB

Calculate the total size of a directory recursively.

Args:
    path: Directory path
    format: Output format ('human', 'bytes', or 'json')
    ctx: MCP context

Returns:
    Directory size information

Inputs: path (required), format.

compare_filesB

Compare two text files and show differences.

Args:
    file1: First file path
    file2: Second file path
    encoding: Text encoding (default: utf-8)
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Comparison results

Inputs: file1 (required), file2 (required), encoding, format.

create_directoryA

Create a new directory or ensure a directory exists.

Args:
    path: Path to the directory
    parents: Create parent directories if they don't exist
    exist_ok: Don't raise an error if directory already exists
    ctx: MCP context

Returns:
    Success or error message

Inputs: path (required), parents, exist_ok.

directory_treeA

Get a recursive tree view of files and directories.

Args:
    path: Root directory
    max_depth: Maximum recursion depth
    include_files: Whether to include files (not just directories)
    pattern: Optional glob pattern to filter entries
    exclude_patterns: Optional patterns to exclude
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Formatted directory tree

Inputs: path (required), max_depth, include_files, pattern, +2 more.

edit_fileA

Make line-based edits to a text file.

Args:
    path: Path to the file
    edits: List of {oldText, newText} dictionaries
    encoding: Text encoding (default: utf-8)
    dry_run: If True, return diff but don't modify file
    ctx: MCP context

Returns:
    Git-style diff showing changes

Inputs: path (required), edits (required), encoding, dry_run.

edit_file_at_lineA

Edit specific lines in a text file.

Args:
    path: Path to the file
    line_edits: List of edits to apply. Each edit is a dict with:
        - line_number: Line number to edit (0-based if relative_line_numbers=True, otherwise 1-based)
        - action: "replace", "insert_before", "insert_after", "delete"
        - content: New content for replace/insert operations (optional for delete)
        - expected_content: (Optional) Expected content of the line being edited for verification
    offset: Line offset (0-based) to start considering lines
    limit: Maximum number of lines to consider
    relative_line_numbers: Whether line numbers in edits are relative to offset
    abort_on_verification_failure: Whether to abort all edits if any verification fails
    encoding: Text encoding (default: utf-8)
    dry_run: If True, returns what would be changed without modifying the file
    ctx: MCP context

Returns:
    Edit results summary

Inputs: path (required), line_edits (required), offset, limit, +4 more.

find_duplicate_filesA

Find duplicate files by comparing file sizes and contents.

Args:
    path: Starting directory
    recursive: Whether to search subdirectories
    min_size: Minimum file size to consider (bytes)
    exclude_patterns: Optional patterns to exclude
    max_files: Maximum number of files to scan
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Duplicate file information

Inputs: path (required), recursive, min_size, exclude_patterns, +2 more.

find_empty_directoriesC

Find empty directories.

Args:
    path: Starting directory
    recursive: Whether to search subdirectories
    exclude_patterns: Optional patterns to exclude
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Empty directory information

Inputs: path (required), recursive, exclude_patterns, format.

find_large_filesB

Find files larger than the specified size.

Args:
    path: Starting directory
    min_size_mb: Minimum file size in megabytes
    recursive: Whether to search subdirectories
    max_results: Maximum number of results to return
    exclude_patterns: Optional patterns to exclude
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Large file information

Inputs: path (required), min_size_mb, recursive, max_results, +2 more.

get_file_infoC

Retrieve detailed metadata about a file or directory.

Args:
    path: Path to the file or directory
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Formatted file information

Inputs: path (required), format.

grep_filesA

Search for pattern in files, similar to grep.

Args:
    path: Starting directory or file path
    pattern: Text or regex pattern to search for
    is_regex: Whether to treat pattern as regex
    case_sensitive: Whether search is case sensitive
    whole_word: Match whole words only
    include_patterns: Only include files matching these patterns
    exclude_patterns: Exclude files matching these patterns
    context_lines: Number of lines to show before AND after matches (like grep -C)
    context_before: Number of lines to show BEFORE matches (like grep -B)
    context_after: Number of lines to show AFTER matches (like grep -A)
    results_offset: Start at Nth match (0-based, for pagination)
    results_limit: Return at most this many matches (for pagination)
    max_results: Maximum total matches to find during search
    max_file_size_mb: Skip files larger than this size
    recursive: Whether to search subdirectories
    max_depth: Maximum directory depth to recurse
    count_only: Only show match counts per file
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Search results

Inputs: path (required), pattern (required), is_regex, case_sensitive, +14 more.

head_fileA

Read the first N lines of a text file.

Args:
    path: Path to the file
    lines: Number of lines to read (default: 10)
    encoding: Text encoding (default: utf-8)
    ctx: MCP context

Returns:
    First N lines of the file

Inputs: path (required), lines, encoding.

list_allowed_directoriesC

Returns the list of directories that this server is allowed to access.

Args:
    ctx: MCP context

Returns:
    List of allowed directories

Inputs: no named parameters.

list_directoryA

Get a detailed listing of files and directories in a path.

Args:
    path: Path to the directory
    include_hidden: Whether to include hidden files (starting with .)
    pattern: Optional glob pattern to filter entries
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Formatted directory listing

Inputs: path (required), include_hidden, pattern, format.

move_fileC

Move or rename files and directories.

Args:
    source: Source path
    destination: Destination path
    overwrite: Whether to overwrite existing destination
    ctx: MCP context

Returns:
    Success or error message

Inputs: source (required), destination (required), overwrite.

read_fileA

Read the complete contents of a file.

Args:
    path: Path to the file
    encoding: File encoding (default: utf-8)
    ctx: MCP context

Returns:
    File contents as a string

Inputs: path (required), encoding.

read_file_linesA

Read specific lines from a text file.

Args:
    path: Path to the file
    offset: Line offset (0-based, starts at first line)
    limit: Maximum number of lines to read (None for all remaining)
    encoding: Text encoding (default: utf-8)
    ctx: MCP context

Returns:
    File content and metadata

Inputs: path (required), offset, limit, encoding.

read_multiple_filesB

Read multiple files at once.

Args:
    paths: List of file paths to read
    encoding: File encoding (default: utf-8)
    ctx: MCP context

Returns:
    Dictionary mapping file paths to contents or error messages

Inputs: paths (required), encoding.

search_filesA

Recursively search for files and directories matching a pattern.

Args:
    path: Starting directory
    pattern: Glob pattern to match against filenames
    recursive: Whether to search subdirectories
    exclude_patterns: Optional patterns to exclude
    content_match: Optional text to search within files
    max_results: Maximum number of results to return
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Search results

Inputs: path (required), pattern (required), recursive, exclude_patterns, +3 more.

tail_fileA

Read the last N lines of a text file.

Args:
    path: Path to the file
    lines: Number of lines to read (default: 10)
    encoding: Text encoding (default: utf-8)
    ctx: MCP context

Returns:
    Last N lines of the file

Inputs: path (required), lines, encoding.

write_fileA

Create a new file or overwrite an existing file with new content.

Args:
    path: Path to write to
    content: Content to write
    encoding: File encoding (default: utf-8)
    create_dirs: Whether to create parent directories if they don't exist
    ctx: MCP context

Returns:
    Success or error message

Inputs: path (required), content (required), encoding, create_dirs.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 21 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose with minimal overlap. For example, read_file reads entire files while head_file reads first lines, and edit_file makes line-based edits while edit_file_at_line targets specific lines. The find_* tools (duplicate_files, empty_directories, large_files) each target different search criteria, preventing confusion.

    Naming Consistency5/5

    All tools follow a consistent verb_noun naming pattern with snake_case throughout. Examples include calculate_directory_size, compare_files, create_directory, and list_directory. There are no deviations in naming conventions, making the tool set predictable and easy to understand.

    Tool Count4/5

    With 21 tools, the count is slightly high but reasonable for a filesystem server covering a broad range of operations. It includes core file operations (read, write, move), directory management, search utilities, and specialized tools like duplicate detection. While comprehensive, it might feel heavy but remains well-scoped for the domain.

    Completeness5/5

    The tool set provides complete coverage for filesystem operations, including CRUD (create_directory, write_file, read_file, move_file, delete implied via move/overwrite), search (grep_files, search_files), metadata (get_file_info), and utilities (compare_files, edit_file). There are no obvious gaps, and tools support common workflows like file editing, directory traversal, and content analysis.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      A Model Context Protocol (MCP) server that allows AI models to safely access and interact with local file systems, enabling reading file contents, listing directories, and retrieving file metadata.
      8 npm
      10
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      A Model Context Protocol server that extends AI capabilities by providing file system access and management functionalities to Claude or other AI assistants.
      235 npm
      5
      -
    • A
      license
      A
      quality
      D
      maintenance
      A secure Model Context Protocol server that provides controlled filesystem access within predefined directories, enabling AI models to perform file and directory operations with strict path validation.
      16
      18 npm
      7
      MIT