dense CLI
One CLI for every coding agent you run.
dense puts Claude Code, Codex, and
OpenCode through condense: install once, log in once. dense keeps the
machine signed in and injects the right base URL and credentials into
each run. No key swap, no per-run configuration. Wiring per agent is
in Agents. It's
open source; releases are built from tagged source on GitHub Actions.
Install
bashcurl -fsSL https://cli.condense.chat/unix | sh
powershellirm https://cli.condense.chat/nt | iex
One install covers every agent. The installer drops the
dense binary on your PATH and hands off to
dense setup, which logs you in; the same
login and token then back Claude Code, Codex, and OpenCode. There is
nothing to install per agent, and dense doesn't bundle the agents
themselves: it routes the ones you already have.
Setup also offers to route the bare
claude command through dense, so you keep
typing claude and it just goes through
condense.
Log in
Login is a browser device flow:
dense login
opens
login.condense.chat with a one-time code,
no key copy/paste. The token is stored under
~/.config/dense/
(%APPDATA%\dense on Windows) with
owner-only permissions.
How it works
-
dense claude <args>resolves the realclaudebinary and runs it as a child process. Your arguments, stdin/stdout, Ctrl-C, and exit code all belong to Claude Code. -
On the child process only (your shell environment is never
modified), dense sets
ANTHROPIC_BASE_URL=https://api.condense.chat/anthropicand injects its credentials (X-Condense-Auth-Token,X-Condense-Session-Id) viaANTHROPIC_CUSTOM_HEADERS. Headers you already set there are preserved. -
Your existing Claude auth keeps working:
ANTHROPIC_API_KEYforwards through verbatim as the upstream key.
dense persist places a thin shim ahead of
the real claude on your PATH, so the bare
command routes through dense. The real binary is never moved or
modified; dense unpersist removes the shim
instantly.
Codex and OpenCode don't need a wrapper process: their own config points them at the same proxy, and every request carries the same headers. See Agents.
Commands
| Command | What it does |
|---|---|
dense login |
Authenticate this machine (browser device flow). |
dense logout |
Clear stored credentials. |
dense claude <args> |
Run Claude Code through the proxy; args pass straight through. |
dense persist [tools…] |
Shim the named tools (no args: all) so the bare command routes through dense. Non-destructive. |
dense unpersist [tools…] |
Remove the shims. |
dense status |
Current login, endpoint, and credential locations. |
dense doctor |
Verify the install is wired correctly. |
dense self update |
Update the binary in place (sha256-verified download from GitHub releases). |
dense self uninstall |
Remove dense, its shims, and PATH wiring. Credentials are kept. |
Binaries ship for macOS and Linux (x86_64 and aarch64) and Windows; other platforms build from source.
Agents
Claude Code, Codex, and OpenCode all reach the same proxy; only the
wiring differs. Claude Code runs through the
dense binary itself. Codex and OpenCode
point at the matching
dialect with a one-time
config and send the condense key in
X-Condense-Auth-Token.
| Agent | Wiring | How |
|---|---|---|
| Claude Code | dense binary |
dense claude, or dense persist and
keep typing claude.
|
| Codex | One-time config |
Point ~/.codex/config.toml at the OpenAI Responses
dialect (below). dense codex will automate this.
|
| OpenCode | One-time config |
Point the provider baseURL at the matching dialect
in opencode.json (below).
|
Claude Code
Claude Code needs no config, it runs through the
dense binary directly.
dense claude <args> launches it with
the condense base URL and credentials injected, or
dense persist puts a shim ahead of
claude on your PATH so the bare command
routes through condense. Your existing
ANTHROPIC_API_KEY forwards through as the
upstream key.
Codex
Codex speaks the Responses API, which condense serves at
/openai/v1/responses. Define condense as a
model provider and select it:
toml# ~/.codex/config.toml
model_provider = "condense"
[model_providers.condense]
name = "condense"
base_url = "https://api.condense.chat/openai/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"
env_http_headers = { "X-Condense-Auth-Token" = "CONDENSE_AUTH_TOKEN" }
Export
CONDENSE_AUTH_TOKEN=ak_… alongside
your OPENAI_API_KEY. Requests
authenticated with a ChatGPT login instead of an
sk- key are detected and forwarded to the
ChatGPT Codex backend automatically.
OpenCode
OpenCode takes a per-provider baseURL and
headers. Point the provider you use at the
matching condense dialect:
json{
"$schema": "https://opencode.ai/config.json",
"provider": {
"anthropic": {
"options": {
"baseURL": "https://api.condense.chat/anthropic/v1",
"headers": {
"X-Condense-Auth-Token": "{env:CONDENSE_AUTH_TOKEN}"
}
}
}
}
}
For OpenAI models, set the
openai provider's
baseURL to
https://api.condense.chat/openai/v1 the
same way.
dense drives the same public API as any other client. Base URL, authentication, per-request headers, and error shapes are documented in the API reference.