DesktopCommanderMCP bootstrap.ts Module: Purpose and Import Order Requirements
The bootstrap.ts module sets the UV_THREADPOOL_SIZE environment variable to 16 before any asynchronous file operations initialize Node.js's libuv thread pool, preventing thread starvation and multi-minute hangs during heavy parallel I/O.
The bootstrap.ts file serves as a critical entry-point initializer in the wonderwhy-er/DesktopCommanderMCP repository. This tiny module ensures that Node.js's libuv thread pool is properly sized before any file system work begins, directly impacting the performance and reliability of the CLI tool under concurrent load.
Why Libuv Thread Pool Size Matters
All asynchronous file operations in Node.js—reading, writing, editing files, and persisting configuration—execute on libuv's internal thread pool. By default, Node.js initializes this pool with only 4 worker threads.
When multiple agents perform slow I/O operations simultaneously (such as accessing cloud-synced drives), these four threads can become blocked for minutes waiting for the operating system to return. Because a blocked thread holds its slot until completion, additional file system requests queue up and experience severe latency. This manifested as multi-minute hangs under heavy parallel load, as noted in the comments within [src/bootstrap.ts](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/bootstrap.ts).
What bootstrap.ts Does
The module performs three critical functions:
- Defines a default size: Sets
DEFAULT_THREADPOOL_SIZEto 16. - Conditionally sets the environment variable: Assigns
process.env.UV_THREADPOOL_SIZEonly if the user has not already supplied a value. - Executes early: Runs before any code triggers thread-pool work.
// src/bootstrap.ts
const DEFAULT_THREADPOOL_SIZE = 16;
if (!process.env.UV_THREADPOOL_SIZE) {
process.env.UV_THREADPOOL_SIZE = String(DEFAULT_THREADPOOL_SIZE);
}
Because libuv reads UV_THREADPOOL_SIZE exactly once when creating the thread pool, this assignment must occur before any asynchronous file operation initializes the pool.
Import Order Requirements and Why Timing Matters
The entry script [src/index.ts](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/index.ts) explicitly imports bootstrap.ts before any other modules:
// src/index.ts
import './bootstrap.js'; // ← MUST be first
import { FilteredStdioServerTransport } from './custom-stdio.js';
// ... other imports
The inline comment states: "MUST be first: raises the libuv threadpool size before any fs work is submitted."
If any other module performing file operations were imported first, the thread pool would initialize with the default size of 4. Subsequent changes to UV_THREADPOOL_SIZE would have no effect because libuv never re-reads this variable. Therefore, the bootstrap module must be the very first import in the runtime execution chain.
Incorrect Import Order (Anti-pattern)
// ❌ Wrong order – file operation triggers pool creation before bootstrap
import { readFile } from 'fs/promises'; // <-- triggers thread-pool creation
import './bootstrap.js'; // <-- too late, has no effect
In this scenario, the pool remains locked at 4 threads regardless of the bootstrap module's settings.
Customizing the Thread Pool Size
Advanced users can override the default by setting the environment variable before launching the CLI:
UV_THREADPOOL_SIZE=32 npx desktop-commander-mcp
When bootstrap.ts detects an existing UV_THREADPOOL_SIZE value, it respects the user-provided setting and does not overwrite it. This allows fine-tuning based on specific hardware capabilities or workload requirements.
Verifying Configuration at Runtime
You can confirm the effective thread pool size in any downstream module by logging the environment variable:
// In any later module (e.g., src/server.ts)
console.log('Threadpool size:', process.env.UV_THREADPOOL_SIZE);
// Expected output: "Threadpool size: 16" (or user-provided value)
Summary
- The
bootstrap.tsmodule prevents I/O bottlenecks by sizing Node.js's libuv thread pool before initialization. - It sets
UV_THREADPOOL_SIZEto 16 by default, quadrupling the standard 4-thread pool. - Import order is critical:
bootstrap.tsmust be imported first insrc/index.tsbefore any file system operations trigger thread-pool creation. - Users can override the default by setting
UV_THREADPOOL_SIZEbefore launching the application. - Once the thread pool initializes, changing the environment variable has no effect until the process restarts.
Frequently Asked Questions
What happens if bootstrap.ts is not imported first?
If bootstrap.ts is not the first import, any preceding module that performs asynchronous file operations will trigger the creation of libuv's thread pool with the default 4 threads. The subsequent bootstrap.ts import will set the environment variable, but libuv ignores it because the pool already exists. This leaves the application vulnerable to thread starvation and multi-minute hangs under heavy I/O load.
Can I change the thread pool size without modifying the source code?
Yes. Export the UV_THREADPOOL_SIZE environment variable before running the CLI command. For example: UV_THREADPOOL_SIZE=64 npx desktop-commander-mcp. The bootstrap.ts module detects existing values and preserves them, allowing you to customize the pool size based on your system's CPU count and I/O patterns.
Why does DesktopCommanderMCP use 16 threads instead of the default 4?
The default 4-thread pool proved insufficient for DesktopCommanderMCP's use case, where multiple agents frequently perform parallel file operations on potentially slow storage (such as cloud-synced drives). The value 16 provides sufficient headroom to prevent queue buildup while remaining conservative enough to avoid excessive memory overhead on typical development machines.
Does the bootstrap.ts module affect all DesktopCommanderMCP operations?
The module specifically affects all operations relying on Node.js's asynchronous file system APIs (such as fs.readFile, fs.writeFile, and file watching). It does not alter the behavior of synchronous file operations or CPU-bound tasks, but since DesktopCommanderMCP is primarily I/O-driven, proper thread-pool sizing benefits most of its core functionality.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →