MCP Hub
Back to servers

@flyingrobots/graft

Context governor and between-commit activity surface for coding agents

npm318/wk
Updated
Apr 11, 2026

Quick Install

npx -y @flyingrobots/graft

Context governor for coding agents

Graft enforces read policy so coding agents consume the smallest structurally correct view of a codebase instead of dumping entire files into their context window. Agent-first, but the structural tools (outlines, diffs, symbol history) are useful to anyone.

v0.5.0 — bounded between-commit activity for humans and agents.

Why

Empirical analysis of 1,091 real coding sessions (Blacklight) found that Read accounts for 96.2 GB of context burden — 6.6x all other tools combined. 58% of reads are full-file. The fattest 2.4% of reads produce 24% of raw bytes. Dynamic read caps + session management reduce this by 75.1%.

Install

npm install -g @flyingrobots/graft

Or use directly:

npx @flyingrobots/graft

Or run in Docker (no Node required):

docker run -i --rm -v "$PWD:/workspace" flyingrobots/graft

Quick start

npx @flyingrobots/graft init

Scaffolds .graftignore, adds .graft/ to .gitignore, generates a CLAUDE.md snippet telling agents to prefer graft tools, and prints Claude Code hook / MCP config for manual setup.

If you use Codex, the explicit --write-codex-mcp path also seeds AGENTS.md so the repo has both the MCP wiring and the instruction layer that tells Codex to prefer graft reads. It also writes a larger Codex startup_timeout_sec because cold npx startup can exceed the default 30 second MCP budget.

For a project-local one-step bootstrap, use explicit write flags:

npx @flyingrobots/graft init --write-claude-mcp --write-claude-hooks
npx @flyingrobots/graft init --write-cursor-mcp
npx @flyingrobots/graft init --write-windsurf-mcp
npx @flyingrobots/graft init --write-continue-mcp
npx @flyingrobots/graft init --write-cline-mcp
npx @flyingrobots/graft init --write-codex-mcp

These writes are idempotent. Existing JSON / TOML config is merged without duplicating graft entries.

Then add graft to your MCP config:

{
  "mcpServers": {
    "graft": {
      "command": "npx",
      "args": ["-y", "@flyingrobots/graft", "serve"]
    }
  }
}

The MCP server works with Codex, Claude Code, Cursor, Windsurf, Continue, Cline, and any MCP-compatible client. Governed native-read behavior differs by client: Claude has hook guardrails, Codex now has repo-local AGENTS.md bootstrap guidance, and the other clients remain MCP-plus-instructions rather than true default-governed reads.

Supported deployment posture today is local-user:

  • repo-local serve remains the standard editor bootstrap path
  • graft daemon now exists as a separate same-user local runtime on a Unix socket or Windows named pipe

The daemon still follows a stricter contract than repo-local stdio: daemon sessions start unbound, workspace binding is the authorization event, /healthz is the liveness surface, and escape hatches like run_capture stay default-denied there unless a workspace is explicitly authorized for that posture through the daemon control plane. Daemon-wide inspection now exists through MCP tools such as daemon_status, daemon_repos, daemon_sessions, workspace_authorizations, and daemon_monitors. Repo-scoped background WARP indexing can now be controlled there too through monitor_start, monitor_pause, monitor_resume, and monitor_stop.

See the Setup decision table for the fastest path by client and mode, and the full Setup Guide for per-editor instructions, Claude Code hooks, .graftignore configuration, troubleshooting, and details on what the agent experiences. For release-facing operator surfaces, see CLI Guide, MCP Guide, and Advanced Guide. Contributors should also read Architecture for the runtime systems map and Code of Conduct for project participation expectations.

What it does

When an agent asks to read a file, Graft applies policy:

  • Small files are returned as-is.
  • Large files are returned as a structural outline with a jump table so the agent can request specific ranges.
  • Banned files (binaries, lockfiles, minified bundles, secrets) are refused with a machine-readable reason code and suggested next steps.
  • Re-reads of unchanged files return a cached outline (no wasted context). Changed files return a structural diff (added/removed/ changed symbols).
  • Ranges are bounded — no stealth cat of a 10,000-line file.
  • Session depth tightens caps as the context window fills.
  • Budget governor — agent declares a byte budget, thresholds tighten as it drains. No single read may consume more than 5% of remaining budget.
  • Structural memory — WARP-backed structural history across git commits. Query what changed structurally without reading files.
  • Tripwires signal when the session is going off the rails.
  • Receipts on every response with session/trace correlation, latency, and compression ratio for usage analysis.
  • MCP runtime observability — metadata-only session and tool-call logs under .graft/logs/mcp-runtime.ndjson.
  • Versioned schemas on every machine-readable MCP / CLI payload.
  • Between-commit activity view — bounded local artifact_history over recent continuity, transitions, staging, and reads, anchored to the current commit when possible.

Every decision is logged. Every refusal is explainable. All output is structured JSON with versioned _schema metadata.

Tools

ToolPurpose
safe_readPolicy-enforced file read (content, outline, refusal, or diff)
file_outlineStructural skeleton with jump table
read_rangeBounded range read (max 250 lines), policy-gated
graft_diffStructural diff between git refs with per-file summary lines and explicit denied-file reporting
graft_sinceStructural changes since a git ref — symbols added/removed/changed with explicit denied-file reporting
graft_mapStructural map of a directory — all files and symbols in one call, with explicit denied-file reporting
code_showFocus on a symbol by name — get its source code in one call
code_findSearch symbols across the project by approximate name or glob, with optional kind/path filters
code_refsSearch import sites, callsites, property access, or literal text references with explicit text-fallback provenance
changed_sinceCheck if a file changed since last read (peek or consume)
run_captureDiagnostic shell-output escape hatch — tail to agent, optional redacted log persistence, explicit enable/disable posture, outside bounded-read policy, with explicit policyBoundary marker
state_saveSave session working state (max 8 KB)
state_loadRestore session working state
set_budgetDeclare session byte budget — governor tightens as it drains
activity_viewRecent bounded local artifact_history for the active workspace, with current commit anchor, grouped activity, and degraded posture
explainHuman-readable help for any reason code
doctorRuntime health check with burden summary and layered-worldline state
statsDecision metrics summary with cumulative burden-by-kind totals

Claude Code hooks

Two hooks work alongside the MCP server to govern native Read calls — a safety net for when agents bypass graft's tools:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read",
        "hooks": [
          {
            "type": "command",
            "command": "node --import tsx node_modules/@flyingrobots/graft/src/hooks/pretooluse-read.ts"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Read",
        "hooks": [
          {
            "type": "command",
            "command": "node --import tsx node_modules/@flyingrobots/graft/src/hooks/posttooluse-read.ts"
          }
        ]
      }
    ]
  }
}

Add to .claude/settings.json in your project root. PreToolUse blocks banned files and redirects large JS/TS reads to safe_read before native Read can dump them into context. PostToolUse is the backstop: it reports what safe_read would have saved when an oversized code read still slips through.

See the Setup Guide for full details on hooks, per-editor MCP config, .graftignore, and troubleshooting.

CLI

npx @flyingrobots/graft init
npx @flyingrobots/graft init --write-claude-mcp --write-claude-hooks
npx @flyingrobots/graft init --write-cursor-mcp
npx @flyingrobots/graft init --write-windsurf-mcp
npx @flyingrobots/graft init --write-continue-mcp
npx @flyingrobots/graft init --write-cline-mcp
npx @flyingrobots/graft init --write-codex-mcp
npx @flyingrobots/graft serve
npx @flyingrobots/graft index
npx @flyingrobots/graft read safe src/app.ts --json
npx @flyingrobots/graft read outline README.md --json
npx @flyingrobots/graft read range src/app.ts --start 10 --end 40 --json
npx @flyingrobots/graft read changed src/app.ts --json
npx @flyingrobots/graft struct diff --json
npx @flyingrobots/graft struct since HEAD~3 --json
npx @flyingrobots/graft struct map src --json
npx @flyingrobots/graft symbol show createServer --path src/mcp/server.ts --json
npx @flyingrobots/graft symbol find 'create*' --json
npx @flyingrobots/graft diag activity --json
npx @flyingrobots/graft diag doctor --json
npx @flyingrobots/graft diag explain CONTENT --json
npx @flyingrobots/graft diag stats --json
npx @flyingrobots/graft diag capture --tail 20 -- pnpm test --json

The CLI now mirrors the core MCP product surface through grouped namespaces:

  • read for bounded reads
  • struct for structural navigation
  • symbol for precision lookup
  • diag for diagnostics

init and index remain explicit CLI-only commands. MCP responses and CLI peer commands both carry versioned _schema metadata, and declared output contracts live in src/contracts/output-schemas.ts.

run_capture remains an explicit shell escape hatch. For shared or release-sensitive environments, you can disable it with GRAFT_ENABLE_RUN_CAPTURE=0. Persisted capture logs can be disabled with GRAFT_RUN_CAPTURE_PERSIST=0, and persisted output is redacted for obvious secret-shaped values by default. In the local daemon runtime, run_capture remains opt-in rather than ambiently available.

Reason codes

Every refusal or policy decision includes a machine-readable reason code. Use explain(code) to get meaning and recommended action.

CodeMeaning
CONTENTFile within thresholds — full content returned
OUTLINEFile exceeds thresholds — structural outline returned
SESSION_CAPSession-depth byte cap triggered
BUDGET_CAPBudget-proportional cap triggered
UNSUPPORTED_LANGUAGENo parser-backed outline for this file type
BINARYBinary file refused
LOCKFILEMachine-generated lockfile refused
MINIFIEDMinified file refused
BUILD_OUTPUTBuild output directory refused
SECRETPotential secrets file refused
GRAFTIGNOREMatches .graftignore pattern

License

Apache 2.0 — see LICENSE.


⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣾⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣶⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢀⣤⣴⣶⣶⣶⣶⣦⣤⣼⣿⣿⣿⣿⣿⠀⢠⣶⣶⣦⡀⠀⢀⣴⣶⣶⣤⠀⠀⠀⠀⣀⣤⣴⣶⣶⣶⣶⣦⣄⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⡄⠀⣀⣀⣠⣤⠀⠀⢀⣾⣿⣿⣀⣀⣀⣤⣤⣄⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣴⣿⣿⠛⠉⠉⠉⠛⠿⣿⣿⣿⡿⠉⠉⠀⠀⢻⣿⣿⣿⣇⠀⣾⣿⣿⣿⣿⡇⠀⢠⣾⣿⣿⣿⡿⠟⠛⢻⣿⣿⣷⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢸⣿⣿⣇⠀⠀⠀⠀⠀⠀⠘⣿⣿⡇⠀⠀⠀⠀⠈⢿⣿⣿⣿⢠⡿⠛⠛⠿⠟⠁⠀⢺⣿⣿⡿⠋⠀⠀⠀⣸⣿⣿⣿⡀⠀⠀⠀⠀⠛⠿⢿⣿⣿⠟⠛⠛⠛⠛⠀⠘⠻⠿⢿⣿⣿⠛⠛⠛⠛⠋⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠉⠉⠀⠀⠀⣠⣾⠟⢻⣿⣿⡇⠀⠀⠀⠀⠀⠀⠈⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣶⣤⣤⣤⣾⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⡿⠋⠀⢸⣿⣿⡇⠀⢀⣤⡀⠀⠀⠀⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡆⠀⠀⠀⢀⣀⡀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⣨⣿⡿⠟⠛⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⡏⠀⠀⠀⢸⣿⣿⡇⠀⢸⣿⡇⠀⠀⠀⢻⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣇⠀⠀⠀⢸⣿⣿⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣼⣿⣿⡀⠀⢀⣀⣀⣤⣤⣤⣴⣦⣤⣄⠀⠀⠀⠀⢰⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⢾⣿⣿⣇⠀⠀⣠⣿⢻⣿⣿⡀⣸⣿⡇⠀⠀⠀⠸⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣦⣀⣠⣾⣿⡟⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠹⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⢸⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⠏⠀⢿⣿⣿⣿⣿⠇⠀⠀⠀⠀⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⠟⠉⠁⠀⠀⠀⠀⠀⢻⣿⣿⡟⠀⠀⠀⠈⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠛⠛⠁⠀⠀⠀⠙⠛⠛⠁⠀⠀⠀⠀⠀⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠙⠛⠛⠛⠋⠁⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠈⢿⣿⣿⣷⣤⣤⣤⣤⣤⣾⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠙⠛⠻⠿⠿⠿⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⠿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Reviews

No reviews yet

Sign in to write a review