Sender integration
Drive the Claudium brain from any agent runtime. Five-line patch — authenticate over WebSocket, send tool-use events as JSON.
The default sender is sender.js in the repo — it tails Claude Code's .jsonl session files and forwards parsed events to the hub. You don't have to use it. If your agent runtime emits tool calls in any form, you can ship them directly to the hub's WebSocket endpoint.
Wire format
The hub accepts two message types from a sender, both JSON over WebSocket.
auth
The first frame after connecting. Authenticates the sender and tells the hub which contributor is firing events.
{
"type": "auth",
"token": "<your contributor token>",
"sharing": "full"
}
token— issued by the hub's admin tool (npm run gen-tokenlocally, or/admin/invitein production). The hub stores only the SHA-256 hash, so a leaked DB never exposes live tokens.sharing—"full"(default),"tool", or"region". Controls how much detail viewers receive. Most teams stay onfull.
The hub replies with { type: "authed", user: "<name>" } on success, or { type: "denied", reason: "..." } and closes the socket on failure.
event
Every frame after auth. One tool call per message.
{
"type": "event",
"region": "motor",
"tokens": 42,
"task": "npm test",
"tool": "Bash",
"project": "claudium",
"session": "f0f3a9c2..."
}
| Field | Required | Notes |
|---|---|---|
region | yes | One of: prefrontal, motor, parietal, visual, broca, wernicke, temporal, cerebellum. See region mapping. |
tokens | no | Output tokens emitted by this tool call. Drives the firing intensity. Clamped to [0, 100000]. |
task | no | Free-form description (file path, query string, command). Bounded to 200 chars. |
tool | no | Tool name (Read, Edit, Bash, …). Bounded to 80 chars. |
project | no | Agent label shown in the left panel. Bounded to 80 chars. |
session | no | Opaque session id used by the turn stitcher to group consecutive events. Bounded to 80 chars. Include this when you can — it improves pattern detection. |
Events that fail validation (unknown region, missing required fields) are silently dropped. Events sent before auth are dropped.
Minimal JS sender
import WebSocket from 'ws';
const ws = new WebSocket('wss://hub.example.com/ws');
ws.on('open', () => {
ws.send(JSON.stringify({
type: 'auth',
token: process.env.CLAUDIUM_TOKEN,
sharing: 'full',
}));
});
ws.on('message', (raw) => {
const msg = JSON.parse(raw);
if (msg.type === 'authed') {
// You're live. Start firing events.
ws.send(JSON.stringify({
type: 'event',
region: 'visual',
tool: 'Read',
task: 'auth.ts',
tokens: 1200,
project: 'my-app',
session: 'abc123',
}));
}
if (msg.type === 'denied') {
console.error('hub denied:', msg.reason);
process.exit(1);
}
});
Rate limiting
The hub caps events at 20 per second per sender. Bursts above that are dropped (no error returned — the sender just stops seeing those events). Your runtime probably can't generate that many tool calls, but if you batch and replay, throttle on your side.
What the hub does with your events
- Validate — drops malformed payloads. See
lib/validate.js. - Broadcast — fans the event out to every connected viewer in real time. This is what makes the brain glow.
- Persist — when the hub is running with
DATABASE_URLset, it writes a row toevents(org-partitioned, RLS-enforced). The turn-stitcher groups events into turns; the embedding worker vectorizes turn summaries. See per-org learning.
Browser-side driver
If you'd rather skip the WebSocket and call into the visualization directly from a browser:
window.brain.fire('broca', 42);
// fires a burst in Broca's area + adds 42 tokens
Useful for prototyping integrations against the visualization without standing up a hub.