A cross-platform desktop and mobile client for OpenClaw AI assistant. Built with Electron, React, and TypeScript.
Latest Release: v1.5.0 — Download the Windows Installer or Portable EXE for Windows.
- Concurrent Agent Streaming: Talk to multiple agents simultaneously with per-session stream isolation
- Chat Interface: Clean, modern chat UI with streaming support, markdown rendering, and code block copy buttons
- Image Send/Receive: Attach and send images in chat (PNG, JPG, GIF, WebP) with inline preview and gallery display
- Voice Dictation: Microphone button for speech-to-text input via WebSpeech API (browser) or native speech recognition (iOS/Android)
- Wake-Word Detection: Continuous voice monitoring with configurable trigger phrases — auto-starts dictation hands-free
- Thinking Mode: Toggle extended thinking for complex tasks with visible reasoning display
- Agent Selection: Switch between different AI agents with per-session agent identity
- Agent Management: Create, rename, delete, and browse agent profiles, configuration, and workspace files
- Agent Dashboard: Live activity grid showing all agents with real-time status
- Sessions Management: Create, view, and manage chat sessions with message caching and unread indicators
- Pinned Sessions: Pin important sessions to the top of the sidebar for quick access
- Subagent Spawning: Spawn isolated subagent sessions for parallel task execution, with inline status blocks and popout windows
- ClawHub Skill Browser: Search and browse available skills with VirusTotal security scan badges, download stats, and one-click install
- Rich Tool Call Cards: See tool calls inline during chat with per-tool icons, detail text, and popout viewer
- Stop Button: Abort in-progress chat streams at any time
- Server Settings: Full-page editor for OpenClaw server configuration — agent defaults, tools & memory, features (TTS & VoiceWake) and channel settings with dirty tracking and conflict detection
- Usage View: Monitor server limits, resources, and usage cost estimates with daily cost tracking, token/cost charts, and activity heatmaps
- Device Pairing: Ed25519 device identity with pairing code display, copy/share buttons, and auto-recovery from stale identity
- Cron Jobs: View, create, manually run, delete, and manage scheduled tasks with live status updates
- Dark/Light Theme: Full theme support with system preference detection
- Mobile Gestures: Swipe-to-delete sessions and long-press context menus on mobile
- Node Mode: Parallel WebSocket connection for agent-invoked device commands with granular permissions
- Auto-Retry Connection: Automatic reconnection with WebSocket health checks for half-open connection detection
- Cross-Platform: Windows, macOS, Linux, iOS, and Android support via Electron and Capacitor
Main chat interface with session sidebar and quick-start prompts
Agent profile view with configuration and workspace files
ClawHub skill browser with search, security scan badges, and skill details
Inline subagent status blocks with popout links
Subagent popout window showing an isolated conversation
Connection and authentication settings
Pre-built binaries are available on the Releases page:
- ClawControl Setup 1.5.0.exe — Windows installer (NSIS)
- ClawControl 1.5.0.exe — Windows portable
Major Features
- Node mode — parallel WebSocket connection for agent-invoked device commands
- Node permissions dialog — granular approve/deny control over device command access
- Multi-connection WebSocket pool for resilient parallel communication
- Playwright end-to-end test suite with mock OpenClaw v3 WebSocket server
Audio & Media
- TTS audio playback fixes — CSP-safe audio, MEDIA streaming, subagent delivery, and expired-URL fallback
- Base64 data URL support and media route fixes for image rendering
- Filter base64 image data from streaming and suppress agent state JSON in chat
Android
- Foreground service keeps node-mode WebSocket alive in background
- Fixed swipe-to-type lag, keyboard STT conflicts, and composition edge cases
- Moved WebSocket connect/disconnect off main thread to prevent ANR
- In-app review prompt
Fixes
- Fixed mobile WebSocket Origin header to use http/https instead of capacitor://
- Corrected cron job RPC params to match server schema (jobId + patch object)
- Fixed image rendering, typing indicator avatars, and removed debug logging
See the full release notes for details.
# Clone the repository
git clone git@github.com:jakeledwards/ClawControl.git
cd ClawControl
# Install dependencies
npm install
# Run in development mode
npm run devThe app connects to your local OpenClaw instance. Default configuration:
- Server URL:
wss://your-server.localorws://localhost:8080
- Make sure your OpenClaw server is running on your local network.
- In the app, open Settings (gear icon).
- Set Server URL to your local WebSocket endpoint (for example:
ws://192.168.1.50:8080). - Click Save & Connect.
- On first connect, approve the device pairing request on the server.
You must be connected to Tailscale before the app can reach your OpenClaw server.
- Connect your computer to Tailscale.
- Get your server's Tailscale hostname or IP.
- In the app, open Settings (gear icon).
- Set Server URL to your Tailscale endpoint (for example:
wss://your-server.tailnet-123.ts.net). - Click Save & Connect.
- On first connect, approve the device pairing request on the server.
You can configure the connection details directly in the application by clicking the Settings (Gear) icon in the top bar.
Available Options:
- Server URL: The WebSocket URL of your OpenClaw instance.
- Validation: Must start with
ws://(insecure) orwss://(secure). - Example:
wss://your-server.localorws://localhost:8080
- Validation: Must start with
- Device Name: A friendly name for your device (shown on the server).
- Device Identity: Ed25519 keypair generated automatically for pairing.
Settings are automatically persisted between sessions. If you change the URL or credentials, click Save & Connect to apply the changes and attempt a reconnection.
Once connected, you can configure the OpenClaw server itself from within ClawControl:
- Open Settings (gear icon) and click OpenClaw Server Settings.
- Browse three tabs of server configuration:
- Agent Defaults: Primary model, thinking level, verbose/elevated modes, timezone, time format, context token limits, timeouts, concurrency, workspace, compaction mode, human delay
- Tools & Memory: Tool profile preset, web search/fetch toggles and limits, code execution host and timeout, elevated tools, memory backend, citations, memory search provider
- Channels: Per-channel enable toggles for WhatsApp, Telegram, Discord, Slack, Signal, iMessage, and Mattermost, with DM/group policies and history limits
- Make changes — a save bar appears at the bottom when edits are detected.
- Click Save to apply. The server restarts automatically and the app reconnects.
ClawControl uses Ed25519 device identity pairing for authentication. On first connection:
- The app generates a device keypair and displays a pairing code.
- Approve the pairing request on the server to grant access.
- Subsequent connections authenticate automatically using the device signature.
You can set a custom Device Name in the connection settings to identify your device on the server.
When connecting to a server with a self-signed or untrusted SSL certificate, you may encounter a certificate error.
To resolve:
- ClawControl will detect the certificate error and show a modal
- Click "Open URL to Accept Certificate" to open the HTTPS URL in your browser
- Accept the browser's certificate warning (e.g., "Proceed to site" or "Accept the risk")
- Close the browser tab and retry the connection in ClawControl
You can change this in the app settings or by modifying src/store/index.ts.
# Start development server with hot reload
npm run dev
# Run type checking
npm run typecheck
# Run tests
npm run test
# Run tests once
npm run test:runnpm run build:winOutput: release/ClawControl Setup.exe and release/ClawControl Portable.exe
npm run build:macOutput: release/ClawControl.dmg
npm run build:linuxOutput: release/ClawControl-*.AppImage and release/clawcontrol_*_amd64.deb
Notes:
- On Ubuntu/Debian you may need
libfuse2installed for AppImage support (build/run).
Install:
- AppImage:
chmod +x release/ClawControl-*.AppImagethen run it - Debian/Ubuntu (.deb):
sudo dpkg -i release/clawcontrol_*_amd64.deb
Building Windows packages from Linux/WSL requires Wine. For best results:
- Build Windows packages on Windows
- Build macOS packages on macOS
clawcontrol/
├── electron/ # Electron main process
│ ├── main.ts # Main process entry
│ └── preload.ts # Preload script (IPC bridge)
├── src/
│ ├── components/ # React components
│ │ ├── ChatArea.tsx
│ │ ├── InputArea.tsx # Message input with voice dictation & image attach
│ │ ├── RightPanel.tsx
│ │ ├── Sidebar.tsx # Session list with pinned sessions
│ │ ├── TopBar.tsx
│ │ ├── SettingsModal.tsx
│ │ ├── CertErrorModal.tsx
│ │ ├── AgentDashboard.tsx # Live agent activity grid
│ │ ├── AgentDetailView.tsx
│ │ ├── CreateAgentView.tsx # Agent creation form
│ │ ├── SkillDetailView.tsx
│ │ ├── ClawHubSkillDetailView.tsx # ClawHub browser detail
│ │ ├── CronJobDetailView.tsx
│ │ ├── CreateCronJobView.tsx # Cron job creation form
│ │ ├── UsageView.tsx # Usage charts, cost tracking, heatmaps
│ │ ├── ServerSettingsView.tsx
│ │ ├── SubagentBlock.tsx # Inline subagent status
│ │ ├── SubagentViewer.tsx # Popout subagent window
│ │ ├── ToolCallViewer.tsx # Tool call detail popout
│ │ ├── ToolIcon.tsx # Per-tool icon mapping
│ │ ├── MobileGestureLayer.tsx # Mobile swipe/long-press
│ │ └── SessionContextMenu.tsx # Session right-click menu
│ ├── hooks/
│ │ ├── useSwipeGesture.ts # Touch swipe gesture hook
│ │ └── useLongPress.ts # Long-press gesture hook
│ ├── lib/
│ │ ├── openclaw/ # Modular WebSocket client
│ │ │ ├── client.ts # Core connection, event routing, per-session stream state
│ │ │ ├── types.ts # Protocol frame types, domain interfaces
│ │ │ ├── chat.ts # chat.send, chat.history, chat.abort
│ │ │ ├── sessions.ts # Session CRUD and sessions.spawn
│ │ │ ├── agents.ts # Agent listing, identity, files, create/delete
│ │ │ ├── config.ts # Server config read/write (config.get, config.patch)
│ │ │ ├── skills.ts # Skill listing, toggle, install
│ │ │ ├── cron-jobs.ts # Cron job listing, toggle, details
│ │ │ ├── features.ts # Usage, TTS, and voice wake RPC methods
│ │ │ ├── utils.ts # ANSI stripping, content extraction, helpers
│ │ │ └── index.ts # Public re-exports
│ │ ├── openclaw-client.test.ts # Integration tests (Vitest)
│ │ ├── appMeta.ts # Centralized app version and client identity
│ │ ├── platform.ts # Platform abstraction (Electron/Capacitor/web)
│ │ ├── device-identity.ts # Ed25519 device identity and pairing
│ │ ├── native-websocket.ts # Native Capacitor WebSocket bridge
│ │ └── clawhub.ts # ClawHub skill browser API
│ ├── store/
│ │ └── index.ts # Zustand state management
│ ├── styles/
│ │ └── index.css # Main stylesheet
│ ├── App.tsx
│ └── main.tsx
├── build/ # App icons and build assets
├── scripts/ # Utility scripts
└── capacitor.config.ts # Capacitor mobile config
ClawControl communicates with OpenClaw using a custom frame-based protocol (v3) over WebSocket. The protocol uses three frame types:
Request Frame - Client to server RPC calls:
{
type: 'req',
id: '1',
method: 'chat.send',
params: { sessionKey: 'session-123', message: 'Hello!' }
}Response Frame - Server responses to requests:
{
type: 'res',
id: '1',
ok: true,
payload: { /* result data */ }
}Event Frame - Server-pushed events (streaming, presence, etc.):
{
type: 'event',
event: 'chat',
payload: { state: 'delta', message: { content: '...' } }
}On connect, the server sends a connect.challenge event. The client responds with:
{
type: 'req',
id: '1',
method: 'connect',
params: {
minProtocol: 3,
maxProtocol: 3,
role: 'operator',
client: { id: 'openclaw-control-ui', displayName: 'ClawControl', version: '1.5.0' },
auth: { deviceId: '...', signature: '...', timestamp: 1234567890 }
}
}Sessions
sessions.list- List all sessions (supportsincludeDerivedTitles,includeLastMessage,limit)sessions.delete- Delete a session by keysessions.patch- Update session properties (e.g., label)
Chat
chat.send- Send a message (sessionKey,message,thinking,images)chat.history- Get messages for a sessionchat.abort- Abort an in-progress chat stream
Agents
agents.list- List available agentsagent.identity.get- Get agent identity and profileagents.files.list- List agent workspace filesagents.files.get- Read an agent fileagents.files.set- Write an agent file
Skills
skills.status- List skills with full metadata (enabled state, requirements, install options)skills.update- Enable/disable a skillskills.install- Install a skill
Configuration
config.get- Read the full server config (returns config object + hash for conflict detection)config.patch- Write partial config updates via JSON merge patch (triggers server restart)
Usage & Billing
usage.status- Server limits, providers, rate windowsusage.cost- Daily cost breakdown with token details
TTS & Voice
tts.status- Check TTS enabled/disabled statetts.providers- List available TTS providerstts.enable/tts.disable- Toggle TTStts.setProvider- Switch TTS providervoicewake.get/voicewake.set- Configure wake-word detection
Cron Jobs
cron.list- List scheduled jobscron.get- Get full cron job detailscron.add- Create a new cron jobcron.update- Update job status (active/paused)cron.remove- Delete a cron jobcron.run- Manually trigger a cron jobcron.runs- Get run history for a job
This is the complete set of RPC method names reported by the server in hello-ok.payload.features.methods. This list can vary by server version and configuration.
health
logs.tail
channels.status
channels.logout
status
usage.status
usage.cost
tts.status
tts.providers
tts.enable
tts.disable
tts.convert
tts.setProvider
config.get
config.set
config.apply
config.patch
config.schema
exec.approvals.get
exec.approvals.set
exec.approvals.node.get
exec.approvals.node.set
exec.approval.request
exec.approval.resolve
wizard.start
wizard.next
wizard.cancel
wizard.status
talk.mode
models.list
agents.list
agents.files.list
agents.files.get
agents.files.set
skills.status
skills.bins
skills.install
skills.update
update.run
voicewake.get
voicewake.set
sessions.list
sessions.preview
sessions.patch
sessions.reset
sessions.delete
sessions.compact
last-heartbeat
set-heartbeats
wake
node.pair.request
node.pair.list
node.pair.approve
node.pair.reject
node.pair.verify
device.pair.list
device.pair.approve
device.pair.reject
device.token.rotate
device.token.revoke
node.rename
node.list
node.describe
node.invoke
node.invoke.result
node.event
cron.list
cron.status
cron.add
cron.update
cron.remove
cron.run
cron.runs
system-presence
system-event
send
agent
agent.identity.get
agent.wait
browser.request
chat.history
chat.abort
chat.send
Chat responses stream via event frames. All events include an optional sessionKey for per-session routing.
chatevent withstate: 'delta'— Cumulative text chunkschatevent withstate: 'final'— Complete message (canonical)agentevent withstream: 'assistant'— Text output (cumulative per content block)agentevent withstream: 'tool'— Tool call start/resultagentevent withstream: 'lifecycle'— Agent lifecycle (complete/end signals)presenceevent — Agent online/offline status
The client uses per-session stream isolation (Map<string, SessionStreamState>) so multiple agents can stream concurrently without cross-contaminating text buffers. Stream source arbitration ensures only one event type (chat or agent) handles text for each session.
- Electron - Desktop app framework
- Capacitor - Native mobile (iOS/Android)
- React 18 - UI framework
- TypeScript - Type safety
- Vite - Build tool
- Zustand - State management
- Recharts - Usage charts and data visualization
- Vitest - Testing framework
MIT

