snapedit
Snapshot-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.
README
snapedit
Snapshot-based file editing for AI agents — send only the NEW content, never the old block.
snapedit lets an editing agent (Claude Code, OpenCode, or any MCP client)
edit files by sending only the new content — never the old text. Files are
captured as immutable, content-addressed snapshots; edits reference the
snapshot's 1-based line numbers, so lines shifted by prior edits elsewhere
never silently misapply.
Agent snapedit Filesystem
│ read_snapshot(path) │
├────────────────────────────────►│ sha256(bytes) → blob_id
│◄── blob_id + numbered page ────┤
│ │ …(agent thinks)…
│ apply_snapshot_patch(blob, │
│ from, to, NEW_CONTENT) ──────►│ base=snapshot · ours=live
│ │ 3-way merge OR splice
│◄── ok:true / conflict / err ────┤
│ │ atomic write + lock
Why
Direct rewrite tools force the agent to transmit the old text to locate a
change; when a file changes between reads, misalignment silently corrupts
files. snapedit replaces that with:
- Immutable snapshots —
blob_id = sha256(bytes). The agent carries only the id; content is never re-sent. - 3-way merge on apply — base = snapshot, ours = live file. Earlier edits (even insertions above the hunk) are preserved; the patch lands exactly where the snapshot said it should.
- Explicit conflicts — if the live file changed inside the hunk with different content, no write happens; a structured conflict is returned with previews of both sides.
- Safety over guesswork — ambiguous patches (hunk text duplicated in the live file) are refused with zero writes, never silently applied to the wrong occurrence.
- No shell transport — all bodies travel over stdio MCP (JSON-RPC lines). Large files are paged, never truncated by a shell.
Features
| Feature | Details |
|---|---|
| Content-addressed store | ~/.snapedit/blobs, sha256 verified on read, recency index |
| Cross-process safety | advisory locks, EEXIST-tolerant writes, stale-lock recovery |
| Concurrency | parallel edits: disjoint ranges both land; same range → clean conflict |
| Ambiguity safety | duplicated hunk text ⇒ refused, file proven byte-identical |
| Store GC | snapedit store prune [--days N] [--dry-run] (blobs never garbage-collected automatically) |
| Zero dependencies | plain Node.js ≥ 18, ESM |
Install
git clone https://github.com/rianprei/snapedit.git
cd snapedit
npm test # 55 tests, no deps required
npm link # optional: expose `snapedit` on PATH
Quick start (CLI)
# snapshot + numbered page (default page 0, 300 lines)
snapedit read path/to/file.txt
# apply NEW content to snapshot lines 2..4 (1-based, inclusive)
snapedit apply path/to/file.txt <blob_id> 2 4 --content $'wrote new lines\n'
# where does the hunk map in the live file today?
snapedit locate path/to/file.txt <blob_id> 2 4
# run the MCP server over stdio
snapedit mcp
Claude Code configuration
Add an MCP server entry (Claude Code ~/.claude.json, or OpenCode's "type": "local" MCP):
{
"mcpServers": {
"snapedit": {
"command": "/abs/path/to/snapedit/bin/snapedit",
"args": ["mcp"]
}
}
}
Agent edit protocol (keep this short)
read_snapshot(page containing region) — rememberblob_id.apply_snapshot_patch(path, blob_id, from, to, new_content).ok:true→ done.mode:"conflict"→ re-read_snapshot, retry on the new snapshot.kind:"snapshot_missing"→ re-read_snapshot.
- Never send the old text; never concatenate whole-file bodies yourself.
new_content is the exact replacement for snapshot lines [from..to]
(1-based, inclusive). Multi-line edits work as a single new_content; the
merge replays the hunk in snapshot coordinates, so earlier shifts don't break
it.
Documentation
- Protocol — full JSON-RPC tool contracts, results, errors
- Architecture — modules, data flow, concurrency model
- Safety & invariants — ambiguity gate, conflict rules, corruption defenses, GC, locking
- Changelog
- Contributing
Security
See docs/SAFETY.md for the full property list. Highlights:
- Refuses ambiguous applies deterministically (
match_count != 1 → write == false, proven byte-identical by sha256 in tests). - Path-like
blob_ids rejected (no filesystem traversal via the store). - MCP input validation: malformed JSON-RPC →
-32600, invalid tool args →bad_arg, never a crash of the server. - Atomic write: temp file in same dir +
rename→ readers never observe partial content.
License
MIT — see LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.