Stop overpaying
your coding agent.
Kit is a coding agent runtime. Each turn, the model writes one short program that reads files, runs tests, edits, retries, and delegates. Kit runs it in one round trip and returns the result. Half the tokens and a third of the time of Claude Code and Codex CLI, measured on sixteen merged production pull requests.
curl -fsSL https://kitagent.dev/install.sh | shEvery tool call is a round trip. Kit makes it one.
Most harnesses give the model dozens of tools and pay a full model request for each call. The conversation is re-sent every time, and it grows every time. Kit gives the model one tool, compose, whose argument is a program. The program does the calling.
Measured on production work, not benchmarks. Sixteen pull requests across admin dashboards, billing, auth, telemetry, integrations, and CI, all merged, July to August 2026.
| Median per hand-written line | Kit | Codex CLI | Claude Code |
|---|---|---|---|
| Input tokens | 49.7k | 113k | 99.6k |
| Output tokens | 274 | 321 | 325 |
| Active time | 0.13 min | 0.31 min | 0.31 min |
| User messages per session | 5 | 14 | 11 |
PRs between 300 and 1000 lines. Two Kit runs merged from a single message.
A program is a better tool than a toolbox.
The program is written in Runlet, a small dataflow language. Bindings that do not depend on each other run concurrently. A value reference creates an order. after creates one without passing data.
Failures are handled in the program, not in another model turn. Aboundary retry repeats transient work, andfail() raises an error the caller can catch. The result is structured data, so the model reads a value, not a wall of stdout.
Kit validates every input against the exact tool schema. Missing fields, extra fields, and wrong types are rejected rather than guessed at. Edits are hunks anchored on context, applied atomically, with no Git required.
- shell
- edit
- subagent
- prompt
- fork
- close
- tool_search
- tool_schema
- tool
- auth
- skill
- a2a
- docs
review = boundary retry 2 { return a2a({ url: reviewer, prompt: "Review this diff for unsafe migrations." }) } catch err { return fail("REVIEW_FAILED", err.code + ": " + err.message) } checks = for cmd in ["cargo fmt --check", "cargo clippy", "cargo test"] { return { cmd, ok: shell({ command: cmd }).success } } notes = after checks { return edit({ path: "CHANGELOG.md", hunks: [entry] }) } return { review, checks, notes: notes.applied }
review and the three checks run at the same time. notes waits for all checks, then writes once.
design = subagent({ name: "Visual Designer", harness: "acp.claude", model: "designer", prompt: "Inspect the dashboard. Propose one direction.", output_schema: { type: "object", required: ["direction", "risks"], … } }) refined = prompt({ subagent: design, prompt: "Make it concrete enough to implement." }) alt = fork({ subagent: refined, prompt: "Explore a bolder alternative." }) return { refined: refined.output, alternative: alt.output, active: subagents({}) }
Kit stays the orchestrator. The design work runs in Claude over ACP, the implementation stays in Kit, and both results land in the same program.
Subagents are values.
A subagent is not a fire-and-forget task. It is a handle with an id, an output, and a generation. Continue it with prompt. Branch it withfork. Stop it with close. A stale generation is rejected, so two continuations never race on one session.
The harness is a config line. Kit ships acp.kit, and any agent that speaks ACP v1 over stdio plugs in the same way: Claude Code, Codex, Cursor, or your own. Kit reads each harness's capabilities at runtime and uses nativesession/fork when it is advertised.
Ask for JSON that matches a schema and Kit enforces it. Each child starts with only the prompt you give it, never the parent's history. Depth is capped at two and each session may hold 120 live subagents, so a runaway tree cannot happen.
- acp.kit
- built in, inherits root, instructions, provider, and MCP config
- acp.claude
- Claude Code through the official ACP adapter
- acp.codex
- Codex through the official ACP adapter
- acp.cursor
- cursor-agent acp
The terminal is one client. The runtime is the product.
kit tui is an ACP client talking to kit serve. So is an editor. So is your app. The same binary runs headless on a server, holds long-lived sessions on disk, and answers over HTTP, SSE, WebSocket, or A2A. Build an assistant on it and the context-efficient loop comes for free.
- kit tuiACP v2 over stdio
- Zed, or any ACP editorkit acp
- Your assistant or appHTTP/SSE or WebSocket at /acp
- Another agentA2A v1, both directions
- ChatGPT subscriptionnative OAuth, PKCE, 24-hour retry
- OpenRouterlive catalog, any model
- Speakeasy AI Control Planeshared threads, governance
- Sessions as append-only JSONL, synced before use
- Automatic compaction at 80% of the window
- Crash-safe locks, resumable from any client
- MCP servers, Agent Skills, Agent Plugins
- OpenTelemetry spans for every session and child
Run it as a daemon
No stdin, one bearer token file, graceful drain on SIGTERM. Put it behind the network boundary you already trust.
kit serve --root /srv/app --remote-acp --no-stdio --http 0.0.0.0:8081 --server-credential-file /private/tokenOr as a container
Headless images for amd64 and arm64, in slim, bookworm, and alpine variants. They serve ACP, A2A, and one-shot prompts.
docker run --rm -i -v "$PWD:/workspace" -v ~/.kit:/home/kit/.kit ghcr.io/speakeasy-api/kit:latest acp --credential-store fileOr inside an editor
Any ACP-capable editor can launch Kit as an external agent. In Zed, add this to settings.json.
{"agent_servers": {"Kit": {"command": "kit", "args": ["acp", "--root", "."]}}}Kit is a runtime, not a security boundary. It has no permissions framework, no sandbox, and no web UI. Run it inside the sandbox, container, or VM you already use, and read the trust model first.
Try it in three commands.
Nothing to sign up for. Bring a ChatGPT subscription, an OpenRouter key, or a Speakeasy account.
- 1
Install
curl -fsSL https://kitagent.dev/install.sh | shVerified against SHA256SUMS, installed to ~/.local/bin. Also available as mise use -g github:speakeasy-api/kit.
- 2
Write a config and log in
kit init && kit auth login openaiOr kit auth login openrouter and kit auth login speakeasy. Switch models mid-session with /model.
- 3
Open a project
kit tui --root /path/to/projectOne-shot: kit prompt --root . "Summarize this repo in three lines". It prints a session id you can resume later.
Coming from Claude Code or Codex?
Your CLAUDE.md, skills, and MCP servers carry over. Kit loadsAGENTS.md chains, .agents/skills, and.mcp.json. There is no import command; the agent does the migration and shows you conflicts first. Start kit tui in the project and paste:
Help me migrate my Claude Code and Codex project instructions, skills, and MCP servers into Kit. Consult your version-matched bundled documentation for the migration procedure. Preserve my source files, do not copy credentials, and show me any conflicts before changing an existing Kit file.