Skip to content

WebSocket Protocol

This is the complete message contract between the Antimatter Gateway and the mobile client (Android or iOS). All frames are UTF-8 JSON text objects with a type discriminator field.

  • Compression: permessage-deflate enabled
  • Max payload: 10 MiB
  • Binding: Gateway binds to 127.0.0.1:8765 (IPC) and is exposed via Cloudflare tunnel

Connection Lifecycle

Mobile App Antimatter Gateway
β”‚ β”‚
β”‚ WSS upgrade (Authorization: Bearer) β”‚
β”‚ ────────────────────────────────────────►│ Origin check + token verify
β”‚ ◄────────── 101 Switching Protocols ─────│ (or 401/403/close 4001)
β”‚ β”‚
β”‚ AUTH_CHALLENGE { challenge: base64 } β”‚
β”‚ ────────────────────────────────────────►│ Sign nonce with Ed25519 key
β”‚ ◄────── AUTH_RESPONSE { signature } ────│ Client marked authenticated
β”‚ β”‚
β”‚ GET_AVAILABLE_AGENTS β”‚
β”‚ ────────────────────────────────────────►│
β”‚ ◄────── AVAILABLE_AGENTS { agents[] } ──│
β”‚ β”‚
β”‚ ←──── Bidirectional message exchange ───►│
β”‚ SEND_MESSAGE / GET_FILES / PTY_* ... β”‚

1. Transport & Origin Validation

The Gateway rejects WebSocket upgrades unless the Origin header matches the allow-list:

  • vscode-webview://… (extension webview)
  • https://<team>.cloudflareaccess.com (Cloudflare Access)
  • Mobile app origins (dynamic β€” derived from platform)

Rejected origins β†’ HTTP 403 Forbidden (Cross-Site WebSocket Hijacking prevention).

2. Bearer Token Authentication

The mobile client presents the 256-bit pairing token, checked in priority order:

  1. Authorization: Bearer <token> header
  2. First Sec-WebSocket-Protocol value
  3. ?token=<token> URL query parameter

The token is compared with timing-safe equality (crypto.timingSafeEqual). Invalid token β†’ close code 4001 Unauthorized.

3. Ed25519 Handshake

After the socket opens, the client sends AUTH_CHALLENGE with a random base64 nonce. The Gateway signs the raw nonce bytes with its persistent Ed25519 private key (stored in OS keychain) and returns AUTH_RESPONSE. The client verifies the signature against the Ed25519 public key received during QR pairing β€” proving the Gateway’s identity and preventing MITM attacks.


WebSocket Close Codes

CodeMeaningCause
1000Normal closureClean disconnect
4000Rate limitedToo many failed token attempts (60s ban)
4001UnauthorizedMissing or invalid pairing token
403Forbidden Origin (HTTP)Origin header not in allow-list

Inbound Messages (App β†’ Gateway)

These are sent from the mobile client to the Gateway.

AUTH_CHALLENGE

Begin the Ed25519 cryptographic handshake.

{
"type": "AUTH_CHALLENGE",
"challenge": "base64-encoded-random-nonce"
}

GET_AVAILABLE_AGENTS

Request the list of currently connected adapters.

{
"type": "GET_AVAILABLE_AGENTS"
}

SEND_MESSAGE

Inject a prompt into the target AI agent.

{
"type": "SEND_MESSAGE",
"target": "ag",
"content": "Refactor the authentication module"
}
FieldTypeRequiredDescription
targetstringβœ“Adapter name ("ag", "ag2", "cc")
contentstringβœ“Text prompt to inject
imagesstring[]β€”Base64-encoded image attachments

GET_FILES

Request the workspace file tree from the target adapter.

{
"type": "GET_FILES",
"target": "ag",
"path": "/"
}

READ_FILE

Read the contents of a specific file.

{
"type": "READ_FILE",
"target": "ag",
"path": "/src/main/App.kt"
}

WRITE_FILE

Write content to a file in the workspace.

{
"type": "WRITE_FILE",
"target": "ag",
"path": "/src/main/App.kt",
"content": "package com.example\n..."
}

SUBSCRIBE_CONVERSATION

Subscribe to real-time trajectory updates for a specific conversation.

{
"type": "SUBSCRIBE_CONVERSATION",
"conversationId": "uuid-string"
}

PTY Messages

Control a remote terminal session.

Start a PTY session
{
"type": "PTY_START",
"id": "session-uuid",
"cols": 80,
"rows": 24
}
Send keystrokes
{
"type": "PTY_INPUT",
"id": "session-uuid",
"data": "ls -la\n"
}
Resize terminal
{
"type": "PTY_RESIZE",
"id": "session-uuid",
"cols": 120,
"rows": 40
}

PING

Keepalive ping to prevent Cloudflare from closing idle connections.

{ "type": "PING" }

Outbound Messages (Gateway β†’ App)

These are sent from the Gateway to the mobile client.

AUTH_RESPONSE

Reply to AUTH_CHALLENGE with the Ed25519 signature.

{
"type": "AUTH_RESPONSE",
"signature": "base64-encoded-ed25519-signature"
}

AVAILABLE_AGENTS

List of currently registered and connected adapters.

{
"type": "AVAILABLE_AGENTS",
"agents": ["ag", "ag2", "cc"]
}

STEP

A single trajectory step from the AI agent β€” streamed in real-time.

{
"type": "STEP",
"conversationId": "uuid-string",
"stepIndex": 42,
"stepType": "tool_call",
"content": "...",
"toolName": "bash",
"toolInput": { "command": "git status" },
"toolResult": "On branch main..."
}
stepTypeDescription
thinkingAgent internal reasoning (may be truncated)
textAgent text response
tool_callAgent invokes a tool
tool_resultTool execution result
artifactFile artifact created by agent

FILE_TREE

Response to GET_FILES.

{
"type": "FILE_TREE",
"path": "/",
"entries": [
{ "name": "src", "isDirectory": true },
{ "name": "README.md", "isDirectory": false, "size": 4096 }
]
}

FILE_CONTENT

Response to READ_FILE.

{
"type": "FILE_CONTENT",
"path": "/src/main/App.kt",
"content": "package com.example\n...",
"encoding": "utf-8"
}

PTY_OUTPUT

Terminal output from the remote PTY session.

{
"type": "PTY_OUTPUT",
"id": "session-uuid",
"data": "base64-encoded-bytes"
}

PONG

Reply to PING.

{ "type": "PONG" }

ERROR

Returned when a handler throws or an unknown message type is received.

{
"type": "ERROR",
"code": "UNKNOWN_TYPE",
"message": "Unrecognized message type: FOO"
}

Writing a Custom Adapter

Any adapter that speaks this IPC protocol can integrate with Antimatter. Here’s a minimal example:

Minimal Python adapter
import asyncio, websockets, json
async def main():
async with websockets.connect("ws://127.0.0.1:8765") as ws:
# Register with the Gateway
await ws.send(json.dumps({
"type": "REGISTER_ADAPTER",
"name": "my-custom-agent"
}))
async for message in ws:
msg = json.loads(message)
if msg["type"] == "SEND_MESSAGE":
print(f"Received prompt: {msg['content']}")
# Process and respond...
asyncio.run(main())

Saif Mukhtar

Saif Mukhtar

Creator & Lead Developer of Antimatter Β· Android, iOS & Python engineer