A context governor for coding agents. Graft enforces read policy so agents consume the smallest structurally correct view of a codebase instead of dumping raw files into their context window.
What it is: Graft sits between your AI coding agent and the filesystem. Instead of dumping entire files into the context window, it returns the minimum structurally correct view — full content for small files, AST-derived outlines for large ones, hard refusals for secrets and binaries. Every response carries a receipt so agents know exactly how much context they've consumed.
Why you want it: Agents that read files naively fill their context window with lockfiles, minified output, and 2,000-line modules they only needed 10 lines of. Graft fixes that automatically.
# Install and bootstrap your repo
npx @flyingrobots/graft init --write-claude-hooks --write-codex-mcp
# Start serving (MCP over stdio — point your agent at this)
npx @flyingrobots/graft serve
# Or try a governed read from the CLI right now
npx @flyingrobots/graft read safe src/app.tsThat's it. init scaffolds .graftignore and writes the MCP config your agent needs. serve starts listening on stdio. Your agent calls safe_read instead of reading files directly, and Graft handles the rest.
AI coding agents read files the same way a first-year developer does: grab the whole thing, every time. A 2,000-line module goes straight into the context window. So does the lockfile. So does the compiled output. So does the .env.
Context windows are finite. Once they fill up, the agent starts forgetting what it already read. Performance degrades. Hallucinations increase. You burn tokens on noise.
Graft sits between the agent and the filesystem and enforces a simple rule: return the minimum structurally correct view.
- Small file? Full content.
- Large file? A structural outline — function names, signatures, line ranges. The agent can drill in with a range read if it needs a specific function body.
- Binary, secret, or lockfile? Hard refusal with a machine-readable reason code and a suggested alternative.
Every response carries a receipt: bytes consumed, bytes avoided, session depth, policy decision. Agents can self-regulate. Operators can audit.
-
Parser-backed outlines. Outlines come from Tree-Sitter ASTs, not heuristic line-scanning. Function signatures, class hierarchies, and jump tables are structurally accurate across JavaScript, TypeScript, Rust, Python, Go, GraphQL, JSON, TOML, YAML, Markdown, and more.
-
Machine-readable contracts. Every response carries versioned
_schemametadata and a decision receipt. Agents reason about outcomes without scraping prose. Receipts accumulate cumulative session stats so agents know when they're burning budget. -
Structural memory across Git history. WARP (Structural Worldline Memory) indexes AST outlines per commit into a Git-backed graph. Query what changed structurally — which symbols were added, removed, or renamed — without reading a single byte of source. No checkout required.
-
Session governance. The
GovernorTrackerwatches for anti-patterns: runaway tool loops, late-session large reads, edit/bash thrash. Tripwire signals surface in receipts so agents and operators can act before context is exhausted. -
Industrial-grade daemon. A same-user local runtime manages multi-repo authorization, background indexing, and shared worker pools. WARP graphs stay warm in memory across sessions. Multi-repo work happens without file conflicts.
Graft exposes the same core capabilities through four integration points. Choose based on your deployment context.
npx @flyingrobots/graft read safe src/app.ts
npx @flyingrobots/graft struct since HEAD~3
npx @flyingrobots/graft struct dead-symbols --limit 20
npx @flyingrobots/graft symbol history createUser --path src/users.ts
npx @flyingrobots/graft review --base HEAD~1
npx @flyingrobots/graft review cooldown --pr 48Stateless. Print and exit. Good for scripting, spot-checking policy decisions, and inspecting structural history.
The simplest path for single-repo agent work. The current checkout is the authority. No workspace binding required.
npx @flyingrobots/graft servePoint your MCP client at this process. Graft speaks JSON-RPC over stdin/stdout. The same binary auto-detects non-TTY stdio and enters serve mode automatically — so npx @flyingrobots/graft with no arguments works as an MCP server when piped.
A persistent same-user runtime for long-running or multi-repo agent work. WARP graphs stay warm between sessions.
npx @flyingrobots/graft daemonDaemon sessions start unbound. The normal agent flow:
workspace_openwith the target repo'scwd- Optionally
workspace_list_openedto inspect active workspaces - Use repository-scoped tools:
safe_read,file_outline,graft_diff, etc.
See docs/SETUP.md for client-specific bootstrap and daemon control-plane configuration.
Embed Graft directly when you want structural reads or syntax data without spawning a subprocess or going through MCP transport.
Governed repo reads (same policy enforcement as MCP, no receipts):
import { createRepoWorkspace } from "@flyingrobots/graft";
const workspace = await createRepoWorkspace({ cwd: process.cwd() });
const result = await workspace.safeRead({ path: "src/app.ts" });
// result.projection: "content" | "outline" | "refused"In-process tool calls with receipts (full MCP behavior, no subprocess):
import { createRepoLocalGraft, callGraftTool } from "@flyingrobots/graft";
const graft = createRepoLocalGraft({ cwd: process.cwd() });
const outline = await callGraftTool(graft, "file_outline", { path: "src/app.ts" });Editor-native syntax highlighting (Tree-Sitter WASM, no I/O, viewport-aware):
import { createProjectionBundle, ensureParserReady } from "@flyingrobots/graft";
await ensureParserReady();
const bundle = createProjectionBundle("src/app.tsx", liveEditorText, {
basis: { kind: "editor_head", headId: "head-42", tick: 17 },
viewport: {
start: { row: 0, column: 0 },
end: { row: 80, column: 0 },
},
});
// bundle.syntax.spans — highlight ranges for the visible viewport onlycreateProjectionBundle owns the WASM buffer lifecycle internally. Use createStructuredBuffer directly if you need to hold a buffer across multiple operations and manage dispose() yourself.
# 1. Bootstrap the repo: scaffold .graftignore, seed agent instructions
npx @flyingrobots/graft init --write-claude-hooks --write-codex-mcp
# 2. Start serving (repo-local stdio MCP)
npx @flyingrobots/graft serve| Document | What it covers |
|---|---|
| Technical Teardown | Zero-to-hero deep dive: entry points, golden paths, data schemas, policy engine, WARP, session governance, trade-offs |
| Guide | Orientation, the fast path, and agent bootstrap |
| Setup Guide | Client-specific MCP setup, daemon posture, and workspace binding |
| Advanced Guide | Pipeline internals, worldlines, and daemon mechanics |
| Architecture | Authoritative structural reference: Ports, Adapters, WARP |
| Public API Contract | Semver-public root import surface and stability policy |
| Three-Surface Capability Matrix | API / CLI / MCP feature baseline and peer posture |
| Repo Topology | Where API, CLI, MCP, and core live in the source tree |
| Security Model | Same-user daemon trust boundaries, authz, and observability |
| Causal Provenance | Transport sessions, causal workspaces, strands, and handoff truth |
| North Star | Long-term stack position and Continuum-shaped direction |
| Vision | Core tenets and the provenance-aware mission |
| Method | Repo work doctrine and the cycle loop |
Built with precision by FLYING ROBOTS