#3602·servers

server-filesystem: MCP roots protocol overwrites CLI-provided allowed directories

Author: milnet01Created Mar 16, 2026Updated Sep 16, 2026

Description

When the MCP client supports the roots protocol, the filesystem server's oninitialized handler replaces all command-line allowed directories with only the roots provided by the client. This means any additional directories passed via CLI args are silently discarded.

Steps to Reproduce

  1. Configure the filesystem MCP server with multiple allowed directories via CLI args:
    npx @modelcontextprotocol/server-filesystem /home/user /mnt/Storage /mnt/Games /mnt/Emulators
    
  2. Connect from a client that supports the MCP roots protocol (e.g., Claude Code) where the working directory is /home/user
  3. Call list_allowed_directories

Expected Behavior

All four directories should be listed as allowed:

/home/user
/mnt/Storage
/mnt/Games
/mnt/Emulators

Actual Behavior

Only the client-provided root is listed:

/home/user

The other three directories are silently dropped and become inaccessible.

Root Cause

In dist/index.js, the oninitialized handler (around line 564) unconditionally replaces allowedDirectories with the client roots when the client supports the roots protocol:

server.server.oninitialized = async () => {
    const clientCapabilities = server.server.getClientCapabilities();
    if (clientCapabilities?.roots) {
        const response = await server.server.listRoots();
        if (response && 'roots' in response) {
            await updateAllowedDirectoriesFromRoots(response.roots);
        }
    }
};

And updateAllowedDirectoriesFromRoots does a full replacement:

allowedDirectories = [...validatedRootDirs];

Suggested Fix

CLI-provided directories should be preserved and merged with client roots, not replaced. For example:

async function updateAllowedDirectoriesFromRoots(requestedRoots) {
    const validatedRootDirs = await getValidRootDirectories(requestedRoots);
    if (validatedRootDirs.length > 0) {
        // Merge with existing CLI-provided directories instead of replacing
        const merged = new Set([...allowedDirectories, ...validatedRootDirs]);
        allowedDirectories = [...merged];
        setAllowedDirectories(allowedDirectories);
    }
}

The same fix should apply to the RootsListChangedNotificationSchema handler.

Environment

  • @modelcontextprotocol/server-filesystem version: 2026.1.14
  • Client: Claude Code (supports MCP roots protocol)
  • OS: Linux (openSUSE Tumbleweed)
  • All directories exist and are mounted ext4 partitions

Source: modelcontextprotocol/servers