{"id":51095563,"url":"https://github.com/jahala/umbel","last_synced_at":"2026-06-24T06:01:32.725Z","repository":{"id":366024657,"uuid":"1246082213","full_name":"jahala/umbel","owner":"jahala","description":"Remote-control interactive agent CLIs (Claude Code, Codex, Gemini) over tmux. One binary, three faces, one provider abstraction. Subscription-billed.","archived":false,"fork":false,"pushed_at":"2026-06-19T22:43:25.000Z","size":843,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-20T00:14:02.129Z","etag":null,"topics":["agent-orchestration","ai-tools","automation","bun","claude-code","codex","gemini","mcp","multi-agent","tmux","typescript"],"latest_commit_sha":null,"homepage":"https://jahala.github.io/umbel/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jahala.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"buy_me_a_coffee":"jahala"}},"created_at":"2026-05-21T21:20:29.000Z","updated_at":"2026-06-19T22:43:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jahala/umbel","commit_stats":null,"previous_names":["jahala/umbel"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/jahala/umbel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahala%2Fumbel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahala%2Fumbel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahala%2Fumbel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahala%2Fumbel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jahala","download_url":"https://codeload.github.com/jahala/umbel/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahala%2Fumbel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34719307,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-orchestration","ai-tools","automation","bun","claude-code","codex","gemini","mcp","multi-agent","tmux","typescript"],"created_at":"2026-06-24T06:01:29.617Z","updated_at":"2026-06-24T06:01:32.706Z","avatar_url":"https://github.com/jahala.png","language":"TypeScript","funding_links":["https://buymeacoffee.com/jahala"],"categories":[],"sub_categories":[],"readme":"# umbel\n\n[![Live site](https://img.shields.io/badge/live_site-E89227?logo=githubpages\u0026logoColor=white)](https://jahala.github.io/umbel/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Build](https://img.shields.io/github/actions/workflow/status/jahala/umbel/ci.yml?branch=master)](https://github.com/jahala/umbel/actions)\n\n🌱 **[What is umbel? →](https://jahala.github.io/umbel/)** \u0026nbsp;·\u0026nbsp; the visual overview\n\n**Spawn other-provider agent workers from inside your agent session.** Drive `claude`, `codex`, `gemini`, or `opencode` interactively in tmux from a CLI, MCP server, or YAML workflow. One binary, one provider abstraction — subscription-billed for claude/codex/gemini, bring-any-model for opencode.\n\n## Claude Code orchestrating Codex (and Gemini, in parallel)\n\nYour `claude` session can't spawn a `codex` session directly. With `umbel mcp` configured, it can:\n\n```jsonc\n// .mcp.json\n{ \"mcpServers\": { \"umbel\": { \"command\": \"umbel\", \"args\": [\"mcp\"] } } }\n```\n\nYour Claude Code agent now has `umbel_spawn`, `umbel_send`, `umbel_wait`, `umbel_read`, `umbel_kill`, and `umbel_help` in its toolbelt. Tell it:\n\n\u003e Spawn a Codex reviewer in `./worktrees/a` and a Gemini tester in `./worktrees/b`. Have them work in parallel, then synthesize their findings.\n\nIt'll stand up both workers, dispatch the prompts, wait for completion, and read their outputs. Three subscriptions, three roles, one orchestration. The host's context stays clean — it spends tokens on planning and synthesis, not on doing the work itself.\n\nThe server ships a server-level `instructions` block plus an on-demand `umbel_help` tool (topics: `lifecycle`, `workflow`, `providers`) so your agent learns when to reach for umbel and how to use it without being drowned in upfront context.\n\n## Supervisor mode (CLI)\n\nThe same verbs from your shell — useful in scripts, cron, or when driving umbel without an MCP host:\n\n```bash\numbel spawn --name reviewer --provider claude --cwd ./worktrees/review --model sonnet\numbel spawn --name fixer    --provider codex  --cwd ./worktrees/fix    --model o4-mini\numbel send reviewer \"review the diff and write findings to review.md\"\numbel wait reviewer\numbel read reviewer\n```\n\nA single supervisor can drive workers across providers concurrently. The provider is recorded in `meta.json` per session so `send`/`wait`/`read`/`kill` auto-route — no `--provider` needed after spawn.\n\nFull verb list: `spawn`, `send`, `wait`, `status`, `ls`, `kill`, `attach`, `read`, `capture`, `logs`, `run`, `mcp`.\n\n## Workflow mode\n\nDeclarative multi-step pipelines, mixed-provider per step:\n\n```yaml\nworkers:\n  reviewer:\n    provider: claude\n    model: sonnet\n    cwd: ./worktrees/review\n  fixer:\n    provider: codex\n    model: o4-mini\n    cwd: ./worktrees/fix\n\nsteps:\n  - run: reviewer\n    prompt: \"Review PR #{{ env.PR }}. Write findings to review.md.\"\n    wait: { stop: $session, timeout: 10m }\n    outputs:\n      review: file:./worktrees/review/review.md\n\n  - run: fixer\n    needs: [reviewer]\n    prompt: \"Apply these fixes:\\n{{ steps.reviewer.outputs.review }}\"\n    wait:\n      all:\n        - { stop: $session }\n        - { file: ./worktrees/fix/tests-passed }\n```\n\n```bash\numbel run review-then-fix.yaml\n```\n\nSteps run in parallel where `needs` allows. Templating is intentionally minimal: `{{ env.X }}`, `{{ steps.NAME.outputs.X }}`, `{{ $session }}`.\n\n## `umbel -p` — drop-in for `claude -p` / `codex -p` / `gemini -p`\n\nSame flags as the vendor `-p` mode, with provider as a parameter:\n\n```bash\numbel -p \"summarise $FILE\" --provider claude --model sonnet --allowedTools Read\numbel -p \"summarise $FILE\" --provider codex  --model o4-mini\numbel -p \"summarise $FILE\" --provider gemini --model gemini-2.5-pro\numbel -p \"summarise $FILE\" --provider opencode --model opencode/big-pickle   # free, keyless\numbel -p \"summarise $FILE\" --provider opencode --model ollama/qwen2.5-coder  # local\n```\n\n`--provider` defaults to `claude` (so `umbel -p` mirrors `claude -p`). Cold-start ~3–5s on first call; use `--name` / `--resume` to keep a session warm:\n\n```bash\numbel -p --name analyst --provider claude \"first question\"\numbel -p --resume analyst \"follow-up\"   # reuses the warm session, same provider\n```\n\n## Install\n\n```bash\nbun install \u0026\u0026 bun run build\n```\n\nHomebrew tap coming. For now, build from source.\n\n## Requires\n\n- `tmux` \u003e= 3.0\n- macOS or Linux\n- At least one provider CLI installed:\n  - `claude` (Claude Pro / Max — subscription-billed)\n  - `codex` (ChatGPT Plus / Pro / Team / Enterprise — subscription-billed)\n  - `gemini` (Google AI Pro / Ultra — subscription-billed)\n  - `opencode` (no subscription — local via `ollama/…`, free-tier via `opencode/big-pickle`, or API-billed via `anthropic/…` / `openrouter/…` with your own key)\n\nProviders without their binary installed simply can't be selected. `umbel spawn --provider gemini` fails loudly when tmux can't exec `gemini`.\n\n## Architecture\n\nNo daemon. `tmux` is the daemon; `~/.umbel/` is the state store. Every `umbel` invocation is short-lived. Completion detection uses each provider's native lifecycle event (Claude `Stop`, Codex `Stop`, Gemini `AfterAgent`, OpenCode `session.status` idle) — not terminal scraping. Agent output is read from each provider's transcript (JSONL for claude/codex/gemini; `opencode export` JSON for opencode), never from `capture-pane`. Providers are pluggable via a small interface (`src/core/providers/types.ts`) — adding a new CLI is a ~150 LOC implementation, not a rewrite. See [`docs/architecture-v3.md`](docs/architecture-v3.md) for the full design.\n\n**What it is, and where it's headed:** umbel is the reliable, neutral execution boundary for *one unit of agent work* — the worker an orchestrator (agent, workflow, or human) commands and reads structured results back from. The thesis, the contract, and the trust-layer roadmap (typed + verified results) live in [`docs/positioning.md`](docs/positioning.md).\n\n## Why this exists\n\nAnthropic, OpenAI, and Google all priced their `-p` / `--print` modes at API rates while leaving the interactive TUI on subscription. `umbel` gives you a programmatic surface over the *interactive* binary of whichever vendor you're paying — so the work you'd otherwise do by hand in the TUI runs against the subscription you already pay for, not per-token API billing on top.\n\nOpenCode has no subscription. It adds a different lane: **local** (your hardware, free, `ollama/…`), **free-tier** (OpenCode Zen, keyless, limited), or **API-billed** (your own key for `anthropic/…`, `openrouter/…`). Together, OpenCode makes umbel a **unified orchestration layer over any agent CLI** — great for running free local workers alongside your subscription claude/codex/gemini without any cost trade-off.\n\nThe `claude` provider can also point at any Anthropic-compatible endpoint — DeepSeek, OpenRouter, a local proxy — via `--env` (`ANTHROPIC_BASE_URL` + `ANTHROPIC_AUTH_TOKEN` + `ANTHROPIC_MODEL`): Claude Code's harness, a different model, billed per-token. See [custom model endpoints](docs/cli-reference.md#custom-model-endpoints-claude-provider).\n\nAimed at solo developers automating their own work. Not for commercial resale or evasion at scale. See [`docs/tos.md`](docs/tos.md) for the defensibility spectrum across all three vendors.\n\n## Sister project\n\n[**walkie-clawkie**](https://github.com/jahala/walkie-clawkie) — push-to-talk messaging between agents while their sessions are running. Complementary, not overlapping: umbel dispatches and waits; walkie-clawkie lets sessions talk to each other mid-turn.\n\n## Contributing\n\nPRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md). Test first — every fix and feature starts with a failing test.\n\n## Support\n\n[![\"Buy Me A Coffee\"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://buymeacoffee.com/jahala)\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahala%2Fumbel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjahala%2Fumbel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahala%2Fumbel/lists"}