How to Use `edit_block` for Precise Text Replacement in DesktopCommanderMCP
The edit_block tool lets you make exact text changes in files by specifying an old_string/new_string pair or a range/content pair, with built-in safety checks and atomic editing that preserves surrounding content.
DesktopCommanderMCP exposes the edit_block tool as a safer alternative to full-file rewrites. Whether you're swapping a line in a shell script or updating a specific cell in an Excel workbook, this tool minimizes collateral damage by touching only the matched text.
Understanding the edit_block Architecture
The tool is implemented across several modules in the wonderwhy-er/DesktopCommanderMCP repository. Each layer enforces correctness and provides clear feedback when operations fail.
Tool Registration and Schema Validation
In src/server.ts (lines 812-854), edit_block is registered as a JSON-RPC tool with a detailed description:
"Make a targeted edit to a file using the
edit_blocktool. This tool applies a single block of text replacement to a file. It is safer thanwrite_filebecause it only modifies the specified text block... Make separate edit_block calls for each distinct change."
The Zod schema in src/tools/schemas.ts (lines 148-168) validates that exactly one editing mode is selected:
- Text replacement mode requires
old_stringandnew_string - Range mode requires
rangeandcontent(for structured files like Excel)
If you provide neither mode or mix parameters incorrectly, validation fails before any file is touched.
Execution Flow in edit.ts
The dispatcher logic in src/tools/edit.ts (lines 391-465) routes requests based on file type:
| File Type | Handler | Location |
|---|---|---|
| Plain text | performSearchReplace |
src/tools/edit.ts#L116-L204 |
| Excel (.xlsx) | ExcelFileHandler.editRange |
src/utils/files/excel.ts#L160-L237 |
| DOCX (.docx) | DocxFileHandler.editRange (or XML search) |
src/utils/files/docx.ts#L229-L242 |
If range is supplied for a file type that doesn't support range editing, the tool returns: "Range-based editing not supported for [file_type]" (line 460).
Text Replacement Mode: old_string and new_string
For most files, performSearchReplace scans the entire document and replaces occurrences of old_string with new_string.
Safety Parameter: expected_replacements
This parameter (default: 1) guards against accidental multi-line changes. In src/tools/edit.ts (line 243), when the actual count differs from the expectation, the tool returns warning code server_edit_block_unexpected_count but still applies the edit.
Example: Precision Edit in a Configuration File
await callTool('edit_block', {
file_path: '/app/config.yml',
old_string: 'timeout: 30s',
new_string: 'timeout: 120s',
expected_replacements: 1
});
The server returns a ServerResult containing:
editsApplied: number of successful replacements- Warning flags if expectations weren't met
Range Mode: range and content
Structured files expose editRange for coordinate-based editing.
Excel: Cell-Level Updates
In src/utils/files/excel.ts (line 63), the range syntax follows standard spreadsheet notation (SheetName!CellReference).
await callTool('edit_block', {
file_path: '/data/financials.xlsx',
range: 'Q3!B4',
content: [[ 154000 ]],
expected_replacements: 1
});
The content parameter is a 2-D array: each inner array represents a row. To update a 3×2 block starting at B4:
content: [
[100, 200], // B4, C4
[300, 400], // B5, C5
[500, 600] // B6, C6
]
DOCX: XML Fragment Replacement
For Word documents, you can edit the underlying XML directly. From src/utils/files/docx.ts (lines 229-242), the handler unzips the .docx, locates the target XML, and applies the replacement.
await callTool('edit_block', {
file_path: '/contracts/agreement.docx',
old_string: '<w:t>Initial Payment: $5,000</w:t>',
new_string: '<w:t>Initial Payment: $7,500</w:t>',
expected_replacements: 1
});
Multiple Distinct Changes: The Recommended Pattern
As documented in src/server.ts (line 854), you should make separate edit_block calls for each distinct change. This improves auditability and error isolation.
await Promise.all([
callTool('edit_block', {
file_path: '/scripts/deploy.sh',
old_string: 'docker build -t app:latest .',
new_string: 'docker build -t app:v1.2.0 .',
expected_replacements: 1
}),
callTool('edit_block', {
file_path: '/scripts/deploy.sh',
old_string: 'docker run -p 8080:8080 app:latest',
new_string: 'docker run -p 8080:8080 --restart unless-stopped app:v1.2.0',
expected_replacements: 1
})
]);
Each call is logged independently with telemetry codes like server_edit_block_exact_success, enabling precise debugging in production workflows.
Error Handling and UI Integration
When edit_block fails, src/ui/file-preview/src/payload-utils.ts (lines 102-121) transforms server responses into actionable error messages. Common failure modes include:
- Exact match not found:
old_stringdoesn't appear in the file - Unexpected replacement count:
expected_replacementswas 1 but 3 matches found - File type mismatch:
rangeprovided for unsupported format
The UI layer in src/ui/file-preview/src/markdown/controller.ts (line 829) automatically splits user edits into minimal edit_block payloads, ensuring LLM-driven workflows stay within safe operational bounds.
Summary
edit_blockperforms atomic text replacement using eitherold_string/new_stringorrange/content- Registration:
src/server.ts#L812-L854defines the tool schema and usage constraints - Validation:
src/tools/schemas.ts#L148-L168enforces mutually exclusive parameter sets - Dispatch:
src/tools/edit.ts#L391-L465routes to appropriate handlers based on file type - Text engine:
src/tools/edit.ts#L116-L204implementsperformSearchReplacewithexpected_replacementssafety checks - Excel handler:
src/utils/files/excel.ts#L160-L237supportsSheet!Cellrange syntax with 2-D array content - DOCX handler:
src/utils/files/docx.ts#L229-L242enables XML-level precision editing - One
edit_blockcall per logical change is the enforced best practice for reliability and telemetry clarity
Frequently Asked Questions
What happens if old_string appears multiple times in a file?
By default, expected_replacements is 1. If your old_string appears more than once, the tool still performs replacements but returns warning server_edit_block_unexpected_count. Set expected_replacements to the actual count to suppress this warning, or scope your old_string with additional surrounding context to make it unique.
Can I use edit_block on binary files like PDFs?
DesktopCommanderMCP does not implement editRange for PDF files. Providing range to a PDF returns "Range-based editing not supported for pdf" from src/tools/edit.ts line 460. For PDF modifications, use the read_file tool to extract text, then write_file or external tools.
Why does the tool require expected_replacements?
This parameter prevents silent bulk changes. In automated LLM workflows, a model might accidentally match a generic string like "return" dozens of times. The default expectation of 1 replacement forces explicit acknowledgment when multiple matches exist, catching logic errors before they propagate.
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 →