agent-relay-server 0.1.0
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.
- package/README.md +200 -0
- package/package.json +44 -0
- package/public/index.html +501 -0
- package/src/config.ts +11 -0
- package/src/db.ts +499 -0
- package/src/index.ts +82 -0
- package/src/routes.ts +343 -0
- package/src/types.ts +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Agent Relay
|
|
2
|
+
|
|
3
|
+
A lightweight HTTP message bus that lets AI coding agents talk to each other — across sessions, projects, and machines.
|
|
4
|
+
|
|
5
|
+
Built for [Claude Code](https://docs.anthropic.com/en/docs/claude-code), but the relay server is a plain HTTP API that any agent or script can use.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
When you run multiple Claude Code sessions — one debugging a backend, another writing tests, a third reviewing code on a different machine — they're isolated. Agent Relay connects them:
|
|
10
|
+
|
|
11
|
+
- **Direct messaging** between sessions (`"tell the backend agent to check the migration"`)
|
|
12
|
+
- **Capability-based routing** — send to `cap:review` and any agent with that capability picks it up
|
|
13
|
+
- **Fan-out by label** — name your sessions (`"backend fixing"`, `"test writer"`) and address them by name
|
|
14
|
+
- **Claim-based task routing** — post a claimable task and exactly one agent grabs it
|
|
15
|
+
- **Threading** — full conversation chains between agents
|
|
16
|
+
- **Live dashboard** — see all agents, messages, and stats in real time
|
|
17
|
+
|
|
18
|
+
## How It Works
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
22
|
+
│ Claude Code │ │ Claude Code │ │ Claude Code │
|
|
23
|
+
│ Session A │ │ Session B │ │ Session C │
|
|
24
|
+
│ (machine 1) │ │ (machine 1) │ │ (machine 2) │
|
|
25
|
+
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
|
26
|
+
│ │ │
|
|
27
|
+
└────────────────────┼────────────────────┘
|
|
28
|
+
│
|
|
29
|
+
┌───────▼───────┐
|
|
30
|
+
│ Agent Relay │
|
|
31
|
+
│ HTTP + SQLite│
|
|
32
|
+
│ :4850 │
|
|
33
|
+
└───────────────┘
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The **relay server** (Bun + SQLite) handles agent registration, message routing, and the dashboard. The **plugin** (Claude Code plugin) auto-registers each session as an agent and injects messaging capabilities.
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
### 1. Start the relay server
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# requires Bun (https://bun.sh)
|
|
44
|
+
bunx agent-relay-server
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The server starts on `http://localhost:4850`. Open it in a browser to see the dashboard.
|
|
48
|
+
|
|
49
|
+
Or from source:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
git clone https://github.com/edimuj/agent-relay.git
|
|
53
|
+
cd agent-relay
|
|
54
|
+
bun run dev
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2. Install the Claude Code plugin
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
claude plugin marketplace add edimuj/agent-relay
|
|
61
|
+
claude plugin install agent-relay@agent-relay
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Or for local development:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
claude --plugin-dir ./plugin
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 3. Start talking
|
|
71
|
+
|
|
72
|
+
Every Claude Code session now auto-registers as an agent. In any session:
|
|
73
|
+
|
|
74
|
+
> "Tell the other agent to check the test results"
|
|
75
|
+
|
|
76
|
+
> "Send a broadcast: deployment is done"
|
|
77
|
+
|
|
78
|
+
> "Send to cap:review — please review src/db.ts"
|
|
79
|
+
|
|
80
|
+
## Message Targeting
|
|
81
|
+
|
|
82
|
+
Messages can be addressed five ways:
|
|
83
|
+
|
|
84
|
+
| Target | Example | Behavior |
|
|
85
|
+
|--------|---------|----------|
|
|
86
|
+
| Agent ID | `"macmini2-cli-myproject-a1b2c3"` | Direct to one agent |
|
|
87
|
+
| Tag | `"tag:backend"` | All agents with that tag |
|
|
88
|
+
| Capability | `"cap:review"` | All agents with that capability |
|
|
89
|
+
| Label | `"label:test writer"` | All agents with that human-set label |
|
|
90
|
+
| Broadcast | `"broadcast"` | Everyone |
|
|
91
|
+
|
|
92
|
+
## Claim-Based Task Routing
|
|
93
|
+
|
|
94
|
+
For tasks that should be handled by exactly one agent:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Send a claimable task to any agent with the "review" capability
|
|
98
|
+
curl -X POST http://localhost:4850/api/messages \
|
|
99
|
+
-H 'Content-Type: application/json' \
|
|
100
|
+
-d '{"from":"user","to":"cap:review","body":"Review PR #42","claimable":true}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The first agent to claim it wins (atomic, 409 on conflict). Other agents never see it in their inbox.
|
|
104
|
+
|
|
105
|
+
## API
|
|
106
|
+
|
|
107
|
+
Base URL: `http://localhost:4850/api`
|
|
108
|
+
|
|
109
|
+
### Agents
|
|
110
|
+
|
|
111
|
+
| Method | Path | Purpose |
|
|
112
|
+
|--------|------|---------|
|
|
113
|
+
| `POST` | `/agents` | Register or update an agent |
|
|
114
|
+
| `GET` | `/agents` | List agents (filter: `?tag=`, `?machine=`, `?status=`) |
|
|
115
|
+
| `GET` | `/agents/find` | Find by capability (`?capability=review`) |
|
|
116
|
+
| `GET` | `/agents/:id` | Get one agent |
|
|
117
|
+
| `POST` | `/agents/:id/heartbeat` | Keep-alive |
|
|
118
|
+
| `PATCH` | `/agents/:id/label` | Set human-friendly label |
|
|
119
|
+
| `DELETE` | `/agents/:id` | Remove agent |
|
|
120
|
+
|
|
121
|
+
### Messages
|
|
122
|
+
|
|
123
|
+
| Method | Path | Purpose |
|
|
124
|
+
|--------|------|---------|
|
|
125
|
+
| `POST` | `/messages` | Send a message |
|
|
126
|
+
| `GET` | `/messages` | Poll inbox (`?for=agentId&unread=true`) |
|
|
127
|
+
| `GET` | `/messages/:id` | Get single message |
|
|
128
|
+
| `GET` | `/messages/:id/thread` | Get full thread |
|
|
129
|
+
| `POST` | `/messages/:id/claim` | Claim a claimable task |
|
|
130
|
+
| `PATCH` | `/messages/:id` | Mark as read |
|
|
131
|
+
| `DELETE` | `/messages/:id` | Delete message |
|
|
132
|
+
| `GET` | `/messages/cursor` | Latest message ID (for poller bootstrap) |
|
|
133
|
+
|
|
134
|
+
### Stats
|
|
135
|
+
|
|
136
|
+
| Method | Path | Purpose |
|
|
137
|
+
|--------|------|---------|
|
|
138
|
+
| `GET` | `/stats` | Agent counts, message counts |
|
|
139
|
+
|
|
140
|
+
## Plugin Configuration
|
|
141
|
+
|
|
142
|
+
The plugin reads these environment variables:
|
|
143
|
+
|
|
144
|
+
| Variable | Default | Purpose |
|
|
145
|
+
|----------|---------|---------|
|
|
146
|
+
| `AGENT_RELAY_URL` | `http://localhost:4850` | Relay server URL |
|
|
147
|
+
| `AGENT_RELAY_CAPS` | `chat` | Comma-separated agent capabilities |
|
|
148
|
+
|
|
149
|
+
If the relay runs on a different machine, set `AGENT_RELAY_URL` to its address — e.g. a Tailscale IP like `http://100.x.y.z:4850`.
|
|
150
|
+
|
|
151
|
+
Agent IDs are deterministic: `{hostname}-{rig}-{project}-{session-hash}`.
|
|
152
|
+
|
|
153
|
+
## Architecture
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
src/
|
|
157
|
+
├── index.ts # Bun.serve entry point, static files, CORS
|
|
158
|
+
├── routes.ts # HTTP router and API handlers
|
|
159
|
+
├── db.ts # SQLite schema, queries, CRUD
|
|
160
|
+
└── types.ts # TypeScript interfaces
|
|
161
|
+
|
|
162
|
+
public/
|
|
163
|
+
└── index.html # Dashboard SPA
|
|
164
|
+
|
|
165
|
+
plugin/
|
|
166
|
+
├── .claude-plugin/plugin.json # Plugin manifest
|
|
167
|
+
└── hooks/
|
|
168
|
+
├── hooks.json # SessionStart + SessionEnd events
|
|
169
|
+
├── session-start.sh # Register agent, inject messaging context
|
|
170
|
+
├── session-end.sh # Mark agent offline
|
|
171
|
+
└── poll-inbox.sh # Inbox poller for Monitor
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Deployment
|
|
175
|
+
|
|
176
|
+
Agent Relay is designed to run on a single machine on your network (or behind Tailscale). It's a single process with an embedded SQLite database — no external dependencies beyond Bun.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# one-liner
|
|
180
|
+
bunx agent-relay-server
|
|
181
|
+
|
|
182
|
+
# with options
|
|
183
|
+
PORT=8080 HOST=0.0.0.0 bunx agent-relay-server
|
|
184
|
+
|
|
185
|
+
# or install globally
|
|
186
|
+
bun install -g agent-relay-server
|
|
187
|
+
agent-relay
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
| Variable | Default | Purpose |
|
|
191
|
+
|----------|---------|---------|
|
|
192
|
+
| `PORT` | `4850` | Server port |
|
|
193
|
+
| `HOST` | `127.0.0.1` | Bind address (`0.0.0.0` for remote access) |
|
|
194
|
+
| `DB_PATH` | `agent-relay.db` | SQLite database path |
|
|
195
|
+
| `RETENTION_DAYS` | `30` | Auto-prune messages older than this |
|
|
196
|
+
| `AGENT_RELAY_LOG_REQUESTS` | `0` | Set to `1` to log all API requests |
|
|
197
|
+
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-relay-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight HTTP message relay for inter-agent communication across machines",
|
|
5
|
+
"module": "src/index.ts",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"agent-relay": "src/index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src/**/*.ts",
|
|
12
|
+
"!src/**/*.test.ts",
|
|
13
|
+
"public/**",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "bun run src/index.ts",
|
|
18
|
+
"dev": "bun --watch run src/index.ts"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"agent",
|
|
22
|
+
"relay",
|
|
23
|
+
"message-bus",
|
|
24
|
+
"claude-code",
|
|
25
|
+
"multi-agent",
|
|
26
|
+
"inter-agent",
|
|
27
|
+
"ai-agents"
|
|
28
|
+
],
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/edimuj/agent-relay"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"author": "Edin Mujkanovic",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/bun": "latest"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"typescript": "^5"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"bun": ">=1.0.0"
|
|
43
|
+
}
|
|
44
|
+
}
|