Skip to content

fix(filesystem): sort directory_tree entries in stable lexicographic order#3651

Open
jasonmatthewsuhari wants to merge 2 commits intomodelcontextprotocol:mainfrom
jasonmatthewsuhari:fix/filesystem-directory-tree-sort-order
Open

fix(filesystem): sort directory_tree entries in stable lexicographic order#3651
jasonmatthewsuhari wants to merge 2 commits intomodelcontextprotocol:mainfrom
jasonmatthewsuhari:fix/filesystem-directory-tree-sort-order

Conversation

@jasonmatthewsuhari
Copy link

Closes #3539

Problem

fs.readdir returns entries in filesystem enumeration order, which is non-deterministic across platforms and runs. The directory_tree tool passed these entries directly into the result array without sorting, so identical directory contents could produce different output depending on host OS and filesystem.

Fix

Sort entries by name using localeCompare after each readdir call in buildTree, applied at every level of the recursive traversal:

const entries = (await fs.readdir(validPath, { withFileTypes: true }))
  .sort((a, b) => a.name.localeCompare(b.name));

No behaviour changes beyond ordering — no new parameters, no schema changes.

Tests

Applied the same fix to buildTreeForTesting in directory-tree.test.ts and added three new tests under a buildTree ordering describe block:

  • Stable sibling order — asserts each name ≤ next name (lexicographically) at the root level
  • Stable nested sibling order — same assertion on children of a subdirectory
  • IdempotencyJSON.stringify of two consecutive calls produces identical output

All 149 filesystem tests pass.

Adds MCP tool annotations to the fetch tool as requested in modelcontextprotocol#3572.
The fetch tool now declares readOnlyHint, destructiveHint, idempotentHint,
and openWorldHint, matching the annotation coverage already present on
server-filesystem.

Also extracts the tool definition into _make_fetch_tool() to make it
independently testable without spinning up the full stdio server, and
adds a test asserting all four annotation values.
…order

fs.readdir returns entries in filesystem enumeration order, which varies
across platforms and runs. This caused directory_tree to produce
non-deterministic output for the same directory contents.

Sort entries by name using localeCompare after each readdir call in
buildTree so sibling ordering is stable at every level of the tree.

Applies the same fix to the buildTreeForTesting helper in the test file
and adds three new tests: sibling order, nested sibling order, and
idempotency across repeated calls.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make filesystem directory-tree output ordering deterministic

1 participant