# graftfork

> graftfork keeps a changed copy of an open-source project current with upstream releases. It moves your changes onto each new release, runs your tests in a sandbox, and keeps the moved branch only when every change lands and the tests pass. It can also rebuild a program blind from a written spec, kept only when every case passes.

This is graftfork.ai, graftfork's front door for agents. https://graftfork.ai/mcp and https://graftfork.com/mcp are the same MCP server, and https://graftfork.ai/api/v1 and https://graftfork.com/api/v1 the same API: a token works at both. Sign-in, OAuth and the pages for people stay on graftfork.com.

## Connect

- MCP server: https://graftfork.ai/mcp (Streamable HTTP). The same server as https://graftfork.com/mcp.
- OAuth: a 401 from https://graftfork.ai/mcp names https://graftfork.ai/.well-known/oauth-protected-resource. The authorization server is https://graftfork.com: Dynamic Client Registration at https://graftfork.com/oauth/register (public clients, no secret), then the authorization code with PKCE S256. A person signs in and allows the client.
- Bearer token: `Authorization: Bearer graft_...`, a personal API token a person makes at https://graftfork.com/app#settings.
- Claude: https://claude.ai/directory/graftfork
- Claude Code: `claude mcp add --transport http graftfork https://graftfork.ai/mcp`
- Command line: `npm install -g graftfork` (Node 22.18 or newer), then `graft copies` with the token in GRAFT_TOKEN.
- HTTP API: https://graftfork.ai/api/v1, described at https://graftfork.ai/api/v1/openapi.json
- No token at all: `POST https://graftfork.ai/api/try` with `Content-Type: application/json` and `{"repo": "owner/name"}` tries a public fork. It never pushes and runs no agent.
- No person at all: an agent with a wallet makes its own account with `POST https://graftfork.ai/api/v1/agents` (x402, 12 USD in USDC for 30 days of Premium).

## Tools

A token sees the ones its scopes allow.

- `track_change`: Track a repository with Graft (sync)
- `list_copies`: List tracked copies (read)
- `status`: Copy status (read)
- `sync_now`: Sync now (sync)
- `set_copy`: Set a copy's desired state (sync)
- `take_move`: Take a delivered move (read)
- `revert_move`: Revert a move (sync)
- `send_upstream`: Send a change upstream (read)
- `build_upstream`: Build a change for upstream (sync)
- `upstream_status`: An upstream build (read)
- `track_upstream_pr`: Track an upstream pull request (sync)
- `explain_stop`: Why a sync stayed (read)
- `list_pending_conflicts`: List waiting conflicts (read)
- `get_conflict`: Get a conflict (read)
- `submit_resolution`: Submit a resolved file (resolve)
- `answer_question`: Answer a question (resolve)
- `check_change`: Check a change (sync)
- `check_status`: A change check's result (read)
- `upgrade_dependency`: Upgrade a dependency (sync)
- `get_upgrade`: An upgrade's result (read)
- `regen_connect`: Connect a spec for rebuilds (sync)
- `regen_run`: Rebuild a spec now (sync)
- `regen_set`: Set a spec's desired state (sync)
- `regen_disconnect`: Disconnect a spec (sync)
- `regen_status`: Specs and rebuilds (read)
- `regen_record`: A rebuild's signed record (read)
- `regen_rejudge`: Judge a rebuild's builds again (sync)
- `regen_report`: A spec's report (read)
- `regen_report_refresh`: Grade a spec's record again (sync)
- `regen_draft_check`: Check a branch's record (sync)
- `regen_draft_rebuild`: Rebuild a branch's record (sync)
- `regen_draft_status`: A spec's drafts (read)
- `regen_order_create`: Start a change order (sync)
- `regen_order_write`: Write a change order's files (sync)
- `regen_order_check`: Check a change order (sync)
- `regen_order_rebuild`: Rebuild from a change order (sync)
- `regen_order_status`: A spec's change orders (read)
- `regen_order_discard`: Discard a change order (sync)
- `usage`: Plan and usage (read)
- `webhook_add`: Add a webhook (sync)
- `webhook_list`: Webhooks and deliveries (read)
- `webhook_remove`: Remove a webhook (sync)
- `webhook_test`: Test a webhook (sync)
- `list_fork_alerts`: List fork watch alerts (read)
- `path_policy`: Protected paths (read)
- `org_settings`: An organization's settings (read)
- `org_settings_set`: Change an organization's settings (admin)
- `org_notify_set`: Mute organization email (sync)
- `org_channels`: An organization's team channels (read)
- `org_channel_add`: Add a team channel (admin)
- `org_channel_set`: Change a team channel (admin)
- `org_channel_remove`: Remove a team channel (admin)
- `org_channel_test`: Send a test to a team channel (admin)
- `org_audit_verify`: Check an organization's audit log (read)
- `org_review_queue`: Review queue (read)

## Prices

- Free: $0. 10 syncs a month, 5 copies, the first conflict resolved free once (up to $1.25 of agent work).
- Premium: $12 a month. 40 syncs a month and $6 of agent work included, up to $1.25 a sync. Top-up: $10 adds $7.
- Team: $15 per fork a month, 1 to 20 forks.
- Machine-readable: https://graftfork.ai/pricing.json

## Limits that matter to an agent

- Spend is quoted first. Give a run a ceiling with `max_usd`; if it could cost more, the answer is `price_quote` and nothing is spent.
- Monthly caps. Agent work stops at the plan's included amount (no overage; it waits for the 1st, UTC) and at the token's own monthly cap, which the person sets (402 `token_budget_spent`). The `usage` tool shows what is left.
- Rate: 120 requests a minute per token, 30 of them changes.
- graftfork never pushes to your branches. By default it writes nothing to your repository: the moved branch, `graft/<release>`, waits for you to take it. A pull request is opt-in per copy.
- Nothing an agent sends moves a copy by itself. A resolution is stored, graftfork syncs again, and the tests decide.

## More

- Every tool with its input schema, and every HTTP operation: https://graftfork.ai/llms-full.txt
- OpenAPI: https://graftfork.ai/api/v1/openapi.json
- MCP Server Card: https://graftfork.ai/mcp/server-card
- API catalog: https://graftfork.ai/.well-known/api-catalog
- For people: https://graftfork.com (try it, pricing, results, docs)
- Support: support@graftfork.com, by email only.
