agent-hub-mcp 0.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.
- agent_hub_mcp-0.2.0/.gitignore +39 -0
- agent_hub_mcp-0.2.0/LICENSE +21 -0
- agent_hub_mcp-0.2.0/PKG-INFO +234 -0
- agent_hub_mcp-0.2.0/README.md +207 -0
- agent_hub_mcp-0.2.0/docs/architecture.md +72 -0
- agent_hub_mcp-0.2.0/docs/deployment.md +87 -0
- agent_hub_mcp-0.2.0/examples/agents.env.example +8 -0
- agent_hub_mcp-0.2.0/examples/config.yaml.example +26 -0
- agent_hub_mcp-0.2.0/examples/mcp.json.example +13 -0
- agent_hub_mcp-0.2.0/migrations/001_init.sql +156 -0
- agent_hub_mcp-0.2.0/pyproject.toml +48 -0
- agent_hub_mcp-0.2.0/scripts/install.sh +42 -0
- agent_hub_mcp-0.2.0/src/agent_hub/__init__.py +1 -0
- agent_hub_mcp-0.2.0/src/agent_hub/auth.py +56 -0
- agent_hub_mcp-0.2.0/src/agent_hub/cli.py +71 -0
- agent_hub_mcp-0.2.0/src/agent_hub/models.py +101 -0
- agent_hub_mcp-0.2.0/src/agent_hub/server.py +191 -0
- agent_hub_mcp-0.2.0/src/agent_hub/service.py +273 -0
- agent_hub_mcp-0.2.0/src/agent_hub/storage.py +341 -0
- agent_hub_mcp-0.2.0/systemd/agent-hub.service.template +16 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Byte-compiled / optimized
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Virtual environments
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
env/
|
|
10
|
+
|
|
11
|
+
# Database (runtime-generated)
|
|
12
|
+
*.db
|
|
13
|
+
*.db-wal
|
|
14
|
+
*.db-shm
|
|
15
|
+
|
|
16
|
+
# Secrets (NEVER commit these)
|
|
17
|
+
agents.env
|
|
18
|
+
.mcp.json
|
|
19
|
+
config.yaml
|
|
20
|
+
|
|
21
|
+
# IDE
|
|
22
|
+
.vscode/
|
|
23
|
+
.idea/
|
|
24
|
+
*.swp
|
|
25
|
+
*.swo
|
|
26
|
+
|
|
27
|
+
# OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
|
|
31
|
+
# Distribution
|
|
32
|
+
dist/
|
|
33
|
+
build/
|
|
34
|
+
*.egg-info/
|
|
35
|
+
|
|
36
|
+
# Testing
|
|
37
|
+
.pytest_cache/
|
|
38
|
+
htmlcov/
|
|
39
|
+
.coverage
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ma Zheng (mazhengeod)
|
|
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,234 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-hub-mcp
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Agent Hub MCP — multi-agent task coordination with MCP transport
|
|
5
|
+
Author-email: Ma Zheng <mazhengeod@users.noreply.github.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: agent-hub,mcp,multi-agent,task-coordination
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
|
+
Requires-Dist: fastmcp>=2.0.0
|
|
18
|
+
Requires-Dist: httpx>=0.27
|
|
19
|
+
Requires-Dist: mcp[cli]>=1.8.0
|
|
20
|
+
Requires-Dist: pydantic>=2.0
|
|
21
|
+
Requires-Dist: pyyaml>=6.0
|
|
22
|
+
Requires-Dist: uuid7>=0.1
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# Agent Hub MCP
|
|
29
|
+
|
|
30
|
+
> Multi-agent task coordination server built on the [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
31
|
+
|
|
32
|
+
Agent Hub is a lightweight coordination layer for multi-agent workflows. It provides structured task dispatch, assignment tracking, inter-agent messaging, handoff documents, and human-in-the-loop approval — all accessible via the MCP protocol.
|
|
33
|
+
|
|
34
|
+
## ✨ Features
|
|
35
|
+
|
|
36
|
+
- 🔌 **MCP Streamable HTTP** — any MCP client connects directly
|
|
37
|
+
- 📋 **Task → Round → Assignment** state machine with operator approval gates
|
|
38
|
+
- 💬 **Inter-agent messaging** with deduplication and inbox pull
|
|
39
|
+
- 🤝 **Structured handoff documents** — agents pass work with context, not just messages
|
|
40
|
+
- 🔒 **Distributed locks** with TTL-based lease expiry
|
|
41
|
+
- 🛡️ **Bearer token authentication** — each agent authenticates independently
|
|
42
|
+
- 📦 **Zero-dependency database** — SQLite with WAL mode, no external DB needed
|
|
43
|
+
- ⚡ **5-minute setup** — install, configure tokens, run
|
|
44
|
+
|
|
45
|
+
## 🚀 Quick Start
|
|
46
|
+
|
|
47
|
+
### Install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Clone and install
|
|
51
|
+
git clone https://github.com/mazhengeod/agent-hub.git
|
|
52
|
+
cd agent-hub
|
|
53
|
+
pip install -e .
|
|
54
|
+
|
|
55
|
+
# Or with uv (recommended)
|
|
56
|
+
uv pip install -e .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Configure Agent Tokens
|
|
60
|
+
|
|
61
|
+
Create `~/.config/agent-hub/agents.env`:
|
|
62
|
+
|
|
63
|
+
```env
|
|
64
|
+
# Format: AGENT_ID=BEARER_TOKEN
|
|
65
|
+
claude-code=your-secret-token-here
|
|
66
|
+
codex-desktop=another-secret-token
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Optionally, create `~/.config/agent-hub/config.yaml` for tuning:
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
max_rounds: 3
|
|
73
|
+
max_assignments_per_round: 6
|
|
74
|
+
max_messages_per_task: 40
|
|
75
|
+
lease_minutes: 90
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Run
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Start the MCP server (defaults to 127.0.0.1:8765)
|
|
82
|
+
python -m agent_hub.server
|
|
83
|
+
|
|
84
|
+
# Or use the CLI
|
|
85
|
+
hubctl serve
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Connect from Claude Code
|
|
89
|
+
|
|
90
|
+
Add to your project's `.mcp.json`:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"mcpServers": {
|
|
95
|
+
"agent-hub": {
|
|
96
|
+
"type": "streamable-http",
|
|
97
|
+
"url": "http://127.0.0.1:8765/mcp",
|
|
98
|
+
"headers": {
|
|
99
|
+
"Authorization": "Bearer your-secret-token-here"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 🏗️ Architecture
|
|
107
|
+
|
|
108
|
+
### State Machine
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
Task (draft)
|
|
112
|
+
│
|
|
113
|
+
├─► Round 1: awaiting_operator_approval
|
|
114
|
+
│ ├─► Operator approves ─► dispatched
|
|
115
|
+
│ │ ├─► Assignment: pending ─► claimed ─► in_progress ─► completed
|
|
116
|
+
│ │ └─► All assignments done ─► awaiting_review
|
|
117
|
+
│ └─► Operator rejects ─► back to awaiting_operator_approval
|
|
118
|
+
│
|
|
119
|
+
└─► Review verdict: approved ─► Task completed
|
|
120
|
+
Review verdict: changes_requested ─► Round 2 (re-plan)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 16 MCP Tools
|
|
124
|
+
|
|
125
|
+
| Tool | Description |
|
|
126
|
+
|------|-------------|
|
|
127
|
+
| `hub_status` | Server version and transport info |
|
|
128
|
+
| `agent_register` | Register an agent with name and capabilities |
|
|
129
|
+
| `agent_heartbeat` | Ping to confirm agent is alive |
|
|
130
|
+
| `inbox_pull` | Pull unread messages for the calling agent |
|
|
131
|
+
| `message_send` | Send a message to another agent |
|
|
132
|
+
| `message_ack` | Mark a message as read |
|
|
133
|
+
| `task_draft_create` | Create a new task in draft state |
|
|
134
|
+
| `round_plan_submit` | Submit a round plan with assignments |
|
|
135
|
+
| `assignment_list` | List assignments for the calling agent |
|
|
136
|
+
| `assignment_claim` | Claim a pending assignment |
|
|
137
|
+
| `assignment_progress` | Report progress on an assignment |
|
|
138
|
+
| `assignment_complete` | Complete an assignment with a handoff document |
|
|
139
|
+
| `handoff_get` | Retrieve a handoff document |
|
|
140
|
+
| `review_submit` | Submit a review verdict (approved/changes_requested) |
|
|
141
|
+
| `lock_acquire` | Acquire a distributed lock with TTL |
|
|
142
|
+
| `lock_release` | Release a held lock |
|
|
143
|
+
|
|
144
|
+
### Operator CLI
|
|
145
|
+
|
|
146
|
+
`hubctl` provides manual operator controls:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
hubctl approve <round-id> [note] # Approve a round for dispatch
|
|
150
|
+
hubctl reject <round-id> [note] # Reject a round (needs re-plan)
|
|
151
|
+
hubctl close <task-id> # Close a task
|
|
152
|
+
hubctl status <round-id> # Show round status
|
|
153
|
+
hubctl list-tasks # List all tasks
|
|
154
|
+
hubctl list-rounds [task-id] # List rounds
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## 🔐 Security
|
|
158
|
+
|
|
159
|
+
- **Bearer token auth** — each agent has its own token in `agents.env`
|
|
160
|
+
- **Tokens are SHA-256 hashed** in the database, never stored in plaintext
|
|
161
|
+
- **Local-only by default** — server binds to `127.0.0.1:8765`
|
|
162
|
+
- **No external dependencies** — SQLite WAL mode, no Redis/Postgres needed
|
|
163
|
+
|
|
164
|
+
> ⚠️ **Never commit `agents.env` or `.mcp.json` to version control.** They contain authentication tokens.
|
|
165
|
+
|
|
166
|
+
## 🚢 Production Deployment
|
|
167
|
+
|
|
168
|
+
### systemd
|
|
169
|
+
|
|
170
|
+
A template service file is provided in `systemd/agent-hub.service.template`. Install with:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Generate service file with your user and path
|
|
174
|
+
./scripts/install.sh
|
|
175
|
+
|
|
176
|
+
# Or manually:
|
|
177
|
+
sed -e "s|%USER%|$(whoami)|g" \
|
|
178
|
+
-e "s|%WORKDIR%|$(pwd)|g" \
|
|
179
|
+
-e "s|%VENV%|$(pwd)/.venv|g" \
|
|
180
|
+
systemd/agent-hub.service.template > ~/.config/systemd/user/agent-hub.service
|
|
181
|
+
|
|
182
|
+
systemctl --user daemon-reload
|
|
183
|
+
systemctl --user enable --now agent-hub
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Environment Variables
|
|
187
|
+
|
|
188
|
+
| Variable | Default | Description |
|
|
189
|
+
|----------|---------|-------------|
|
|
190
|
+
| `AGENT_HUB_HOST` | `127.0.0.1` | Server bind address |
|
|
191
|
+
| `AGENT_HUB_PORT` | `8765` | Server bind port |
|
|
192
|
+
| `AGENT_HUB_DB` | `~/.local/share/agent-hub/hub.db` | SQLite database path |
|
|
193
|
+
|
|
194
|
+
## 📂 Project Structure
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
agent-hub/
|
|
198
|
+
├── src/agent_hub/
|
|
199
|
+
│ ├── __init__.py # Package init
|
|
200
|
+
│ ├── server.py # FastMCP server with 16 tools
|
|
201
|
+
│ ├── service.py # State machine logic & rules
|
|
202
|
+
│ ├── storage.py # SQLite storage layer
|
|
203
|
+
│ ├── models.py # Pydantic data models
|
|
204
|
+
│ ├── auth.py # Bearer token verification
|
|
205
|
+
│ └── cli.py # hubctl operator CLI
|
|
206
|
+
├── migrations/
|
|
207
|
+
│ └── 001_init.sql # Database schema
|
|
208
|
+
├── tests/ # Test suite
|
|
209
|
+
├── examples/ # Example configs
|
|
210
|
+
├── systemd/ # Service templates
|
|
211
|
+
├── docs/ # Documentation
|
|
212
|
+
└── pyproject.toml # Package config
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## 🧪 Development
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Install dev dependencies
|
|
219
|
+
uv pip install -e ".[dev]"
|
|
220
|
+
|
|
221
|
+
# Run tests
|
|
222
|
+
pytest
|
|
223
|
+
|
|
224
|
+
# Run with auto-reload (if using uvicorn)
|
|
225
|
+
python -m agent_hub.server
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## 📄 License
|
|
229
|
+
|
|
230
|
+
[MIT](LICENSE) — use it, fork it, ship it.
|
|
231
|
+
|
|
232
|
+
## 🙏 Acknowledgments
|
|
233
|
+
|
|
234
|
+
Built with [FastMCP](https://github.com/jlowin/fastmcp) and the [Model Context Protocol](https://modelcontextprotocol.io/) specification.
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Agent Hub MCP
|
|
2
|
+
|
|
3
|
+
> Multi-agent task coordination server built on the [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
4
|
+
|
|
5
|
+
Agent Hub is a lightweight coordination layer for multi-agent workflows. It provides structured task dispatch, assignment tracking, inter-agent messaging, handoff documents, and human-in-the-loop approval — all accessible via the MCP protocol.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🔌 **MCP Streamable HTTP** — any MCP client connects directly
|
|
10
|
+
- 📋 **Task → Round → Assignment** state machine with operator approval gates
|
|
11
|
+
- 💬 **Inter-agent messaging** with deduplication and inbox pull
|
|
12
|
+
- 🤝 **Structured handoff documents** — agents pass work with context, not just messages
|
|
13
|
+
- 🔒 **Distributed locks** with TTL-based lease expiry
|
|
14
|
+
- 🛡️ **Bearer token authentication** — each agent authenticates independently
|
|
15
|
+
- 📦 **Zero-dependency database** — SQLite with WAL mode, no external DB needed
|
|
16
|
+
- ⚡ **5-minute setup** — install, configure tokens, run
|
|
17
|
+
|
|
18
|
+
## 🚀 Quick Start
|
|
19
|
+
|
|
20
|
+
### Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Clone and install
|
|
24
|
+
git clone https://github.com/mazhengeod/agent-hub.git
|
|
25
|
+
cd agent-hub
|
|
26
|
+
pip install -e .
|
|
27
|
+
|
|
28
|
+
# Or with uv (recommended)
|
|
29
|
+
uv pip install -e .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Configure Agent Tokens
|
|
33
|
+
|
|
34
|
+
Create `~/.config/agent-hub/agents.env`:
|
|
35
|
+
|
|
36
|
+
```env
|
|
37
|
+
# Format: AGENT_ID=BEARER_TOKEN
|
|
38
|
+
claude-code=your-secret-token-here
|
|
39
|
+
codex-desktop=another-secret-token
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Optionally, create `~/.config/agent-hub/config.yaml` for tuning:
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
max_rounds: 3
|
|
46
|
+
max_assignments_per_round: 6
|
|
47
|
+
max_messages_per_task: 40
|
|
48
|
+
lease_minutes: 90
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Run
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Start the MCP server (defaults to 127.0.0.1:8765)
|
|
55
|
+
python -m agent_hub.server
|
|
56
|
+
|
|
57
|
+
# Or use the CLI
|
|
58
|
+
hubctl serve
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Connect from Claude Code
|
|
62
|
+
|
|
63
|
+
Add to your project's `.mcp.json`:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"mcpServers": {
|
|
68
|
+
"agent-hub": {
|
|
69
|
+
"type": "streamable-http",
|
|
70
|
+
"url": "http://127.0.0.1:8765/mcp",
|
|
71
|
+
"headers": {
|
|
72
|
+
"Authorization": "Bearer your-secret-token-here"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 🏗️ Architecture
|
|
80
|
+
|
|
81
|
+
### State Machine
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Task (draft)
|
|
85
|
+
│
|
|
86
|
+
├─► Round 1: awaiting_operator_approval
|
|
87
|
+
│ ├─► Operator approves ─► dispatched
|
|
88
|
+
│ │ ├─► Assignment: pending ─► claimed ─► in_progress ─► completed
|
|
89
|
+
│ │ └─► All assignments done ─► awaiting_review
|
|
90
|
+
│ └─► Operator rejects ─► back to awaiting_operator_approval
|
|
91
|
+
│
|
|
92
|
+
└─► Review verdict: approved ─► Task completed
|
|
93
|
+
Review verdict: changes_requested ─► Round 2 (re-plan)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 16 MCP Tools
|
|
97
|
+
|
|
98
|
+
| Tool | Description |
|
|
99
|
+
|------|-------------|
|
|
100
|
+
| `hub_status` | Server version and transport info |
|
|
101
|
+
| `agent_register` | Register an agent with name and capabilities |
|
|
102
|
+
| `agent_heartbeat` | Ping to confirm agent is alive |
|
|
103
|
+
| `inbox_pull` | Pull unread messages for the calling agent |
|
|
104
|
+
| `message_send` | Send a message to another agent |
|
|
105
|
+
| `message_ack` | Mark a message as read |
|
|
106
|
+
| `task_draft_create` | Create a new task in draft state |
|
|
107
|
+
| `round_plan_submit` | Submit a round plan with assignments |
|
|
108
|
+
| `assignment_list` | List assignments for the calling agent |
|
|
109
|
+
| `assignment_claim` | Claim a pending assignment |
|
|
110
|
+
| `assignment_progress` | Report progress on an assignment |
|
|
111
|
+
| `assignment_complete` | Complete an assignment with a handoff document |
|
|
112
|
+
| `handoff_get` | Retrieve a handoff document |
|
|
113
|
+
| `review_submit` | Submit a review verdict (approved/changes_requested) |
|
|
114
|
+
| `lock_acquire` | Acquire a distributed lock with TTL |
|
|
115
|
+
| `lock_release` | Release a held lock |
|
|
116
|
+
|
|
117
|
+
### Operator CLI
|
|
118
|
+
|
|
119
|
+
`hubctl` provides manual operator controls:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
hubctl approve <round-id> [note] # Approve a round for dispatch
|
|
123
|
+
hubctl reject <round-id> [note] # Reject a round (needs re-plan)
|
|
124
|
+
hubctl close <task-id> # Close a task
|
|
125
|
+
hubctl status <round-id> # Show round status
|
|
126
|
+
hubctl list-tasks # List all tasks
|
|
127
|
+
hubctl list-rounds [task-id] # List rounds
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 🔐 Security
|
|
131
|
+
|
|
132
|
+
- **Bearer token auth** — each agent has its own token in `agents.env`
|
|
133
|
+
- **Tokens are SHA-256 hashed** in the database, never stored in plaintext
|
|
134
|
+
- **Local-only by default** — server binds to `127.0.0.1:8765`
|
|
135
|
+
- **No external dependencies** — SQLite WAL mode, no Redis/Postgres needed
|
|
136
|
+
|
|
137
|
+
> ⚠️ **Never commit `agents.env` or `.mcp.json` to version control.** They contain authentication tokens.
|
|
138
|
+
|
|
139
|
+
## 🚢 Production Deployment
|
|
140
|
+
|
|
141
|
+
### systemd
|
|
142
|
+
|
|
143
|
+
A template service file is provided in `systemd/agent-hub.service.template`. Install with:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Generate service file with your user and path
|
|
147
|
+
./scripts/install.sh
|
|
148
|
+
|
|
149
|
+
# Or manually:
|
|
150
|
+
sed -e "s|%USER%|$(whoami)|g" \
|
|
151
|
+
-e "s|%WORKDIR%|$(pwd)|g" \
|
|
152
|
+
-e "s|%VENV%|$(pwd)/.venv|g" \
|
|
153
|
+
systemd/agent-hub.service.template > ~/.config/systemd/user/agent-hub.service
|
|
154
|
+
|
|
155
|
+
systemctl --user daemon-reload
|
|
156
|
+
systemctl --user enable --now agent-hub
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Environment Variables
|
|
160
|
+
|
|
161
|
+
| Variable | Default | Description |
|
|
162
|
+
|----------|---------|-------------|
|
|
163
|
+
| `AGENT_HUB_HOST` | `127.0.0.1` | Server bind address |
|
|
164
|
+
| `AGENT_HUB_PORT` | `8765` | Server bind port |
|
|
165
|
+
| `AGENT_HUB_DB` | `~/.local/share/agent-hub/hub.db` | SQLite database path |
|
|
166
|
+
|
|
167
|
+
## 📂 Project Structure
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
agent-hub/
|
|
171
|
+
├── src/agent_hub/
|
|
172
|
+
│ ├── __init__.py # Package init
|
|
173
|
+
│ ├── server.py # FastMCP server with 16 tools
|
|
174
|
+
│ ├── service.py # State machine logic & rules
|
|
175
|
+
│ ├── storage.py # SQLite storage layer
|
|
176
|
+
│ ├── models.py # Pydantic data models
|
|
177
|
+
│ ├── auth.py # Bearer token verification
|
|
178
|
+
│ └── cli.py # hubctl operator CLI
|
|
179
|
+
├── migrations/
|
|
180
|
+
│ └── 001_init.sql # Database schema
|
|
181
|
+
├── tests/ # Test suite
|
|
182
|
+
├── examples/ # Example configs
|
|
183
|
+
├── systemd/ # Service templates
|
|
184
|
+
├── docs/ # Documentation
|
|
185
|
+
└── pyproject.toml # Package config
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 🧪 Development
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Install dev dependencies
|
|
192
|
+
uv pip install -e ".[dev]"
|
|
193
|
+
|
|
194
|
+
# Run tests
|
|
195
|
+
pytest
|
|
196
|
+
|
|
197
|
+
# Run with auto-reload (if using uvicorn)
|
|
198
|
+
python -m agent_hub.server
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## 📄 License
|
|
202
|
+
|
|
203
|
+
[MIT](LICENSE) — use it, fork it, ship it.
|
|
204
|
+
|
|
205
|
+
## 🙏 Acknowledgments
|
|
206
|
+
|
|
207
|
+
Built with [FastMCP](https://github.com/jlowin/fastmcp) and the [Model Context Protocol](https://modelcontextprotocol.io/) specification.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Data Model
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
┌─────────┐ ┌──────────┐ ┌─────────────┐
|
|
7
|
+
│ Agent │────►│ Task │────►│ Round │
|
|
8
|
+
│ (auth) │ │ (root) │ │ (dispatch) │
|
|
9
|
+
└─────────┘ └──────────┘ └──────┬──────┘
|
|
10
|
+
│
|
|
11
|
+
┌──────┴──────┐
|
|
12
|
+
│ Assignment │
|
|
13
|
+
│ (per agent) │
|
|
14
|
+
└──────┬─────┘
|
|
15
|
+
│
|
|
16
|
+
┌──────┴──────┐
|
|
17
|
+
│ Handoff │
|
|
18
|
+
│ (completion)│
|
|
19
|
+
└─────────────┘
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## State Machines
|
|
23
|
+
|
|
24
|
+
### Task States
|
|
25
|
+
```
|
|
26
|
+
draft → awaiting_operator_approval → dispatched → completed
|
|
27
|
+
↘ closed
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Round States
|
|
31
|
+
```
|
|
32
|
+
awaiting_operator_approval → dispatched → in_progress → awaiting_review → completed
|
|
33
|
+
↖──────────────────────────────────────────────────────────┘
|
|
34
|
+
(changes_requested → new round)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Assignment States
|
|
38
|
+
```
|
|
39
|
+
pending → claimed → in_progress → completed
|
|
40
|
+
↘ cancelled
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Authentication Flow
|
|
44
|
+
|
|
45
|
+
1. Admin creates `~/.config/agent-hub/agents.env` with `AGENT_ID=TOKEN` pairs
|
|
46
|
+
2. Agent connects via MCP with `Authorization: Bearer <TOKEN>` header
|
|
47
|
+
3. Server verifies token against `agents.env`, returns `agent_id`
|
|
48
|
+
4. All subsequent tool calls are scoped to that agent
|
|
49
|
+
|
|
50
|
+
## Message Flow
|
|
51
|
+
|
|
52
|
+
- Agents send messages to specific agents (`to_agent`) or broadcast (`to_agent=null`)
|
|
53
|
+
- Messages support deduplication via `dedupe_key`
|
|
54
|
+
- `hop_count` tracks message forwarding depth (max 3 hops)
|
|
55
|
+
- Inbox is pull-based: agents call `inbox_pull` to retrieve unread messages
|
|
56
|
+
|
|
57
|
+
## Lock Mechanism
|
|
58
|
+
|
|
59
|
+
- Distributed locks with TTL-based lease expiry
|
|
60
|
+
- Acquire with `lock_acquire(key, resource_type, resource_id, ttl_seconds)`
|
|
61
|
+
- Release with `lock_release(key)` — only the lock holder can release
|
|
62
|
+
- Expired locks are automatically cleaned up on next `acquire` call
|
|
63
|
+
|
|
64
|
+
## Operator Gate
|
|
65
|
+
|
|
66
|
+
The operator (human) acts as a gate between Round submission and Assignment dispatch:
|
|
67
|
+
|
|
68
|
+
1. Dispatcher creates a task and submits a round plan
|
|
69
|
+
2. Round enters `awaiting_operator_approval` state
|
|
70
|
+
3. Operator uses `hubctl approve <round-id>` or `hubctl reject <round-id>`
|
|
71
|
+
4. Approved rounds become `dispatched` — agents can now claim assignments
|
|
72
|
+
5. Rejected rounds stay in `awaiting_operator_approval` for re-planning
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
## Local Development
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Clone and install
|
|
7
|
+
git clone https://github.com/mazhengeod/agent-hub.git
|
|
8
|
+
cd agent-hub
|
|
9
|
+
python -m venv .venv
|
|
10
|
+
source .venv/bin/activate
|
|
11
|
+
pip install -e .
|
|
12
|
+
|
|
13
|
+
# Configure tokens
|
|
14
|
+
mkdir -p ~/.config/agent-hub
|
|
15
|
+
cp examples/agents.env.example ~/.config/agent-hub/agents.env
|
|
16
|
+
# Edit agents.env with your tokens
|
|
17
|
+
|
|
18
|
+
# Run
|
|
19
|
+
python -m agent_hub.server
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Production (systemd)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Use the installer script
|
|
26
|
+
./scripts/install.sh
|
|
27
|
+
|
|
28
|
+
# Or manually:
|
|
29
|
+
sed -e "s|%USER%|$(whoami)|g" \
|
|
30
|
+
-e "s|%WORKDIR%|$(pwd)|g" \
|
|
31
|
+
-e "s|%VENV%|$(pwd)/.venv|g" \
|
|
32
|
+
systemd/agent-hub.service.template > ~/.config/systemd/user/agent-hub.service
|
|
33
|
+
|
|
34
|
+
systemctl --user daemon-reload
|
|
35
|
+
systemctl --user enable --now agent-hub
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Environment Variables
|
|
39
|
+
|
|
40
|
+
| Variable | Default | Description |
|
|
41
|
+
|----------|---------|-------------|
|
|
42
|
+
| `AGENT_HUB_HOST` | `127.0.0.1` | Bind address (use `0.0.0.0` for LAN access) |
|
|
43
|
+
| `AGENT_HUB_PORT` | `8765` | Bind port |
|
|
44
|
+
| `AGENT_HUB_DB` | `~/.local/share/agent-hub/hub.db` | SQLite database path |
|
|
45
|
+
|
|
46
|
+
## Connecting Multiple Agents
|
|
47
|
+
|
|
48
|
+
Each agent needs its own token in `agents.env`:
|
|
49
|
+
|
|
50
|
+
```env
|
|
51
|
+
claude-code=token-alpha-bravo-charlie
|
|
52
|
+
codex-desktop=token-delta-echo-foxtrot
|
|
53
|
+
my-agent=token-golf-hotel-india
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Each agent's MCP client configuration uses its own token:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"agent-hub": {
|
|
62
|
+
"type": "streamable-http",
|
|
63
|
+
"url": "http://127.0.0.1:8765/mcp",
|
|
64
|
+
"headers": { "Authorization": "Bearer token-alpha-bravo-charlie" }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Database Backups
|
|
71
|
+
|
|
72
|
+
The SQLite database is at `~/.local/share/agent-hub/hub.db`. Back it up with:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
sqlite3 ~/.local/share/agent-hub/hub.db ".backup /path/to/backup.db"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Troubleshooting
|
|
79
|
+
|
|
80
|
+
**Server won't start**: Check if port 8765 is already in use:
|
|
81
|
+
```bash
|
|
82
|
+
lsof -i :8765
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Agent can't connect**: Verify token in `.mcp.json` matches `agents.env`.
|
|
86
|
+
|
|
87
|
+
**Database locked**: Ensure only one server instance is running. WAL mode handles concurrent reads well.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Agent token configuration
|
|
2
|
+
# Format: AGENT_ID=BEARER_TOKEN
|
|
3
|
+
# Generate tokens with: python -c "import secrets; print(secrets.token_urlsafe(32))"
|
|
4
|
+
#
|
|
5
|
+
# Example:
|
|
6
|
+
# claude-code=vd0Fe9dR8OqSKSamST4qYb3VlCxct4xI
|
|
7
|
+
# codex-desktop=another-secret-token-here
|
|
8
|
+
# my-agent=my-generated-token
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Agent Hub configuration
|
|
2
|
+
# Place at ~/.config/agent-hub/config.yaml
|
|
3
|
+
|
|
4
|
+
# Maximum rounds per task (default: 3)
|
|
5
|
+
max_rounds: 3
|
|
6
|
+
|
|
7
|
+
# Maximum assignments per round (default: 6)
|
|
8
|
+
max_assignments_per_round: 6
|
|
9
|
+
|
|
10
|
+
# Maximum messages per task round (default: 40)
|
|
11
|
+
max_messages_per_task: 40
|
|
12
|
+
|
|
13
|
+
# Maximum hop count for messages (default: 3)
|
|
14
|
+
max_hop_count: 3
|
|
15
|
+
|
|
16
|
+
# Maximum simultaneous assignments per agent (default: 4)
|
|
17
|
+
max_simultaneous_assignments: 4
|
|
18
|
+
|
|
19
|
+
# Assignment lease duration in minutes (default: 90)
|
|
20
|
+
lease_minutes: 90
|
|
21
|
+
|
|
22
|
+
# Auto-approve rounds without operator review (default: false)
|
|
23
|
+
auto_approve: false
|
|
24
|
+
|
|
25
|
+
# Auto-create next round on changes_requested (default: false)
|
|
26
|
+
auto_create_next_round: false
|