@skvil/piertotum 1.0.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/LICENSE +21 -0
- package/README.md +327 -0
- package/broker.js +520 -0
- package/mcp-server.js +745 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 LCGF00
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="logo.png" width="150" alt="Skvil-Piertotum logo" />
|
|
3
|
+
|
|
4
|
+
# Skvil-Piertotum
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/skvil-piertotum)
|
|
7
|
+
[](https://nodejs.org)
|
|
8
|
+
[](./LICENSE)
|
|
9
|
+
|
|
10
|
+
**Let your Claude Code instances talk to each other.**
|
|
11
|
+
|
|
12
|
+
Skvil-Piertotum is a lightweight MCP + HTTP broker that connects multiple Claude Code terminals — across projects, machines, WSL, or VMs — so they can exchange messages, share context, and even delegate tasks autonomously.
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Claude Code (API project) Claude Code (Frontend project)
|
|
18
|
+
│ │
|
|
19
|
+
│ sp_send / sp_broadcast │ sp_read
|
|
20
|
+
└──────────────┬────────────────────────┘
|
|
21
|
+
│ HTTP
|
|
22
|
+
┌──────┴──────┐
|
|
23
|
+
│ broker │
|
|
24
|
+
│ :4800 │
|
|
25
|
+
│ │
|
|
26
|
+
│ messages │
|
|
27
|
+
│ contexts │
|
|
28
|
+
│ agents │
|
|
29
|
+
└─────────────┘
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## How it works
|
|
35
|
+
|
|
36
|
+
Two components, zero infrastructure:
|
|
37
|
+
|
|
38
|
+
**`broker.js`** — a tiny Express HTTP server that holds all state in memory (agents, message queues, shared key/value context). Run it once on any machine in your network.
|
|
39
|
+
|
|
40
|
+
**`mcp-server.js`** — an MCP stdio server that runs inside each Claude Code instance. It auto-registers on startup, heartbeats every 30s, and exposes 11 tools so Claude can send/receive messages and share data with other instances.
|
|
41
|
+
|
|
42
|
+
When `AUTO_PROCESS=true`, the MCP server polls for incoming messages and uses **MCP Sampling** (`createMessage`) to inject them directly into Claude's context — enabling fully autonomous agent-to-agent workflows without human intervention.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
### 1. Install
|
|
49
|
+
|
|
50
|
+
**Requirements:** Node.js 18 or later (`node --version` to check).
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/LCGF00/skvil-piertotum
|
|
54
|
+
cd skvil-piertotum
|
|
55
|
+
npm install
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Start the broker
|
|
59
|
+
|
|
60
|
+
Run this once, on any machine accessible to your terminals:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
node broker.js
|
|
64
|
+
# custom port:
|
|
65
|
+
node broker.js 5000
|
|
66
|
+
# or via env:
|
|
67
|
+
BROKER_PORT=5000 node broker.js
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The broker listens on `0.0.0.0` — reachable from any IP on your network.
|
|
71
|
+
|
|
72
|
+
> **Tip:** Run the broker on your main machine or a server that stays on. Use `hostname -I` (Linux/WSL) or `ipconfig` (Windows) to find its IP.
|
|
73
|
+
|
|
74
|
+
### 3. Add the MCP server to each Claude Code terminal
|
|
75
|
+
|
|
76
|
+
Each terminal gets a unique `AGENT_ID`:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Terminal 1 — API project
|
|
80
|
+
claude mcp add skvil-piertotum \
|
|
81
|
+
-e BROKER_URL=http://YOUR-IP:4800 \
|
|
82
|
+
-e AGENT_ID=api \
|
|
83
|
+
-e AGENT_NAME="API Project" \
|
|
84
|
+
-e PROJECT_NAME="my-saas" \
|
|
85
|
+
-- node /path/to/skvil-piertotum/mcp-server.js
|
|
86
|
+
|
|
87
|
+
# Terminal 2 — Frontend project
|
|
88
|
+
claude mcp add skvil-piertotum \
|
|
89
|
+
-e BROKER_URL=http://YOUR-IP:4800 \
|
|
90
|
+
-e AGENT_ID=front \
|
|
91
|
+
-e AGENT_NAME="Frontend Project" \
|
|
92
|
+
-e PROJECT_NAME="my-saas" \
|
|
93
|
+
-- node /path/to/skvil-piertotum/mcp-server.js
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If everything is on the same machine, use `BROKER_URL=http://localhost:4800`.
|
|
97
|
+
|
|
98
|
+
### 4. Or configure via `~/.claude.json`
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"skvil-piertotum": {
|
|
104
|
+
"type": "stdio",
|
|
105
|
+
"command": "node",
|
|
106
|
+
"args": ["/absolute/path/to/skvil-piertotum/mcp-server.js"],
|
|
107
|
+
"env": {
|
|
108
|
+
"BROKER_URL": "http://192.168.1.10:4800",
|
|
109
|
+
"AGENT_ID": "api",
|
|
110
|
+
"AGENT_NAME": "API Project",
|
|
111
|
+
"PROJECT_NAME": "my-saas"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
> Each terminal must have a **different** `AGENT_ID`.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Usage examples
|
|
123
|
+
|
|
124
|
+
Once configured, just talk to Claude naturally:
|
|
125
|
+
|
|
126
|
+
### See who's connected
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
Register in the broker and show me who else is online
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Send context from one project to another
|
|
133
|
+
|
|
134
|
+
**In the API terminal:**
|
|
135
|
+
```
|
|
136
|
+
I just finished the auth endpoints. Send the full request/response
|
|
137
|
+
structure to the 'front' terminal as type 'endpoint'.
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**In the Frontend terminal:**
|
|
141
|
+
```
|
|
142
|
+
Read incoming messages and use the endpoint spec to build the Axios services.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Share a schema or config
|
|
146
|
+
|
|
147
|
+
**In the API terminal:**
|
|
148
|
+
```
|
|
149
|
+
Save the full Prisma schema we just defined to shared context under the key 'db-schema'.
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**In any other terminal:**
|
|
153
|
+
```
|
|
154
|
+
Read the shared context 'db-schema' and use it as the source of truth for TypeScript types.
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Broadcast an announcement
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
Broadcast to all agents that the base API URL changed from /api/v1 to /api/v2.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Check system status
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
Show broker status with all connected agents and their unread message counts.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Available MCP Tools
|
|
172
|
+
|
|
173
|
+
| Tool | Description |
|
|
174
|
+
|---|---|
|
|
175
|
+
| `sp_register` | Re-register this terminal (runs automatically on startup) |
|
|
176
|
+
| `sp_list_agents` | List all connected agents with staleness indicators |
|
|
177
|
+
| `sp_send` | Send a message to a specific agent |
|
|
178
|
+
| `sp_broadcast` | Send a message to all connected agents |
|
|
179
|
+
| `sp_read` | Read received messages (with pagination and explicit ACK) |
|
|
180
|
+
| `sp_clear` | Delete all messages in this agent's queue |
|
|
181
|
+
| `sp_set_context` | Save shared data by key (schema, config, endpoints, etc.) |
|
|
182
|
+
| `sp_get_context` | Read shared data by key |
|
|
183
|
+
| `sp_list_contexts` | List all available context keys |
|
|
184
|
+
| `sp_status` | Broker status: uptime, agents, unread counts, autonomous mode state |
|
|
185
|
+
| `sp_auto_process` | Toggle autonomous message processing at runtime |
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Environment Variables
|
|
190
|
+
|
|
191
|
+
### MCP server (`mcp-server.js`)
|
|
192
|
+
|
|
193
|
+
| Variable | Default | Description |
|
|
194
|
+
|---|---|---|
|
|
195
|
+
| `BROKER_URL` | `http://localhost:4800` | URL of the broker |
|
|
196
|
+
| `AGENT_ID` | machine hostname | Unique identifier for this instance — **must differ per terminal** |
|
|
197
|
+
| `AGENT_NAME` | `SP-{id}` | Human-readable display name |
|
|
198
|
+
| `PROJECT_NAME` | `unknown` | Used for grouping agents by project |
|
|
199
|
+
| `AUTO_PROCESS` | `false` | Set to `true` to enable autonomous message processing via MCP Sampling |
|
|
200
|
+
| `POLL_INTERVAL_MS` | `10000` | Polling interval in ms when `AUTO_PROCESS=true` (minimum: 1000) |
|
|
201
|
+
|
|
202
|
+
### Broker (`broker.js`)
|
|
203
|
+
|
|
204
|
+
| Variable | Default | Description |
|
|
205
|
+
|---|---|---|
|
|
206
|
+
| `BROKER_PORT` | `4800` | Port to listen on (also accepts first CLI argument) |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Autonomous Mode
|
|
211
|
+
|
|
212
|
+
When `AUTO_PROCESS=true`, the MCP server polls for unread messages and uses **MCP Sampling** to process them without human input:
|
|
213
|
+
|
|
214
|
+
1. Polls the broker every `POLL_INTERVAL_MS` for unread messages
|
|
215
|
+
2. For each message: marks itself `busy`, calls `createMessage()` with the message injected into Claude's context
|
|
216
|
+
3. Sends Claude's response back to the original sender
|
|
217
|
+
4. Marks itself `idle` and ACKs the message
|
|
218
|
+
|
|
219
|
+
Enable it at startup via env var, or toggle it at runtime with `sp_auto_process`:
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
Enable autonomous processing mode
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Agents broadcast their availability via shared context under `{AGENT_ID}-status`:
|
|
226
|
+
- `idle` — ready to receive tasks
|
|
227
|
+
- `busy | task: ... | início: HH:MM:SS` — working
|
|
228
|
+
- `offline` — gracefully shut down
|
|
229
|
+
|
|
230
|
+
> **Requirements:** The Claude Code client must support MCP Sampling. If it doesn't, the mode disables itself automatically and reports the reason in `sp_status`.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Broker REST API
|
|
235
|
+
|
|
236
|
+
The broker exposes a plain HTTP API — useful for debugging or integration:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Status overview
|
|
240
|
+
curl http://localhost:4800/status
|
|
241
|
+
|
|
242
|
+
# List agents
|
|
243
|
+
curl http://localhost:4800/agents
|
|
244
|
+
|
|
245
|
+
# Read messages for an agent (unread only, limit 10)
|
|
246
|
+
curl "http://localhost:4800/messages/api?unread=true&limit=10"
|
|
247
|
+
|
|
248
|
+
# ACK messages by ID
|
|
249
|
+
curl -X POST http://localhost:4800/messages/api/ack \
|
|
250
|
+
-H "Content-Type: application/json" \
|
|
251
|
+
-d '{"ids": ["msg_123", "msg_456"]}'
|
|
252
|
+
|
|
253
|
+
# Send a message
|
|
254
|
+
curl -X POST http://localhost:4800/messages/send \
|
|
255
|
+
-H "Content-Type: application/json" \
|
|
256
|
+
-d '{"from":"api","to":"front","content":"hello","type":"text"}'
|
|
257
|
+
|
|
258
|
+
# Shared context
|
|
259
|
+
curl http://localhost:4800/context
|
|
260
|
+
curl http://localhost:4800/context/db-schema
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Full endpoint reference:
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
POST /agents/register Register an agent
|
|
267
|
+
GET /agents List agents
|
|
268
|
+
POST /agents/:id/heartbeat Heartbeat (404 if not registered)
|
|
269
|
+
DELETE /agents/:id Deregister agent
|
|
270
|
+
|
|
271
|
+
POST /messages/send Send to one agent
|
|
272
|
+
POST /messages/broadcast Send to all agents except sender
|
|
273
|
+
GET /messages/:id Read messages (?unread=true, ?limit=N)
|
|
274
|
+
POST /messages/:id/ack Mark message IDs as read
|
|
275
|
+
DELETE /messages/:id Clear all messages
|
|
276
|
+
|
|
277
|
+
POST /context Save context entry
|
|
278
|
+
GET /context List context keys
|
|
279
|
+
GET /context/:key Read context value
|
|
280
|
+
DELETE /context/:key Delete context entry
|
|
281
|
+
|
|
282
|
+
GET /status Broker overview
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Design Notes
|
|
288
|
+
|
|
289
|
+
- **In-memory only** — all state is lost if the broker restarts. Agents re-register automatically on the next heartbeat (within 30s). For persistence, adapt the broker to use SQLite.
|
|
290
|
+
- **Resource limits** — max 100 agents, 200 messages per queue (oldest dropped), 1000 context keys, 100 KB per context value.
|
|
291
|
+
- **Stale agent cleanup** — agents that miss 3 heartbeats (90s) are automatically removed.
|
|
292
|
+
- **Message types** — `text`, `code`, `schema`, `endpoint`, `config`. Used by agents to route and handle responses appropriately.
|
|
293
|
+
- **Prompt injection protection** — in autonomous mode, incoming message content is wrapped in XML tags with a random nonce before being injected into Claude's context.
|
|
294
|
+
- **ES modules** — both files use `import/export` (`"type": "module"` in `package.json`).
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Use Cases
|
|
299
|
+
|
|
300
|
+
**Monorepo with multiple services**
|
|
301
|
+
Each service runs in its own terminal. When the API changes a contract, it notifies the frontend automatically.
|
|
302
|
+
|
|
303
|
+
**Distributed setup (PC + WSL + VM)**
|
|
304
|
+
Run the broker on the host machine. WSL and VM terminals connect via the host IP.
|
|
305
|
+
|
|
306
|
+
**Multi-agent orchestration**
|
|
307
|
+
An orchestrator terminal delegates tasks to worker terminals. Workers report status via shared context. The orchestrator checks `sp_get_context("{worker}-status")` before assigning new work.
|
|
308
|
+
|
|
309
|
+
**Team knowledge sharing**
|
|
310
|
+
Each developer registers their terminal. Share schemas, decisions, and context across the team in real time — without copy-pasting into chat.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Contributing
|
|
315
|
+
|
|
316
|
+
Issues and pull requests are welcome. For non-trivial changes, please open an issue first to discuss the approach.
|
|
317
|
+
|
|
318
|
+
## License
|
|
319
|
+
|
|
320
|
+
MIT — see [LICENSE](./LICENSE).
|
|
321
|
+
|
|
322
|
+
## References
|
|
323
|
+
|
|
324
|
+
The tool design, security hardening, and MCP best practices in this project were based on:
|
|
325
|
+
|
|
326
|
+
- [Writing tools for agents — Anthropic Engineering](https://www.anthropic.com/engineering/writing-tools-for-agents)
|
|
327
|
+
- [MCP Security Best Practices — Model Context Protocol](https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices)
|