agenthub-gateway 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agenthub_gateway-1.2.0/LICENSE +21 -0
- agenthub_gateway-1.2.0/PKG-INFO +289 -0
- agenthub_gateway-1.2.0/README.md +266 -0
- agenthub_gateway-1.2.0/pyproject.toml +44 -0
- agenthub_gateway-1.2.0/setup.cfg +4 -0
- agenthub_gateway-1.2.0/src/agenthub/__init__.py +3 -0
- agenthub_gateway-1.2.0/src/agenthub/__main__.py +4 -0
- agenthub_gateway-1.2.0/src/agenthub/adapters/__init__.py +62 -0
- agenthub_gateway-1.2.0/src/agenthub/adapters/aider.py +37 -0
- agenthub_gateway-1.2.0/src/agenthub/adapters/antigravity.py +208 -0
- agenthub_gateway-1.2.0/src/agenthub/adapters/base.py +144 -0
- agenthub_gateway-1.2.0/src/agenthub/adapters/claude.py +67 -0
- agenthub_gateway-1.2.0/src/agenthub/adapters/codex.py +254 -0
- agenthub_gateway-1.2.0/src/agenthub/adapters/generic.py +129 -0
- agenthub_gateway-1.2.0/src/agenthub/adapters/goose.py +69 -0
- agenthub_gateway-1.2.0/src/agenthub/cli.py +459 -0
- agenthub_gateway-1.2.0/src/agenthub/config.py +199 -0
- agenthub_gateway-1.2.0/src/agenthub/errors.py +65 -0
- agenthub_gateway-1.2.0/src/agenthub/health.py +82 -0
- agenthub_gateway-1.2.0/src/agenthub/http_server.py +308 -0
- agenthub_gateway-1.2.0/src/agenthub/hub.py +650 -0
- agenthub_gateway-1.2.0/src/agenthub/mcp_server.py +470 -0
- agenthub_gateway-1.2.0/src/agenthub/process.py +171 -0
- agenthub_gateway-1.2.0/src/agenthub/runner.py +61 -0
- agenthub_gateway-1.2.0/src/agenthub/security.py +300 -0
- agenthub_gateway-1.2.0/src/agenthub/tasks.py +315 -0
- agenthub_gateway-1.2.0/src/agenthub/worktree.py +116 -0
- agenthub_gateway-1.2.0/src/agenthub_gateway.egg-info/PKG-INFO +289 -0
- agenthub_gateway-1.2.0/src/agenthub_gateway.egg-info/SOURCES.txt +35 -0
- agenthub_gateway-1.2.0/src/agenthub_gateway.egg-info/dependency_links.txt +1 -0
- agenthub_gateway-1.2.0/src/agenthub_gateway.egg-info/entry_points.txt +2 -0
- agenthub_gateway-1.2.0/src/agenthub_gateway.egg-info/top_level.txt +1 -0
- agenthub_gateway-1.2.0/tests/test_adapters.py +187 -0
- agenthub_gateway-1.2.0/tests/test_features.py +251 -0
- agenthub_gateway-1.2.0/tests/test_http.py +93 -0
- agenthub_gateway-1.2.0/tests/test_hub.py +184 -0
- agenthub_gateway-1.2.0/tests/test_mcp.py +205 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 prempathak
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agenthub-gateway
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: Secure MCP + HTTP gateway that lets Claude Code delegate work to Codex, Antigravity, Aider, Goose and custom coding agents.
|
|
5
|
+
Author: prempathak
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/premanand8800/agenthub-mcp
|
|
8
|
+
Project-URL: Repository, https://github.com/premanand8800/agenthub-mcp
|
|
9
|
+
Project-URL: Issues, https://github.com/premanand8800/agenthub-mcp/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/premanand8800/agenthub-mcp/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: mcp,claude-code,codex,coding-agents,model-context-protocol
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Topic :: Software Development
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# AgentHub
|
|
25
|
+
|
|
26
|
+
[](https://github.com/premanand8800/agenthub-mcp/actions/workflows/ci.yml)
|
|
27
|
+

|
|
28
|
+

|
|
29
|
+
[](https://github.com/premanand8800/agenthub-mcp/blob/main/LICENSE)
|
|
30
|
+
|
|
31
|
+
[](https://github.com/premanand8800/agenthub-mcp/releases/download/v1.2.0/agenthub-demo.mp4)
|
|
32
|
+
|
|
33
|
+
▶ **[Watch the demo in full quality (MP4, 50 s)](https://github.com/premanand8800/agenthub-mcp/releases/download/v1.2.0/agenthub-demo.mp4)**: a real run, not a mock-up.
|
|
34
|
+
|
|
35
|
+
**Let Claude Code hand work to other coding agents (Codex, Antigravity, Claude, Aider, Goose, or any CLI) without handing them your whole machine.**
|
|
36
|
+
|
|
37
|
+
AgentHub is a small MCP server, CLI and optional HTTP API. Use it to:
|
|
38
|
+
|
|
39
|
+
- **Get a second opinion.** Send one question to several agents and compare the answers (`compare`).
|
|
40
|
+
- **Get a cross-model review** of your diff before you commit (`review`).
|
|
41
|
+
- **Delegate safely.** An agent works in its own git worktree. You see the diff, then apply or discard it.
|
|
42
|
+
- **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.
|
|
43
|
+
- **Run long jobs in the background,** wait for them, read readable logs.
|
|
44
|
+
- **Search other agents' past sessions,** or continue them.
|
|
45
|
+
|
|
46
|
+
Every request goes through one policy layer: trusted folders, permission modes, a minimal environment, timeouts, quota tracking and a hash-chained audit log.
|
|
47
|
+
|
|
48
|
+
Pure Python standard library. No dependencies. Linux and macOS. About 20 MB of RAM.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Quick start
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pipx install agenthub-gateway # or: uv tool install agenthub-gateway
|
|
56
|
+
agenthub config --init # writes ~/.agenthub/config.json
|
|
57
|
+
$EDITOR ~/.agenthub/config.json # set "trusted_workspaces": ["~/code"]
|
|
58
|
+
agenthub doctor
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Then connect it to Claude Code in **one** of two ways:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# A) Plugin: MCP server plus slash commands (/second-opinion, /cross-review, /delegate, /agent-tasks)
|
|
65
|
+
claude plugin marketplace add premanand8800/agenthub-mcp
|
|
66
|
+
claude plugin install agenthub@agenthub
|
|
67
|
+
|
|
68
|
+
# B) MCP server only
|
|
69
|
+
agenthub install-claude
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Restart Claude Code and try:
|
|
73
|
+
|
|
74
|
+
> /cross-review codex
|
|
75
|
+
|
|
76
|
+
> /delegate codex add input validation to the signup handler and run its tests
|
|
77
|
+
|
|
78
|
+
> Use agenthub to compare codex and claude on: what's the safest way to migrate this table?
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## How a delegated change works
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
start_task(isolation="worktree") → agent edits a private checkout (your files are untouched)
|
|
86
|
+
wait_task → blocks until done; returns final output, session_id, token usage
|
|
87
|
+
get_task_diff → file list + patch
|
|
88
|
+
review(task_id=…) → optional: another model reviews that patch
|
|
89
|
+
apply_task | discard_task → patch lands in your working tree (uncommitted), or is thrown away
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
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.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Permission modes
|
|
97
|
+
|
|
98
|
+
| Mode | Meaning | Codex | Claude | Antigravity | Aider | Goose |
|
|
99
|
+
|---|---|---|---|---|---|---|
|
|
100
|
+
| `read-only` | Inspect only | `-s read-only` | `plan` | `--mode plan --sandbox` | `--dry-run` | `GOOSE_MODE=chat` |
|
|
101
|
+
| `workspace-write` **(default)** | Edit files in `workdir` | `-s workspace-write` | `acceptEdits` | `--mode accept-edits --sandbox` | no shell commands | – |
|
|
102
|
+
| `full` | No sandbox, no approvals | `--dangerously-bypass-…` | `bypassPermissions` | `--dangerously-skip-permissions` | `--yes-always` | `GOOSE_MODE=auto` |
|
|
103
|
+
|
|
104
|
+
- `full` is **off** until a human sets `"allow_full_access": true`. A model cannot turn it on.
|
|
105
|
+
- `review` and `compare` always run `read-only`.
|
|
106
|
+
- If an agent can't enforce a mode, AgentHub refuses the request instead of quietly running with weaker settings.
|
|
107
|
+
- A delegated Claude runs with `--strict-mcp-config`, so it can't use your other MCP servers (email, chat, AgentHub itself).
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## MCP tools
|
|
112
|
+
|
|
113
|
+
| Tool | What it does | Read-only |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| `list_agents` | Installed agents, modes, features, **quota health** | yes |
|
|
116
|
+
| `ask` | Run a prompt and wait. Returns `reply`, `session_id`, `usage`, `cost_usd` | no |
|
|
117
|
+
| `start_task` | Background job, optionally `isolation:"worktree"` | no |
|
|
118
|
+
| `wait_task` | Block until a task finishes (up to 10 min per call) | yes |
|
|
119
|
+
| `get_task` / `get_task_logs` / `list_tasks` | Status, final output, readable logs | yes |
|
|
120
|
+
| `cancel_task` | Kill a task and all its child processes | no |
|
|
121
|
+
| `get_task_diff` | What a worktree task changed | yes |
|
|
122
|
+
| `apply_task` / `discard_task` | Land or drop a worktree task's changes | no |
|
|
123
|
+
| `review` | Read-only review of `git diff <base>` or of a task's diff | yes* |
|
|
124
|
+
| `compare` | Same prompt to 2–5 agents in parallel | yes* |
|
|
125
|
+
| `list_sessions` / `search_sessions` / `get_transcript` | Other agents' history | yes |
|
|
126
|
+
| `list_models` | Model IDs per agent | yes |
|
|
127
|
+
| `send_message` | Message a live session | no |
|
|
128
|
+
|
|
129
|
+
\* These don't change your files, but they do send code to the agents' vendors and use quota.
|
|
130
|
+
|
|
131
|
+
**Options for `ask` and `start_task`:** `workdir`, `permission_mode`, `model`, and `session_id` (continue a conversation). Also:
|
|
132
|
+
|
|
133
|
+
- `add_dirs`: extra directories
|
|
134
|
+
- `images`: Codex only
|
|
135
|
+
- `output_schema`: a JSON Schema; the answer comes back parsed in `structured`
|
|
136
|
+
- `fallback_agents`: other agents to try if this one is out of quota or not installed
|
|
137
|
+
|
|
138
|
+
**Long calls** send MCP progress notifications every 10 s when the client asks for them.
|
|
139
|
+
|
|
140
|
+
To skip permission prompts for tools that only read:
|
|
141
|
+
|
|
142
|
+
```jsonc
|
|
143
|
+
// ~/.claude/settings.json
|
|
144
|
+
{ "permissions": { "allow": [
|
|
145
|
+
"mcp__agenthub__list_agents", "mcp__agenthub__wait_task", "mcp__agenthub__get_task",
|
|
146
|
+
"mcp__agenthub__get_task_logs", "mcp__agenthub__list_tasks", "mcp__agenthub__get_task_diff",
|
|
147
|
+
"mcp__agenthub__list_sessions", "mcp__agenthub__search_sessions", "mcp__agenthub__get_transcript",
|
|
148
|
+
"mcp__agenthub__list_models"
|
|
149
|
+
] } }
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Reliability
|
|
155
|
+
|
|
156
|
+
- **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_exhausted` until the reset time. `fallback_agents` moves on to the next agent automatically. `list_agents` shows each agent's health.
|
|
157
|
+
- **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.
|
|
158
|
+
- **Survives restarts.** Background tasks keep running if Claude Code closes, and their status still works from any process. In-flight `ask` calls are killed when the client disconnects, so nothing keeps spending.
|
|
159
|
+
- **Global limits.** `max_concurrent_tasks` holds across every Claude Code session, enforced with a file lock.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## CLI (also built for agents)
|
|
164
|
+
|
|
165
|
+
Every command is non-interactive, has `--json`, and uses stable exit codes. Other agents can call AgentHub from their own terminals.
|
|
166
|
+
|
|
167
|
+
```text
|
|
168
|
+
agenthub agents [--json]
|
|
169
|
+
agenthub ask codex "explain main.py" -m read-only [--session ID] [--schema s.json] [--fallback claude]
|
|
170
|
+
agenthub run codex "add tests" --isolation worktree → prints task ID
|
|
171
|
+
agenthub wait ID [--timeout 600] exit 0 succeeded · 1 failed · 3 still running
|
|
172
|
+
agenthub diff ID | apply ID | discard ID
|
|
173
|
+
agenthub review codex [--base main | --task ID]
|
|
174
|
+
agenthub compare codex,claude "which approach is safer?"
|
|
175
|
+
agenthub tasks | task ID | logs ID | cancel ID
|
|
176
|
+
agenthub audit [--verify] · config [--init] · token [--rotate] · serve · doctor
|
|
177
|
+
agenthub approve antigravity "Bash(npm test)" human-only
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Exit codes: `0` ok · `1` the agent or task failed · `2` usage error · `3` still running (for `wait`).
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Configuration
|
|
185
|
+
|
|
186
|
+
`~/.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.
|
|
187
|
+
|
|
188
|
+
| Key | Default | |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| `trusted_workspaces` | `["~"]` | Agents may only run inside these. **Narrow this.** |
|
|
191
|
+
| `denied_paths` | `~/.ssh`, `~/.gnupg`, `~/.aws`, `~/.config/gcloud`, `~/.kube`, `~/.agenthub` | Always refused |
|
|
192
|
+
| `default_permission_mode` | `workspace-write` | |
|
|
193
|
+
| `allow_full_access` | `false` | Allows `full` mode |
|
|
194
|
+
| `env_passthrough` | `[]` | Extra env vars for agents (globs), e.g. `["GH_TOKEN"]` |
|
|
195
|
+
| `inherit_env` | `false` | `true` passes your entire environment (not recommended) |
|
|
196
|
+
| `ask_timeout_seconds` / `task_timeout_seconds` | `900` / `14400` | |
|
|
197
|
+
| `max_concurrent_tasks` | `4` | Across all sessions |
|
|
198
|
+
| `max_prompt_chars` / `max_output_chars` | `100000` / `60000` | |
|
|
199
|
+
| `max_delegation_depth` | `2` | Stops agent → hub → agent loops |
|
|
200
|
+
| `quota_backoff_seconds` | `900` | How long to skip an agent after a quota error with no reset time |
|
|
201
|
+
| `audit_prompt_preview_chars` | `80` | `0` logs only prompt length and SHA-256 |
|
|
202
|
+
| `task_retention_days` | `7` | Old tasks and their worktrees are deleted |
|
|
203
|
+
| `http_allowed_origins` | `[]` | Browser origins allowed to call the HTTP API |
|
|
204
|
+
|
|
205
|
+
**Environment:** agents get only what they need:
|
|
206
|
+
|
|
207
|
+
- `PATH`, `HOME`, locale, proxies, CA bundles
|
|
208
|
+
- toolchain variables (nvm, cargo, go, java, venv, …)
|
|
209
|
+
- their own API-key variables (`OPENAI_*` for Codex, `ANTHROPIC_*` for Claude, …)
|
|
210
|
+
|
|
211
|
+
Cloud credentials such as `AWS_*` and `GH_TOKEN` are **not** passed unless you list them in `env_passthrough`.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Custom agents
|
|
216
|
+
|
|
217
|
+
Put a JSON file in `~/.agenthub/agents/` (mode `600`). See [`examples/custom-agent.json`](https://github.com/premanand8800/agenthub-mcp/blob/main/examples/custom-agent.json).
|
|
218
|
+
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"name": "myagent",
|
|
222
|
+
"command": "myagent",
|
|
223
|
+
"args": ["run", "--prompt={prompt}"],
|
|
224
|
+
"model_args": ["--model", "{model}"],
|
|
225
|
+
"add_dir_args": ["--add-dir", "{dir}"],
|
|
226
|
+
"output_schema_args": ["--schema", "{schema_file}"],
|
|
227
|
+
"json_output": { "reply": "result", "session_id": "session_id", "cost_usd": "cost" },
|
|
228
|
+
"env_passthrough": ["MYAGENT_API_KEY"],
|
|
229
|
+
"modes": { "read-only": ["--no-write"], "workspace-write": ["--sandbox"] }
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
- `modes` lists only what your CLI can really enforce.
|
|
234
|
+
- `json_output` tells AgentHub where to find the reply and session ID when your CLI prints JSON.
|
|
235
|
+
- Specs that are group- or world-writable are refused, and so are specs that reuse a built-in name. `agenthub doctor` reports why.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## HTTP API (optional)
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
agenthub serve # 127.0.0.1:8765
|
|
243
|
+
TOKEN=$(agenthub token)
|
|
244
|
+
curl -s localhost:8765/v1/agents/codex/ask -H "Authorization: Bearer $TOKEN" \
|
|
245
|
+
-H 'Content-Type: application/json' -d '{"prompt":"hi","permission_mode":"read-only"}'
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
| Method | Path |
|
|
249
|
+
|---|---|
|
|
250
|
+
| GET | `/health` (no auth) · `/v1/agents` · `/v1/agents/{agent}/models` |
|
|
251
|
+
| POST | `/v1/agents/{agent}/ask` · `/v1/agents/{agent}/tasks` · `/v1/review` · `/v1/compare` |
|
|
252
|
+
| GET | `/v1/agents/{agent}/sessions` · `…/sessions/search?q=` · `…/sessions/{id}` |
|
|
253
|
+
| POST | `/v1/agents/{agent}/sessions/{id}/messages` |
|
|
254
|
+
| GET | `/v1/tasks` · `/v1/tasks/{id}` · `/v1/tasks/{id}/wait?timeout=` · `/v1/tasks/{id}/logs?tail=` · `/v1/tasks/{id}/diff` |
|
|
255
|
+
| POST | `/v1/tasks/{id}/cancel` · `/v1/tasks/{id}/apply` · `/v1/tasks/{id}/discard` |
|
|
256
|
+
|
|
257
|
+
Errors are always `{"ok": false, "error": {"code", "message"}}`. A `quota_exhausted` error also includes `retry_after_seconds`.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Security model
|
|
262
|
+
|
|
263
|
+
See [SECURITY.md](https://github.com/premanand8800/agenthub-mcp/blob/main/SECURITY.md). In short:
|
|
264
|
+
|
|
265
|
+
- **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 `full` mode or approve its own tools.
|
|
266
|
+
- **No shell, ever.** Prompts can't become CLI options.
|
|
267
|
+
- **Private state.** All state lives in `~/.agenthub` (0700), never in `/tmp`.
|
|
268
|
+
- **Tamper-evident audit log.** `agenthub audit --verify`.
|
|
269
|
+
|
|
270
|
+
## Development
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
git clone https://github.com/premanand8800/agenthub-mcp && cd agenthub-mcp
|
|
274
|
+
PYTHONPATH=src python -m unittest discover -s tests -t tests -v
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Tests use a fake agent: no API keys, no quota. To add a built-in adapter, subclass `agenthub.adapters.base.Adapter`, then:
|
|
278
|
+
|
|
279
|
+
- implement `build_command(spec)`, and `parse_output` if your CLI prints JSON
|
|
280
|
+
- declare `modes` and `env_allow`
|
|
281
|
+
- register it in `adapters/__init__.py`
|
|
282
|
+
|
|
283
|
+
## Contributing
|
|
284
|
+
|
|
285
|
+
Issues and PRs welcome — see [CONTRIBUTING.md](https://github.com/premanand8800/agenthub-mcp/blob/main/CONTRIBUTING.md). Security reports: [SECURITY.md](https://github.com/premanand8800/agenthub-mcp/blob/main/SECURITY.md).
|
|
286
|
+
|
|
287
|
+
## License
|
|
288
|
+
|
|
289
|
+
MIT
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# AgentHub
|
|
2
|
+
|
|
3
|
+
[](https://github.com/premanand8800/agenthub-mcp/actions/workflows/ci.yml)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
[](https://github.com/premanand8800/agenthub-mcp/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
[](https://github.com/premanand8800/agenthub-mcp/releases/download/v1.2.0/agenthub-demo.mp4)
|
|
9
|
+
|
|
10
|
+
▶ **[Watch the demo in full quality (MP4, 50 s)](https://github.com/premanand8800/agenthub-mcp/releases/download/v1.2.0/agenthub-demo.mp4)**: a real run, not a mock-up.
|
|
11
|
+
|
|
12
|
+
**Let Claude Code hand work to other coding agents (Codex, Antigravity, Claude, Aider, Goose, or any CLI) without handing them your whole machine.**
|
|
13
|
+
|
|
14
|
+
AgentHub is a small MCP server, CLI and optional HTTP API. Use it to:
|
|
15
|
+
|
|
16
|
+
- **Get a second opinion.** Send one question to several agents and compare the answers (`compare`).
|
|
17
|
+
- **Get a cross-model review** of your diff before you commit (`review`).
|
|
18
|
+
- **Delegate safely.** An agent works in its own git worktree. You see the diff, then apply or discard it.
|
|
19
|
+
- **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.
|
|
20
|
+
- **Run long jobs in the background,** wait for them, read readable logs.
|
|
21
|
+
- **Search other agents' past sessions,** or continue them.
|
|
22
|
+
|
|
23
|
+
Every request goes through one policy layer: trusted folders, permission modes, a minimal environment, timeouts, quota tracking and a hash-chained audit log.
|
|
24
|
+
|
|
25
|
+
Pure Python standard library. No dependencies. Linux and macOS. About 20 MB of RAM.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pipx install agenthub-gateway # or: uv tool install agenthub-gateway
|
|
33
|
+
agenthub config --init # writes ~/.agenthub/config.json
|
|
34
|
+
$EDITOR ~/.agenthub/config.json # set "trusted_workspaces": ["~/code"]
|
|
35
|
+
agenthub doctor
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then connect it to Claude Code in **one** of two ways:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# A) Plugin: MCP server plus slash commands (/second-opinion, /cross-review, /delegate, /agent-tasks)
|
|
42
|
+
claude plugin marketplace add premanand8800/agenthub-mcp
|
|
43
|
+
claude plugin install agenthub@agenthub
|
|
44
|
+
|
|
45
|
+
# B) MCP server only
|
|
46
|
+
agenthub install-claude
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Restart Claude Code and try:
|
|
50
|
+
|
|
51
|
+
> /cross-review codex
|
|
52
|
+
|
|
53
|
+
> /delegate codex add input validation to the signup handler and run its tests
|
|
54
|
+
|
|
55
|
+
> Use agenthub to compare codex and claude on: what's the safest way to migrate this table?
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## How a delegated change works
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
start_task(isolation="worktree") → agent edits a private checkout (your files are untouched)
|
|
63
|
+
wait_task → blocks until done; returns final output, session_id, token usage
|
|
64
|
+
get_task_diff → file list + patch
|
|
65
|
+
review(task_id=…) → optional: another model reviews that patch
|
|
66
|
+
apply_task | discard_task → patch lands in your working tree (uncommitted), or is thrown away
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
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.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Permission modes
|
|
74
|
+
|
|
75
|
+
| Mode | Meaning | Codex | Claude | Antigravity | Aider | Goose |
|
|
76
|
+
|---|---|---|---|---|---|---|
|
|
77
|
+
| `read-only` | Inspect only | `-s read-only` | `plan` | `--mode plan --sandbox` | `--dry-run` | `GOOSE_MODE=chat` |
|
|
78
|
+
| `workspace-write` **(default)** | Edit files in `workdir` | `-s workspace-write` | `acceptEdits` | `--mode accept-edits --sandbox` | no shell commands | – |
|
|
79
|
+
| `full` | No sandbox, no approvals | `--dangerously-bypass-…` | `bypassPermissions` | `--dangerously-skip-permissions` | `--yes-always` | `GOOSE_MODE=auto` |
|
|
80
|
+
|
|
81
|
+
- `full` is **off** until a human sets `"allow_full_access": true`. A model cannot turn it on.
|
|
82
|
+
- `review` and `compare` always run `read-only`.
|
|
83
|
+
- If an agent can't enforce a mode, AgentHub refuses the request instead of quietly running with weaker settings.
|
|
84
|
+
- A delegated Claude runs with `--strict-mcp-config`, so it can't use your other MCP servers (email, chat, AgentHub itself).
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## MCP tools
|
|
89
|
+
|
|
90
|
+
| Tool | What it does | Read-only |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `list_agents` | Installed agents, modes, features, **quota health** | yes |
|
|
93
|
+
| `ask` | Run a prompt and wait. Returns `reply`, `session_id`, `usage`, `cost_usd` | no |
|
|
94
|
+
| `start_task` | Background job, optionally `isolation:"worktree"` | no |
|
|
95
|
+
| `wait_task` | Block until a task finishes (up to 10 min per call) | yes |
|
|
96
|
+
| `get_task` / `get_task_logs` / `list_tasks` | Status, final output, readable logs | yes |
|
|
97
|
+
| `cancel_task` | Kill a task and all its child processes | no |
|
|
98
|
+
| `get_task_diff` | What a worktree task changed | yes |
|
|
99
|
+
| `apply_task` / `discard_task` | Land or drop a worktree task's changes | no |
|
|
100
|
+
| `review` | Read-only review of `git diff <base>` or of a task's diff | yes* |
|
|
101
|
+
| `compare` | Same prompt to 2–5 agents in parallel | yes* |
|
|
102
|
+
| `list_sessions` / `search_sessions` / `get_transcript` | Other agents' history | yes |
|
|
103
|
+
| `list_models` | Model IDs per agent | yes |
|
|
104
|
+
| `send_message` | Message a live session | no |
|
|
105
|
+
|
|
106
|
+
\* These don't change your files, but they do send code to the agents' vendors and use quota.
|
|
107
|
+
|
|
108
|
+
**Options for `ask` and `start_task`:** `workdir`, `permission_mode`, `model`, and `session_id` (continue a conversation). Also:
|
|
109
|
+
|
|
110
|
+
- `add_dirs`: extra directories
|
|
111
|
+
- `images`: Codex only
|
|
112
|
+
- `output_schema`: a JSON Schema; the answer comes back parsed in `structured`
|
|
113
|
+
- `fallback_agents`: other agents to try if this one is out of quota or not installed
|
|
114
|
+
|
|
115
|
+
**Long calls** send MCP progress notifications every 10 s when the client asks for them.
|
|
116
|
+
|
|
117
|
+
To skip permission prompts for tools that only read:
|
|
118
|
+
|
|
119
|
+
```jsonc
|
|
120
|
+
// ~/.claude/settings.json
|
|
121
|
+
{ "permissions": { "allow": [
|
|
122
|
+
"mcp__agenthub__list_agents", "mcp__agenthub__wait_task", "mcp__agenthub__get_task",
|
|
123
|
+
"mcp__agenthub__get_task_logs", "mcp__agenthub__list_tasks", "mcp__agenthub__get_task_diff",
|
|
124
|
+
"mcp__agenthub__list_sessions", "mcp__agenthub__search_sessions", "mcp__agenthub__get_transcript",
|
|
125
|
+
"mcp__agenthub__list_models"
|
|
126
|
+
] } }
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Reliability
|
|
132
|
+
|
|
133
|
+
- **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_exhausted` until the reset time. `fallback_agents` moves on to the next agent automatically. `list_agents` shows each agent's health.
|
|
134
|
+
- **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.
|
|
135
|
+
- **Survives restarts.** Background tasks keep running if Claude Code closes, and their status still works from any process. In-flight `ask` calls are killed when the client disconnects, so nothing keeps spending.
|
|
136
|
+
- **Global limits.** `max_concurrent_tasks` holds across every Claude Code session, enforced with a file lock.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## CLI (also built for agents)
|
|
141
|
+
|
|
142
|
+
Every command is non-interactive, has `--json`, and uses stable exit codes. Other agents can call AgentHub from their own terminals.
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
agenthub agents [--json]
|
|
146
|
+
agenthub ask codex "explain main.py" -m read-only [--session ID] [--schema s.json] [--fallback claude]
|
|
147
|
+
agenthub run codex "add tests" --isolation worktree → prints task ID
|
|
148
|
+
agenthub wait ID [--timeout 600] exit 0 succeeded · 1 failed · 3 still running
|
|
149
|
+
agenthub diff ID | apply ID | discard ID
|
|
150
|
+
agenthub review codex [--base main | --task ID]
|
|
151
|
+
agenthub compare codex,claude "which approach is safer?"
|
|
152
|
+
agenthub tasks | task ID | logs ID | cancel ID
|
|
153
|
+
agenthub audit [--verify] · config [--init] · token [--rotate] · serve · doctor
|
|
154
|
+
agenthub approve antigravity "Bash(npm test)" human-only
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Exit codes: `0` ok · `1` the agent or task failed · `2` usage error · `3` still running (for `wait`).
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Configuration
|
|
162
|
+
|
|
163
|
+
`~/.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.
|
|
164
|
+
|
|
165
|
+
| Key | Default | |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `trusted_workspaces` | `["~"]` | Agents may only run inside these. **Narrow this.** |
|
|
168
|
+
| `denied_paths` | `~/.ssh`, `~/.gnupg`, `~/.aws`, `~/.config/gcloud`, `~/.kube`, `~/.agenthub` | Always refused |
|
|
169
|
+
| `default_permission_mode` | `workspace-write` | |
|
|
170
|
+
| `allow_full_access` | `false` | Allows `full` mode |
|
|
171
|
+
| `env_passthrough` | `[]` | Extra env vars for agents (globs), e.g. `["GH_TOKEN"]` |
|
|
172
|
+
| `inherit_env` | `false` | `true` passes your entire environment (not recommended) |
|
|
173
|
+
| `ask_timeout_seconds` / `task_timeout_seconds` | `900` / `14400` | |
|
|
174
|
+
| `max_concurrent_tasks` | `4` | Across all sessions |
|
|
175
|
+
| `max_prompt_chars` / `max_output_chars` | `100000` / `60000` | |
|
|
176
|
+
| `max_delegation_depth` | `2` | Stops agent → hub → agent loops |
|
|
177
|
+
| `quota_backoff_seconds` | `900` | How long to skip an agent after a quota error with no reset time |
|
|
178
|
+
| `audit_prompt_preview_chars` | `80` | `0` logs only prompt length and SHA-256 |
|
|
179
|
+
| `task_retention_days` | `7` | Old tasks and their worktrees are deleted |
|
|
180
|
+
| `http_allowed_origins` | `[]` | Browser origins allowed to call the HTTP API |
|
|
181
|
+
|
|
182
|
+
**Environment:** agents get only what they need:
|
|
183
|
+
|
|
184
|
+
- `PATH`, `HOME`, locale, proxies, CA bundles
|
|
185
|
+
- toolchain variables (nvm, cargo, go, java, venv, …)
|
|
186
|
+
- their own API-key variables (`OPENAI_*` for Codex, `ANTHROPIC_*` for Claude, …)
|
|
187
|
+
|
|
188
|
+
Cloud credentials such as `AWS_*` and `GH_TOKEN` are **not** passed unless you list them in `env_passthrough`.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Custom agents
|
|
193
|
+
|
|
194
|
+
Put a JSON file in `~/.agenthub/agents/` (mode `600`). See [`examples/custom-agent.json`](https://github.com/premanand8800/agenthub-mcp/blob/main/examples/custom-agent.json).
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"name": "myagent",
|
|
199
|
+
"command": "myagent",
|
|
200
|
+
"args": ["run", "--prompt={prompt}"],
|
|
201
|
+
"model_args": ["--model", "{model}"],
|
|
202
|
+
"add_dir_args": ["--add-dir", "{dir}"],
|
|
203
|
+
"output_schema_args": ["--schema", "{schema_file}"],
|
|
204
|
+
"json_output": { "reply": "result", "session_id": "session_id", "cost_usd": "cost" },
|
|
205
|
+
"env_passthrough": ["MYAGENT_API_KEY"],
|
|
206
|
+
"modes": { "read-only": ["--no-write"], "workspace-write": ["--sandbox"] }
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
- `modes` lists only what your CLI can really enforce.
|
|
211
|
+
- `json_output` tells AgentHub where to find the reply and session ID when your CLI prints JSON.
|
|
212
|
+
- Specs that are group- or world-writable are refused, and so are specs that reuse a built-in name. `agenthub doctor` reports why.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## HTTP API (optional)
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
agenthub serve # 127.0.0.1:8765
|
|
220
|
+
TOKEN=$(agenthub token)
|
|
221
|
+
curl -s localhost:8765/v1/agents/codex/ask -H "Authorization: Bearer $TOKEN" \
|
|
222
|
+
-H 'Content-Type: application/json' -d '{"prompt":"hi","permission_mode":"read-only"}'
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
| Method | Path |
|
|
226
|
+
|---|---|
|
|
227
|
+
| GET | `/health` (no auth) · `/v1/agents` · `/v1/agents/{agent}/models` |
|
|
228
|
+
| POST | `/v1/agents/{agent}/ask` · `/v1/agents/{agent}/tasks` · `/v1/review` · `/v1/compare` |
|
|
229
|
+
| GET | `/v1/agents/{agent}/sessions` · `…/sessions/search?q=` · `…/sessions/{id}` |
|
|
230
|
+
| POST | `/v1/agents/{agent}/sessions/{id}/messages` |
|
|
231
|
+
| GET | `/v1/tasks` · `/v1/tasks/{id}` · `/v1/tasks/{id}/wait?timeout=` · `/v1/tasks/{id}/logs?tail=` · `/v1/tasks/{id}/diff` |
|
|
232
|
+
| POST | `/v1/tasks/{id}/cancel` · `/v1/tasks/{id}/apply` · `/v1/tasks/{id}/discard` |
|
|
233
|
+
|
|
234
|
+
Errors are always `{"ok": false, "error": {"code", "message"}}`. A `quota_exhausted` error also includes `retry_after_seconds`.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Security model
|
|
239
|
+
|
|
240
|
+
See [SECURITY.md](https://github.com/premanand8800/agenthub-mcp/blob/main/SECURITY.md). In short:
|
|
241
|
+
|
|
242
|
+
- **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 `full` mode or approve its own tools.
|
|
243
|
+
- **No shell, ever.** Prompts can't become CLI options.
|
|
244
|
+
- **Private state.** All state lives in `~/.agenthub` (0700), never in `/tmp`.
|
|
245
|
+
- **Tamper-evident audit log.** `agenthub audit --verify`.
|
|
246
|
+
|
|
247
|
+
## Development
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
git clone https://github.com/premanand8800/agenthub-mcp && cd agenthub-mcp
|
|
251
|
+
PYTHONPATH=src python -m unittest discover -s tests -t tests -v
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Tests use a fake agent: no API keys, no quota. To add a built-in adapter, subclass `agenthub.adapters.base.Adapter`, then:
|
|
255
|
+
|
|
256
|
+
- implement `build_command(spec)`, and `parse_output` if your CLI prints JSON
|
|
257
|
+
- declare `modes` and `env_allow`
|
|
258
|
+
- register it in `adapters/__init__.py`
|
|
259
|
+
|
|
260
|
+
## Contributing
|
|
261
|
+
|
|
262
|
+
Issues and PRs welcome — see [CONTRIBUTING.md](https://github.com/premanand8800/agenthub-mcp/blob/main/CONTRIBUTING.md). Security reports: [SECURITY.md](https://github.com/premanand8800/agenthub-mcp/blob/main/SECURITY.md).
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "agenthub-gateway"
|
|
7
|
+
version = "1.2.0"
|
|
8
|
+
description = "Secure MCP + HTTP gateway that lets Claude Code delegate work to Codex, Antigravity, Aider, Goose and custom coding agents."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
keywords = ["mcp", "claude-code", "codex", "coding-agents", "model-context-protocol"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Operating System :: POSIX :: Linux",
|
|
19
|
+
"Operating System :: MacOS",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Topic :: Software Development",
|
|
22
|
+
]
|
|
23
|
+
authors = [{ name = "prempathak" }]
|
|
24
|
+
dependencies = []
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/premanand8800/agenthub-mcp"
|
|
28
|
+
Repository = "https://github.com/premanand8800/agenthub-mcp"
|
|
29
|
+
Issues = "https://github.com/premanand8800/agenthub-mcp/issues"
|
|
30
|
+
Changelog = "https://github.com/premanand8800/agenthub-mcp/blob/main/CHANGELOG.md"
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
agenthub = "agenthub.cli:main"
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
where = ["src"]
|
|
37
|
+
|
|
38
|
+
[tool.ruff]
|
|
39
|
+
line-length = 120
|
|
40
|
+
target-version = "py310"
|
|
41
|
+
|
|
42
|
+
[tool.ruff.lint]
|
|
43
|
+
select = ["E", "F", "W", "B", "I", "UP"]
|
|
44
|
+
ignore = ["UP006", "UP007", "UP035", "UP045"] # keep typing.List/Optional for readability on 3.10
|