fix(filesystem): merge MCP roots with CLI-provided directories instead of replacing them - #3616
fix(filesystem): merge MCP roots with CLI-provided directories instead of replacing them#3616flobo3 wants to merge 2 commits into
Conversation
…d of replacing them
|
@claude review |
|
Claude finished @cliffhall's task in 1m 28s —— View job Code Review
The fix addresses a real problem and is a clear improvement over the original behavior, but it introduces a subtle security issue in the What the PR changesBefore ( allowedDirectories = [...validatedRootDirs];After: const merged = new Set([...allowedDirectories, ...validatedRootDirs]);
allowedDirectories = [...merged];The
Issue 1: Accumulation bug (security concern)The merge approach works correctly for case 1 (initialization). For case 2 (dynamic updates), it causes Scenario:
The intent of Recommended fix: Track CLI-provided directories separately so each roots update cleanly replaces the MCP-roots portion while preserving CLI dirs: // At the top of the file, save CLI dirs immutably after startup
const cliAllowedDirectories = [...allowedDirectories];
// In updateAllowedDirectoriesFromRoots:
async function updateAllowedDirectoriesFromRoots(requestedRoots: Root[]) {
const validatedRootDirs = await getValidRootDirectories(requestedRoots);
if (validatedRootDirs.length > 0) {
const merged = new Set([...cliAllowedDirectories, ...validatedRootDirs]);
allowedDirectories = [...merged];
setAllowedDirectories(allowedDirectories);
console.error(`Updated allowed directories from MCP roots: ${validatedRootDirs.length} valid directories`);
} else {
console.error("No valid root directories provided by client");
}
}This way CLI dirs always remain, and MCP roots replace the previous MCP roots on each update. Fix this → Issue 2: Stale comment at line 719The comment above the // Handles dynamic roots updates during runtime, when client sends "roots/list_changed" notification, server fetches the updated roots and replaces all allowed directories with the new roots."replaces all allowed directories" is no longer accurate and should be updated to reflect the new merge semantics. Issue 3: No tests for the merge behaviour
…would prevent regressions here. SummaryThe core intent of this PR is correct — CLI-provided directories should not be silently dropped when an MCP client provides roots. The merge using |
|
Thanks for the thorough review! All three points addressed in 65c4a49:
|
LuuOW
left a comment
There was a problem hiding this comment.
Technical audit: Verified MCP server implementation for consistency with current SDK patterns.
Fixes #3602
Problem
When an MCP client supports the roots protocol, the filesystem server's
oninitializedhandler unconditionally replaces all command-line allowed directories with only the roots provided by the client. This causes any additional directories passed via CLI arguments to be silently discarded and become inaccessible.Solution
Modified
updateAllowedDirectoriesFromRootsinsrc/filesystem/index.tsto merge the client-provided roots with the existingallowedDirectories(which contains the CLI-provided directories) using aSetto ensure uniqueness, instead of completely replacing them.This ensures that both CLI-provided directories and client-provided roots are accessible to the server.