spawn · send · wait · read

drive every agent CLI from one session.

umbel runs claude, codex, gemini, and opencode as interactive workers in tmux — spawned, prompted, and waited on from your shell, an MCP server, or a YAML workflow. one binary, one provider contract, the subscription you already pay for.

an umbel: one stem, many stalks, every bloom fed from a single point.

claude codex deepseek gemini opencode your session
the gap

your agent can't reach the other agents.

a claude session plans and writes — but it can't pick up a codex session, or run a gemini tester in parallel. and every vendor prices its -p / --print mode at API rates while the interactive TUI you already pay for sits idle.

one provider, one session

you're billed for claude, codex, or gemini as an interactive subscription — but that surface is a terminal, not an API. a script can't drive it, and your agent can't fan work out to a sibling.

umbel makes the TUI programmable

a clean surface over the interactive binary of whichever vendor you pay for — so the work runs against your subscription, not per-token billing on top. add opencode and you get free local workers in the same breath.

one point, many workers

spawn a worker. command it. read it back.

each worker is a named tmux session running a provider's TUI in its own directory — a git worktree, if you like, so several run in parallel without stepping on each other. a supervisor — your agent, a script, or a workflow — drives them and reads structured results back.

step 01
spawn

start a worker on a provider, in a cwd. returns a session name the other verbs route by.

step 02
send

enqueue a prompt. returns immediately — pair it with wait.

step 03
wait

block until the turn ends. resolves stop, needs-input, idle, or dead — never a guess.

step 04
read

the last message verbatim, or a structured digest of what changed. then loop, or kill.

completion, not guesswork

read from the provider's own lifecycle

done is read from each provider's native end-of-turn event — claude's Stop, gemini's AfterAgent — never by scraping the terminal. a worker blocked on a permission prompt is reported as needs-input, with the question, so a supervisor answers instead of hanging.

no daemon

tmux is the daemon; the filesystem is the store

every umbel call is short-lived. session state lives under ~/.umbel/; output is read from each provider's transcript, structured — so you ask "what happened?" and get files touched, commands run, and errors, not a wall of text.

four faces, one contract

the surface that fits where you are.

the same worker — spawn, send, wait, read — reached through whichever surface suits the caller. the worker is the noun; orchestration stays with you.

mount it in your agent

point an MCP host at umbel mcp and your agent gets umbel_spawn, umbel_send, umbel_wait, umbel_read, umbel_kill, plus an on-demand umbel_help — so it learns when to reach for a worker without drowning in upfront context.

// .mcp.json { "mcpServers": { "umbel": { "command": "umbel", "args": ["mcp"] } } }

the verbs, from your shell

useful in scripts, in cron, or anywhere you drive umbel without an MCP host. the provider is recorded per session, so later verbs route on their own.

umbel spawn --name reviewer --provider claude --cwd ./wt/review umbel spawn --name fixer --provider codex --cwd ./wt/fix umbel send reviewer "review the diff, write findings.md" umbel wait reviewer umbel read reviewer

declarative pipelines

multi-step, mixed-provider per step. steps with satisfied needs run in the same wave; outputs flow downstream.

workers: reviewer: { provider: claude, cwd: ./wt/review } fixer: { provider: codex, cwd: ./wt/fix } steps: - run: reviewer prompt: "Review PR #{{ env.PR }}. Write findings.md." outputs: { review: file:./wt/review/findings.md } - run: fixer needs: [reviewer] prompt: "Apply:\n{{ steps.reviewer.outputs.review }}"

a drop-in for claude -p

the same flags as the vendor print modes, with provider as a parameter. defaults to claude, so umbel -p mirrors claude -p.

umbel -p "summarise $FILE" --provider claude --model sonnet umbel -p "summarise $FILE" --provider codex --model o4-mini umbel -p "summarise $FILE" --provider opencode --model ollama/qwen2.5-coder # local, free
claude · codex · gemini · opencode

the subscription you pay for — and any model.

one provider contract, four CLIs behind it. the cloud vendors run on the subscription you already hold; opencode opens a second lane — local, free, or your own key — so a free worker can labour beside the paid ones.

claude

Claude Code over its interactive TUI. point it at any Anthropic-compatible endpoint via env, too.

subscription

codex

OpenAI's Codex CLI — a tight completion loop, driven the same way.

subscription

gemini

Google's Gemini CLI for analysis and long-context summarisation.

subscription

opencode

bring any model: ollama/… local, free keyless Zen, or your own key.

local · free · byok
the honest answer

is umbel for you?

umbel runs one unit of agent work reliably and hands back a result you can branch on. orchestration belongs to the caller, not to umbel. so:

reach for umbel when — a fit

  • you want a provider you aren't — a codex reviewer from a claude session
  • workers run in parallel in separate worktrees
  • a persistent worker across many turns — review → fix → verify
  • you'd rather spend the subscription than the API bill

reach for your host's subagent when — not this

  • a single-shot research question with one answer
  • a context-isolated one-shot result your host already gives you
  • there's no tmux, or no provider CLI installed
  • you need orchestration logic baked in — that stays yours
start

one binary. build it, point an agent at it.

install

bun install && bun run build
  • tmux ≥ 3.0 — the substrate
  • macOS or Linux
  • at least one provider CLI — claude, codex, gemini, or opencode

a provider you don't have installed simply can't be selected — umbel spawn fails loudly, never silently.

where umbel is

version
0.0.1
providers
4 claude · codex · gemini · opencode
surfaces
4 MCP · CLI · workflow · -p

this page grows with the project — it's checked against the brand on every change, and the numbers above move as umbel does. follow along on GitHub →