agent-dispatch 0.1.0__py3-none-any.whl
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_dispatch/__init__.py +3 -0
- agent_dispatch/cache.py +91 -0
- agent_dispatch/cli.py +178 -0
- agent_dispatch/config.py +153 -0
- agent_dispatch/models.py +84 -0
- agent_dispatch/runner.py +331 -0
- agent_dispatch/server.py +710 -0
- agent_dispatch-0.1.0.dist-info/METADATA +353 -0
- agent_dispatch-0.1.0.dist-info/RECORD +12 -0
- agent_dispatch-0.1.0.dist-info/WHEEL +4 -0
- agent_dispatch-0.1.0.dist-info/entry_points.txt +2 -0
- agent_dispatch-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-dispatch
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server that lets Claude Code agents delegate tasks to agents in other project directories
|
|
5
|
+
Project-URL: Homepage, https://github.com/ginkida/agent-dispatch
|
|
6
|
+
Project-URL: Repository, https://github.com/ginkida/agent-dispatch
|
|
7
|
+
Project-URL: Issues, https://github.com/ginkida/agent-dispatch/issues
|
|
8
|
+
Author: ginkida
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent,claude,dispatch,mcp,multi-agent
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: click>=8.0
|
|
23
|
+
Requires-Dist: mcp[cli]>=1.2.0
|
|
24
|
+
Requires-Dist: pyyaml>=6.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# agent-dispatch
|
|
32
|
+
|
|
33
|
+
**MCP server that lets Claude Code agents delegate tasks to agents in other project directories.**
|
|
34
|
+
|
|
35
|
+
Each agent runs as a separate `claude -p` session in its own project directory — inheriting that project's MCP servers, CLAUDE.md, and tools. The calling agent just gets the result back.
|
|
36
|
+
|
|
37
|
+
Works with OAuth, API key, and Claude subscription authentication.
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install agent-dispatch
|
|
43
|
+
|
|
44
|
+
# Initialize: creates config + registers MCP server with Claude Code
|
|
45
|
+
agent-dispatch init
|
|
46
|
+
|
|
47
|
+
# Add agents (description auto-generated from project files)
|
|
48
|
+
agent-dispatch add infra ~/projects/infra
|
|
49
|
+
agent-dispatch add backend ~/projects/backend
|
|
50
|
+
|
|
51
|
+
# Test it works
|
|
52
|
+
agent-dispatch test infra
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Done. Every Claude Code session now has access to all dispatch tools.
|
|
56
|
+
|
|
57
|
+
## When to Dispatch
|
|
58
|
+
|
|
59
|
+
**Do dispatch** when a task needs tools, files, or context from another project:
|
|
60
|
+
- Check container logs via infra agent's Portainer MCP
|
|
61
|
+
- Query a database via db agent's postgres MCP
|
|
62
|
+
- Read code or run tests in another repository
|
|
63
|
+
|
|
64
|
+
**Don't dispatch** when you can do it yourself — dispatching spawns a full Claude session.
|
|
65
|
+
|
|
66
|
+
## MCP Tools Reference
|
|
67
|
+
|
|
68
|
+
### `list_agents`
|
|
69
|
+
|
|
70
|
+
Lists all configured agents. **Call this first** to see what's available.
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
// Response
|
|
74
|
+
[
|
|
75
|
+
{
|
|
76
|
+
"name": "infra",
|
|
77
|
+
"directory": "/home/user/projects/infra",
|
|
78
|
+
"description": "Infrastructure agent. MCP: portainer. Stack: Python, Docker",
|
|
79
|
+
"healthy": true,
|
|
80
|
+
"has_claude_md": true,
|
|
81
|
+
"has_mcp_config": true
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `dispatch`
|
|
87
|
+
|
|
88
|
+
One-shot task delegation. Results are cached — identical requests within TTL return instantly.
|
|
89
|
+
|
|
90
|
+
| Parameter | Type | Required | Description |
|
|
91
|
+
|-----------|------|----------|-------------|
|
|
92
|
+
| `agent` | string | yes | Agent name from `list_agents` |
|
|
93
|
+
| `task` | string | yes | What to do — be specific, the agent has no context from your conversation |
|
|
94
|
+
| `context` | string | no | Extra context: error messages, code snippets, stack traces |
|
|
95
|
+
| `caller` | string | no | Your project/role — helps the agent understand who's asking |
|
|
96
|
+
| `goal` | string | no | Broader objective — helps the agent make better trade-offs |
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
// Response
|
|
100
|
+
{
|
|
101
|
+
"agent": "infra",
|
|
102
|
+
"success": true,
|
|
103
|
+
"result": "Found 3 errors in container logs: TypeError in scheduler.py:42...",
|
|
104
|
+
"session_id": "sess-abc-123",
|
|
105
|
+
"cost_usd": 0.02,
|
|
106
|
+
"duration_ms": 5000,
|
|
107
|
+
"num_turns": 2
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Always pass `caller` and `goal`** — the dispatched agent sees a structured prompt:
|
|
112
|
+
|
|
113
|
+
```markdown
|
|
114
|
+
## Goal
|
|
115
|
+
debug production crash
|
|
116
|
+
|
|
117
|
+
## Dispatched by
|
|
118
|
+
backend
|
|
119
|
+
|
|
120
|
+
## Context
|
|
121
|
+
Error: TypeError at scheduler.py:42
|
|
122
|
+
|
|
123
|
+
## Task
|
|
124
|
+
Check container logs for recent errors related to the scheduler service
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### `dispatch_session`
|
|
128
|
+
|
|
129
|
+
Multi-turn: continue a conversation with an agent. First call starts a session, pass `session_id` back to continue. Never cached.
|
|
130
|
+
|
|
131
|
+
| Parameter | Type | Required | Description |
|
|
132
|
+
|-----------|------|----------|-------------|
|
|
133
|
+
| `agent` | string | yes | Agent name |
|
|
134
|
+
| `task` | string | yes | Task or follow-up message |
|
|
135
|
+
| `session_id` | string | no | From previous response — empty for new session |
|
|
136
|
+
| `context` | string | no | Extra context |
|
|
137
|
+
| `caller` | string | no | Who is dispatching |
|
|
138
|
+
| `goal` | string | no | Broader objective |
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
Turn 1: dispatch_session("infra", "List running containers")
|
|
142
|
+
→ session_id: "sess-abc"
|
|
143
|
+
|
|
144
|
+
Turn 2: dispatch_session("infra", "Restart the nginx one", session_id="sess-abc")
|
|
145
|
+
→ agent remembers previous context
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `dispatch_parallel`
|
|
149
|
+
|
|
150
|
+
Run multiple tasks concurrently. Much faster than sequential `dispatch` calls.
|
|
151
|
+
|
|
152
|
+
| Parameter | Type | Required | Description |
|
|
153
|
+
|-----------|------|----------|-------------|
|
|
154
|
+
| `dispatches` | string (JSON) | yes | JSON array of `{"agent", "task", "context?", "caller?", "goal?"}` |
|
|
155
|
+
| `aggregate` | string | no | Agent name to synthesize all results into one answer |
|
|
156
|
+
|
|
157
|
+
**Important:** `dispatches` is a JSON string, not a list.
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
// Input
|
|
161
|
+
[
|
|
162
|
+
{"agent": "infra", "task": "check pod logs for errors", "caller": "backend", "goal": "debug crash"},
|
|
163
|
+
{"agent": "db", "task": "are all migrations applied?", "caller": "backend", "goal": "debug crash"}
|
|
164
|
+
]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
// Response (without aggregate)
|
|
169
|
+
[
|
|
170
|
+
{"agent": "infra", "success": true, "result": "No errors in pod logs", ...},
|
|
171
|
+
{"agent": "db", "success": true, "result": "All migrations applied", ...}
|
|
172
|
+
]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
// Response (with aggregate="backend")
|
|
177
|
+
{
|
|
178
|
+
"individual_results": [
|
|
179
|
+
{"agent": "infra", "success": true, "result": "No errors in pod logs", ...},
|
|
180
|
+
{"agent": "db", "success": true, "result": "All migrations applied", ...}
|
|
181
|
+
],
|
|
182
|
+
"aggregated": {
|
|
183
|
+
"agent": "backend",
|
|
184
|
+
"success": true,
|
|
185
|
+
"result": "Summary: all systems nominal. No pod errors, all migrations applied."
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### `dispatch_stream`
|
|
191
|
+
|
|
192
|
+
Same as `dispatch` but shows live progress while the agent works. Use for long-running tasks. Not cached.
|
|
193
|
+
|
|
194
|
+
Parameters are identical to `dispatch`.
|
|
195
|
+
|
|
196
|
+
### `dispatch_dialogue`
|
|
197
|
+
|
|
198
|
+
Two agents collaborate through multi-turn conversation. Never cached.
|
|
199
|
+
|
|
200
|
+
| Parameter | Type | Required | Description |
|
|
201
|
+
|-----------|------|----------|-------------|
|
|
202
|
+
| `requester` | string | yes | Agent with the problem/context |
|
|
203
|
+
| `responder` | string | yes | Agent with the expertise/tools |
|
|
204
|
+
| `topic` | string | yes | Problem or question to discuss |
|
|
205
|
+
| `max_rounds` | int | no | Max back-and-forth rounds (default: 3, max: 10) |
|
|
206
|
+
|
|
207
|
+
Each round costs up to 2 dispatches. Agents signal completion with `[RESOLVED]`.
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
// Response
|
|
211
|
+
{
|
|
212
|
+
"resolved": true,
|
|
213
|
+
"rounds": 2,
|
|
214
|
+
"total_cost_usd": 0.04,
|
|
215
|
+
"total_duration_ms": 12000,
|
|
216
|
+
"final_answer": "Staging had 1 pending migration. Applied successfully.",
|
|
217
|
+
"conversation": [
|
|
218
|
+
{"agent": "db", "role": "responder", "round": 1, "message": "Which environment?", "cost_usd": 0.01},
|
|
219
|
+
{"agent": "backend", "role": "requester", "round": 1, "message": "Staging", "cost_usd": 0.01},
|
|
220
|
+
{"agent": "db", "role": "responder", "round": 2, "message": "Applied. [RESOLVED]", "cost_usd": 0.01}
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### `add_agent`
|
|
226
|
+
|
|
227
|
+
Register a new project directory as an agent. Description is auto-generated from project files if omitted.
|
|
228
|
+
|
|
229
|
+
| Parameter | Type | Required | Description |
|
|
230
|
+
|-----------|------|----------|-------------|
|
|
231
|
+
| `name` | string | yes | Agent name (letters, digits, hyphens, underscores) |
|
|
232
|
+
| `directory` | string | yes | Absolute path to project directory |
|
|
233
|
+
| `description` | string | no | What this agent can do — auto-generated if empty |
|
|
234
|
+
|
|
235
|
+
### `remove_agent`
|
|
236
|
+
|
|
237
|
+
Remove an agent from config.
|
|
238
|
+
|
|
239
|
+
| Parameter | Type | Required | Description |
|
|
240
|
+
|-----------|------|----------|-------------|
|
|
241
|
+
| `name` | string | yes | Agent name to remove |
|
|
242
|
+
|
|
243
|
+
### `cache_stats` / `cache_clear`
|
|
244
|
+
|
|
245
|
+
View cache hit rate and size, or clear all cached results.
|
|
246
|
+
|
|
247
|
+
### Error Responses
|
|
248
|
+
|
|
249
|
+
All tools return errors as:
|
|
250
|
+
|
|
251
|
+
```json
|
|
252
|
+
{"error": "Unknown agent: 'foo'. Available: infra, db, monitoring"}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Which Tool to Use
|
|
256
|
+
|
|
257
|
+
| Scenario | Tool |
|
|
258
|
+
|----------|------|
|
|
259
|
+
| Quick one-off question to another project | `dispatch` |
|
|
260
|
+
| Multi-step workflow with follow-ups | `dispatch_session` |
|
|
261
|
+
| Need answers from several agents at once | `dispatch_parallel` |
|
|
262
|
+
| Long task, want to see progress | `dispatch_stream` |
|
|
263
|
+
| Two agents need to collaborate | `dispatch_dialogue` |
|
|
264
|
+
| Need a combined summary from multiple agents | `dispatch_parallel` with `aggregate` |
|
|
265
|
+
|
|
266
|
+
## Configuration
|
|
267
|
+
|
|
268
|
+
Config at `~/.config/agent-dispatch/agents.yaml` (override: `AGENT_DISPATCH_CONFIG` env var):
|
|
269
|
+
|
|
270
|
+
```yaml
|
|
271
|
+
agents:
|
|
272
|
+
infra:
|
|
273
|
+
directory: ~/projects/infra
|
|
274
|
+
description: "Infrastructure agent. MCP: portainer."
|
|
275
|
+
timeout: 300 # seconds, default: 300
|
|
276
|
+
# model: sonnet # optional model override
|
|
277
|
+
# max_budget_usd: 1.0 # cost limit per dispatch
|
|
278
|
+
# permission_mode: auto # permission mode for the agent
|
|
279
|
+
# allowed_tools: # restrict which tools the agent can use
|
|
280
|
+
# - Read
|
|
281
|
+
# - Grep
|
|
282
|
+
# disallowed_tools: # block specific tools
|
|
283
|
+
# - Write
|
|
284
|
+
|
|
285
|
+
settings:
|
|
286
|
+
default_timeout: 300
|
|
287
|
+
max_dispatch_depth: 3 # recursion protection
|
|
288
|
+
max_concurrency: 5 # max parallel claude -p processes
|
|
289
|
+
cache:
|
|
290
|
+
enabled: true
|
|
291
|
+
ttl: 300 # seconds
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Config is reloaded on every tool call — add agents without restarting.
|
|
295
|
+
|
|
296
|
+
### Auto-Description
|
|
297
|
+
|
|
298
|
+
`agent-dispatch add` without `--description` generates one from:
|
|
299
|
+
|
|
300
|
+
- `CLAUDE.md` — first meaningful paragraph (priority)
|
|
301
|
+
- `README.md` — first substantial line (fallback)
|
|
302
|
+
- `pyproject.toml` / `package.json` — project description
|
|
303
|
+
- `.mcp.json` — lists MCP server names
|
|
304
|
+
- Stack indicators — Docker, Rust, Go, Python, Node.js
|
|
305
|
+
- DB indicators — Prisma, Alembic, migrations
|
|
306
|
+
|
|
307
|
+
## How It Works
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
Your Claude Code session
|
|
311
|
+
│
|
|
312
|
+
├─ dispatch("infra", "find errors", caller="backend", goal="debug crash")
|
|
313
|
+
│
|
|
314
|
+
▼
|
|
315
|
+
agent-dispatch MCP server
|
|
316
|
+
├─ cache check → hit? return cached result
|
|
317
|
+
├─ semaphore → limit concurrent processes
|
|
318
|
+
└─ subprocess.run("claude -p ...", cwd=~/projects/infra/)
|
|
319
|
+
│
|
|
320
|
+
▼
|
|
321
|
+
New Claude Code session in ~/projects/infra/
|
|
322
|
+
├─ Inherits: CLAUDE.md, .mcp.json, project tools
|
|
323
|
+
├─ Receives structured prompt with goal/caller/context/task
|
|
324
|
+
└─ Returns result → cached for future identical requests
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Safety
|
|
328
|
+
|
|
329
|
+
- **Recursion protection** — `AGENT_DISPATCH_DEPTH` env var tracks nesting. Default limit: 3.
|
|
330
|
+
- **Cost control** — `max_budget_usd` per agent or globally.
|
|
331
|
+
- **Concurrency** — `max_concurrency` (default: 5) limits parallel `claude -p` processes.
|
|
332
|
+
- **Timeout** — per-agent or global (default: 300s). Orphaned processes are cleaned up.
|
|
333
|
+
- **Caching** — identical `(agent, task, context)` requests return cached results. Only successes are cached. Sessions and dialogues are never cached.
|
|
334
|
+
|
|
335
|
+
## CLI
|
|
336
|
+
|
|
337
|
+
| Command | Description |
|
|
338
|
+
|---------|-------------|
|
|
339
|
+
| `agent-dispatch init` | Create config + register MCP server with Claude Code |
|
|
340
|
+
| `agent-dispatch add <name> <dir>` | Add an agent (auto-generates description) |
|
|
341
|
+
| `agent-dispatch remove <name>` | Remove an agent |
|
|
342
|
+
| `agent-dispatch list` | List agents with health status |
|
|
343
|
+
| `agent-dispatch test <name> [task]` | Test an agent with a dispatch |
|
|
344
|
+
| `agent-dispatch serve` | Start MCP server (stdio, used by Claude Code) |
|
|
345
|
+
|
|
346
|
+
## Requirements
|
|
347
|
+
|
|
348
|
+
- Python >= 3.10
|
|
349
|
+
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated
|
|
350
|
+
|
|
351
|
+
## License
|
|
352
|
+
|
|
353
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
agent_dispatch/__init__.py,sha256=2UOB2UAl5uLq-CqqvA_TgGqigkNaGT5nvFaC9vnQOpo,104
|
|
2
|
+
agent_dispatch/cache.py,sha256=JLiN1LTgTJOFGyEAouTR3LPbh405Z5aO0BYGvJo_5mA,2730
|
|
3
|
+
agent_dispatch/cli.py,sha256=L884HbTJsv6DV4L-QsOfSz9J-syparPdpd_BivayfwI,5607
|
|
4
|
+
agent_dispatch/config.py,sha256=lMPwqvyNyUfbTgAfRTdh6m1cnKUToidT44k9-qFaO2g,5454
|
|
5
|
+
agent_dispatch/models.py,sha256=d9zw_1tTCVMuRktSde_u0tk6BgG9d4SfqS7Rc45FAcg,2415
|
|
6
|
+
agent_dispatch/runner.py,sha256=sBag2k_ck5P4rYEefYHgk4t1U3CXHwqVG9nucbLur3w,10102
|
|
7
|
+
agent_dispatch/server.py,sha256=QFLVZR6DfyJmfUgd-DZLXy9GT2VeaT9fJuXXB1clCvE,23313
|
|
8
|
+
agent_dispatch-0.1.0.dist-info/METADATA,sha256=e3KTHZOD3MBFa_ZG7kzWMLZ-OeQ--Jdp75R9NMg-b-g,11595
|
|
9
|
+
agent_dispatch-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
10
|
+
agent_dispatch-0.1.0.dist-info/entry_points.txt,sha256=_2zBe-YP0LtgoqvKTgOy5OpmgfqPW1ACM0Amgsp7QZA,58
|
|
11
|
+
agent_dispatch-0.1.0.dist-info/licenses/LICENSE,sha256=_NC4Ynfw1Yrq4y3PeaFHHd-3QpIyLU23nQpaYat-UVk,1064
|
|
12
|
+
agent_dispatch-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ginkida
|
|
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.
|