MCP Hub
Back to servers

openclaw-control-mcp

MCP server bridging Claude Code to the OpenClaw gateway management plane via JSON-RPC.

Registry
Updated
May 1, 2026

Quick Install

npx -y openclaw-control-mcp

openclaw-control-mcp

npm CI license

MCP server bridging Claude Code (or any MCP client) to the OpenClaw gateway management plane via WebSocket JSON-RPC. 134 typed tools wrapping all 128 JSON-RPC methods the gateway publishes — cron, sessions, agents, channels, chat, logs, models, usage, status/health, config, secrets, skills, exec/plugin approvals, wizard, doctor memory, nodes, voice (TTS / talk / voicewake) — plus device pairing and in-chat setup.

The upstream openclaw-mcp package only wraps /v1/chat/completions. This wrapper talks the JSON-RPC protocol used by the OpenClaw Control panel SPA, so you can operate on the full management plane (list / trigger / configure jobs, sessions, agents, channels …) directly from the assistant.

Status

0.4.0 / preview. Multi-instance gateway configs + 134+ typed tools wrapping the 128 JSON-RPC methods the gateway publishes — cron, sessions, agents, channels, chat, logs, models, usage, status/health/heartbeats, config, secrets, skills, exec/plugin approvals, wizard, doctor.memory, node, tts/talk/voicewake, plus device pairing & in-chat setup. The two introspection tools openclaw_introspect (lists every method/event the gateway publishes in its hello-ok) and openclaw_call (escape hatch for any method) make new gateway endpoints reachable without waiting on a release.

WS connect + signed Ed25519 handshake working against a managed Hostinger gateway (verified 2026.4.12). On first start, the wrapper generates a long-lived device identity, persists it under ${XDG_CONFIG_HOME:-~/.config}/openclaw-control-mcp/store.json (mode 0600), signs the connect frame, and surfaces the resulting pairing request id so you can approve it once via the Control panel. After approval the gateway issues a device token (in hello-ok.auth.deviceToken) which is cached per-gateway and used on subsequent connects to grant scopes.

The wire format (frame types, field names, signing canonicalisation, scopes) was reverse-engineered from the minified Control panel bundle (/api-docs/assets/index-*.js) and cross-checked against openclaw/openclaw/scripts/dev/gateway-smoke.ts. It is not officially documented. Behaviour may change without notice if OpenClaw updates the gateway.

First-run / pairing flow

  1. Start the wrapper (Claude Code does this automatically once registered in ~/.claude.json).
  2. Ask Claude to run openclaw_device_status. The first call:
    • generates an Ed25519 keypair and persists it to disk,
    • opens a WS to the gateway,
    • sends a signed connect frame,
    • the gateway replies with PAIRING_REQUIRED and a requestId,
    • the tool returns { pendingPairing: { requestId }, nextStep: "approve in Control panel…" }.
  3. Open the OpenClaw Control panel → Devices tab → approve the request whose id matches.
  4. Ask Claude to run openclaw_device_status again. This time the gateway accepts the connect, returns auth.deviceToken in hello-ok, the wrapper caches it, and paired: true plus the granted scopes appear in the response.
  5. From then on, scoped tools (openclaw_cron_list, _status, …) work normally.

Install

From npm (recommended)

claude mcp add openclaw-control -- npx -y openclaw-control-mcp

Restart Claude Code, then jump to Configuration.

From source (for contributors)

git clone https://github.com/smurfy92/openclaw-control-mcp.git
cd openclaw-control-mcp
npm install
npm run build
claude mcp add openclaw-control -- node "$(pwd)/dist/index.js"

Configuration

The wrapper requires the WebSocket URL of your OpenClaw gateway. The public Hostinger HTTPS hostname does not expose the WS endpoint — you need the URL the Control panel itself uses internally.

Find it from your browser:

  1. Open the Control panel and log in.
  2. In the DevTools console run:
    Object.entries(localStorage).find(([k]) => k.startsWith("openclaw.control.settings.v1"))?.[1]
    
  3. Copy the gatewayUrl field (typically ws://127.0.0.1:18789, a Tailscale ws://100.x.y.z:18789, or a dedicated wss://… host).

Use with Claude Code

Recommended: register, then configure in chat

The slickest path — no ~/.claude.json editing, no env vars. After installing (npx or from source), in chat:

"Configure OpenClaw with gateway wss://openclaw-xxx.srv.hstgr.cloud and token <your-token>"

Claude calls openclaw_setup({ gatewayUrl, gatewayToken }), the values get persisted to ~/.config/openclaw-control-mcp/store.json (mode 0600). The next call to openclaw_device_status triggers the WS handshake and pairing flow.

openclaw_setup_show reports the effective configuration, openclaw_setup_clear wipes the persisted config (without touching the device identity / token).

Alternative: env-var-driven

If you prefer env vars (they take precedence over the stored config), edit ~/.claude.json:

"openclaw-control": {
  "type": "stdio",
  "command": "npx",
  "args": ["-y", "openclaw-control-mcp"],
  "env": {
    "OPENCLAW_GATEWAY_URL": "wss://openclaw-xxx.srv.hstgr.cloud",
    "OPENCLAW_GATEWAY_TOKEN": "<your-token>",
    "OPENCLAW_TIMEOUT_MS": "30000"
  }
}

Restart Claude Code — openclaw_cron_list and friends will be available.

Environment variables

VariableRequiredDescription
OPENCLAW_GATEWAY_URLyesWebSocket URL of the gateway (ws:// or wss://)
OPENCLAW_GATEWAY_TOKENrecommendedGateway login token
OPENCLAW_GATEWAY_PASSWORDoptionalExtra password (some gateway configs require it)
OPENCLAW_TIMEOUT_MSoptionalConnect / request timeout (default 30000)
OPENCLAW_DEBUGoptionalSet to 1 to log every WS frame to stderr
OPENCLAW_CONTROL_HOMEoptionalOverride the directory used to persist store.json (defaults to ${XDG_CONFIG_HOME:-~/.config}/openclaw-control-mcp/). The legacy OPENCLAW_CLAW_HOME is still read as a fallback.

Tools

134 typed tools wrapping the 128 JSON-RPC methods the gateway publishes (and 2 standalone introspection tools). Run openclaw_introspect once paired to see the live list of methods + events on your specific gateway.

Introspection (no scopes required)

ToolNotes
openclaw_introspectReturns server version, your role/scopes, and the full methods[] / events[] list the gateway publishes in its hello-ok.
openclaw_callEscape hatch — call any JSON-RPC method with arbitrary params. Useful when the gateway adds new methods between releases. Prefer typed wrappers when they exist.

Setup (no scopes required)

ToolNotes
openclaw_setupPersist { gatewayUrl, gatewayToken, gatewayPassword? } to local config.
openclaw_setup_showReport effective config (env vs store), without printing tokens.
openclaw_setup_clearWipe persisted gateway config. Device identity + tokens are kept.

Device & pairing (device.pair.*, device.token.*)

openclaw_device_status / openclaw_device_pair_list / _pair_approve / _pair_reject / _pair_remove / openclaw_device_token_revoke / _token_rotate. Manages your local Ed25519 identity and the per-gateway tokens it's been issued.

Coverage by domain (require operator.read / operator.write / operator.admin)

DomainToolsJSON-RPC methods wrapped
cron7list status run runs add update remove
sessions17list preview create patch send abort reset delete compact compaction.{list,get,restore,branch} subscribe/unsubscribe messages.subscribe/unsubscribe
agents7list create update delete files.{list,get,set}
chat3send history abort
channels2status logout
logs1tail
models1list
usage2status cost
Root status12status health last-heartbeat set-heartbeats system-presence system-event wake send agent agent.identity.get agent.wait gateway.identity.get
config6get set patch apply schema schema.lookup
secrets2reload resolve
skills6status search detail install update bins
tools2tools.catalog tools.effective
exec.approval9list get request resolve waitDecision + global / per-node policy get/set
plugin.approval4list request resolve waitDecision
wizard4start next cancel status
doctor.memory7status dreamDiary backfillDreamDiary dedupeDreamDiary repairDreamingArtifacts resetDreamDiary resetGroundedShortTerm
node16list describe invoke + invoke.result event rename pair.{request,verify,approve,reject,list} pending.{ack,drain,enqueue,pull} canvas.capability.refresh
tts6status enable disable providers setProvider convert
talk3config mode speak
voicewake2get set
Misc3update.run commands.list message.action

Tool names follow openclaw_<domain>_<method>. Method-name dots become underscores: cron.listopenclaw_cron_list, sessions.compaction.restoreopenclaw_sessions_compaction_restore.

Destructive tools

These carry destructive side effects (data loss, service interruption, revoked access). Their description is marked accordingly so Claude Code's confirmation gate prompts before each call:

  • Cron: cron_remove, cron_run (real execution), cron_update
  • Sessions: sessions_{abort,reset,delete,compaction_restore}
  • Agents: agents_{delete,files_set}
  • Chat: chat_abort
  • Channels: channels_logout
  • Device: device_{pair_remove,token_revoke,token_rotate}
  • Config: config_{set,patch,apply}
  • Secrets: secrets_resolve (returns secret material)
  • Doctor memory: doctor_memory_{resetDreamDiary,resetGroundedShortTerm,repairDreamingArtifacts,backfillDreamDiary,dedupeDreamDiary}
  • Node: node_{invoke,rename,pending_drain,pending_enqueue,pending_ack,pair_approve,pair_reject}
  • Skills: skills_{install,update}
  • Approvals: exec_approval_resolve, exec_approvals_{set,node_set}, plugin_approval_resolve
  • Self-update: update_run (gateway-wide, may interrupt sessions)

Examples

Copy-paste prompts you can drop into Claude after the MCP is paired. Each one targets the corresponding tool and shows the kind of natural-language phrasing that resolves to a concrete call.

Health & sanity

> Run a full openclaw health check.

→ Calls openclaw_health, reports MCP version, gateway server version, paired device fingerprint, granted scopes, and how recently the last successful call ran.

> What gateway methods do I have access to right now?

→ Calls openclaw_introspect, returns the 128 JSON-RPC methods + 24 events the gateway publishes in its hello-ok.

Cron

> List all openclaw cron jobs, including disabled ones.

openclaw_cron_list({ enabled: "all" }).

> Show me the last 5 runs of cron job <id> — compact mode, just the summaries.

openclaw_cron_runs({ id: "<job-id>", limit: 5, compact: true }) — summaries truncated to 200 chars, each entry gets a runAtAgo: "3d ago" field.

> Create a cron that runs every Friday at 1pm Paris and posts a summary to Telegram group -1001234567890.

→ Generates an openclaw_cron_add payload with the right schedule.kind: "cron", expr: "0 13 * * 5", tz: "Europe/Paris", and delivery.mode: "announce".

Sessions

> List the 10 most recent active openclaw sessions, ranked by last activity.

openclaw_sessions_list({ limit: 10, sortBy: "updatedAt", sortDir: "desc" }).

> Show me the last 8 messages of session agent:main:cron:<id>.

openclaw_sessions_preview({ keys: ["agent:main:cron:<id>"] }) — returns role/text turns straight from the gateway.

Agents & channels

> List the agents configured on this gateway and which model they use.

openclaw_agents_list.

> What's the connection state of my Telegram channel?

openclaw_channels_status.

Escape hatch

> Use openclaw_call to invoke "config.schema" with no params and return the keys it exposes.

→ Useful when a gateway-side method doesn't yet have a typed wrapper, or you want to inspect a feature still in beta.

Resilience

request() retries transient errors (network drop, ws close, timeout, DNS) with exponential backoff: defaults to 1s → 2s → 4s, max 4 attempts. Non-retryable errors (PAIRING_REQUIRED, INVALID, MISSING_SCOPE, etc.) fail fast — no point retrying a permission issue. Tune via:

  • OPENCLAW_RETRY_ATTEMPTS — total attempts (default 4, range 110)
  • OPENCLAW_RETRY_BASE_MS — initial backoff in ms (default 1000, range 10060000)
  • OPENCLAW_DEBUG=1 — prints every retry decision to stderr

When a request gives up, the thrown error carries gateway request '<method>' failed (attempt N/M): as a prefix and the original error is preserved as cause for inspection. GatewayError code / details / retryable flags are propagated through the wrap.

The client tracks lastSuccessAtMs for openclaw_health's lastSuccessAgo field — useful for "is the gateway still talking to me?" debug.

Diagnostic CLI

For one-shot health checks without wiring the MCP into a client:

npx -y openclaw-control-mcp --health

Prints a JSON report (MCP version, gateway URL, paired state, scopes, server version, last-success age, error if any) and exits non-zero on failure. Handy in CI / scripts.

Schema looseness

Most v0.3.0 wrappers use z.passthrough() for params — they accept the documented fields plus anything else, and pass them through to the gateway. This trades strict client-side validation for forward-compat: as the gateway evolves, calls don't break on new fields. The downside is you'll only learn about a wrong field when the gateway rejects the request. If you hit a "missing required property" error, look at the gateway's response — it tells you the exact wire shape — and either correct your call, or open an issue / PR to tighten the wrapper's Zod schema.

Roadmap

  • Auto-reconnect with backoff (currently single-shot — Claude Code respawns the stdio process on demand).
  • Stream session messages back into the MCP client (currently sessions.subscribe registers server-side but stdio can't surface deltas to Claude Code).
  • Tighten Zod schemas for the wrappers added in 0.3.0 — most use passthrough() until the gateway shape for each domain is fully nailed down. PRs welcome.

Migrating from openclaw-claw-mcp (early adopters)

If you used the wrapper under its previous name (openclaw-claw-mcp):

  • The Store automatically reads ~/.config/openclaw-claw-mcp/store.json as a fallback when the new path is empty, so your paired device token keeps working.
  • On the next successful connect, the new path (~/.config/openclaw-control-mcp/store.json) is created. You can then delete the old directory.
  • Update the entry name in ~/.claude.json from openclaw-claw to openclaw-control (purely cosmetic — only changes the tool prefix mcp__openclaw-control__*).
  • The local working dir / build output keeps the same path you cloned to; nothing else needs moving.

Caveats

  • The protocol is reverse-engineered, not documented. Behaviour may change with gateway updates.
  • The connect frame matches what openclaw/openclaw/scripts/dev/gateway-smoke.ts sends today (client.id: "openclaw-ios", mode: "ui", role + scopes per the iOS operator default). Different client.id values trigger different server policies — openclaw-control-ui and openclaw-tui for example require device identity and a secure-context origin.
  • OPENCLAW_DEBUG=1 logs every WS frame to stderr (truncated at 8 KB). Useful when comparing handshakes against the live Control panel SPA.

Reviews

No reviews yet

Sign in to write a review