@dolusoft/claude-collab 1.10.3 → 1.11.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 +146 -56
- package/dist/cli.js +313 -477
- package/dist/cli.js.map +1 -1
- package/dist/mcp-main.js +312 -476
- package/dist/mcp-main.js.map +1 -1
- package/package.json +80 -81
package/README.md
CHANGED
|
@@ -7,13 +7,12 @@ Real-time collaboration between Claude Code terminals via MCP (Model Context Pro
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Claude Collab lets multiple Claude Code terminals communicate
|
|
10
|
+
Claude Collab lets multiple Claude Code terminals communicate directly — no central server needed. Each peer runs its own node; peers discover each other automatically on the LAN via UDP multicast and connect directly over WebSocket.
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
alice
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
└─────────────────┘
|
|
13
|
+
alice ◄──────────────────► bob
|
|
14
|
+
direct WebSocket
|
|
15
|
+
(auto-discovered)
|
|
17
16
|
```
|
|
18
17
|
|
|
19
18
|
## Setup
|
|
@@ -28,55 +27,39 @@ claude mcp add claude-collab -- npx -y @dolusoft/claude-collab --name <your-name
|
|
|
28
27
|
|-------------|-------------|
|
|
29
28
|
| `<your-name>` | Your identifier on the network (e.g. `alice`, `backend`, `frontend`) |
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
### Step 2 — Connect to peers
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
In Claude Code, call the `start_hub` tool:
|
|
32
|
+
Call `peer_find` in Claude Code:
|
|
36
33
|
|
|
37
34
|
```
|
|
38
|
-
|
|
39
|
-
start_hub(port=8888) # custom port
|
|
35
|
+
peer_find()
|
|
40
36
|
```
|
|
41
37
|
|
|
42
38
|
This will:
|
|
43
|
-
1.
|
|
44
|
-
2.
|
|
45
|
-
3.
|
|
46
|
-
|
|
47
|
-
Everyone else will auto-connect within seconds. No IP address sharing needed.
|
|
39
|
+
1. Open a **Windows UAC prompt** — click **Yes** to open your firewall
|
|
40
|
+
2. Wait 30 seconds while peers are discovered and connected
|
|
41
|
+
3. Close the firewall (another UAC prompt) — existing connections persist
|
|
48
42
|
|
|
49
|
-
|
|
43
|
+
Everyone on the team should call `peer_find` at the same time when setting up.
|
|
50
44
|
|
|
51
|
-
|
|
52
|
-
stop_hub()
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
This stops the server and removes the firewall rule (UAC prompt shown once).
|
|
56
|
-
|
|
57
|
-
---
|
|
45
|
+
### Step 3 — Adding a new peer later
|
|
58
46
|
|
|
59
|
-
|
|
47
|
+
Only the **new peer** needs to call `peer_find`. Existing peers will connect to them automatically — no action needed from others.
|
|
60
48
|
|
|
61
|
-
|
|
49
|
+
### Step 4 — After a disconnect or restart
|
|
62
50
|
|
|
63
|
-
|
|
64
|
-
# Start hub manually in a terminal:
|
|
65
|
-
npx @dolusoft/claude-collab --hub --port 9999
|
|
51
|
+
The disconnecting peer calls `peer_find` again. Others reconnect automatically.
|
|
66
52
|
|
|
67
|
-
|
|
68
|
-
claude mcp add claude-collab -- npx -y @dolusoft/claude-collab --name <your-name> --server <hub-ip>:<hub-port>
|
|
69
|
-
```
|
|
53
|
+
---
|
|
70
54
|
|
|
71
55
|
## MCP Tools
|
|
72
56
|
|
|
73
57
|
| Tool | Description |
|
|
74
58
|
|------|-------------|
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `peers` | Show currently connected peers and your own name. |
|
|
59
|
+
| `peer_find` | Discover and connect to peers. Opens firewall, waits 30s, closes firewall. |
|
|
60
|
+
| `ask` | Ask a peer a question by name. Waits up to 5 minutes for a reply. |
|
|
61
|
+
| `reply` | Reply to an incoming question. |
|
|
62
|
+
| `peers` | Show connected peers and your own name/port. |
|
|
80
63
|
| `history` | Show past questions and answers from this session. |
|
|
81
64
|
|
|
82
65
|
## Example
|
|
@@ -85,38 +68,145 @@ claude mcp add claude-collab -- npx -y @dolusoft/claude-collab --name <your-name
|
|
|
85
68
|
# Alice asks Bob
|
|
86
69
|
ask("bob", "What's the response format for the /users endpoint?")
|
|
87
70
|
|
|
88
|
-
# Bob sees the question
|
|
89
|
-
reply("
|
|
71
|
+
# Bob sees the question injected into his terminal and replies
|
|
72
|
+
reply("<question-id>", "Returns JSON: { id, name, email }")
|
|
73
|
+
|
|
74
|
+
# Alice receives the answer
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Use Case: Sharing Context Between Agents
|
|
78
|
+
|
|
79
|
+
Claude Code works best when focused on a single context — one terminal per feature, service, or role. But when multiple Claude instances work in parallel, they can't share what they know.
|
|
90
80
|
|
|
91
|
-
|
|
81
|
+
**Claude Collab bridges that gap.** If a user told Alice Claude Code about an API key 10 messages ago, Bob Claude Code can ask Alice Claude Code directly — and Alice Claude Code answers from her own conversation context. No copy-paste. No switching tabs. The knowledge travels between agents.
|
|
82
|
+
|
|
83
|
+
Alice Claude Code and Bob Claude Code are both connected via Claude Collab. During Alice Claude Code's session, the user manually entered an API key:
|
|
84
|
+
|
|
85
|
+
> *"My API key is sk-abc123..."*
|
|
86
|
+
|
|
87
|
+
This is now part of Alice Claude Code's context. Bob Claude Code doesn't know — he's been working in a separate terminal and needs the key to make API calls.
|
|
88
|
+
|
|
89
|
+
Bob Claude Code asks Alice Claude Code directly:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
ask("alice", "What is the API key?")
|
|
92
93
|
```
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
Alice Claude Code's terminal receives the question, and she replies from what she already knows:
|
|
95
96
|
|
|
96
97
|
```
|
|
97
|
-
|
|
98
|
-
├── infrastructure/
|
|
99
|
-
│ ├── hub/
|
|
100
|
-
│ │ ├── hub-server.ts # WebSocket hub — routes messages by name
|
|
101
|
-
│ │ ├── hub-client.ts # Connects to hub, implements ICollabClient
|
|
102
|
-
│ │ ├── hub-manager.ts # Orchestrates hub + firewall + mDNS advertising
|
|
103
|
-
│ │ └── hub-protocol.ts # Wire protocol types
|
|
104
|
-
│ ├── mdns/
|
|
105
|
-
│ │ ├── mdns-advertiser.ts # Broadcasts hub presence on LAN via mDNS
|
|
106
|
-
│ │ └── mdns-discovery.ts # Discovers hub on LAN via mDNS
|
|
107
|
-
│ └── terminal-injector/ # Injects incoming questions into Claude Code
|
|
108
|
-
└── presentation/
|
|
109
|
-
└── mcp/ # MCP server + tools (start_hub, stop_hub, ask, reply, peers, history)
|
|
98
|
+
reply("<question-id>", "sk-abc123...")
|
|
110
99
|
```
|
|
111
100
|
|
|
101
|
+
Bob Claude Code gets the answer and continues working — without the user having to repeat themselves.
|
|
102
|
+
|
|
103
|
+
```mermaid
|
|
104
|
+
sequenceDiagram
|
|
105
|
+
participant User
|
|
106
|
+
participant Alice Claude Code
|
|
107
|
+
participant Bob Claude Code
|
|
108
|
+
|
|
109
|
+
Alice Claude Code->>Alice Claude Code: peer_find()
|
|
110
|
+
Note over Alice Claude Code: UAC popup → firewall opens
|
|
111
|
+
Bob Claude Code->>Bob Claude Code: peer_find()
|
|
112
|
+
Note over Bob Claude Code: UAC popup → firewall opens
|
|
113
|
+
|
|
114
|
+
Alice Claude Code-)Bob Claude Code: UDP multicast discovery
|
|
115
|
+
Bob Claude Code-)Alice Claude Code: UDP multicast discovery
|
|
116
|
+
Alice Claude Code->>Bob Claude Code: WebSocket HELLO
|
|
117
|
+
Bob Claude Code-->>Alice Claude Code: HELLO_ACK
|
|
118
|
+
Note over Alice Claude Code,Bob Claude Code: P2P connection established
|
|
119
|
+
|
|
120
|
+
Note over Alice Claude Code: firewall closes (connection persists)
|
|
121
|
+
Note over Bob Claude Code: firewall closes (connection persists)
|
|
122
|
+
|
|
123
|
+
User->>Alice Claude Code: "My API key is sk-abc123..."
|
|
124
|
+
Note over Alice Claude Code: Stored in context
|
|
125
|
+
|
|
126
|
+
Bob Claude Code->>Alice Claude Code: ask("alice", "What is the API key?")
|
|
127
|
+
Alice Claude Code-->>Bob Claude Code: ASK_ACK
|
|
128
|
+
Note over Alice Claude Code: Question injected into terminal
|
|
129
|
+
Alice Claude Code->>Bob Claude Code: reply(questionId, "sk-abc123...")
|
|
130
|
+
Note over Bob Claude Code: Uses API key
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## How it works
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Startup:
|
|
139
|
+
Each peer binds a WebSocket server on a random port (10000–19999)
|
|
140
|
+
Each peer broadcasts UDP multicast (239.255.42.42:11776) every 5s
|
|
141
|
+
|
|
142
|
+
Discovery:
|
|
143
|
+
Peer A hears Peer B's multicast → connects outbound to B's WS port
|
|
144
|
+
If multicast is one-way (e.g. VMware + WiFi), the receiving side
|
|
145
|
+
sends a unicast reply so both peers discover each other
|
|
146
|
+
|
|
147
|
+
peer_find:
|
|
148
|
+
Opens firewall (inbound TCP + UDP 11776) → wait → closes firewall
|
|
149
|
+
Established connections persist after firewall closes (stateful TCP)
|
|
150
|
+
New peers only need to open their own firewall — existing peers
|
|
151
|
+
connect outbound to them automatically
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Limitations
|
|
155
|
+
|
|
156
|
+
- **Windows only** — terminal injection uses `kernel32.dll` Win32 APIs (`AttachConsole`, `WriteConsoleInput`) compiled via PowerShell. macOS and Linux are not supported.
|
|
157
|
+
- **LAN only** — UDP multicast TTL is set to 1, so packets cannot cross routers. Does not work over the internet or VPNs that don't forward multicast.
|
|
158
|
+
- **No encryption** — peer connections use plain `ws://` WebSocket. Traffic is unencrypted on the network.
|
|
159
|
+
- **5-minute answer timeout** — if the peer does not reply within 5 minutes, `ask()` times out. The question is not retried automatically.
|
|
160
|
+
- **One queued answer per offline peer** — if a peer is offline and you reply to multiple questions from them, only the last reply is queued and delivered on reconnect.
|
|
161
|
+
- **No persistence** — all questions, answers, and history are stored in memory. Restarting the process clears everything.
|
|
162
|
+
- **No broadcast** — `ask()` targets a single peer by name. There is no tool to send a message to all peers at once.
|
|
163
|
+
- **Peer names are not unique** — if two peers join with the same name, the second connection is silently dropped.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
112
167
|
## Development
|
|
113
168
|
|
|
114
169
|
```bash
|
|
115
170
|
git clone https://github.com/dolusoft/claude-collab.git
|
|
116
171
|
cd claude-collab
|
|
117
172
|
pnpm install
|
|
118
|
-
pnpm build
|
|
119
|
-
pnpm
|
|
173
|
+
pnpm build # tsup → dist/mcp-main.js + dist/cli.js
|
|
174
|
+
pnpm typecheck # tsc --noEmit
|
|
175
|
+
pnpm test # vitest unit tests
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Testing locally with two peers
|
|
179
|
+
|
|
180
|
+
Open two terminals on the same machine and run:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Terminal 1
|
|
184
|
+
node dist/mcp-main.js --name alice
|
|
185
|
+
|
|
186
|
+
# Terminal 2
|
|
187
|
+
node dist/mcp-main.js --name bob
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Both nodes will bind on random ports in the `10000–19999` range and discover each other via UDP multicast automatically.
|
|
191
|
+
|
|
192
|
+
### Project structure
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
src/
|
|
196
|
+
├── infrastructure/
|
|
197
|
+
│ ├── discovery/
|
|
198
|
+
│ │ └── multicast-discovery.ts # UDP multicast (239.255.42.42:11776) + unicast reply
|
|
199
|
+
│ ├── firewall/
|
|
200
|
+
│ │ └── firewall.ts # Windows Firewall via UAC-elevated netsh
|
|
201
|
+
│ ├── p2p/
|
|
202
|
+
│ │ ├── p2p-node.ts # WS server + client + peer management
|
|
203
|
+
│ │ └── p2p-protocol.ts # Wire protocol: HELLO, ASK, ASK_ACK, ANSWER
|
|
204
|
+
│ └── terminal-injector/
|
|
205
|
+
│ └── windows-injector.ts # Injects questions into Claude Code via WriteConsoleInput
|
|
206
|
+
└── presentation/
|
|
207
|
+
└── mcp/
|
|
208
|
+
├── server.ts # MCP server setup
|
|
209
|
+
└── tools/ # ask, reply, peers, history, peer_find
|
|
120
210
|
```
|
|
121
211
|
|
|
122
212
|
## License
|