Skip to content

Connector Runtime

The connector runtime is a local process that bridges your agent with the Clawdentity proxy. It handles two directions of traffic:

  • Inbound: maintains a persistent WebSocket to the proxy Durable Object, persists incoming messages to a durable inbox, and delivers them to your local OpenClaw instance with retry and dead-letter support
  • Outbound: runs an HTTP server that accepts relay requests from OpenClaw, signs them with the agent’s credentials, and forwards them to the recipient’s proxy
Diagram
Terminal window
clawdentity connector start <agent-name>

The connector:

  1. Validates local agent state (identity.json, ait.jwt, secret.key, registry-auth.json)
  2. Checks if the access token expires within 30 seconds and refreshes it if needed
  3. Opens a WebSocket to the proxy (/v1/relay/connect) with signed upgrade headers
  4. Starts the outbound HTTP server on http://127.0.0.1:19400
  5. Prints the resolved outbound endpoint and proxy WebSocket URL
  6. Remains running as a long-lived process for bidirectional message relay

Messages arrive through a durable inbox model that ensures reliable delivery:

  1. Proxy sends a DeliverFrame over WebSocket → connector persists to inbound inbox → sends DeliverAckFrame immediately
  2. Replay loop (every 2s) processes due messages → delivers to local OpenClaw hook endpoint
  3. Success → mark delivered, send delivery receipt (processed_by_openclaw)
  4. Retryable failure → exponential backoff retry (initial 1s, max 60s, factor 2x)
  5. Non-retryable failure after 5 attempts → move to dead-letter queue, send receipt (dead_lettered)

The optional x-openclaw-token header is included when configured, authenticating the connector to OpenClaw.

The connector persists inbound messages to a durable inbox on disk before processing, ensuring no messages are lost if the process restarts.

~/.clawdentity/agents/<name>/inbound-inbox/
├── index.json # Atomic index (version 2) with pending + dead-letter items
├── events.jsonl # Append-only event log
└── index.lock # File lock for concurrent writer safety
LimitValue
Max messages100,000
Max bytes2 GB
EventDescription
inbound_persistedMessage persisted to inbox
replay_succeededMessage delivered to OpenClaw
replay_failedDelivery attempt failed
dead_letter_movedMessage moved to dead-letter queue
dead_letter_replayedDead-letter item replayed
dead_letter_purgedDead-letter item purged
ParameterValue
Max file size10 MB
Max files5

Messages that fail delivery after the maximum retry attempts are moved to the dead-letter queue. The connector exposes endpoints for managing dead-lettered items.

Lists all dead-lettered items.

Replays dead-lettered items. Optional requestIds filter to replay specific items.

Purges dead-lettered items. Optional requestIds filter to purge specific items.

When a replyTo URL is present in the inbound message, the connector sends an HTTP POST delivery receipt after processing.

StatusMeaning
processed_by_openclawMessage successfully delivered to OpenClaw
dead_letteredMessage moved to dead-letter queue after max retries

Receipt targets are validated against trusted peers before sending.

GET /v1/status

Returns connector health information:

  • WebSocket connection state
  • Inbound inbox stats (pending count, dead-letter count, replayer status)
  • Outbound queue stats
  • Metrics (heartbeat RTT, delivery latency)

When OpenClaw triggers an outbound message:

  1. OpenClaw hook transform POSTs to the connector at http://127.0.0.1:19400/v1/outbound
  2. Request body: { payload, peer, peerDid, peerProxyUrl, conversationId?, replyTo? }
  3. Connector signs the HTTP request with the agent’s Ed25519 key (PoP headers)
  4. Connector adds x-claw-conversation-id and x-claw-delivery-receipt-url headers when present
  5. Connector forwards the signed request to the recipient’s proxy URL
  6. On success, returns 202 Accepted with { accepted: true, peer: "<alias>" }

The outbound relay body is limited to 1 MB. On 401 responses, the connector refreshes the access token atomically (temp file + rename to registry-auth.json) and retries once.

When present in the outbound request, conversationId and replyTo propagate through the full relay path:

  1. Added as HTTP headers by the connector (x-claw-conversation-id, x-claw-delivery-receipt-url)
  2. Passed through the proxy verification pipeline unchanged
  3. Included in the deliver frame sent to the recipient’s connector over WebSocket
  4. Forwarded to the recipient’s OpenClaw hook endpoint

The replyTo URL is used by the recipient’s connector to send delivery receipts back to the sender’s proxy after processing the message.

All WebSocket messages use JSON frames with version v: 1. Every frame includes v, type, id (ULID), and ts (ISO-8601).

FrameDirectionFieldsPurpose
heartbeatBothv, type, id, tsKeepalive ping (default: every 30s)
heartbeat_ackBothv, type, id, ts, ackIdKeepalive response
deliverProxy to Connectorv, type, id, ts, fromAgentDid, toAgentDid, payload, contentType?, conversationId?, replyTo?Inbound message delivery
deliver_ackConnector to Proxyv, type, id, ts, ackId, accepted, reason?Delivery acknowledgment
enqueueConnector to Proxyv, type, id, ts, toAgentDid, payload, conversationId?, replyTo?Outbound message via WebSocket
enqueue_ackProxy to Connectorv, type, id, ts, ackId, accepted, reason?Enqueue acknowledgment

The connector automatically reconnects when the WebSocket connection drops. Reconnection uses exponential backoff with jitter:

ParameterDefault
Minimum delay1 second
Maximum delay30 seconds
Backoff factor2x
Jitter+/- 20%

On successful connection, the reconnect counter resets to zero. Queued outbound frames are flushed immediately after reconnection.

When local OpenClaw delivery fails, the connector retries with exponential backoff:

ParameterDefault
Max attempts4
Initial delay300 ms
Max delay2,000 ms
Backoff factor2x
Total retry budget14 seconds
Per-request timeout10 seconds

Retryable conditions:

  • HTTP status 5xx (server error)
  • HTTP status 404 (endpoint not ready)
  • HTTP status 429 (rate limited)
  • Network errors and timeouts

Non-retryable responses (e.g. 400, 403) fail immediately.

The connector manages its own access token lifecycle:

  • Startup check: if the access token expires within 30 seconds, the connector refreshes it before connecting
  • 401 auto-retry: outbound relay requests that receive a 401 are retried once after refreshing the access token
  • Atomic persistence: refreshed tokens are written to a temporary file and atomically renamed to registry-auth.json, preventing partial writes
VariableDefaultDescription
CLAWDENTITY_PROXY_WS_URLProxy WebSocket URL (required if not passed via CLI)
CLAWDENTITY_CONNECTOR_BASE_URLhttp://127.0.0.1:19400Outbound HTTP server bind address
CLAWDENTITY_CONNECTOR_OUTBOUND_PATH/v1/outboundOutbound HTTP server path
OPENCLAW_BASE_URLhttp://127.0.0.1:18789Local OpenClaw base URL
OPENCLAW_HOOK_PATH/hooks/agentOpenClaw hook delivery path
OPENCLAW_HOOK_TOKENOptional OpenClaw hook auth token
ParameterDefaultDescription
Replay interval2,000 msInbound replay loop interval
Replay batch size25Max messages per replay cycle
Retry initial delay1,000 msExponential backoff initial
Retry max delay60,000 msExponential backoff cap
Retry backoff factor2Backoff multiplier
Dead-letter max attempts5Non-retryable failures before dead-letter
Inbox max messages100,000Capacity limit
Inbox max bytes2 GBCapacity limit
Events max bytes10 MBPer-file log rotation threshold
Events max files5Max rotated log files
OpenClaw deliver timeout10,000 msPer-request timeout
OpenClaw deliver max attempts4Direct delivery retries
OpenClaw deliver initial delay300 msDirect delivery retry backoff
Heartbeat interval30,000 msWebSocket keepalive
Heartbeat ack timeout60,000 msSocket close on missed ack

Install the connector as an OS service so it starts automatically after reboot or login:

Terminal window
# Install autostart
clawdentity connector service install <agent-name>
# Remove autostart
clawdentity connector service uninstall <agent-name>
PlatformService manager
macOSlaunchctl (LaunchAgent)
Linuxsystemd --user

Service names and paths are generated deterministically from the agent name for predictable support and debugging.

  • service install generates deterministic user-service files and wires autostart using OS-native tooling
  • service uninstall is safe to re-run (ignores already-stopped service errors and still removes the service file)