Skip to content

Latest commit

Β 

History

38 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

OpenClaw Pincers

OpenClaw Pincers

Get a grip on your gateway.

A standalone, cross-platform desktop control center for OpenClaw β€” chat, config, cron, approvals, models, files, logs, and updates. Everything the CLI does, with claws. Now on Android too.

Platform Stack License Protocol


Why Pincers?

OpenClaw's gateway speaks a fully-documented WebSocket protocol β€” but the only desktop surfaces are a terminal and a browser tab. Pincers is a real native client: it pairs with your gateway like any other device, signs its handshakes with its own Ed25519 identity, and puts every control-plane surface one click away.

  • No terminal required. First-run onboarding detects your local gateway and fills in URL + token for you.
  • Real protocol client. Not a CLI wrapper, not screen-scraping β€” the same signed WS handshake (protocol v4) the official clients use.
  • Keys stay in Rust. The device private key never touches JavaScript; the frontend only ever receives signatures.
  • 13 themes. From Synthwave '84 to Carapace Noir to The Lobster Quadrille. Pick your fighter.

Features

Section What you get
πŸ’¬ Chat Sessions sidebar, streaming deltas, abort, full history
πŸ“Š Dashboard Gateway status, health, usage/quota, presence at a glance
🧠 Models Runtime model catalog with search and catalog views
βš™οΈ Config Live config editor with validated writes + schema lookup drill-down
πŸ“ Files Agent workspace browser (gateway-confined, read-only)
⏰ Cron Create, enable/disable, run-now, and delete scheduled jobs
πŸ›‘οΈ Approvals Exec approval inbox with auto-refresh β€” allow/deny in one click, plus native notifications
πŸ“± Devices Paired-device manager: approve/reject pending pairings inline, generate mobile setup QR codes
⌨️ Terminal Embedded host PTY (xterm.js) over the gateway β€” full shell from desktop or phone
πŸ”Š Voice On-device TTS read-aloud for replies (auto-read toggle + per-message speak)
✨ Skills Installed skills grid
πŸ”§ Tools Full gateway tool catalog with filter
πŸ“œ Logs Gateway log tail with follow mode
πŸ–₯️ System Channel status, nodes, one-click gateway updates
πŸš€ Setup Onboarding hub + setup wizard over RPC

Install

Linux

Distro Package
Debian / Ubuntu sudo dpkg -i OpenClaw\ Pincers_*_amd64.deb
Fedora / openSUSE sudo dnf install OpenClaw\ Pincers-*.x86_64.rpm
Any distro .AppImage β€” chmod +x and run
Arch / CachyOS / Manjaro cd packaging && makepkg -si

Runtime deps: webkit2gtk-4.1, gtk3, libsoup3 (preinstalled on most desktops).

Running the raw release binary instead of a package? Install the launcher + official icons with:

./scripts/install-desktop.sh   # idempotent; re-run after pulling new brand assets

macOS

Download the DMG for your chip (arm64 = Apple Silicon, x64 = Intel) and drag to Applications. Builds are currently unsigned β€” on first launch:

xattr -dr com.apple.quarantine "/Applications/OpenClaw Pincers.app"

Windows

Download the .msi (or NSIS .exe) and install. Builds are currently unsigned β€” click More info β†’ Run anyway on the SmartScreen prompt.

First run

  1. Launch Pincers. 🦞
  2. Hit ⚑ Detect local gateway β€” it reads ~/.openclaw/openclaw.json and fills in the gateway URL + auth token (local installs only; remote gateways: paste URL + token manually).
  3. Hit Connect. On first contact the gateway asks you to approve the new device β€” the app shows you the exact openclaw devices approve command and auto-retries until you're in.

Build from source

Prereqs: Rust toolchain, Node 18+, and the Tauri system dependencies for your platform.

npm install
npm run tauri dev      # dev build with hot reload
npm run tauri build    # release bundles for your host OS
npm run check          # svelte-check typecheck

Releases are built by GitHub Actions: push a v* tag and the pipeline ships Linux (deb/rpm/AppImage), macOS (arm64 + x64 dmg), and Windows (msi/nsis) artifacts to a GitHub Release.

Android

Prereqs: JDK 17, Android SDK (platform 36, build-tools 36) + NDK r28, and Rust Android targets:

rustup target add aarch64-linux-android armv7-linux-androideabi \
  i686-linux-android x86_64-linux-android
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
export ANDROID_HOME=$HOME/Android/Sdk
export NDK_HOME=$ANDROID_HOME/ndk/28.2.13676358

npx tauri android init                      # once β€” scaffolds src-tauri/gen/android
npx tauri android dev                       # dev on a connected device/emulator
npx tauri android build --apk --target aarch64   # signed release APK

Release signing uses src-tauri/gen/android/keystore.properties (gitignored) pointing at pincers-release.jks. The APK enables cleartext traffic so it can reach plain ws:// gateways on your LAN or tailnet β€” pair it like any new device (openclaw devices approve).

Connecting your phone from anywhere (Tailscale)

Gateways bind to loopback by default, and many routers block client-to-client traffic ("AP isolation") β€” so the reliable path is a tailnet:

  1. Set gateway.bind: "lan" in ~/.openclaw/openclaw.json and restart the gateway (token auth is required for non-loopback binds β€” the default).
  2. If you run a firewall, allow the port (e.g. sudo ufw allow 18789/tcp).
  3. Install Tailscale on both the gateway host and your phone, sign into the same account.
  4. In Pincers on your phone, use the host's tailnet IP: ws://100.x.y.z:18789 + your gateway token.
  5. First connect raises a pairing request β€” approve it: openclaw devices approve <requestId> (the requestId shows in the app, or in the gateway log).

Works on home wifi, mobile data, coffee-shop wifi β€” anywhere Tailscale reaches. Note: Android allows one VPN at a time, so Tailscale and other VPN apps trade places on the phone.

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Svelte 5 UI (13 sections, theme engine)    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ GatewayClient (TypeScript)                 β”‚
β”‚   WS transport Β· req/res correlation       β”‚
β”‚   event routing Β· tolerant extraction      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Rust backend (Tauri commands)              β”‚
β”‚   Ed25519 keygen Β· storage Β· signing       β”‚
β”‚   local gateway detection                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ ws://your-gateway (protocol v4)            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
src/lib/gateway/protocol.ts   Protocol v4 types (frames, handshake, chat events)
src/lib/gateway/client.ts     GatewayClient β€” transport, handshake, events
src/lib/state/app.svelte.ts   Svelte 5 runes app state + RPC passthrough
src/lib/views/*.svelte        The 12 sections
src/lib/themes.ts             Theme catalog (13 themes)
src-tauri/src/lib.rs          Device identity + signing + local detection
.github/workflows/release.yml Cross-platform release pipeline

Protocol notes (learned from the source, so you don't have to)

  • client.id is a closed enum β€” external apps must use gateway-client with mode ui.
  • Device auth payload v3: v3|deviceId|clientId|clientMode|role|scopes|signedAtMs|token|nonce|platform|deviceFamily (scopes normalized/sorted, platform lowercased).
  • device.id = sha256hex(raw Ed25519 public key); device.publicKey = base64url(raw key); signature = base64url(Ed25519 signature over payload).
  • Gateways with gateway.auth.token require the token in both auth.token and the signed payload.
  • First connect from a new device creates a pending pairing request; loopback connects may be auto-approved.
  • chat.send acks with {runId, status:"started"}; responses stream as chat events (delta/final/aborted/error, deltas via deltaText, replace=true for non-prefix rewrites).

Roadmap

  • Embedded terminal (gateway PTY over terminal.*)
  • Node pairing with QR codes (device.pair.setupCode)
  • Per-session model picker in chat
  • Talk/TTS voice mode (v1: on-device read-aloud; v2: full Talk mode needs a provider API key)
  • Desktop notifications for approvals
  • Signed macOS/Windows builds

Contributing

Issues and PRs welcome. If a gateway RPC returns something a section doesn't render richly, the app falls back to a JSON inspector β€” screenshots of those fallbacks are bug reports gold.

License

MIT β€” see LICENSE.


Built with claws by synth 🎹🀺 & synthclaw 🎹🦞 · This is the wave.

β˜• Support the Developer

If this project saved you time, solved a problem, or just made your day a little more neon, you can fuel the next one:

Buy Me A Coffee

About

🦞 Get a grip on your gateway β€” cross-platform desktop control center for OpenClaw (Tauri 2 + Svelte 5 + Rust)

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages