Kit is a coding agent runtime. It gives the model one tool for writing and running programs.
Kit provides a terminal client, an ACP server, an A2A endpoint, and a subagent orchestrator in one static binary.
curl -fsSL https://raw.githubusercontent.com/speakeasy-api/kit/main/install.sh | sh
kit init && kit auth login openai && kit tuiMost agent harnesses expose many tools and require one model round trip for each call. Kit exposes one tool: compose. The compose argument is a short program in Runlet. In one round trip, the program can read files, run tests, apply edits, retry failed commands, delegate work to subagents, and return structured data.
Fewer model round trips repeat less context and complete more work in each request. In size-matched production tasks, Kit used approximately half the input tokens and active time per hand-written line of Codex CLI or Claude Code (comparison).
- One tool, unlimited composition. The model receives one tool:
compose. Acomposeprogram can callshell,edit,subagent,prompt,fork,tool_search,tool,auth,skill,a2a, anddocs. Independent calls run concurrently. Use data dependencies orafterblocks to control execution order. Useboundary retry Nandfail()to handle errors in the program. - Reusable subagents. A subagent is a reusable value. You can continue, fork, inspect, and close a subagent. You can require JSON that matches a schema. You can also use Claude Code, Codex, Cursor, or Kit as the subagent harness over ACP.
- Open protocols. Kit supports ACP v1 and v2 over stdio, HTTP/SSE, and WebSocket. Kit supports A2A v1 in both directions. It also supports MCP, Agent Skills, and Agent Plugin packages.
- Long sessions. Kit synchronizes each append-only JSONL transcript item to disk before it accepts the item. It compacts context automatically at 80% of the context window. You can resume a session from
tui,prompt, or any ACP client. Kit also uses crash-safe locks. It retries eligibleopenai-subscriptionfailures for up to 24 hours. - Model choice. Kit supports ChatGPT subscriptions through native OAuth. It also supports models through OpenRouter and the Speakeasy AI Control Plane. Use
/modelto change the model during a session. - Small runtime. Kit has no permissions framework, sandbox, or web UI. The
--rootoption sets the working directory. Kit is a runtime, not a security boundary. Run Kit inside a security boundary that you trust. See the trust model.
curl -fsSL https://raw.githubusercontent.com/speakeasy-api/kit/main/install.sh | shThe installation script downloads the release archive. It verifies the archive against SHA256SUMS and installs Kit in ~/.local/bin. Set KIT_VERSION=v0.1.108 to select a release. Set KIT_INSTALL_DIR to change the destination.
mise use -g github:speakeasy-api/kit # latest
mise use -g github:speakeasy-api/kit@0.1.108docker run --rm -it -v "$PWD:/workspace" -v ~/.kit:/home/kit/.kit \
ghcr.io/speakeasy-api/kit:latest tui --credential-store fileKit publishes images for linux/amd64 and linux/arm64. Each image has three variants: slim, bookworm, and alpine. The default slim variant uses Debian slim. The alpine variant uses a native musl build.
Each release adds the tags v<version>, v<version>-slim, v<version>-bookworm, and v<version>-alpine. The newest stable release also updates the latest, slim, bookworm, and alpine tags.
Images run as the non-root kit user with UID 1000. The working directory is /workspace. Images do not include Git or language toolchains. Extend the image if you need these tools:
FROM ghcr.io/speakeasy-api/kit:latest
USER root
RUN apt-get update && apt-get install -y --no-install-recommends git ripgrep && rm -rf /var/lib/apt/lists/*
USER kitTo build Kit from source, use the Rust toolchain specified in rust-toolchain.toml.
git clone https://github.com/speakeasy-api/kit && cd kit
cargo build --release # target/release/kit
scripts/sign-release.sh # macOS only: sign before using the Keychain credential storeRelease binaries for macOS are signed and notarized under com.speakeasy.kit. See Releasing.
kit init # ~/.kit/config.toml + ~/.kit/mcp.json
kit auth login openai # ChatGPT subscription, native OAuth (PKCE)
kit tui --root /path/to/project # interactive
kit prompt --root /path/to/project "Summarize this repo in three lines" # one-shot, prints session_id
kit acp --root /path/to/project # ACP over stdio for editors and clients
kit serve --root /path/to/project --remote-acp --no-a2a --no-stdio --http 0.0.0.0:8081 \
--server-credential-file /private/token # headless daemonOpenRouter and Speakeasy use the same login process. Run kit auth login openrouter or kit auth login speakeasy. Then add --provider openrouter --model anthropic/claude-sonnet-5 to the Kit command that you run. Providers and MCP servers share one credential backend (--credential-store keychain|file|memory).
The model writes a Runlet program. While the program runs, Kit shows the source in the transcript. Kit shows the status of each call and binding. Kit also shows loop and retry counters. When the program finishes, Kit replaces the source with the result.
tests = shell({ command: "python3 -m unittest -q" })
counts = for path in text.split(text.trim(shell({ command: "ls *.py" }).stdout), "\n") {
return { path, lines: number.parse(text.trim(shell({ command: "wc -l < " + path }).stdout)) }
}
fixed = after tests { return edit({ path: "calc.py", hunks: [ ... ] }) }
return { tests: tests.success, counts, fixed }
tests and counts run concurrently. The fixed binding waits for tests because it uses after. A hunk edit uses context_before, old, and context_after as anchors. The anchors must match exactly once. Hunk edits do not require Git. Each file edit is atomic and preserves permissions and CRLF line endings. See Compose and local tools.
A subagent is a Runlet value with an id, output, and generation. Use prompt to continue the session. Use fork to create a branch. Use subagents({}) to list active subagents. Use close to stop a subagent. Kit rejects a stale generation. This check prevents two continuations from updating one session at the same time.
review = subagent({
harness: "acp.claude",
prompt: "Review calc.py for edge cases.",
output_schema: { type: "object", properties: { issues: { type: "array", items: { type: "string" } } }, required: ["issues"] }
})
ranked = prompt({ subagent: review, prompt: "Rank those issues by severity." })
alt = fork({ subagent: ranked, prompt: "Now argue the opposite ranking." })
return { ranked: ranked.output, alt: alt.output, active: subagents({}) }
- Any ACP harness. Kit includes
acp.kit. You can add Claude Code, Codex, Cursor, or another harness that supports ACP v1 over stdio. The TOML configuration below requires four lines. Kit reads each harness'sinitializeresponse at runtime. Kit uses nativesession/forkwhen the harness advertises it. Otherwise, Kit creates an isolated transcript fork for Kit children. - Structured output. Set
output_schemaon any call that produces a turn. If a reply does not match the schema, Kit returns the raw text and advances the generation. The nextpromptcan repair the reply. - Per-harness model aliases.
[subagent.harnesses."acp.claude".models] architect = "opus"lets the model requestmodel: "architect"without knowing the harness namespace. Anallow_model_overrideslist restricts the available models. - Bounded resources. Subagent depth is limited to 2. Each session can have 120 live subagents. The startup handshake has a 30-second limit. Kit rejects or cancels permission requests from headless children. Kit never approves these requests automatically.
- Explicit context. Each child starts without the parent conversation history and receives only the prompt that you provide. An
acp.kitchild also inherits the working directory,AGENTS.mdchain, provider, MCP configuration, and credentials. Skills load into a child on demand withskill({ name }).
See Reusable subagents and ACP harnesses.
Set background: true to detach a compose program immediately. Set background: 60 to keep the program in the foreground for one minute before detachment. The turn ends, but the conversation continues. Kit adds the result to the session when the program finishes. In the TUI, use ⌘B to move the newest running call to the background. Use ^K to stop the selected call. The model can stop a call with close({ call_id }).
While the agent works, press Enter to add a message to the current turn through ACP v2 steer. Kit does not queue the message for the next turn. Press Esc or ^C to interrupt a running turn. When Kit is idle, press ^C to clear a nonempty prompt. Press ^C again to exit after the prompt is empty.
| Provider | Login | Notes |
|---|---|---|
openai-subscription |
kit auth login openai |
Native ChatGPT OAuth uses PKCE, state, nonce, and RS256 tokens validated against OpenAI's JWKS. The callback uses loopback only. Kit refreshes tokens five minutes before expiry and synchronizes refreshes across processes. |
openrouter |
kit auth login openrouter or OPENROUTER_API_KEY |
Kit loads a live model catalog. It uses context-window data for the gauge and compaction. |
speakeasy |
kit auth login speakeasy |
Kit uses the Speakeasy AI Control Plane. Kit maps its session ID to the Gram chat ID so that a resumed conversation stays in one thread. |
/model sonnet switches the live session at the next safe turn boundary. Press Tab in the picker to also update ~/.kit/config.toml. Use /effort low|medium|high|default to change the reasoning effort.
You do not need to restart Kit after you add a server. Kit merges plugins, configured mcp_config, project-root .mcp.json, and --mcp-config in that order, then reloads every named file before each tool_search and auth call. Kit waits for new servers to finish initialization before ranking tools.
Kit detects OAuth from the server's Bearer challenge. An auth block is not necessary. The model calls auth({ name }) and gives you a URL. After you complete the browser flow, Kit resumes the session. If an access token expires, Kit refreshes the token and repeats the rejected call once.
{ "mcpServers": {
"exa": { "url": "https://mcp.exa.ai/mcp", "description": "Hosted web search" },
"linear": { "url": "https://mcp.linear.app/mcp", "description": "Issues and projects" },
"local": { "command": "my-mcp-server", "args": ["--stdio"] } } }See MCP.
Kit loads validated Agent Plugin packages from a local directory or a SHA-256-pinned archive. Kit supports ZIP, tar.gz, tar, and GitHub tag archives.
Plugin skills become available in the skill catalog. Kit starts plugin stdio and streamable-http MCP servers without an mcp.json file.
Kit discovers Agent Skills in <root>/.agents/skills and ~/.agents/skills. Kit initially shows only skill names and descriptions. Kit loads the full SKILL.md only when requested.
[plugins.review]
source = "path"
path = "./plugins/review"
[plugins.gram]
source = "archive"
url = "https://github.com/speakeasy-api/gram-plugin/archive/refs/tags/v1.2.0.tar.gz"
sha256 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
subdir = "plugin"Kit stores each conversation as an append-only JSONL transcript in ~/.kit/sessions. Kit synchronizes each item to disk before it adds the item to memory.
You can resume a session from the TUI or with the --resume option of kit prompt. ACP clients can use session/load or session/resume.
When the provider reports 80% context-window use, Kit converts older history into a structured note. Kit persists the replacement. Kit retains the bootstrap instructions and a tool-safe tail. Use /compact to compact the history on demand.
- Crash-safe. Kit permits only one live process to modify each session. Kit reclaims a stale lock only when the operating system confirms that no process holds it. Use
--forceonly with--resume <session-id>to reclaim a stale lock. The TUI also reclaims a stale lock when you switch sessions. Kit replaces an incomplete tool call with an explicit synthetic error result. - OpenAI subscription retries. Kit retries eligible transient failures with deterministic full-jitter backoff. Eligible failures include 408, 425, 429, 500, 502, 503, 504, and 529 responses. They also include transport failures and stream failures before the first token. The retry deadline is 24 hours. Kit reuses the same idempotency key.
openai-subscriptiondoes not retry authentication failures, quota failures, or failures after output starts. - Daemon operation.
kit serve --remote-acp --no-stdioruns independently of stdin.SIGINTandSIGTERMstop new connections, interrupt live sessions, and allow five seconds for draining. One bearer token file protects the HTTP listener. - Observability. Set
otel_endpoint = "http://localhost:4317"to export AgentKit GenAI spans through OTLP/gRPC. Kit exports spans for the main agent, ACP sessions, nested children, and the compactor. Kit disables message-content capture by default. Kit limits captured message content when you enable it.
kit tui starts kit serve and communicates with the server through ACP. The terminal client uses the same protocol as an editor. You can drag and drop image and audio attachments into the terminal. Terminals that support Kitty graphics, Sixel, or the iTerm2 inline image protocol show inline previews.
Click a code block to copy its contents. Use ^y to copy the last response as Markdown through OSC 52. Use ^l and ^t to toggle the agent log and reasoning views. Use ^o to collapse tool output. See TUI and sessions for the complete key table.
Any ACP-compatible client can use Kit. Use kit acp for stdio. Use kit serve --remote-acp for HTTP/SSE or WebSocket connections at /acp. V2-only clients can use /acp/v2. Kit also supports A2A v1 on the same listener. Kit can call other A2A agents with a2a({ url, prompt }).
kit init writes this configuration. Command-line flags override the configuration.
provider = "openai-subscription" # openrouter | speakeasy
model = "gpt-5.6-sol"
reasoning_effort = "high"
credential_store = "file" # memory | keychain | file
credential_dir = "~/.kit/credentials"
mcp_config = "~/.kit/mcp.json"
otel_endpoint = "http://localhost:4317"
[acp.claude]
command = "npx"
args = ["-y", "@agentclientprotocol/claude-agent-acp@0.69.0"]
permissions = "deny" # deny (default) | cancel — Kit never auto-approves
[acp.codex]
command = "npx"
args = ["-y", "@agentclientprotocol/codex-acp@1.4.0"]
[acp.cursor]
command = "cursor-agent"
args = ["acp"]
[subagent]
harness = "acp.kit"
[subagent.harnesses."acp.claude".models]
architect = "opus"
[subagent.harnesses."acp.kit".models]
flash = "openrouter:openai/gpt-5.6-luna"Kit loads AGENTS.md files from the working directory and its ancestors as project instructions. See Getting started and configuration for all other settings.
Kit, Codex CLI, and Claude Code were used to complete production engineering tasks during July–August 2026. The observed work covered admin dashboards and billing flows, authentication and session fixes, telemetry, external integrations, and CI/build performance. All 16 resulting pull requests merged.
| Median per hand-written line (300–1000-line PRs) | Kit | Codex CLI | Claude Code |
|---|---|---|---|
| Input tokens | Best (49.7k) | 127% more (113k) | 100% more (99.6k) |
| Output tokens | Best (274) | 17% more (321) | 19% more (325) |
| Active time | Best (0.13 min) | 138% more (0.31 min) | 138% more (0.31 min) |
| User messages per session | Best (5) | 180% more (14) | 120% more (11) |
Kit used the fewest tokens, took the least active time, and needed the least steering. Two Kit runs merged from a single message.
- Getting started and configuration
- Compose and local tools
- Reusable subagents and ACP harnesses
- MCP
- Agent Plugins
- TUI and sessions
- Security, limits, and troubleshooting
- Releasing · Third-party notices
Kit compiles the same documentation into the binary. The agent searches this documentation with docs({ query }).
Report issues at speakeasy-api/kit/issues. Include the Kit version and follow the reporting guide. An agent must ask for your permission before it files an issue for you.







