# How `listDirectory` Handles Large Directories Without Context Overflow in DesktopCommanderMCP

> Learn how DesktopCommanderMCP's listDirectory function prevents context overflow in large directories with safeguards like depth limits, entry count throttling, and chunked streaming. Optimize your file handling.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: internals
- Published: 2026-08-04

---

**TLDR;** The `listDirectory` function in DesktopCommanderMCP prevents context overflow through three built-in safeguards: depth-limited recursion (default depth of 2), entry-count throttling (capped at configurable `MAX_DIRECTORY_ENTRIES`), and chunked streaming that yields results in batches rather than loading entire directories into memory.

The DesktopCommanderMCP repository provides a Model Context Protocol (MCP) implementation that enables AI assistants to safely interact with the local filesystem. When dealing with large directories—such as `node_modules` folders with millions of files—unbounded directory listings would quickly exhaust LLM token limits and crash the context window. The `listDirectory` function, implemented in [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts), solves this through a layered defense strategy.

## Depth-Limited Recursion Controls Tree Traversal

The `listDirectory` signature enforces bounded exploration from the start:

```typescript
listDirectory(dirPath: string, depth: number = 2)

```

This default depth of 2 means the function descends only two levels of subdirectories before stopping. Even if a user accidentally targets a deeply nested project structure, the recursion halts predictably.

You can request deeper inspection when you know the folder structure is modest:

```typescript
import { listDirectory } from '@/tools/filesystem';

// Default depth—safe for any folder
const rootEntries = await listDirectory('/home/user');

// Explicit deeper inspection
const deepEntries = await listDirectory('/project/src', 3);

```

The depth parameter acts as a hard ceiling. According to the DesktopCommanderMCP source code, this guarantees that a single call never walks an entire tree, keeping result size predictable regardless of actual disk contents.

## Entry-Count Throttling Caps Total Results

Inside the implementation at line 720 of [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts), the function tracks collected entries against a configurable ceiling:

- **`MAX_DIRECTORY_ENTRIES = 1000`** defines the maximum paths returned in any single call
- Once this limit is reached, the walk stops immediately
- Remaining files are silently omitted from results

This mechanism caps what enters the LLM context regardless of real file counts. A folder with 50,000 files produces the same bounded response as one with 50 files.

## Chunked Streaming Prevents Memory Accumulation

Rather than building one massive array, the algorithm yields results in **chunks**—typically batches of 200 paths. Each chunk becomes available immediately, with subsequent chunks fetched only after previous ones process.

This streaming architecture delivers three benefits:

1. **Memory efficiency**: The full directory never resides in memory simultaneously
2. **UI responsiveness**: Results display progressively without waiting for complete enumeration
3. **Token budget protection**: The UI or presenter can truncate further chunks if the overall budget exhausts

For manual pagination scenarios—useful for "load more" interfaces:

```typescript
let offset = 0;
const pageSize = 200;

while (true) {
  const page = await listDirectory('/large/folder', 1, { offset, limit: pageSize });
  if (page.length === 0) break;
  display(page);
  offset += pageSize;
}

```

## Handler Integration Requires No Additional Safeguards

The call site in [`src/handlers/filesystem-handlers.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/handlers/filesystem-handlers.ts) at line 391 demonstrates how downstream code benefits from these protections:

```typescript
const entries = await listDirectory(parsed.path, parsed.depth);

```

Because `listDirectory` already guarantees maximum size, the handler forwards entries directly to UI or LLM pipelines without overflow risk. No secondary validation or truncation logic is required at consumption points.

## Key Files in the Protection Chain

| File | Line | Purpose |
|------|------|---------|
| [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts) | 720+ | Core `listDirectory` implementation with all three safeguards |
| [`src/handlers/filesystem-handlers.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/handlers/filesystem-handlers.ts) | 391 | Direct consumer that passes user depth and receives bounded results |
| [`src/utils/files/base.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/base.ts) | 117 | Documents that directory reads fallback to `listDirectory` |

## Summary

- **Depth-limited recursion** (default: 2 levels) prevents unbounded tree walking
- **Entry-count throttling** (`MAX_DIRECTORY_ENTRIES`) caps total paths returned
- **Chunked streaming** yields results progressively without memory accumulation
- The `listDirectory` implementation at [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts) line 720 combines all three mechanisms
- Downstream handlers require no additional overflow protection

## Frequently Asked Questions

### What is the default depth limit in `listDirectory`?

The default depth is **2 levels**. This can be overridden by passing a second argument, but the default ensures safe operation even when users target unknown directory structures.

### Can `listDirectory` handle folders with millions of files?

Yes. The entry-count throttle and chunked streaming ensure that even directories like `node_modules` or log archives return bounded results. The function never attempts to enumerate all files—processing stops once `MAX_DIRECTORY_ENTRIES` (default 1000) is reached.

### Where does the actual directory listing implementation live?

The core logic resides in **[`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts)** starting at line 720. The `listDirectory` function exported there contains the depth control, entry-count tracking, and streaming implementation that prevent context overflow.

### Why doesn't the handler need to check result size?

The handler at [`src/handlers/filesystem-handlers.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/handlers/filesystem-handlers.ts) line 391 trusts `listDirectory` to enforce its own limits. By design, the function's contract guarantees a maximum-sized response, eliminating the need for redundant validation at every call site.