Skip to content

fix(filesystem): fix quote style and add fileURLToPath regression test#3353

Open
olaservo wants to merge 1 commit intomodelcontextprotocol:mainfrom
olaservo:fix/filesystem-roots-utils-followup
Open

fix(filesystem): fix quote style and add fileURLToPath regression test#3353
olaservo wants to merge 1 commit intomodelcontextprotocol:mainfrom
olaservo:fix/filesystem-roots-utils-followup

Conversation

@olaservo
Copy link
Copy Markdown
Member

Summary

Follow-up to #3205 with two small improvements:

  • Fix import quote style: Changed import { fileURLToPath } from "url" to use single quotes, matching the rest of the file
  • Add regression test: New test using pathToFileURL() to verify properly-encoded file:// URIs (the format VS Code sends via MCP roots) are handled correctly on all platforms

Test plan

  • npx vitest run src/filesystem/__tests__/roots-utils.test.ts — all 4 tests pass (3 existing + 1 new)

🦉 Generated with Claude Code

Follow-up to modelcontextprotocol#3205. Fixes import quote style inconsistency (double to
single quotes) and adds a regression test using pathToFileURL() to
verify properly-encoded file:// URIs are handled correctly on all
platforms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines +49 to +62
it('should handle standard file URIs from pathToFileURL', async () => {
// pathToFileURL produces properly-encoded URIs (e.g. file:///C:/... on Windows)
// This is the format VS Code and other editors send via MCP roots
const roots: Root[] = [
{ uri: pathToFileURL(testDir1).href, name: 'Standard File URI' },
{ uri: pathToFileURL(testDir2).href, name: 'Standard File URI 2' },
];

const result = await getValidRootDirectories(roots);

expect(result).toContain(testDir1);
expect(result).toContain(testDir2);
expect(result).toHaveLength(2);
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that the tests pass on non-Windows platforms regardless of the changes in #3205. Since CI also does not seem to run tests on Windows, how about converting this into a regression test that can be reproduced on macOS and other platforms as shown below?

Suggested change
it('should handle standard file URIs from pathToFileURL', async () => {
// pathToFileURL produces properly-encoded URIs (e.g. file:///C:/... on Windows)
// This is the format VS Code and other editors send via MCP roots
const roots: Root[] = [
{ uri: pathToFileURL(testDir1).href, name: 'Standard File URI' },
{ uri: pathToFileURL(testDir2).href, name: 'Standard File URI 2' },
];
const result = await getValidRootDirectories(roots);
expect(result).toContain(testDir1);
expect(result).toContain(testDir2);
expect(result).toHaveLength(2);
});
it('should handle standard file URIs from pathToFileURL', async () => {
// pathToFileURL encodes special characters (e.g. spaces become %20, # becomes %23).
// fileURLToPath() decodes them correctly; slice(7) does not.
// e.g. pathToFileURL('/tmp/my dir').href => 'file:///tmp/my%20dir'
// fileURLToPath('file:///tmp/my%20dir') => '/tmp/my dir' (correct)
// 'file:///tmp/my%20dir'.slice(7) => '/tmp/my%20dir' (wrong)
const dirWithSpaces = join(testDir1, 'dir with spaces');
const dirWithHash = join(testDir1, 'dir#hash');
mkdirSync(dirWithSpaces);
mkdirSync(dirWithHash);
const roots: Root[] = [
{ uri: pathToFileURL(dirWithSpaces).href },
{ uri: pathToFileURL(dirWithHash).href },
];
const result = await getValidRootDirectories(roots);
expect(result).toContain(dirWithSpaces);
expect(result).toContain(dirWithHash);
expect(result).toHaveLength(2);
});

@cliffhall cliffhall added bug Something isn't working server-filesystem Reference implementation for the Filesystem MCP server - src/filesystem labels Apr 20, 2026
@cliffhall
Copy link
Copy Markdown
Member

@claude review

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 21, 2026

Claude finished @cliffhall's task in 1m 4s —— View job


PR Review

  • Read changed files
  • Analyze changes
  • Post review feedback

This is a clean, focused PR. Here's my assessment of both changes:

src/filesystem/roots-utils.ts — Quote style fix

Simple consistency fix: "url"'url'. Correct and unambiguous. ✅

src/filesystem/__tests__/roots-utils.test.ts — Regression test

The test is a step in the right direction, but it doesn't actually serve as a regression test for the bug fixed in #3205.

The core issue in #3205 was that slice(7) on a file URI doesn't decode percent-encoded characters, while fileURLToPath() does. For example:

file:///tmp/my%20dir    (space encoded as %20)
  slice(7)        → /tmp/my%20dir   ❌ (wrong)
  fileURLToPath() → /tmp/my dir     ✅ (correct)

The current test uses pathToFileURL(testDir1) where testDir1 is a mkdtempSync-generated path like /tmp/mcp-roots-test1-Xz4aFg. This path contains no special characters, so pathToFileURL produces a URI like file:///tmp/mcp-roots-test1-Xz4aFg — identical to what naive slice(7) would produce. The test would pass even if fileURLToPath were reverted to slice(7).

The review comment from @koic correctly identifies this and proposes a stronger version that creates subdirectories containing spaces and # characters, which would actually fail under the old buggy slice(7) implementation.

I'd recommend adopting koic's suggestion to make this a genuine regression test. It's a small change: create two subdirs (e.g. dir with spaces, dir#hash) inside the existing testDir1, then use pathToFileURL on those paths. Since these subdirs live inside testDir1, they'll be cleaned up automatically by the existing afterEach. Fix this →

Minor nit: The comment // pathToFileURL produces properly-encoded URIs (e.g. file:///C:/... on Windows) focuses on Windows path format, but the key value of fileURLToPath is percent-decoding. A comment like:

// pathToFileURL percent-encodes special characters (spaces → %20, # → %23).
// fileURLToPath() decodes them correctly; slice(7) does not.

...would better document why fileURLToPath is required.

Summary

Change Assessment
Quote style fix ✅ Approve
Regression test ⚠️ Functionally correct but doesn't exercise the encoding bug — koic's suggestion makes it a real regression test

The PR is mergeable as-is (both changes are correct), but incorporating koic's suggestion before merge would meaningfully strengthen the test coverage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working server-filesystem Reference implementation for the Filesystem MCP server - src/filesystem

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants