surgical-editing-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@surgical-editing-serverreplace port = 3000 with 8080 in src/config.ts and src/server.ts, dry run first"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Surgical Editing
Transactional file editing for AI agents: atomic multi-file changes that protect your code, and self-correcting errors that save tokens.
An exact-match editing engine for any MCP client (Cline, Claude Desktop, Python agents, CI/CD pipelines…), exposed as a single tool: surgical_replace.
What is Surgical Editing?
Agents often rewrite whole lines or blocks just to change one word. That costs output tokens and time, and every retyped character is another chance to break something. With Surgical Editing (Edición Quirúrgica, also called Delta Generation) the model sends only the exact snippet to find and its replacement.
surgical_replace guarantees:
Exact and unique: every
findmust appear exactly once in its file. If it appears 0 times or more than once, the call fails. Edits never use fuzzy matching and never guess.Transactional: one call can edit many files. If any replacement fails, no file is written.
Self-correcting errors: on a miss, the error points to the most similar region of the file, so the agent can fix its snippet without re-reading the file.
Dry run: validate everything and get a unified diff without touching the disk.
Efficient I/O: each file is read once, edited in memory and written once.
Related MCP server: Ketan-OS MCP Server
Usage
Multi-file transaction
{
"operations": [
{
"file_path": "src/config.ts",
"replacements": [{ "find": "port = 3000", "replace": "port = 8080" }]
},
{
"file_path": "src/server.ts",
"replacements": [{ "find": "listen(port)", "replace": "listen(port, host)" }]
}
],
"dry_run": false
}Replacements run in order. Operations that target the same file are applied one after another on the same in-memory content.
A
$inreplaceis inserted as-is and is never read as a regex pattern ($&,$1…).The legacy v1 form
{ "file_path": "...", "replacements": [...] }is still accepted. Don't combine it withoperationsin the same call.
Error diagnostics
When a find has no exact match, the tool looks for a region at least 80% similar and reports it. If the only difference is whitespace or line endings, the error adds a hint:
Operation #0, Replacement #0 (/repo/src/app.ts): No exact match found. Line 12 contains (96% similar): 'const x = 1'. Hint: File uses CRLF line endings. No files were written.Ambiguous matches report how many times the snippet appears and on which lines (appears 3 times (lines 4, 18, 52)), so the agent knows which context to add.
Verifiable results
On success, each replacement comes back with its final line number and a numbered excerpt of the result, so the agent can check its edit without re-reading the file:
Applied 1 replacement(s) across 1 file(s):
/repo/src/config.ts
op #0 #0 (line 4): "retries = 3" → "retries = 5"
3 | const host = "localhost";
4 | const retries = 5;
5 | export { port, host, retries };
``` File system errors (missing files, permission denied, read-only file systems) are returned as structured MCP errors (`isError: true`).
### Dry run
With `"dry_run": true`, the tool runs every validation and returns a unified diff per file, without writing anything:
```diff
--- /repo/src/config.ts
+++ /repo/src/config.ts
@@ -1,3 +1,3 @@
import { env } from "./env";
-export const port = 3000;
+export const port = 8080;
export const host = env.HOST;How atomicity works
Every file is read and every replacement is validated in memory. Any failure aborts the call before anything is written.
Each new version is written to a temp file next to its target. Most I/O failures (permissions, a full disk) happen at this step, while the originals are still untouched. If one fails, all temp files are removed.
The temp files replace the originals via
rename(), which is atomic per file on POSIX. If a rename still fails, files that were already replaced are restored to their original content.
Installation
git clone <repo> surgical-editing
cd surgical-editing
npm install
npm run buildOnce the package is on npm, you can run it with npx -y surgical-editing instead.
Configuration
Claude Code
claude mcp add surgical-editing-server -- node /absolute/path/to/surgical-editing/dist/index.js
# or, once it is on npm:
claude mcp add surgical-editing-server -- npx -y surgical-editingOther MCP clients
Most clients (Cline, Claude Desktop via claude_desktop_config.json, project .mcp.json) accept this shape:
{
"mcpServers": {
"surgical-editing-server": {
"command": "node",
"args": ["/absolute/path/to/surgical-editing/dist/index.js"]
}
}
}Relative file_path values resolve against the server's working directory. Use absolute paths when that is ambiguous.
Sandbox
Restrict edits to one directory tree with the SURGICAL_ROOT_DIR environment variable or the --root <dir> flag (the flag wins):
{
"mcpServers": {
"surgical-editing-server": {
"command": "node",
"args": ["/absolute/path/to/surgical-editing/dist/index.js", "--root", "/path/to/project"]
}
}
}When a root is set, relative paths resolve against it. Any target outside it fails with Path traversal blocked, including through a symlink that points outside the root. If the root itself doesn't exist, the server refuses to start.
Safety guarantees
Symlinks: edits are applied to the file the link points to, and the link stays intact.
Encoding: invalid UTF-8 and binary files (with NUL bytes) are rejected before anything is written. A UTF-8 BOM is preserved.
Concurrent changes: if a file's mtime or size changes between the read and the commit, the whole transaction is aborted.
Known limitations
These come from Node.js and POSIX file semantics. They are documented on purpose rather than patched with non-portable workarounds.
Residual race window: the concurrent-modification check runs right before the renames, but a write that lands between that check and the
rename()can still be lost. Closing that gap needs advisory locks (flock), which Node.js does not expose portably.Hard links: a file is replaced through temp file +
rename(), so a file with several hard links is split. The edited path gets the new content and the other links keep the old content.File ownership: permission bits are preserved, but the owner and group are not. If the server runs as a different user than the file's owner, the edited file will belong to the server's user.
Development
npm run dev # run from source with tsx
npm run build # compile to dist/
npm run typecheck # type-check src/ and tests/
npm test # typecheck, then run the node:test suiteLicense
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
- flockfsOAuthcom.flockfs
A real-time, multiplayer filesystem for agents and humans: shared files, live edits, history.
Shared control plane for AI coding agents — tasks, memory, decisions, file locks. 12 tools.
Git-backed platform for skills, tools, and context for AI agents
Code-map tools for AI agents: see a repo's structure first, then edit only what matters.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceEnables AI agents to safely explore directories, read files, search content by pattern or filename, and edit files with checksum verification and dry-run preview within sandboxed filesystem access.98 npm75ISC
- AlicenseAqualityBmaintenanceProvides transactional intelligence for AI agents, enabling safe tool execution with pre-flight invariant checks, sub-second filesystem snapshots/rollback, causal tracing, belief contradiction detection, and 15 native MCP tools for Claude Code.15MIT
- AlicenseNot gradedqualityBmaintenanceSnapshot-based file editing for AI agents. Enables safe file edits by sending only new content against immutable, content-addressed snapshots with 3-way merging and ambiguity protection.2MIT
- AlicenseNot gradedqualityCmaintenanceEnables agents to read, write, edit, search, rename, move, and delete files, perform regex search-and-replace across trees, query and modify JSON documents, and inspect git status and diffs, all through structured tools instead of shell commands. Includes safeguards like dry-run previews, atomic multi-file edits, and protection for denied or sensitive paths.MIT