How startSearch Handles earlyTermination and literalSearch Parameters in DesktopCommanderMCP
The startSearch function in DesktopCommanderMCP uses an AbortController to halt ripgrep processes immediately when result limits are reached via earlyTermination, while the literal parameter maps directly to ripgrep's -F flag for fixed-string matching.
DesktopCommanderMCP provides high-performance text search capabilities through a TypeScript-based search manager that wraps ripgrep. The startSearch entry point in src/search-manager.ts exposes fine-grained control over search execution through optional query parameters processed by the HTTP handler in src/handlers/search-handlers.ts.
Understanding the Search Parameters
When invoking the search endpoint, clients can supply two boolean flags that alter execution behavior and result handling:
earlyTermination– Stops the search immediately once the configured result limit is hit (default: 500 results), preventing unnecessary CPU and memory consumption on large codebases.literal– Treats the search query as an exact literal string rather than a regular expression, disabling regex parsing entirely.
How earlyTermination Implements Abortable Search
The early termination mechanism relies on Node.js AbortController to manage the lifecycle of the underlying ripgrep child process.
1. AbortController Creation
startSearch instantiates an AbortController whose signal is attached to the spawned ripgrep process. This signal acts as a kill switch that can terminate the process externally without waiting for natural completion.
2. Result Count Streaming As ripgrep streams output lines back to the Node.js process, DesktopCommanderMCP increments an internal counter. Each line represents a match found in the target directory.
3. Threshold Evaluation
When the counter reaches the maxResults threshold (or the user-supplied limit when earlyTermination: true), the controller invokes abort(). This triggers a SIGTERM signal to the ripgrep process, immediately closing its streams.
4. Graceful Resolution
Despite the abrupt termination, the promise returned by startSearch resolves with the partial result set already collected, ensuring the client receives valid data even when the search is truncated.
How literal Enables Fixed-String Matching
The literal parameter provides a direct mapping to ripgrep's fixed-string search mode, bypassing the regex engine entirely.
- Handler Extraction: The HTTP handler in
src/handlers/search-handlers.tsextracts theliteralflag from the request query string and passes it through tostartSearch. - Flag Translation: When
literal: true,startSearchappends the-Foption to the ripgrep command line, resulting inrg -F <term>. - Performance Optimization: Fixed-string searches avoid regex compilation overhead and prevent accidental interpretation of special characters (like
.or*) as pattern metacharacters. - Consistent Output: The rest of the processing pipeline—including result pagination, syntax highlighting, and JSON serialization—remains unchanged regardless of search mode.
Implementation Details in search-manager.ts
The core logic resides in src/search-manager.ts, where startSearch orchestrates process spawning and stream management. The function signature accepts an options object containing earlyTermination, literal, maxResults, and cwd parameters.
According to the DesktopCommanderMCP source code, the implementation creates a command-line invocation that respects both flags simultaneously:
// src/search-manager.ts
// Command construction when both parameters are enabled
const args = [
literal ? '-F' : '', // Fixed-string flag
'--json', // Structured output
'--max-count', maxResults.toString(),
query
].filter(Boolean);
The handler in src/handlers/search-handlers.ts validates incoming HTTP requests and normalizes parameter types before forwarding them to the search manager.
Practical Code Examples
Early termination after 100 results:
import { startSearch } from './search-manager';
await startSearch({
query: 'TODO',
cwd: '/path/to/project',
earlyTermination: true,
maxResults: 100 // Hard stop at 100 matches
});
Literal search with regex metacharacters:
await startSearch({
query: 'foo.*bar', // Dot and asterisk treated literally
cwd: '/path/to/project',
literal: true // Invokes rg -F
});
Summary
earlyTerminationleveragesAbortControllerto send SIGTERM to ripgrep once result limits are reached, conserving system resources on large searches.literaltranslates to ripgrep's-Fflag, enabling fixed-string matching that avoids regex overhead and special-character interpretation.- Both parameters are processed by the HTTP handler in
src/handlers/search-handlers.tsand executed withinsrc/search-manager.ts. - The default result limit is 500 matches when early termination logic is triggered.
Frequently Asked Questions
What happens if earlyTermination is false but maxResults is set?
When earlyTermination is false, ripgrep continues searching the entire directory tree even after exceeding maxResults, but the implementation may still truncate the final output array to the specified limit. Setting earlyTermination: true is the only way to stop the underlying process early and reclaim resources immediately.
Does literal search improve performance significantly?
Yes. By passing the -F flag to ripgrep, the search bypasses the regular expression engine entirely. This eliminates regex compilation overhead and is particularly beneficial when searching for strings containing dots, asterisks, or other regex metacharacters that would otherwise require escaping.
How does the AbortController affect ripgrep process cleanup?
The AbortController signal is bound to the ripgrep child process via the signal option in child_process.spawn. Calling abort() sends a SIGTERM to the process, which closes stdout and stderr streams. DesktopCommanderMCP wraps this in a try-catch block to handle the resulting process exit gracefully and return partial results.
Where are the search parameters defined in the API?
The earlyTermination and literal parameters are defined as optional boolean query parameters in src/handlers/search-handlers.ts. This file parses incoming HTTP requests, validates the cwd (current working directory) path, and constructs the options object passed to startSearch in src/search-manager.ts.
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 →