Source control for agent swarms
Graft moves commits, rebases and merges to the server. An agent reads, writes and lands a change in one call: no clone, no pull, no push. With 48 agents on one branch, the median change landed in 5 ms. Through Git it took 15.5 s.
Recorded run, played in real time. Each row is an agent. Gray is thinking; color is time spent in source control: ■ commit/land ■ push ■ pull --rebase ■ conflict recovery.
One request instead of a retry loop
Git assumes every client keeps a full copy and works offline. Agents are always online and land small changes, many at once. Graft keeps history on the server and does the merge work where the data already is.
Read at an exact revision
Agents list, search and read files over MCP. Every answer names the changeset it came from. Nothing is cloned.
graft_read_file path="app.js"
@ 3f9c1e0a2b77 app.js
Send the change and its base
One call carries the revision the agent read and its edits: whole files, exact string replacements, moves or deletes.
graft_commit base="3f9c1e0a2b77"
edits: "// routes" → "…"
The server lands it
If main moved, the server rebases the change in memory with a three-way merge and swaps the branch pointer. Only a real textual conflict comes back.
Landed on main: 8be21c…
(auto-rebased from 51aa9e…)
Everything an agent team needs
One container for the server. One file for the MCP plugin. A CLI for agents that need real files to run tests.
MCP plugin
13 tools for Claude Code and any MCP client: read, search, find, commit-and-land, diff, log, blame, branches. Plus a skill that teaches the loop.
Lock-free landing
Branches move only by compare-and-swap on one row. No merge queue, no global lock. Lost races are retried on the server.
Small changesets
A commit stores only the paths it changed. Trees, blame and path history are derived from parents and cached, with checkpoints every 64 generations.
Sparse workspaces
graft clone --sparse src/ fetches only what you ask for. Every workspace on a machine shares one content-addressed cache.
Secure by default
Loopback-only until you set a token. CSRF and DNS-rebinding defenses, strict CSP, hash-verified blobs, sandboxed client paths.
Web viewer
Live history, changeset diffs, a file browser with blame, and code search for the people watching the agents.
Measured, not promised
The same workload ran through three backends at 8, 16, 32 and 48 agents, then 16 real Claude agents built the same pages in two teams. Every finished app was checked for lost work.
Median time from "ready to commit" to "on main"
Log scale: each gridline is ten times the one below. One Mac, no network, which favors Git.
Real Claude agents, 8 per team
Same model, same 8 pages, same instructions. Only the source-control loop differed.
Audited before this release
Every network-facing module was reviewed before v0.2.0 shipped. Each finding is fixed and pinned by a regression test: 30 tests in all.
11 security findings fixed
Plus 16 correctness bugs from a repository-wide scan, and a clean npm audit.
- S1Cross-site request forgery
JSON bodies require
content-type: application/json, blob uploads requireapplication/octet-stream; requests a browser marks cross-site (Origin,Sec-Fetch-Site) are refused. - S2Open by default + DNS rebinding
Default bind is
127.0.0.1; listening elsewhere withoutGRAFT_TOKENexits with an error (opt-out:GRAFT_ALLOW_OPEN=1); tokens must be ≥ 16 chars; without a token only loopback host names are served (GRAFT_ALLOWED_HOSTSto extend). - S3Path traversal from the server
Paths must be canonical and resolve inside the workspace after following symlinks;
.gitsegments are rejected by both server and client. - S6zod < 4.6.6
Upgraded to zod 4.6.7;
npm auditreports 0 vulnerabilities.
Running in three commands
Node 22.5+ or Docker. The deployment guide covers TLS, backups, upgrades and releases.
Start Graft
export GRAFT_TOKEN=$(openssl rand -hex 32)
docker compose up -d --build
curl -s localhost:7070/api/versionConnect Claude Code
claude plugin marketplace add ./graft
claude plugin install graft@graft
export GRAFT_URL=https://graft.example.comWorkspaces for tests
graft clone app work --sparse src
# edit, run tests…
graft commit -m "Fix the router"