WebSocket API
The WebSocket API provides real-time status updates for monitored sessions.
Connection
Connect to the WebSocket server:
ws://localhost:3000
The connection uses the same port as the HTTP server.
Message Format
All messages are JSON-encoded with a type field indicating the message type.
interface WebSocketMessage {
type: string;
[key: string]: any;
}
Server Messages
claude_status_updated
Sent when a session's status changes.
{
"type": "claude_status_updated",
"session": {
"name": "my-project",
"claude": {
"primary": "active",
"detail": "thinking",
"health": "ALIVE",
"timestamp": "2024-01-15T10:30:00.000Z",
"unchangedCount": 0
}
}
}
Fields
| Field | Type | Description |
|---|---|---|
type | "claude_status_updated" | Message type identifier |
session.name | string | Session identifier |
session.claude.primary | string | Primary status: idle, active, waiting, stuck, dead |
session.claude.detail | string | null | Detail status |
session.claude.health | string | Health: ALIVE, STUCK, DEAD, RECOVERED |
session.claude.timestamp | string | ISO 8601 timestamp |
session.claude.unchangedCount | number | Consecutive unchanged checks |
session_created
Sent when a new session is added to monitoring.
{
"type": "session_created",
"session": {
"name": "my-project",
"claude": {
"primary": "idle",
"detail": "waiting_input",
"health": "ALIVE",
"timestamp": "2024-01-15T10:30:00.000Z",
"unchangedCount": 0
}
}
}
session_deleted
Sent when a session is removed from monitoring.
{
"type": "session_deleted",
"sessionName": "my-project"
}
sessions_list
Sent on connection with the current state of all sessions.
{
"type": "sessions_list",
"sessions": [
{
"name": "project-a",
"claude": { ... }
},
{
"name": "project-b",
"claude": { ... }
}
]
}
error
Sent when an error occurs.
{
"type": "error",
"message": "Error description"
}
Client Messages
Clients can send messages to request actions.
request_sessions
Request the current list of all sessions.
{
"type": "request_sessions"
}
Response: Server sends sessions_list message.
Detail Status Values
Activity Details (when primary is active)
| Value | Description |
|---|---|
thinking | Claude is processing the request |
using_tools | Claude is executing tool calls |
responding | Claude is generating response text |
compacting | Claude is compressing conversation history |
Waiting Details (when primary is waiting)
| Value | Description |
|---|---|
permission | Claude needs permission (Yes/No prompt) |
question | Claude has asked a question |
Idle Details (when primary is idle)
| Value | Description |
|---|---|
ready | Initial ready state |
waiting_input | Waiting for user command |
Connection Example
Browser JavaScript
const ws = new WebSocket('ws://localhost:3000');
ws.onopen = () => {
console.log('Connected to Claude Session Tools');
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'sessions_list':
console.log('Current sessions:', message.sessions);
break;
case 'claude_status_updated':
console.log(`Session ${message.session.name}: ${message.session.claude.primary}`);
break;
case 'session_created':
console.log(`New session: ${message.session.name}`);
break;
case 'session_deleted':
console.log(`Session removed: ${message.sessionName}`);
break;
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Disconnected from server');
};
React Hook
import { useState, useEffect, useCallback, useRef } from 'react';
interface Session {
name: string;
claude: ClaudeStatus;
}
export function useWebSocket() {
const [sessions, setSessions] = useState<Session[]>([]);
const [connected, setConnected] = useState(false);
const wsRef = useRef<WebSocket | null>(null);
useEffect(() => {
const ws = new WebSocket('ws://localhost:3000');
wsRef.current = ws;
ws.onopen = () => setConnected(true);
ws.onclose = () => setConnected(false);
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'sessions_list':
setSessions(message.sessions);
break;
case 'claude_status_updated':
setSessions(prev =>
prev.map(s =>
s.name === message.session.name ? message.session : s
)
);
break;
case 'session_created':
setSessions(prev => [...prev, message.session]);
break;
case 'session_deleted':
setSessions(prev =>
prev.filter(s => s.name !== message.sessionName)
);
break;
}
};
return () => ws.close();
}, []);
return { sessions, connected };
}
Reconnection
The WebSocket connection may drop due to network issues. Implement reconnection logic:
function createWebSocket() {
const ws = new WebSocket('ws://localhost:3000');
ws.onclose = () => {
console.log('Connection closed, reconnecting in 3s...');
setTimeout(createWebSocket, 3000);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
ws.close();
};
return ws;
}
Message Frequency
Status updates are sent:
- Immediately when status changes
- On each file system change detection (approximately every 200ms during activity)
- Once per second during stable states (for unchanged count updates)
For high-frequency updates, consider debouncing on the client side if needed.