AgentHub
▶ Watch the demo in full quality (MP4, 50 s): a real run, not a mock-up.
Let Claude Code hand work to other coding agents (Codex, Antigravity, Claude, Aider, Goose, or any CLI) without handing them your whole machine.
AgentHub is a small MCP server, CLI and optional HTTP API. Use it to:
- Get a second opinion. Send one question to several agents and compare the answers (
compare). - Get a cross-model review of your diff before you commit (
review). - Delegate safely. An agent works in its own git worktree. You see the diff, then apply or discard it.
- Use the subscriptions you already pay for. ChatGPT through Codex, Google through Antigravity, all from one place, with automatic fallback when one runs out of quota.
- Run long jobs in the background, wait for them, read readable logs.
- Search other agents' past sessions, or continue them.
Every request goes through one policy layer: trusted folders, permission modes, a minimal environment, timeouts, quota tracking and a hash-chained audit log.
Pure Python standard library. No dependencies. Linux and macOS. About 20 MB of RAM.
Quick start
pipx install agenthub-gateway # or: uv tool install agenthub-gateway
# or run without installing: uvx agenthub-gateway doctor
agenthub config --init # writes ~/.agenthub/config.json
$EDITOR ~/.agenthub/config.json # set "trusted_workspaces": ["~/code"]
agenthub doctor
Then connect it to Claude Code in one of two ways:
# A) Plugin: MCP server plus slash commands (/second-opinion, /cross-review, /delegate, /agent-tasks)
# Starts the server with `uvx agenthub-gateway mcp`, so it needs uv (https://docs.astral.sh/uv/).
claude plugin marketplace add premanand8800/agenthub-mcp
claude plugin install agenthub@agenthub
# B) MCP server only
agenthub install-claude
Restart Claude Code and try:
/cross-review codex
/delegate codex add input validation to the signup handler and run its tests
Use agenthub to compare codex and claude on: what's the safest way to migrate this table?
How a delegated change works
start_task(isolation="worktree") → agent edits a private checkout (your files are untouched)
wait_task → blocks until done; returns final output, session_id, token usage
get_task_diff → file list + patch
review(task_id=…) → optional: another model reviews that patch
apply_task | discard_task → patch lands in your working tree (uncommitted), or is thrown away
The worktree starts from your current state, including uncommitted changes to tracked files. Build junk (__pycache__, node_modules, …) is left out of the diff. If your files changed in the meantime, apply_task tries a 3-way merge. If that conflicts, it keeps the worktree so you can resolve it by hand.
Permission modes
| Mode | Meaning | Codex | Claude | Antigravity | Aider | Goose |
|---|---|---|---|---|---|---|
read-only |
Inspect only | -s read-only |
plan |
--mode plan --sandbox |
--dry-run |
GOOSE_MODE=chat |
workspace-write (default) |
Edit files in workdir |
-s workspace-write |
acceptEdits |
--mode accept-edits --sandbox |
no shell commands | – |
full |
No sandbox, no approvals | --dangerously-bypass-… |
bypassPermissions |
--dangerously-skip-permissions |
--yes-always |
GOOSE_MODE=auto |
fullis off until a human sets"allow_full_access": true. A model cannot turn it on.reviewandcomparealways runread-only.- If an agent can't enforce a mode, AgentHub refuses the request instead of quietly running with weaker settings.
- A delegated Claude runs with
--strict-mcp-config, so it can't use your other MCP servers (email, chat, AgentHub itself).
MCP tools
| Tool | What it does | Read-only |
|---|---|---|
list_agents |
Installed agents, modes, features, quota health | yes |
ask |
Run a prompt and wait. Returns reply, session_id, usage, cost_usd |
no |
start_task |
Background job, optionally isolation:"worktree" |
no |
wait_task |
Block until a task finishes (up to 10 min per call) | yes |
get_task / get_task_logs / list_tasks |
Status, final output, readable logs | yes |
cancel_task |
Kill a task and all its child processes | no |
get_task_diff |
What a worktree task changed | yes |
apply_task / discard_task |
Land or drop a worktree task's changes | no |
review |
Read-only review of git diff <base> or of a task's diff |
yes* |
compare |
Same prompt to 2–5 agents in parallel | yes* |
list_sessions / search_sessions / get_transcript |
Other agents' history | yes |
list_models |
Model IDs per agent | yes |
send_message |
Message a live session | no |
* These don't change your files, but they do send code to the agents' vendors and use quota.
Options for ask and start_task: workdir, permission_mode, model, and session_id (continue a conversation). Also:
add_dirs: extra directoriesimages: Codex onlyoutput_schema: a JSON Schema; the answer comes back parsed instructuredfallback_agents: other agents to try if this one is out of quota or not installed
Long calls send MCP progress notifications every 10 s when the client asks for them.
To skip permission prompts for tools that only read:
// ~/.claude/settings.json
{ "permissions": { "allow": [
"mcp__agenthub__list_agents", "mcp__agenthub__wait_task", "mcp__agenthub__get_task",
"mcp__agenthub__get_task_logs", "mcp__agenthub__list_tasks", "mcp__agenthub__get_task_diff",
"mcp__agenthub__list_sessions", "mcp__agenthub__search_sessions", "mcp__agenthub__get_transcript",
"mcp__agenthub__list_models"
] } }
Reliability
- Quota-aware. When a provider reports a quota or rate limit, AgentHub records it, including the reset time when the message gives one ("Resets in 137h"). That agent then fails fast with
quota_exhausteduntil the reset time.fallback_agentsmoves on to the next agent automatically.list_agentsshows each agent's health. - No unsafe retries. An agent run that failed partway may already have edited files, so AgentHub never retries it automatically. Falling back to another agent only happens when nothing ran.
- Survives restarts. Background tasks keep running if Claude Code closes, and their status still works from any process. In-flight
askcalls are killed when the client disconnects, so nothing keeps spending. - Global limits.
max_concurrent_tasksholds across every Claude Code session, enforced with a file lock.
CLI (also built for agents)
Every command is non-interactive, has --json, and uses stable exit codes. Other agents can call AgentHub from their own terminals.
agenthub agents [--json]
agenthub ask codex "explain main.py" -m read-only [--session ID] [--schema s.json] [--fallback claude]
agenthub run codex "add tests" --isolation worktree → prints task ID
agenthub wait ID [--timeout 600] exit 0 succeeded · 1 failed · 3 still running
agenthub diff ID | apply ID | discard ID
agenthub review codex [--base main | --task ID]
agenthub compare codex,claude "which approach is safer?"
agenthub tasks | task ID | logs ID | cancel ID
agenthub audit [--verify] · config [--init] · token [--rotate] · serve · doctor
agenthub approve antigravity "Bash(npm test)" human-only
Exit codes: 0 ok · 1 the agent or task failed · 2 usage error · 3 still running (for wait).
Configuration
~/.agenthub/config.json. Every key is optional. Unknown keys are an error, so typos don't fail silently. Set AGENTHUB_HOME to move the whole directory.
| Key | Default | |
|---|---|---|
trusted_workspaces |
["~"] |
Agents may only run inside these. Narrow this. |
denied_paths |
~/.ssh, ~/.gnupg, ~/.aws, ~/.config/gcloud, ~/.kube, ~/.agenthub |
Always refused |
default_permission_mode |
workspace-write |
|
allow_full_access |
false |
Allows full mode |
env_passthrough |
[] |
Extra env vars for agents (globs), e.g. ["GH_TOKEN"] |
inherit_env |
false |
true passes your entire environment (not recommended) |
ask_timeout_seconds / task_timeout_seconds |
900 / 14400 |
|
max_concurrent_tasks |
4 |
Across all sessions |
max_prompt_chars / max_output_chars |
100000 / 60000 |
|
max_delegation_depth |
2 |
Stops agent → hub → agent loops |
quota_backoff_seconds |
900 |
How long to skip an agent after a quota error with no reset time |
audit_prompt_preview_chars |
80 |
0 logs only prompt length and SHA-256 |
task_retention_days |
7 |
Old tasks and their worktrees are deleted |
http_allowed_origins |
[] |
Browser origins allowed to call the HTTP API |
Environment: agents get only what they need:
PATH,HOME, locale, proxies, CA bundles- toolchain variables (nvm, cargo, go, java, venv, …)
- their own API-key variables (
OPENAI_*for Codex,ANTHROPIC_*for Claude, …)
Cloud credentials such as AWS_* and GH_TOKEN are not passed unless you list them in env_passthrough.
Custom agents
Put a JSON file in ~/.agenthub/agents/ (mode 600). See examples/custom-agent.json.
{
"name": "myagent",
"command": "myagent",
"args": ["run", "--prompt={prompt}"],
"model_args": ["--model", "{model}"],
"add_dir_args": ["--add-dir", "{dir}"],
"output_schema_args": ["--schema", "{schema_file}"],
"json_output": { "reply": "result", "session_id": "session_id", "cost_usd": "cost" },
"env_passthrough": ["MYAGENT_API_KEY"],
"modes": { "read-only": ["--no-write"], "workspace-write": ["--sandbox"] }
}
modeslists only what your CLI can really enforce.json_outputtells AgentHub where to find the reply and session ID when your CLI prints JSON.- Specs that are group- or world-writable are refused, and so are specs that reuse a built-in name.
agenthub doctorreports why.
HTTP API (optional)
agenthub serve # 127.0.0.1:8765
TOKEN=$(agenthub token)
curl -s localhost:8765/v1/agents/codex/ask -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' -d '{"prompt":"hi","permission_mode":"read-only"}'
| Method | Path |
|---|---|
| GET | /health (no auth) · /v1/agents · /v1/agents/{agent}/models |
| POST | /v1/agents/{agent}/ask · /v1/agents/{agent}/tasks · /v1/review · /v1/compare |
| GET | /v1/agents/{agent}/sessions · …/sessions/search?q= · …/sessions/{id} |
| POST | /v1/agents/{agent}/sessions/{id}/messages |
| GET | /v1/tasks · /v1/tasks/{id} · /v1/tasks/{id}/wait?timeout= · /v1/tasks/{id}/logs?tail= · /v1/tasks/{id}/diff |
| POST | /v1/tasks/{id}/cancel · /v1/tasks/{id}/apply · /v1/tasks/{id}/discard |
Errors are always {"ok": false, "error": {"code", "message"}}. A quota_exhausted error also includes retry_after_seconds.
Security model
See SECURITY.md. In short:
- The model is untrusted. Defaults assume a prompt injection will reach AgentHub. Every agent run is sandboxed, limited to trusted folders, given a minimal environment, time-limited and audited. A model can't enable
fullmode or approve its own tools. - No shell, ever. Prompts can't become CLI options.
- Private state. All state lives in
~/.agenthub(0700), never in/tmp. - Tamper-evident audit log.
agenthub audit --verify.
Development
git clone https://github.com/premanand8800/agenthub-mcp && cd agenthub-mcp
PYTHONPATH=src python -m unittest discover -s tests -t tests -v
Tests use a fake agent: no API keys, no quota. To add a built-in adapter, subclass agenthub.adapters.base.Adapter, then:
- implement
build_command(spec), andparse_outputif your CLI prints JSON - declare
modesandenv_allow - register it in
adapters/__init__.py
Contributing
Issues and PRs welcome — see CONTRIBUTING.md. Security reports: SECURITY.md.
License
MIT
Metadata
Release files for agenthub-gateway 1.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agenthub_gateway-1.2.1.tar.gz | 67.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agenthub_gateway-1.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 131.0 kB
Release files / agenthub_gateway-1.2.1.tar.gz
| Download URL | agenthub_gateway-1.2.1.tar.gz |
|---|---|
| Size | 67.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cdfcc36a77d85cd4288a8c81d79141395d926ba7e7aab3fd10710a8e8da9a047
|
|
BLAKE2b-256 checksum How to use checksums |
116c8b0d6b7e5532331a3c852561ef93180a4a4009c8eafb95ba14b8821b92c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / agenthub_gateway-1.2.1-py3-none-any.whl
| Download URL | agenthub_gateway-1.2.1-py3-none-any.whl |
|---|---|
| Size | 63.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c064e1aed5ccf7e35f261c5ee8cb3791de868c126956497d6d4e15e674fe1812
|
|
BLAKE2b-256 checksum How to use checksums |
c390b87c42dd84a1d70c1ed375db177affec1fcbd6bff36949d4e2aadc11092a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|