How Recursive Directory Listing Handles Large Directories Without Context Overflow in DesktopCommanderMCP

DesktopCommanderMCP prevents context overflow by enforcing a configurable depth limit (default 2), capping nested directories at 100 items, and rejecting unbounded requests that attempt to dump entire filesystems at once.

The list_directory tool in DesktopCommanderMCP provides hierarchical filesystem traversal while implementing strict output boundaries to protect LLM context windows. According to the source code in wonderwhy-er/DesktopCommanderMCP, the implementation combines recursive depth controls with per-directory item limits to ensure predictable output sizes regardless of underlying directory size.

Depth-Based Recursion Control

The primary defense against runaway context usage is a configurable depth limit that terminates recursion before it can traverse deeply nested trees.

In src/tools/filesystem.ts, the listDirectory function accepts a depth parameter defaulting to 2:

export async function listDirectory(dirPath: string, depth: number = 2): Promise<string>

The recursive helper tracks currentDepth and stops when it reaches zero, preventing unbounded walks through deeply nested directories. This guarantees that even when scanning complex project structures or deep /var/log hierarchies, the output remains constrained to a finite number of nesting levels.

Per-Directory Item Caps

Beyond depth limits, the implementation enforces a hard cap of 100 items for any non-top-level directory to prevent wide directories from flooding the output.

The constant is defined in src/tools/filesystem.ts:

const MAX_NESTED_ITEMS = 100;

When processing nested directories, the logic checks:

if (!isTopLevel && totalEntries > MAX_NESTED_ITEMS) {
  // Truncate to first 100 and append warning
}

If a directory contains more than 100 entries, the tool returns only the first 100 and appends a warning line indicating how many items were hidden. This allows the LLM to understand the directory's scale without receiving overwhelming detail, and it can request deeper inspection of specific subdirectories if needed.

Safety Guards Against Unbounded Requests

DesktopCommanderMCP explicitly blocks attempts to dump entire filesystems in a single call. When callers attempt to request the entire top-level directory without pagination, the function throws an error forcing the client to use proper pagination parameters.

The guard in src/tools/filesystem.ts (lines 623-627) checks:

if (offset === 0 && length >= Number.MAX_SAFE_INTEGER) {
  throw new Error("Directory listing timed out...");
}

This prevents the anti-pattern of requesting offset: 0 with length: Number.MAX_SAFE_INTEGER to dump millions of files at once, which would certainly overflow context limits.

Graceful Directory Fallback

The tool integrates with the read_file handler to prevent workflow interruptions. When a file read request accidentally targets a directory, the system automatically invokes listDirectory instead of throwing an "EISDIR" error.

As implemented in src/tools/filesystem.ts (lines 454-463):

if (err.message?.includes('Directory listing')) {
  // Fallback to listDirectory
}

This ensures that even mistaken tool calls return useful hierarchical data rather than crashing the interaction.

Usage Examples

Basic Recursive Listing

Request a default depth-2 view of a project directory:

const result = await callTool('list_directory', {
  path: '/home/user/projects',
  depth: 2,
  origin: 'ui'
});

Sample output showing the 100-item cap warning:


/home/user/projects
├─ src
│  ├─ index.ts
│  ├─ utils
│  │  ├─ helper.ts
│  └─ ...
├─ README.md
[WARNING] src/utils: 542 items hidden (showing first 100 of 642 total)

Deep Recursion with Safety Limits

Request deeper traversal while maintaining safety caps:

await callTool('list_directory', {
  path: '/var/log',
  depth: 5  // Still bounded by MAX_NESTED_ITEMS per directory
});

Even with increased depth, each interior directory respects the 100-item limit, keeping total output predictable.

Summary

  • Depth limiting: The depth parameter (default 2) prevents unbounded recursive traversal of deeply nested trees in listDirectory.
  • Item capping: MAX_NESTED_ITEMS = 100 restricts any nested directory to 100 entries, with warning messages indicating truncation.
  • Anti-overflow guards: Requests with length >= Number.MAX_SAFE_INTEGER are rejected to prevent attempts to dump entire filesystems.
  • Automatic fallback: The read_file handler gracefully redirects directory targets to listDirectory instead of failing.

Frequently Asked Questions

What is the default recursion depth for list_directory?

The default depth is 2 levels. You can specify a higher depth (up to practical limits), but each nested directory still faces the 100-item cap regardless of depth setting.

How many items does the tool show per directory?

The tool shows all items for the top-level directory requested, but caps nested directories at 100 items. If a subdirectory contains more than 100 entries, you receive the first 100 plus a warning message indicating how many items were omitted.

What happens if I try to list an entire large filesystem?

The tool throws an error if you attempt to request the entire directory with offset: 0 and length: Number.MAX_SAFE_INTEGER. You must use pagination parameters (offset and length) to browse large directories in chunks, preventing single-tool-call context overflow.

The implementation focuses on depth and item limits rather than circular reference detection. The hard depth limit of 2 (or user-specified value) naturally prevents infinite recursion through circular symlink structures, as the recursion terminates at the specified depth regardless of filesystem topology.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →