# How the `list_directory` Tool Handles Recursive Listings with Context Overflow Protection

> Learn how the list_directory tool manages recursive listings. Discover its depth limits and overflow protection to prevent context issues.

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

---

**The `list_directory` tool enforces a default depth limit of 2 levels and caps nested directories at 100 items each, with explicit warnings when truncation occurs.**

Recursively listing directories in an AI-powered environment requires strict safeguards. The `DesktopCommanderMCP` repository implements `list_directory` as a bounded, deterministic tool that prevents massive file trees from overwhelming model context windows while delivering useful hierarchical data.

## Depth-Based Recursion Control

The tool accepts an optional `depth` parameter that defaults to **2 levels**. This limit propagates through the internal `listRecursive` helper function, which terminates early when `currentDepth <= 0`.

In [[`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts#L720-L785), the recursion logic follows this pattern:

```typescript
async function listRecursive(
  dirPath: string,
  currentDepth: number,
  prefix: string = ''
): Promise<string[]> {
  if (currentDepth <= 0) {
    return []; // Hard stop at depth limit
  }
  
  const entries = await fs.readdir(dirPath, { withFileTypes: true });
  // ... process and recurse for subdirectories with currentDepth - 1
}

```

This approach guarantees **predictable output size** regardless of how deeply nested the actual filesystem may be.

## Per-Directory Item Limits (Context Overflow Protection)

The core overflow protection mechanism is **`MAX_NESTED_ITEMS = 100`**, applied to every directory **except** the top-level target. When a nested directory contains more than 100 entries, the tool:

- Emits exactly 100 formatted lines
- Appends a warning indicating the hidden count
- Continues recursion only on the shown items

This prevents notoriously large directories—such as `node_modules/`, `.git/objects/`, or `vendor/`—from saturating the response.

## Warning and Visibility System

When truncation occurs, the tool inserts an explicit warning line:

```

[WARNING] /path/to/large-dir: 237 items hidden (showing first 100 of 337 total)

```

This pattern appears in the implementation at approximately line 765 of [`filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/filesystem.ts). The warning serves two purposes: it keeps users informed of data completeness, and it signals to downstream AI processors that the listing is partial.

## Robust Error Handling

The tool distinguishes multiple failure modes with structured prefixes:

| Error Type | Prefix | Typical Cause |
|------------|--------|-------------|
| Not found | `[NOT_FOUND]` | `ENOENT`—path does not exist |
| Access denied | `[DENIED]` | `EPERM`, `EACCES`, `ETIMEDOUT`—permission or timeout issues |
| General error | `[ERROR]` | Unexpected `fs` failures |

Each error produces a single descriptive line rather than throwing, allowing the listing to continue for accessible portions of the requested tree.

## Path Validation Before Recursion

Before entering any subdirectory, the tool invokes `validatePath(fullPath)` as implemented in the same file. Failed validation causes **silent skipping** of that branch, with the entry already marked appropriately. This enforces sandbox boundaries and prevents traversal outside allowed roots.

## Output Format and Parser Compatibility

Every emitted line uses a machine-readable prefix convention:

```typescript
[DIR]  relative/path/to/directory
[FILE] relative/path/to/file.ext

```

This format requires **no additional path manipulation** by consuming code, making it ideal for both human-readable tree views and automated parsing by AI agents.

## Complete Usage Examples

### Default shallow listing (depth 2)

```typescript
const entries = await listDirectory('./src');
// Output: ['[DIR] components', '[FILE] index.ts', '[DIR] utils', ...]

```

### Explicit deep listing (depth 4)

```typescript
const deep = await listDirectory('/home/user/projects', 4);

```

### Triggering overflow protection

```typescript
const limited = await listDirectory('/var/log', 2);
// May include: '[WARNING] /var/log/nginx: 412 items hidden (showing first 100 of 512 total)'

```

### Handling inaccessible paths

```typescript
const result = await listDirectory('/root/secret');
// Output: ['[DENIED] /root/secret — not accessible (permission denied)']

```

## Source File References

| File | Lines | Responsibility |
|------|-------|----------------|
| [[`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts#L720-L785) | 720–785 | Core `listDirectory` implementation with overflow protection |
| [[`src/handlers/filesystem-handlers.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/handlers/filesystem-handlers.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/handlers/filesystem-handlers.ts) | — | Tool registration and CLI integration |
| [[`src/utils/files/base.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/base.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/base.ts) | — | Notes `read_file` fallback to `list_directory` for directories |

## Summary

- **Hard depth limit** (`default: 2`) prevents unbounded recursion regardless of filesystem depth
- **`MAX_NESTED_ITEMS = 100`** caps per-directory output, with explicit truncation warnings
- **Structured error prefixes** maintain flow continuity when individual paths fail
- **`validatePath` enforcement** preserves sandbox boundaries at every recursion step
- **Machine-readable format** supports both AI parsing and human tree rendering

## Frequently Asked Questions

### What happens if I request depth 0 or a negative number?

The tool treats `depth <= 0` as a request for **zero recursion**, returning only the top-level directory entry itself with no children enumerated.

### Why is the 100-item limit applied only to nested directories?

The top-level directory is exempt from `MAX_NESTED_ITEMS` to ensure the user's explicitly requested target is fully visible. Subdirectories receive the limit because they are discovered incidentally and may contain unbounded automatic-generated content.

### Can the overflow limits be configured at runtime?

No. Both the default depth (2) and `MAX_NESTED_ITEMS` (100) are **compile-time constants** in the current implementation. Callers must implement additional filtering if they need different bounds.

### How does the tool handle circular symlinks or mount loops?

Each recursion step validates the path before proceeding, and the depth limit provides an absolute upper bound on traversal. The tool does not maintain a visited-set for symlink detection, relying instead on depth exhaustion to prevent infinite loops.