ov/skills/openclaw/SKILL.md
Topic skill (no dedicated `ov openclaw` command — the surface is layer composition + image deployment). MUST be invoked before any work involving: OpenClaw gateway configuration, model auth, browser integration, channel setup, or any image composing `openclaw-*` layers (`openclaw`, `openclaw-ollama`, `openclaw-sway-browser`, `openclaw-full`, `openclaw-full-ml`, `openclaw-full-sway`, `openclaw-ollama-sway-browser`, `openclaw-browser-bootc`).
npx skillsauth add overthinkos/overthink-plugins openclawInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
OpenClaw is an AI gateway that connects LLM agents to messaging channels (WhatsApp, Telegram, Discord, Slack, Signal, iMessage, IRC, Teams) and exposes them via a WebSocket API, CLI, and web Control UI. It runs as a Node.js process with an embedded agent runtime, model failover, browser automation, and multi-agent routing.
In Overthink, OpenClaw runs as a supervisord service inside containers. The openclaw layer provides the npm package, and openclaw-sway-browser combines it with a full Sway desktop, Chrome browser, and VNC server for browser-based workflows like OAuth and web automation.
The gateway listens on port 18789 (WebSocket + HTTP). All CLI commands (openclaw *) connect to the gateway WebSocket. The Control UI is served at the gateway root URL. Config is stored in ~/.openclaw/openclaw.json (JSON5 format).
| Action | Command | Description |
|--------|---------|-------------|
| Gateway health | openclaw health | Check gateway connectivity |
| Gateway status | openclaw status --all | Full status with channels |
| Model status | openclaw models status | Show model, auth, and usage |
| Browser status | openclaw browser status | Show browser connection state |
| Browser tabs | openclaw browser tabs | List open Chrome tabs |
| Open URL | openclaw browser open <url> | Open URL in Chrome |
| Page snapshot | openclaw browser snapshot | Accessible page structure (AI refs) |
| Screenshot | openclaw browser screenshot | Capture PNG to media dir |
| Config get/set | openclaw config get/set <key> <val> | Read/write config values |
| Doctor | openclaw doctor --fix | Health checks + auto-fixes |
| Security audit | openclaw security audit | Check security posture |
| Channel login | openclaw channels login --channel <ch> | Connect a messaging channel |
| Agent message | openclaw agent --agent main --message "..." | Send test prompt |
| Setup wizard | openclaw configure | Interactive config wizard |
| Logs | openclaw logs --follow | Tail gateway logs |
For container lifecycle, use ov commands -- see /ov:service.
The openclaw layer (layers/openclaw/) depends on nodejs and supervisord. It installs the openclaw npm package globally, exposes port 18789, declares a data volume at ~/.openclaw, and runs as a supervisord service:
[program:openclaw]
command=%(ENV_HOME)s/.npm-global/bin/openclaw gateway --port 18789
The gateway binds to loopback only (no --bind lan). External access is handled by port_relay (socat), which forwards from the container interface to loopback. This avoids CORS origin checks entirely — the gateway only ever sees loopback connections.
The openclaw-sway-browser image combines openclaw + sway-desktop on a Fedora base:
| Port | Service | Protocol | |------|---------|----------| | 18789 | Gateway WebSocket + Control UI | HTTP | | 5900 | VNC (wayvnc) | TCP | | 9222 | Chrome DevTools | HTTP |
Tunnel config exposes all ports via Tailscale (ports: all). Platform: linux/amd64 only.
ov alias add openclaw openclaw-sway-browser
# Now: openclaw --help (runs inside the container)
ov image build openclaw-sway-browser # Build image
ov config openclaw-sway-browser # Generate quadlet, daemon-reload
ov start openclaw-sway-browser # Start via systemd
ov stop openclaw-sway-browser # Stop
ov status openclaw-sway-browser # Check systemd status
ov logs openclaw-sway-browser -f # Follow container logs
The gateway binds to loopback only (no --bind lan). Only one config value is required before the gateway will start:
openclaw config set gateway.mode local
Without gateway.mode=local, the gateway refuses to start.
dangerouslyAllowHostHeaderOriginFallback is NOT needed because port_relay (socat) handles external access — the gateway only sees loopback connections, so no CORS origin checks are triggered.
For Chrome integration, also set:
openclaw config set browser.cdpUrl "http://127.0.0.1:9222"
After setting these, restart the gateway:
supervisorctl restart openclaw
| Mode | Description |
|------|-------------|
| none | No auth (loopback only) |
| token | Bearer token in WebSocket handshake |
| password | Password auth |
| trusted-proxy | Proxy handles auth (e.g., Tailscale identity headers) |
| Mode | Description |
|------|-------------|
| loopback | 127.0.0.1 only (default) |
| lan | All interfaces (0.0.0.0) -- requires auth |
| tailnet | Tailscale interface only |
openclaw health --json # Gateway health
openclaw doctor --fix # Diagnose and fix issues
openclaw status --all --deep # Full status with channels
# HTTP endpoints on gateway port:
# GET /healthz -- liveness
# GET /readyz -- readiness
// In ~/.openclaw/openclaw.json
agents: {
defaults: {
model: {
primary: "openai-codex/gpt-5.4",
fallbacks: ["anthropic/claude-sonnet-4-5"]
}
}
}
Critical: The openclaw models auth login TUI requires a real terminal to complete the post-callback token exchange. Do NOT pipe through tee or redirect stdout — it breaks the TUI event loop. Use ov tmux (see /ov:tmux):
IMG=<image>
# 1. Start OAuth in a tmux session (real terminal)
ov tmux run $IMG -s oauth "openclaw models auth login --provider openai-codex --set-default"
# 2. Read the OAuth URL from tmux output
sleep 5
ov tmux capture $IMG -s oauth | grep -o 'https://auth.openai.com/[^ ]*'
# 3. Open URL in Chrome, click "Continue with Google", then "Continue" on consent
ov test cdp open $IMG "<oauth-url>"
TAB=$(ov test cdp list $IMG | grep -i "openai" | head -1 | awk '{print $1}')
ov test cdp click $IMG $TAB 'button._buttonStyleFix_wvuha_65' --vnc # Continue with Google
sleep 5
ov test cdp click $IMG $TAB 'button._primary_3rdp0_107' --vnc # Continue (consent)
# 4. Verify completion
sleep 10
ov tmux capture $IMG -s oauth
# Should show: "OpenAI OAuth complete", "Default model set to openai-codex/gpt-5.4"
Prerequisites: Chrome must have an active Google session. The "Continue with Google" button on OpenAI's auth page uses Chrome's Google cookies. See /ov-images:openclaw-ollama-sway-browser for the full Chrome sign-in procedure.
Callback architecture: The OAuth callback hits http://127.0.0.1:1455/auth/callback inside the container. Chrome and openclaw-models share the same network namespace — no port mapping needed for 1455. The BROWSER=browser-open env var (set by the chrome layer) auto-opens URLs via CDP, but may not trigger in all TTY contexts — open the URL manually via ov test cdp open as a fallback.
Stale port 1455: If a previous attempt left port 1455 occupied: ov shell $IMG -c 'kill -9 $(ss -tlnp sport = :1455 | grep -oP "pid=\K\d+")'
Tokens persist in ~/.openclaw/agents/main/agent/auth-profiles.json in the data volume. Survive ov stop/ov start and image rebuilds. Only destroyed by ov remove --purge.
Model name: openai-codex/gpt-5.4. The --set-default flag sets it as the default model in openclaw.json.
openclaw models status
# Shows: provider, model, auth profiles, token expiry, usage quotas
Two-stage failure handling:
Backoff: 1min -> 5min -> 25min -> 1hr (capped). Auth profiles pin per session and reset on /new or compaction.
models: {
providers: {
"my-local": {
baseUrl: "http://localhost:4000/v1",
api: "openai-completions",
models: [{ id: "my-model", contextWindow: 128000, maxTokens: 32000 }]
}
}
}
In openclaw-sway-browser, Chrome already runs as a supervisord service on port 9222. OpenClaw must connect to it rather than launching a new instance:
openclaw config set browser.cdpUrl "http://127.0.0.1:9222"
supervisorctl restart openclaw
Do not use openclaw browser start in this image -- it attempts to launch a separate Chrome instance that fails without Wayland environment variables.
After configuration, verify:
openclaw browser status # Should show running: true, cdpPort: 9222
openclaw browser tabs # Lists open Chrome tabs
openclaw browser open https://example.com # Open URL in new tab
openclaw browser navigate https://other.com # Navigate current tab
openclaw browser snapshot # AI-accessible page structure
openclaw browser snapshot --format aria # Accessibility tree
openclaw browser screenshot # PNG to media dir
openclaw browser screenshot --full-page # Full page capture
openclaw browser click 12 # Click element by AI ref
openclaw browser type 23 "hello" --submit # Type + submit
openclaw browser press Enter # Key press
openclaw browser hover 44 # Hover element
openclaw browser fill --fields '[{"ref":"1","value":"Ada"}]'
openclaw browser wait --text "Done" # Wait for text
openclaw browser wait --url "**/dashboard" # Wait for URL pattern
openclaw browser evaluate --fn '(el) => el.textContent' --ref 7
openclaw browser console --level error # Console messages
openclaw browser cookies # Read cookies
openclaw browser pdf # Save page as PDF
Snapshots provide element references for interaction:
click 12, type 23 "text")--interactive): e-prefixed refs (click e12)--efficient): compact + interactive + depth reductionbrowser: {
profiles: {
openclaw: { cdpPort: 18800 }, // managed (default)
user: { driver: "existing-session", attachOnly: true }, // attach to running Chrome
remote: { cdpUrl: "http://10.0.0.42:9222" }, // remote CDP
cloud: { cdpUrl: "wss://connect.browserbase.com?apiKey=<KEY>" }
}
}
agents: {
defaults: {
workspace: "~/.openclaw/workspace",
maxConcurrent: 4,
compaction: { mode: "safeguard" },
subagents: { maxConcurrent: 8, maxChildrenPerAgent: 5, maxSpawnDepth: 1 },
tools: { profile: "coding" }, // coding|minimal|messaging|full
elevatedDefault: "off" // off|on|ask|full
}
}
Placed in the agent workspace, injected on first session turn:
AGENTS.md -- operating instructions and memorySOUL.md -- persona, boundaries, toneTOOLS.md -- user-maintained tool documentationIDENTITY.md -- agent name and characteristicsagents: {
list: [
{ id: "main", default: true, name: "Main", model: "openai-codex/gpt-5.4" },
{ id: "home", name: "Home Assistant", model: "anthropic/claude-sonnet-4-5" }
],
bindings: [
{ agentId: "home", match: { channel: "telegram", peer: { id: "123" } } }
]
}
WhatsApp, Telegram, Discord, Slack, Signal, Google Chat, Mattermost, iMessage, IRC, Microsoft Teams, BlueBubbles.
| Policy | Description |
|--------|-------------|
| pairing | Unknown senders get approval code (default) |
| allowlist | Only pre-approved senders |
| open | Accept all (requires allowFrom: ["*"]) |
| disabled | Ignore all DMs |
# Connect WhatsApp (QR code linking)
openclaw channels login --channel whatsapp
# Connect Telegram (requires bot token from BotFather)
openclaw config set channels.telegram.botToken "BOT_TOKEN"
openclaw channels login --channel telegram
# Connect Discord (requires bot token)
openclaw config set channels.discord.token "BOT_TOKEN"
# Check channel status
openclaw channels status --probe
| Path | Purpose |
|------|---------|
| ~/.openclaw/openclaw.json | Main config (JSON5) |
| ~/.openclaw/agents/<id>/agent/auth-profiles.json | Model auth tokens |
| ~/.openclaw/agents/<id>/sessions/ | Session data |
| ~/.openclaw/workspace/ | Agent workspace |
| ~/.openclaw/media/browser/ | Browser screenshots |
| ~/.openclaw/logs/ | Audit logs |
| /tmp/openclaw/openclaw-YYYY-MM-DD.log | Gateway runtime log |
Check supervisord: supervisorctl status openclaw. If cycling between STARTING and STOPPED:
# Run manually to see error output
supervisorctl stop openclaw
timeout 15 openclaw gateway --port 18789
Common fixes:
gateway.mode not set -> openclaw config set gateway.mode localallowedOrigins errors, verify the relay is running: supervisorctl status relay-18789If openclaw browser status shows running: false:
openclaw config set browser.cdpUrl "http://127.0.0.1:9222"
supervisorctl restart openclaw
Use --tty for the interactive CLI. The BROWSER=browser-open env var auto-opens OAuth URLs in Chrome. The callback URL (http://127.0.0.1:1455/auth/callback) is container-internal and needs no port mapping.
ov shell <image> --tty -c "openclaw models auth login --provider openai-codex --set-default"
For browser-assisted OAuth (Google sign-in), see /ov:cdp.
After the first container start, configure the gateway:
ov shell <image> -c "openclaw config set gateway.mode local"
ov shell <image> -c "openclaw config set browser.cdpUrl 'http://127.0.0.1:9222'"
ov shell <image> -c "supervisorctl restart openclaw"
/ov:cdp -- ov test cdp CDP commands (lower-level container-external automation)/ov:deploy -- Quadlet, tunnels, volume backing, VNC password/ov:service -- ov start/stop/enable/disable/status/logs/update/remove/ov:vnc -- VNC desktop automation and password management/ov:alias -- Host command aliases (ov alias add openclaw)/ov:shell -- ov shell --tty for interactive container commandsMUST be invoked when the task involves OpenClaw gateway configuration, model auth, browser integration, channel setup, or openclaw images. Invoke this skill BEFORE reading source code or launching Explore agents.
Workflow position: Post-deployment. Configure the gateway after the container is running. See also /ov-images:openclaw* (image variants).
tools
OpenCharly CLI (charly) binary installed into container/VM images for in-container use. Use when working with charly binary deployment inside containers, native D-Bus support, or the full charly toolchain (charly binary + virtualization + gocryptfs + socat).
development
Operator CachyOS workstation profile — a kind:local template + target:local deploy that installs the full dev stack (30 candies) onto a CachyOS host via ShellExecutor. Lives in the overthinkos/cachyos submodule. MUST be invoked before editing or applying the charly-cachyos workstation profile.
tools
Fedora box with the full charly toolchain using shared candies. Rootless-first — runs as uid=1000 with passwordless sudo (no root, no cap_add: ALL). Same candy list as charly-arch. Includes NVIDIA GPU runtime. MUST be invoked before building, deploying, configuring, or troubleshooting the charly-fedora box.
tools
Arch Linux box with the full charly toolchain. Rootless-first — runs as uid=1000 with passwordless sudo (no root, no cap_add: ALL). Composes /charly-coder:charly-mcp so the box is reachable as an MCP gateway on port 18765. NVIDIA GPU runtime composed in. MUST be invoked before building, deploying, configuring, or troubleshooting the charly-arch box.