Skip to content

MCP roots protocol overrides CLI-provided allowed directories #3929

@t00ts

Description

@t00ts

Summary

When a client supports the MCP roots protocol, server-filesystem unconditionally replaces CLI-provided allowed directories with the client's roots on initialization. This makes it impossible to scope the server to a directory outside the client's project root.

Reproduction

  1. Configure a filesystem MCP server with an explicit directory argument:

    {
      "my-project": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/external-project"]
      }
    }
  2. Use it from a client that supports MCP roots (e.g., Claude Code with project root at /path/to/my-repo).

  3. Call list_allowed_directories — it returns /path/to/my-repo instead of /path/to/external-project.

Root cause

In dist/index.js, the oninitialized handler fetches roots from the client and calls updateAllowedDirectoriesFromRoots, which replaces the allowedDirectories array entirely — even when directories were explicitly provided via CLI args:

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);
            // ^ this replaces CLI-provided directories
        }
    }
    // ...
};

Expected behavior

CLI arguments should take precedence over MCP roots. If the user explicitly passes directories, those should be respected. MCP roots should only be used as a fallback when no CLI directories are provided.

Suggested fix

Only fetch and apply roots when no CLI args were provided:

if (clientCapabilities?.roots && allowedDirectories.length === 0) {

An alternative would be to merge both sources (CLI args + roots), but that changes the security model since CLI args are meant to be the explicit allowlist.

Version

2026.1.14

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions