Documentation
Hydra has three surfaces, a CLI, an interactive TUI cockpit, and a desktop app: sitting in front of every AI model on your machine. This covers all three, the tools it plugs into, and every command: what it does, how it works, and how to use it. The deep math lives on First Principles.
Overview discover → route → check → observe
Hydra picks the model best suited to each task, and can check the answer before you rely on it. It discovers every model you can reach (hosted APIs, local servers, CLI agents), routes each request to a model measured capable at that task type (today the lowest-cost one that clears the bar, with stronger models as the fallback chain), checks the answer with verifiers when you ask it to, and logs every request. No single vendor is privileged.
discover route execute + observe ┌───────────┐ ┌────────────────┐ ┌──────────────┐ │ PATH scan │─┐ │ policy gate │ │ CLI agents │ claude·codex·cursor │ env keys │─┼▶│ capability rank│─▶ │ API models │ openai·gemini·groq │ port scan │─┘ │ fallback chain │ │ local models │ ollama·lm studio └───────────┘ └────────────────┘ └──────────────┘ │ │ ~1.1µs/decision cost.jsonl · calibration · verdicts
install one binary, no runtime
Pure Go, single static binary.
# Homebrew (recommended) brew install ankit373/hydra/hyctl # npm · or run once, no install: npx hyctl npm install -g hyctl # pip pip install hyctl # Standalone installer curl -fsSL https://raw.githubusercontent.com/ankit373/hydra/main/install.sh | sh # From source (Go 1.26+) git clone https://github.com/ankit373/hydra.git && cd hydra go build -o hyctl ./cmd/hydra
The CLI shipped the whole interface
Everything Hydra does runs through the single hyctl binary: requests, discovery, verification, graph and cost. Scriptable, CI-friendly, zero daemon.
prompt → STANDARD → T5 Primary: gemini pro score 82 Fallback: openrouter score 76 ← if primary rate-limits Local: ollama/qwen3 ← always available, $0 ✔ chain resolved · nothing dispatched (dry-run)
hyctl tui shipped interactive cockpit
A terminal cockpit you operate: type a task, press enter, and it runs. Tab cycles six views: Chat, Agents, Models, Activity, Usage, Audit. Every frame below is a real hyctl tui --snapshot, rendered by the binary itself.
HYDRA chat agents models activity usage audit session $0.0000 · context ▱▱▱▱▱▱▱▱ 0% ──────────────────────────────────────────────────────────────────────────────────────────────────── CONTEXT BUDGET │ 15 models found by the scan. │ CODE · go ░░░░░░░░░░░░░░░ │ │ 1 // paginated users endpoint claude 0% │ Type a task and press enter. shift+tab│ 2 func (s *Server) ListUsers(w ht… │ mode · ctrl+t thread · ? shortcuts · │ 3 page := parsePage(r.URL.Que… MODELS │ :q quits. │ 4 users, err := s.repo.Users(… ✓ Claude Code │ ❯ add pagination to the users endpoint│ 5 if err != nil { ✓ Claude Opus 4.… │ auto-routed · standard work → T7 │ 6 http.Error(w, err.Error… ✓ OpenAI Codex │ qwen2.5-coder · single │ 7 return ✓ Claude Sonnet … │ why code edit, standard scope, no │ 8 } ✓ Gemini 2.0 Fla… │ PII │ 9 json.NewEncoder(w).Encode(u… ✓ Antigravity │ plan ✓ 3 steps · edit ✓ users.go │ 10 } ✓ …1 Pro (High) │ +24/−6 · tests ✓ go test ./... │ ✓ …1 Pro (Low) │ /diff · /undo · /open │ ✓ …5 Flash (High) │ ✓ done 3.2s · $0.0041 est · trace │ ✓ …5 Flash (Medi… │ demo0000, enter opens the trace │ ✓ …5 Flash (Low) │ │ ✓ Qwen2.5-Coder:… │ │ ✓ qwen3:0.6b (Ol… │ │ ✗ Ollama │ │ ✗ nomic-embed-te… │ │ │ │ MODE │ │ auto │ │ │ ╭────────────────────────────────────╮│ │ │ Auto ▾ what do you need done?, ││ │ │ enter runs it ││ │ ╰────────────────────────────────────╯│ ctrl+t thread enter send shift+tab mode ctrl+o route ? shortcuts mode auto · route auto
HYDRA chat agents models activity usage audit session $0.0000 · context ▱▱▱▱▱▱▱▱ 0% ──────────────────────────────────────────────────────────────────────────────────────────────────── ╭─────────────────────────────────────────────────────────────────╮ ╭─────────────────────────────╮ │ MODELS · by provider/server │ │ SERVER │ │ │ │ │ │ ▸ ▾ ● anthropic 1 model │ │ anthropic │ │ ● Claude Code T1 │ │ │ │ ▾ ● antigravity 8 models │ │ models 1 (1 routable) │ │ ● Claude Opus 4.6 (Thin… T2 │ │ state up │ │ ● Claude Sonnet 4.6 (Th… T3 │ ╰─────────────────────────────╯ │ ● Antigravity T4 │ │ ● Gemini 3.1 Pro (High) T5 │ │ ● Gemini 3.1 Pro (Low) T6 │ │ ● …3.8 Flash (High) T7 │ │ ● …3.8 Flash (Medium) T8 │ │ ● …3.8 Flash (Low) T9 │ │ ▾ ● openai 1 model │ │ ● OpenAI Codex T3 │ │ ▾ ● Ollama 3 models │ │ ● Qwen2.5-Coder:7b T10 │ │ ● qwen3:0.6b T10 │ │ ◌ nomic-embed-text:late… T10 embeddings only, never routed │ │ │ │ ● up · ○ down (children unavailable) · ◌ not routable │ ╰─────────────────────────────────────────────────────────────────╯ j/k move enter detail space collapse p pin ? shortcuts scanned 0s ago · r rescan
HYDRA chat agents models activity usage audit session $0.0000 · context ▱▱▱▱▱▱▱▱ 0% ──────────────────────────────────────────────────────────────────────────────────────────────────── ╭─────────────────────────────────────────────────────────────────╮ │ MODEL SCORECARD · calibration │ │ │ │ source domain n sens spec D nats │ │ claude trust-b… 10 0.83 0.50 0.24 │ │ qwen trust-b… 9 0.88 0.20 0.02 │ │ claude trust-b… 5 0.86 0.50 0.28 │ │ ollama/Qwen2.5-Code… trust-b… 5 0.86 0.50 0.28 │ │ qwen trust-b… 5 0.86 0.50 0.28 │ │ test-src test-do… 1 0.67 0.50 0.06 │ │ verifier:go gotest 1 0.67 0.50 0.06 │ │ │ │ consensus checks 0.50 mean confidence over 16 │ │ cleared without review 0% │ │ same-family agreement acme ×0.14 (J=0.86), echo, not evidence │ ╰─────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────╮ │ AUDIT LOG │ │ │ │ chain BROKEN · 635 events, 599 chained │ │ today 89 allowed · 0 denied │ │ all-time ████████████████████ 635 │ ╰────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────╮ │ GUARDRAILS │ │ │ ↓ 9 more j/k move enter resolve v verify i ignore ? shortcuts chain BROKEN · checked 14:20:08
Chat executes: the route line names the routing level, model and strategy the router picked and why, then the proof strip reports what the run planned, edited and verified. shift+tab cycles the modes, Auto (plan → edit → run your tests → fix → repeat), Plan, Edit, Ask, and ctrl+o overrides where the next task runs without changing what it does. Models is the discovered estate by provider, each model at its routing level, with a server's children greyed when the server itself is down. Audit carries the calibration scorecard, the hash-chained log's integrity, the guardrails actually in force, and anything waiting on a human. Agents, Activity and Usage cover work in flight, per-run traces, and where the money went. ? lists every key, rendered from the keymap itself so it cannot drift.
An answer appears as it arrives rather than all at once when the task finishes, so a slow model and a stuck one no longer look the same. The frame repaints five times a second, which is also what coalesces the stream: deltas land every ~20ms and the render never runs per delta.
When a model gives up part-way through, its partial output collapses to one dim line naming the model and the reason, so it cannot be mistaken for the answer, and e expands it again. The text is kept, not re-fetched. Only plain routing streams: a swarm has several models answering at once and consensus picks by judge after N replies, so neither has a single stream to show.
hyctl tui # tab cycles views · shift+tab modes · ctrl+o routing · e expands a # collapsed partial · ? all keys · :q quit hyctl tui --snapshot --view 0..5 # render one static frame
The desktop app download point-and-click cockpit
A native window over the same engine, Wails v2 + React, in desktop/. It opens on the chat, with the other views behind an icon rail. Every release ships a build for macOS, Windows and Linux. Click the sidebar: the views swap live.
# Download from the releases page: hydra-desktop_<version>_darwin_universal.zip # macOS, Intel + Apple Silicon hydra-desktop_<version>_windows_amd64.zip # Windows hydra-desktop_<version>_linux_amd64.tar.gz # Linux # Every artifact ships a .sha256 beside it. Verify before you run: shasum -a 256 -c hydra-desktop_<version>_darwin_universal.zip.sha256 # macOS sha256sum -c hydra-desktop_<version>_linux_amd64.tar.gz.sha256 # Linux # Windows (PowerShell): $f = "hydra-desktop_<version>_windows_amd64.zip" (Get-FileHash $f -Algorithm SHA256).Hash -eq (Get-Content "$f.sha256").Split(' ')[0] # Or build it yourself: go install github.com/wailsapp/wails/v2/cmd/wails@latest cd desktop && wails build # → desktop/build/bin/Hydra.app
How discovery works no plugins, no config
Hydra finds every model on your machine across three channels in under two seconds, scores each with a CapScore, and routes across all of them. Provider-neutral: it routes away from expensive models, never toward a favored vendor.
PATH scan
Finds installed coding agents & CLIs, Claude Code, Codex, Cursor, Gemini CLI, Copilot and more.
Env vars
Detects keys for the major API providers and registers each as a routable model.
Port scan
Queries Ollama (11434), LM Studio (1234), a LiteLLM proxy (4000) and a llama.cpp server (8080), and enumerates every model each one serves.
Coding agents & CLIs discovered on $PATH
Whatever agent you drive Hydra with becomes the orchestrator; the rest are interchangeable sources it can send work to. Hydra shells out to each through its native executor.
--confidence target, or the validator hyctl edit runs).API providers discovered from env keys
Set a provider's API key and it becomes a routable model automatically, through the OpenAI-compatible or provider-native HTTP executor. No config file to touch.
export ANTHROPIC_API_KEY=sk-… # then: hyctl probe # it shows up as a scored model
A key alone gives one routing choice: a single model. Hydra already prices and scores OpenRouter's whole catalogue, so naming models turns each into its own routing choice the router chooses between. Admission is explicit: enumerating hundreds would bury this list. Naming nothing changes nothing.
# ~/.hydra/config.toml
[openrouter]
models = ["anthropic/claude-sonnet-4.5", "google/gemini-2.5-pro"]hyctl probe then lists one entry per model and says how much of the catalogue is enabled ("2 of 423"). A name the catalogue does not hold is shown as not routable with the reason, never dropped.
Local runtimes the free floor
Local models are the terminal fallback: always available, always $0, and where PII-flagged prompts are pinned so sensitive data never leaves the machine.
hyctl init first-run wizard
Scans your machine, ranks every model, and walks you through picking your main model (the orchestrator), a local model calibrated to your real free RAM, and whether you handle sensitive data. Writes ~/.hydra/config.toml.
hyctl init
hyctl probe discover every model
Runs the three discovery channels concurrently and lists every model with its CapScore and status. For a local model it also shows the quantization actually loaded, because the same model id at Q4_K_M and at Q8_0 is not the same model: it differs in accuracy, VRAM and tokens/sec. --json also carries the model's architectural context ceiling, which is what caps the window the budget governor holds a local model to.
hyctl probe
hyctl status live state
The models that can actually run, budget bars, and the rate-aware governor.
Model list comes from live discovery, grouped by the routing level each model would route at, so it cannot drift from the router; anything discovery found but nothing can drive is counted, not listed. The governor models context usage as a drifting process and estimates the first-passage probability of crossing the ceiling before the task ends, escalating before a threshold is hit.
hyctl status
hyctl dispatch the router
Sends a request to a model measured capable at its task type, with automatic fallback. Today that is the lowest-cost model that clears the bar. The core command.
1 · classify → enum/routing level · 2 · policy gate (PII can block before any network call) · 3 · select highest-CapScore available model at/under routing level · 4 · execute · 5 · on failure fall down the chain to local Qwen · 6 · log tokens + cost. ~1.1µs of decision overhead.
hyctl dispatch "refactor auth to JWT refresh" hyctl dispatch --enum SIMPLE "write a User DTO" hyctl dispatch --dry-run "add pagination" hyctl dispatch --local "write unit tests"
On a terminal the answer is drawn as it arrives: a spinner covers the wait before the first token, then tokens append, then the token counts, elapsed time and measured TTFT print as a footer, since none of those numbers exist until the call returns. Measured on a local 7B: 435 deltas spread over 9.9s of a 10.0s call, where before there was nothing on screen for the whole ten seconds.
Piped output never streams and is byte-identical to before, so scripts are unaffected; --no-stream asks for the same buffered rendering on a terminal. When a model fails part-way through, its partial is collapsed off the screen and replaced by one line naming the model and the reason, because a partial left on screen reads as part of the answer. Nothing is erased once it has scrolled past the top of the window.
A fan-out has no single stream to show, so --swarm and --confidence draw a live panel instead: every model that was selected, with its state, elapsed time, tokens and the cost as it accrues. A confidence run adds the running log-odds against the threshold it has to cross, so an ensemble that stops after two models says why it stopped. The panel is erased when the run ends, and the result printed after it is unchanged.
dispatch --swarm fan out, keep the best
race (first success), best (LLM judge), or all (ranked by CapScore), with a pre-flight cost guard.
hyctl dispatch --swarm --swarm-mode best "implement a rate limiter" --swarm-max-heads 5 --swarm-max-cost 0.05 --swarm-judge-tier 1
dispatch --confidence route to a P(correct)
Sample models adaptively until a target confidence is reached, then stop.
An SPRT accumulates the calibrated log-likelihood ratio across votes and stops at the boundary implied by your target. --file raises the bar by blast radius.
hyctl dispatch --confidence 0.95 "is this migration safe for prod?"
hyctl edit safe file edits
Scoped, validated, rollback-safe single-file edit through a model.
hyctl edit --file "$PWD/internal/foo.go" --enum MODERATE --prompt "add a nil check"
hyctl review code review
Review / approve / reject / QA a change.
hyctl review --file internal/foo.gohyctl parallel fan independent tasks
Fan a set of independent tasks across models. Optimal count follows n*=√((1−s)/k).
hyctl parallel --tasks tasks.txthyctl trust calibration and verification
Builds and inspects the calibration behind --confidence. Each source earns a measured reliability from real outcomes.
A Beta-Bernoulli posterior over sensitivity/specificity → a per-vote LLR and a diagnostic power D (KL divergence, nats). A coin-flip source has D≈0 and is ignored. The defect-cost model prices a wrong answer and sets the required confidence.
hyctl trust calibration # per-source se / sp / D hyctl trust record --source ollama/qwen3:4b --domain go --said-correct --outcome correct # a model ID from `hyctl probe` hyctl trust defect --pii --production hyctl trust stats # samples saved vs fixed-N hyctl trust explain <hash> # the LLR ledger for a run hyctl trust benchmark # measured SPRT numbers
hyctl graph blast how dangerous is this file?
Reports a file's blast radius and the confidence a change to it demands.
From graph.json it counts transitive dependents and computes κ = ⟨k²⟩/⟨k⟩ (Molloy-Reed). κ ≥ 2 ⟹ cascade-capable core ⟹ higher confidence bar.
hyctl graph blast internal/auth/token.go
hyctl graph parallel how many agents?
Returns the optimal number of parallel agents for a set of files.
Amdahl + coordination cost: minimizing T(n)=s+(1−s)/n+kn gives n*=√((1−s)/k). Independent files → ~6; coupled → ~2.
hyctl graph parallel internal/a.go internal/b.go
hyctl context entropy signal, not length
Measures context density and tells you when to compact.
ρ = |gzip(C)|/|C| proxies the entropy rate; useful = L·ρ. Compact on falling ρ, not raw length.
hyctl context entropy internal/foo.go cat notes.md | hyctl context entropy -
hyctl mcp accountability ledger
A local, append-only ledger that records, and can gate: what every agent touches.
hyctl mcp check <tool> --agent A --resource R --action write hyctl mcp log --denied # what got blocked hyctl mcp report # allowed / denied by agent & tool
hyctl mcp registry safety score for the MCP servers on your machine
Every existing MCP directory answers "does this server exist", none answer "is it safe to run with my credentials right now," and star/download counts are actively misleading (the most-starred servers score worst on quality in independent research). This scores what's actually installed instead of indexing everything that exists.
hyctl mcp registry sync # pull the official MCP registry into a local cache hyctl mcp registry scan # list servers installed across Claude Code/Desktop, Cursor, Windsurf, VS Code hyctl mcp registry audit # resolve + score installed servers, update lifecycle state hyctl mcp registry export --out DIR # static index.html/index.json of audited servers hyctl mcp registry backtest # validate scoring against known real incidents (postmark-mcp, CVE-2025-6514) hyctl mcp registry list # audited servers by safety score hyctl mcp registry clear <server> # recover a server quarantined in error
Scoring is shaped around the CSA MCP Selection Scorecard's four categories (Security Implementation, Repository Health, Operational Security, Community & Governance), automating a taxonomy the MCP Security Working Group already endorsed, not inventing a new one. Only a confirmed finding (a known advisory match) quarantines a server; a name-similarity heuristic lowers the score without condemning it, because quarantine has no automatic way out, clear is the manual recovery path. A category nothing could be checked in contributes a neutral baseline rather than being dropped from the average, so failing to reach GitHub can never raise a score, and a server nothing is known about reads "insufficient evidence" rather than a number. A server's status (new → provisional → trusted → flagged → quarantined) drops back to provisional on every version bump, detected via a content-hash diff of the manifest, the direct fix for the postmark-mcp rug-pull pattern (15 clean npm versions, then a malicious one). scan never reads env-var or secret values from client configs, only server identity.
Feeds back into the ledger: hyctl mcp check auto-classifies a tool call as mcp-unverified, mcp-flagged, or mcp-quarantined from a server's registry state, the same way PII is auto-detected from content, so a policy rule can gate on it automatically. Below that: mcp-behavior-change, a server whose ledger history has only ever shown one kind of access (read, say) suddenly performing another (network) is flagged from local history alone, no registry data or CVE required. A server's first-ever call is never flagged, there's nothing yet to compare it against.
The exported page (export) carries a disclaimer, this is a probabilistic signal from automated checks, not a guarantee of safety or a claim about a publisher's intent, and every row links a pre-filled dispute issue against this repo, since a public negative signal about a real project needs a correction path before it ships, not as an afterthought.
hyctl oracle verify tests as evidence
Turns a verifier (tests/compile/lint) into a high-D evidence source whose verdict can outweigh a model's opinion.
hyctl oracle verify go test ./... --source verifier:go-testhyctl cost spend, honestly labeled
Reads cost.jsonl; tokens_source marks real-vs-estimated, cost_source is always estimated.
hyctl cost
hyctl stats rollup
Cost rollup by model, routing level, and day: your real spend.
hyctl stats
hyctl pricing live rates
Live OpenRouter rates, cached 24h, with a static YAML fallback offline.
hyctl pricing list [filter] [--json]
hyctl pricing refreshhyctl models runtime registry
Add a model at runtime, no rebuild. Merges into ~/.hydra/models.json.
hyctl models list hyctl models add kimi-k3 --provider moonshot --cap-score 85 hyctl models sync # import the OpenRouter catalog
Routing levels & CapScore how routing decides
Every model gets a CapScore (0-100); tasks route through named routing levels by score. Lower routing level number = stronger.
| Routing level | Score | Example models |
|---|---|---|
| expert | 90-100 | Claude Opus, Claude Code |
| complex | 80-89 | Codex, GPT-class, Gemini Pro |
| standard | 70-79 | Gemini Flash, Claude Haiku |
| simple | 60-69 | Qwen3 8B, Qwen2.5-Coder 7B |
| local | 50-59 | Llama 3.2 3B, Phi-4 Mini |
Budget governor spend attention wisely
Static pressure bands downgrade routing levels as usage climbs; a rate-aware first-passage model escalates before a threshold is crossed. The terminal fallback is always the free local model.
| claude_pct | Mode | Action |
|---|---|---|
| 0-49% | normal | full orchestration |
| 50-64% | compact | compact recommended |
| 65-69% | caution | compact urgently |
| 70-74% | warning | downgrade one routing level |
| 75-79% | critical | routing only |
| 80%+ | emergency | route to local, warn |
PII / local-only enforced, not conventional
With local-only policy on, any prompt containing sensitive data is blocked from leaving your machine at the dispatch layer, before any network call.
SSNs, credit cards, emails, API keys/tokens, IPs, private-key material → re-routed to a local model.
A2A handoffs causal, conflict-aware
Work passed between agents carries a vector clock for causal ordering; concurrent handoffs touching overlapping files are flagged as conflicts. Saved to logs/last_handoff.json, replayed with --a2a.
The math why the router isn't vibes
Six results run the router: Wald's SPRT, calibration diagnostic power (KL), the Bayes defect-cost bar, Molloy-Reed percolation-κ, Amdahl optimal parallelism, and context entropy, each stated, derived, and interactive.
Open First Principles, six interactive proofs →