Understanding bootstrap.ts and libuv Threadpool Initialization in Desktop Commander MCP

Desktop Commander MCP uses src/bootstrap.ts to set the libuv threadpool size to 16 before any file-system operations begin, preventing multi-minute hangs during concurrent filesystem access.

Desktop Commander MCP relies on Node.js's asynchronous file-system capabilities to serve CLI and IDE-style workflows. To ensure responsive performance under heavy parallel loads, the repository implements a critical early-stage configuration in src/bootstrap.ts that must execute before any other module initializes.

Why libuv Threadpool Size Matters

Node.js delegates all asynchronous file-system operations to libuv's threadpool. By default, this pool contains only 4 threads, which creates a significant bottleneck for I/O-intensive applications.

When multiple agents simultaneously access slow or cloud-synced filesystems, these 4 threads can become occupied by long-running system calls. Because a stalled syscall keeps its thread until the OS returns—something JavaScript timeouts cannot cancel—subsequent FS calls queue indefinitely. This causes multi-minute hangs, particularly observed under parallel claude -p loads where numerous concurrent readFile and writeFile operations compete for resources.

Increasing the threadpool size provides headroom to absorb bursts of slow reads without starving other operations, ensuring the MCP server remains responsive during file-intensive tasks.

How bootstrap.ts Works

The src/bootstrap.ts module performs a simple but decisive one-time configuration. It checks for an existing UV_THREADPOOL_SIZE environment variable and defaults to 16 threads if none is set:

// src/bootstrap.ts
const DEFAULT_THREADPOOL_SIZE = 16;

if (!process.env.UV_THREADPOOL_SIZE) {
  process.env.UV_THREADPOOL_SIZE = String(DEFAULT_THREADPOOL_SIZE);
}

This assignment must occur before libuv submits its first work item. Once the threadpool initializes, libuv reads UV_THREADPOOL_SIZE exactly once and ignores any subsequent changes. This immutability makes the timing of bootstrap.ts execution critical to application performance.

Import Order Requirements

The bootstrap module must be the first import in the application entry point. In src/index.ts, the import appears at the very top (lines 3-6) to guarantee execution before any file-system work begins:

// src/index.ts#L3-L6
import './bootstrap.js';
// ... other imports follow

If bootstrap.ts loaded after modules that trigger file-system operations—such as configuration loaders in src/server.ts or handlers in src/handlers/**/*.ts—the default 4-thread pool would already be locked in, rendering the configuration ineffective. This import order ensures that all subsequent asynchronous operations in src/utils/**/*.ts and other modules benefit from the expanded threadpool.

Configuration Options

While the default of 16 threads suits most deployment scenarios, Desktop Commander MCP respects user-provided overrides for specific environments.

Command-line override:


# Increase to 32 threads for high-concurrency environments

UV_THREADPOOL_SIZE=32 mcp start

Programmatic verification:

// Verify the active configuration at runtime
console.log('Current libuv threadpool size:', process.env.UV_THREADPOOL_SIZE);
// Expected output: "Current libuv threadpool size: 16"

Test harness initialization:

// Must set before importing bootstrap or any FS modules
process.env.UV_THREADPOOL_SIZE = '32';
import './src/bootstrap.js';
// Proceed with application logic

Summary

  • src/bootstrap.ts configures UV_THREADPOOL_SIZE to 16 by default, overriding libuv's restrictive 4-thread default.
  • The module must import first in src/index.ts because libuv reads the environment variable only once at first work submission.
  • Increasing threadpool size prevents blocking and multi-minute hangs when concurrent agents access slow filesystems.
  • Users can override the default via the UV_THREADPOOL_SIZE environment variable for custom deployment scenarios.
  • All file-system operations in src/handlers/**/*.ts and src/utils/**/*.ts indirectly depend on this early initialization.

Frequently Asked Questions

What happens if bootstrap.ts is not imported first?

If bootstrap.ts imports after modules that trigger file-system operations, libuv will have already initialized its threadpool with the default 4 threads. The environment variable assignment will be ignored, and the application may experience thread starvation under concurrent loads, resulting in queued operations and unresponsive behavior during file I/O.

Why is the default threadpool size set to 16 specifically?

The value of 16 provides sufficient headroom for Desktop Commander MCP's typical workload—multiple simultaneous file reads and configuration persistence operations—without consuming excessive system resources. This size accommodates parallel claude -p executions and cloud-synced filesystem latency while remaining conservative enough for standard development environments.

Can I change the threadpool size after the application starts?

No. libuv reads UV_THREADPOOL_SIZE exactly once when submitting the first asynchronous operation to the threadpool. Any changes to the environment variable after initialization have no effect. You must set the variable before launching the process or before importing any modules that trigger file-system work.

How do I verify that my custom threadpool size is active?

Check the process.env.UV_THREADPOOL_SIZE value after imports complete but before heavy operations begin. The bootstrap module preserves user-provided values, so if you set UV_THREADPOOL_SIZE=32 before startup, process.env.UV_THREADPOOL_SIZE will reflect "32" throughout the application lifecycle.

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 →