vapor in, liquid out
Keep your model. Keep your harness. Fix everything around them.
Condensate attaches to the harness you already run through two thin seams — one MCP endpoint and one hook — and does the surrounding work: capabilities, identity, steering, honest measurement. Your model traffic goes straight to your provider, untouched.
PostToolUse Grep {"pattern": "registerRoute"} ✓ PostToolUse Grep {"pattern": "registerRoute"} signature repeat x2 PostToolUse Grep {"pattern": "registerRoute"} signature repeat x3 tool_loop fired threshold 3 → template context_note_v1 inject "tool loop detected: Grep has been called 3 times in a row with identical arguments... vary the arguments." PostToolUse Read src/router.ts signature changed — loop broken ledger #4821 fire recorded · digest only, no transcript
How it attaches
Exactly two surfaces.
The client contract is deliberately dumb and deliberately stable. Everything intelligent lives server-side — you never reinstall anything.
01 One MCP endpoint
Add a single server; the whole suite fans in server-side — namespaced, filtered to your principal. Adding a capability never touches your config again.
02 One hook shim
A dependency-free binary your harness's own hook mechanism invokes. Events out, verdicts in. Backend down? It gets out of the way in ~45ms — your agent never depends on condensate being up.
// one server, every capability — fanned in server-side { "mcpServers": { "condensate": { "type": "http", "url": "https://<backend>/mcp", "headers": { "x-api-key": "<executor key>" } } } }
// your harness's own hook mechanism invokes the shim { "hooks": { "PreToolUse": [{ "hooks": [{ "type": "command", "command": "condensate-hook" }] }], "PostToolUse": [{ "hooks": [{ "type": "command", "command": "condensate-hook" }] }], "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "condensate-hook" }] }], "Stop": [{ "hooks": [{ "type": "command", "command": "condensate-hook" }] }] } }
# default mode is observe — nothing intervenes without opt-in. # watch the ledger before you let it steer: # every detector fire AND every suppression is recorded, # append-only, digests not transcripts.
Attaches through the hook mechanism your harness already has. Claude Code today; more adapters landing. Contract: hook-contract.md.
Steering
Your agent loops, stalls, and quits early. Something should notice.
Detectors are pure state machines over hook events. They emit only booleans and scores; the composer speaks only from a fixed template library — there is no path from task content to injected text. Consent defaults to observe; nothing intervenes without opt-in; every fire and every suppression is ledgered.
tool_loop detector
- Same tool, identical canonical args, N times in a row. Signature compare, nothing read.
edit_thrash detector
- The same file rewritten back and forth without the tests moving.
progress_stall detector
- Activity without state change — busy signals, no delta.
premature_stop detector
- Stop event while the session's own task state still shows open work.
filler_inflation detector
- Output growing while information doesn't.
composer templates only
- Verdicts carry a template_id plus scalar params. No free-form generation, ever.
the eval layer refuses to flatter honesty
- sha-bucketed holdout arm runs alongside every steered session
- no outcome claims below 500 pooled sessions — the floor has not been hit, so no numbers are on this page
The suite
Onchain is the first resident, not the product.
The first resident: onchain. 22 EVM tools over MCP — reads, traces, logs, ABIs, verified source, address labels, cross-chain status. BYOK and self-host free, or metered per call from a wallet via x402. Docs: byok.md · x402-gateway.md · endpoint at onchain.condensate.dev/mcp.
The generalization: executor-held connections mean any integration you register rides the same endpoint, same auth, same metering. Onchain proves the plane.
Trust
never your model traffic
- Routing is advisory only. Requests terminate at your own subscription endpoints under your own auth. Condensate is not in the request path — by design decision, not configuration.
content-free by construction
- Prompt text never persists and never reaches inference. Detectors keep digests, not transcripts. Steering text comes from templates, never from your content.
fail-open
- Backend unreachable means your agent runs exactly as it did before condensate existed. The shim's job is to get out of the way in ~45ms.
Identity is bought (WorkOS); custody is owned (executor.sh, MIT, self-hosted). Buy identity, own custody.
What ships today vs in flight
| component | status | proof |
|---|---|---|
| hook shim + contract v1 | shipped | merged; fail-open ~45ms verified |
| detectors + consent + ledger | shipped | merged: detectors, consent tiers, append-only ledger, checkpoints, holdout, eval harness |
| identity + executor connections | shipped | WorkOS merged, verified live against staging; full local emulation with zero external accounts |
| model-routing + executor-auth | shipped | work-kind→model table extracted byte-faithful; fail-closed key validation |
| onchain MCP suite | shipped | live: gateway, x402 metering, BYOK, self-host |
| harness-agnostic core + adapters | landing | proven in review, merging now; Claude Code byte-compat proven |
| /mcp aggregation gateway | landing | proven in review, merging now; live-proven: 30 tools, upstream-failure isolation |
This board mirrors the architecture doc's status board. The site never states more than it does.
Get started
Add the endpoint, install the hook, and stop there. Default mode is observe. Watch the ledger before you let it steer. Config for both surfaces is in how it attaches above.