Protocol
The wire protocol between CrabTalk clients and the daemon — protobuf over UDS or TCP.
The daemon communicates with clients over a length-prefixed protobuf protocol. Every interaction — sending a message, streaming a response, managing sessions, installing packages — is a ClientMessage / ServerMessage pair over a Unix domain socket (or TCP on Windows).
If you're building a client, this is your contract with the daemon.
Transport
The wire format is simple: [u32 BE length][protobuf payload]. Maximum frame size is 16 MiB.
| Transport | When | Path / Port |
|---|---|---|
| Unix domain socket | macOS, Linux | ~/.crabtalk/run/crabtalk.sock |
| TCP | Windows, or --tcp flag | Port from ~/.crabtalk/run/crabtalk.port |
Connect, send ClientMessage frames, receive ServerMessage frames. Each connection gets its own reply channel.
Sending a message
The simplest interaction — send a message to an agent and get a complete response:
// Client sends:
message SendMsg {
string agent = 1; // agent name, e.g. "crab"
string content = 2; // the message
optional uint64 session = 3; // resume a session, or omit for latest
optional string sender = 4; // client identity, e.g. "telegram-12345"
}
// Server responds:
message SendResponse {
string agent = 1;
string content = 2;
uint64 session = 3;
string provider = 4;
string model = 5;
optional TokenUsage usage = 6;
}Streaming
For real-time responses, use StreamMsg instead of SendMsg. The server sends a sequence of StreamEvent messages:
| Event | What it carries |
|---|---|
StreamStart | Agent name + session ID |
StreamChunk | Text delta |
StreamThinking | Reasoning delta (when thinking = true) |
ToolStartEvent | Array of tool calls being dispatched |
ToolResultEvent | Single tool result with call_id and duration_ms |
ToolsCompleteEvent | All pending tool calls finished |
AskUserEvent | Agent needs input — questions with options |
StreamEnd | Final event — agent name, error (if any), provider, model, token usage |
Tool calls arrive as a batch in ToolStartEvent, results stream back individually as each completes. This enables real-time progress visibility during parallel tool execution.
Sessions
Sessions are identified by a uint64 ID. The daemon manages session persistence — clients don't need to store history.
| Operation | Message |
|---|---|
| List sessions | Sessions → SessionList |
| Kill a session | KillMsg { session } |
| Compact history | CompactMsg { session } → CompactResponse { summary } |
| List conversations | ListConversationsMsg { agent, sender } → ConversationList |
Sessions auto-resume — if you omit session in SendMsg, the daemon picks the latest session for that (agent, sender) pair.
Agent management
Create, update, delete, and inspect agents at runtime:
| Operation | Message |
|---|---|
| List agents | ListAgentsMsg → AgentList |
| Get agent details | GetAgentMsg { name } → AgentInfo |
| Create agent | CreateAgentMsg { name, config } |
| Update agent | UpdateAgentMsg { name, config } |
| Delete agent | DeleteAgentMsg { name } |
AgentInfo includes: model, max_iterations, thinking, members, skills, mcps, compact_threshold.
Cron
Schedule skills to run on a cron expression. Fires into a session whether or not a client is connected.
message CreateCronMsg {
string schedule = 1; // standard cron expression
string skill = 2; // fired as /<skill> into the session
uint64 session = 3; // target session
optional string quiet_start = 4; // HH:MM — skip during quiet hours
optional string quiet_end = 5;
bool once = 6; // fire once then delete
}Event subscription
Monitor all agent activity across all sessions from a single connection:
message SubscribeEvents {}
message AgentEventMsg {
string agent = 1;
uint64 session = 2;
AgentEventKind kind = 3; // TEXT_DELTA, THINKING_DELTA, TOOL_START, TOOL_RESULT, TOOLS_COMPLETE, DONE
string content = 4;
string timestamp = 5;
}Daemon lifecycle
| Operation | Message |
|---|---|
| Ping | Ping → Pong |
| Reload config | ReloadMsg |
| Get stats | GetStats → DaemonStats { uptime_secs, active_sessions, active_model } |
Source & design documents
The protocol is defined in a single protobuf file and documented across several RFCs. Start with the proto for the contract, read the RFCs for the reasoning behind each decision.
crabtalk.proto— the full protobuf definition- RFC 0018 — Wire Protocol — transport layer, message dispatch, streaming design
- RFC 0064 — Sessions — JSONL persistence, compaction, auto-injection
- RFC 0080 — Cron — daemon-level scheduling, quiet hours, persistence
- RFC 0009 — Transport — UDS and TCP, frame encoding, accept loop
What's next
- Build a Gateway — build a client that uses this protocol
- Sessions — how session persistence works
- Events — real-time event subscription