Skip to main content

Overview

Mission Control provides real-time visibility into agent activity through three complementary systems: Activity Feed, Live Sessions, and Log Viewer. Updates arrive via WebSocket (gateway) and Server-Sent Events (database changes) with smart polling fallback.
Real-time monitoring requires either a connected gateway (WebSocket) or an active SSE stream. Both pause polling to reduce server load.

Activity Feed

The Activity Feed is a chronological stream of all system events.

Accessing the Feed

1

Open Activity Panel

Click Activity in the left navigation rail.
2

View Live Stream

Events appear instantly as they occur. A pulsing green indicator shows live status.
3

Filter Events

Use the filter bar to narrow by activity type, actor, or limit.

Event Types

The feed tracks 9+ event types:
  • task_created β€” New task added
  • task_updated β€” Task status or details changed
  • task_deleted β€” Task removed
  • assignment β€” Task assigned to agent

Activity Card Structure

Each activity displays:
  1. Icon β€” Color-coded symbol for event type (e.g., + for created, ~ for updated)
  2. Actor β€” Who triggered the event (agent name or β€œsystem”)
  3. Description β€” Human-readable event summary
  4. Entity Details β€” Task title, agent name, or related object info
  5. Timestamp β€” Relative time (β€œ5m ago”, β€œ2h ago”)
  6. Additional Data β€” Expandable JSON details (click β€œShow details”)

Filtering

Narrow the feed using filter controls:
Select from dropdown:
  • All Types
  • task_created
  • agent_status_change
  • comment_added
  • etc.
Filter to specific agent or user:
  • All Actors
  • researcher-01
  • system
  • admin
Control result count:
  • 25 items
  • 50 items (default)
  • 100 items
  • 200 items

Live vs. Paused Mode

Toggle auto-refresh with the Live/Paused button:
  • Live 🟒 β€” Updates every 30 seconds + instant SSE delivery
  • Paused ⚫ β€” Manual refresh only
When SSE is connected, β€œLive” mode pauses polling and relies entirely on event stream. Notifications arrive within ~50ms.

Live Sessions

Track active agent sessions in real-time (gateway-connected agents only).

Session Attributes

FieldDescription
KeyUnique session identifier
KindSession type (e.g., β€œclawd”, β€œagent”, β€œcli”)
AgeTime since session started (e.g., β€œ2h”, β€œ5m”)
ModelLLM model in use (normalized, e.g., β€œsonnet-4”)
TokensUsage (e.g., β€œ12.5K/35K”)
ActiveBoolean indicator (active if updated within last hour)
Message CountNumber of messages exchanged
CostEstimated cost in USD

Viewing Sessions

Sessions appear in the Sessions panel (if gateway is connected) or can be queried via API:
curl http://localhost:3000/api/sessions \
  -H "x-api-key: your-api-key"
Response:
{
  "sessions": [
    {
      "id": "session-abc123",
      "key": "clawd-researcher-01",
      "kind": "clawd",
      "age": "2h",
      "model": "sonnet-4",
      "tokens": "12500/35000",
      "active": true,
      "startTime": 1735689600000,
      "lastActivity": 1735696800000,
      "messageCount": 47,
      "cost": 0.0875
    }
  ]
}

Log Viewer

Stream logs from agents and gateway in real-time.

Accessing Logs

1

Open Log Viewer

Navigate to Logs in the side panel.
2

View Stream

Logs auto-scroll as new entries arrive.
3

Filter

Use level filters (info/warn/error) or search bar.

Log Levels

Debug

Verbose diagnostic messages

Info

Normal operational events

Warn

Potential issues requiring attention

Error

Failures and exceptions

Log Structure

Each log entry includes:
{
  "id": "log-1735696800-abc123",
  "timestamp": 1735696800000,
  "level": "info",
  "source": "agent",
  "session": "clawd-researcher-01",
  "message": "Task #42 completed successfully",
  "data": {"taskId": 42, "duration": 320}
}

Searching Logs

Use the Log Viewer search bar or query via API:
# Search by text
curl http://localhost:3000/api/logs?search=error \
  -H "x-api-key: your-api-key"

# Filter by level
curl http://localhost:3000/api/logs?level=error \
  -H "x-api-key: your-api-key"

# Filter by source
curl http://localhost:3000/api/logs?source=gateway \
  -H "x-api-key: your-api-key"

WebSocket Connection

Mission Control connects to the OpenClaw gateway via WebSocket.

Connection Flow

1

Challenge-Response Handshake

  1. Client connects to ws://gateway:18789
  2. Server sends connect.challenge with nonce
  3. Client signs payload with Ed25519 device identity
  4. Server validates signature and returns device token
2

Authenticated Session

WebSocket connection authenticated. Client can subscribe to events.
3

Heartbeat Monitoring

Client sends ping every 30 seconds. Server responds with pong. RTT tracked.

Connection Status

View connection state in the header bar:
  • 🟒 Connected β€” Gateway online, receiving events
  • 🟑 Connecting β€” Handshake in progress
  • πŸ”΄ Disconnected β€” Offline or connection failed
  • ⚠️ Reconnecting β€” Attempting reconnection (exponential backoff)

Manual Reconnect

If connection drops:
  1. Check gateway status (is it running?)
  2. Verify OPENCLAW_GATEWAY_HOST and OPENCLAW_GATEWAY_PORT in .env
  3. Click Reconnect in the connection status widget
If handshake fails with β€œorigin not allowed”, add your Mission Control URL to gateway.controlUi.allowedOrigins in the gateway’s openclaw.json.

Server-Sent Events (SSE)

Mission Control uses SSE to stream database change events to all connected clients.

Event Types

  • agent.created
  • agent.updated
  • agent.deleted
  • task.created
  • task.updated
  • task.deleted
  • comment.added
  • notification.created

SSE Connection

Clients automatically connect to /api/events on page load:
const eventSource = new EventSource('/api/events')

eventSource.addEventListener('task.updated', (e) => {
  const task = JSON.parse(e.data)
  console.log('Task updated:', task)
})

Connection Indicator

The SSE connection status appears in the Activity Feed:
  • 🟒 SSE Connected β€” Live event stream active
  • πŸ”΄ SSE Disconnected β€” Falling back to polling

Smart Polling

When neither WebSocket nor SSE is available, Mission Control uses intelligent polling:

Polling Behavior

  • Poll every 30 seconds (configurable per component)
  • Fire immediate refresh on visibility change
  • Reset backoff multiplier

Implementation

Components use the useSmartPoll hook:
import { useSmartPoll } from '@/lib/use-smart-poll'

function MyPanel() {
  const fetchData = async () => {
    const response = await fetch('/api/data')
    const data = await response.json()
    setData(data)
  }

  // Poll every 30s, pause when SSE is connected
  useSmartPoll(fetchData, 30000, { 
    pauseWhenSseConnected: true 
  })
}

Heartbeat System

Mission Control tracks agent liveness via periodic heartbeats.

Agent Heartbeat

Agents send heartbeats every 60-300 seconds (configurable):
curl -X POST http://localhost:3000/api/agents/{id}/heartbeat \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "status": "idle",
    "last_activity": "Completed task #42"
  }'

Automatic Timeout

The background scheduler runs every 5 minutes:
  1. Query agents with status != 'offline' and last_seen < threshold
  2. Mark stale agents as offline
  3. Log activity: β€œAgent marked offline (no heartbeat for 10m)”
  4. Create notification for operator
Adjust in Settings β†’ General:
{
  "general.agent_heartbeat_timeout": 600
}
Value in seconds (default: 600 = 10 minutes).

WebSocket Heartbeat

Gateway connections send ping/pong every 30 seconds:
  • Ping sent β€” Client sends {type: "req", method: "ping", id: "ping-1"}
  • Pong received β€” Server responds with {type: "res", id: "ping-1", ok: true}
  • RTT calculated β€” Round-trip time displayed in connection status
  • Missed pongs β€” After 3 missed pongs (90s), force reconnect

Notifications

Real-time notifications appear in the Notifications panel:

Notification Types

  • Info β€” General system messages
  • Warn β€” Potential issues (e.g., agent offline)
  • Error β€” Critical failures (e.g., deployment failed)
  • Heartbeat β€” Agent liveness alerts

Viewing Notifications

1

Open Panel

Click Notifications in the side rail.
2

Review Items

Unread notifications appear bold.
3

Mark Read

Click a notification to mark it read.
4

Clear All

Click Clear All to dismiss all notifications.

API Access

# Get notifications for current user
curl http://localhost:3000/api/notifications \
  -H "x-api-key: your-api-key"

# Mark as read
curl -X PUT http://localhost:3000/api/notifications/{id} \
  -H "Content-Type: application/json" \
  -d '{"read": true}'

Performance Metrics

Connection Latency

WebSocket RTT displayed in connection status widget:
  • < 50ms β€” Excellent
  • 50-100ms β€” Good
  • 100-200ms β€” Fair
  • > 200ms β€” Check network or gateway load

Event Delivery

  • WebSocket β€” Near-instant (< 10ms after gateway receives event)
  • SSE β€” Fast (< 50ms after database write)
  • Polling β€” Delayed (up to 30s depending on interval)

Troubleshooting

  1. Check SSE connection status (green indicator)
  2. Verify browser dev tools for SSE errors
  3. Confirm Live mode is enabled
  4. Try clicking Refresh manually
  1. Verify gateway is running: ps aux | grep gateway
  2. Check gateway port: OPENCLAW_GATEWAY_PORT in .env
  3. Test gateway directly: wscat -c ws://localhost:18789
  4. Check allowedOrigins in gateway openclaw.json
  1. Confirm gateway is connected (green status)
  2. Check log level filters (remove any filters)
  3. Verify agents are sending logs (check gateway logs)
  4. Try /api/logs endpoint directly to rule out UI issue

Next Steps

Cost Tracking

Monitor token usage and costs with per-model breakdowns

Background Automation

Configure automated tasks and monitoring rules