← Back to Plugins
Tools

Clawctl

tomstagl By tomstagl 👁 44 views ▲ 0 votes

kubectl-style wrapper for the openclaw agent gateway, plus a Claude Code plugin in the same repo

GitHub

README

# oc — openclaw client wrapper

A `kubectl`-style wrapper around the [openclaw](https://openclaw.ai) gateway. One binary, no dependencies beyond what's already on your Mac, and a strong opinion that gateway interactions should be **safe by default**, **traceable**, and **secret-redacted at the boundary**.

```bash
clawctl health                                                 # gateway liveness
clawctl models                                                 # registered agents (60s cached)
clawctl msg ops "summarise overnight openclaw runs"            # one-shot chat
clawctl cli cron list --json | jq -r '.[] | "\(.id)\t\(.cron)"'
clawctl verify pr tomstagl/studio-master#42                    # validate an agent's claim
clawctl trace a1f8e5fa…                                        # Jaeger UI link + first 30 spans
```

> **Naming note**: this `clawctl` shares a name with the OpenShift CLI. If you have both, alias one (`alias ocw=~/.local/bin/oc`) or rename the wrapper. The script is self-contained — renaming the file is safe.

## Why this exists

The openclaw gateway speaks an OpenAI-compatible HTTP API plus a separate ops CLI on the host. Talking to it from a Mac means juggling auth tokens, traceparents for observability, redaction of leaked secrets, and SSH for ops commands. Doing that with raw `curl` works once; doing it 50 times a day is how secrets end up in shell history.

`clawctl` collapses that into one wrapper:

- **Auth**: bearer token pulled from macOS Keychain — never on disk, never in env.
- **Tracing**: a W3C `traceparent` is attached to every request. Trace-id is printed to stderr so you can cite it instead of dumping bodies.
- **Redaction**: outputs pass through a regex filter that masks `dt0c01.*`, `dt0s16.*`, `gh[psoru]_*`, AWS access keys, JWTs, and the gateway-token literal. Hits are audited at `~/.cache/clawctl/last-redaction` and warned to stderr.
- **Verification**: `clawctl verify {commit|pr|issue|file}` checks an agent's citation in one command. Exit 0 means verified.
- **Read-only by default**: anything mutating (cron edits, agent adds, skill installs) is gated behind the explicit `clawctl cli` subcommand, never an HTTP shortcut.

If you run a self-hosted openclaw fleet and you've ever wanted "the kubectl of agents," this is that.

## Install

### Homebrew (recommended)

```bash
brew tap tomstagl/clawctl
brew install oc
```

### curl

```bash
curl -fsSL https://raw.githubusercontent.com/tomstagl/clawctl/main/install/install.sh | bash
```

### From source

```bash
git clone https://github.com/tomstagl/clawctl.git
cd oc
./install/install.sh
```

The installer copies `clawctl` to `~/.local/bin/oc` and prints a PATH check. It does not touch your Keychain — you store the bearer token yourself (see below).

## Setup

One required environment variable. Export it in `~/.zshrc` (or equivalent):

```bash
export CLAWCTL_HOST="http://your-openclaw-host:18789"
```

Optional knobs — sensible defaults exist:

| Variable                | Default                         | Purpose                                                  |
| ----------------------- | ------------------------------- | -------------------------------------------------------- |
| `CLAWCTL_HOST`               | _required_                      | Gateway URL                                              |
| `CLAWCTL_KEYCHAIN_SERVICE`   | `openclaw-gateway-token`        | macOS Keychain entry holding the bearer token            |
| `CLAWCTL_TIMEOUT`            | `60`                            | Per-call timeout (seconds)                               |
| `CLAWCTL_CACHE_DIR`          | `~/.cache/clawctl`                   | Where the models cache + redaction audit live            |
| `CLAWCTL_MODELS_TTL`         | `60`                            | `clawctl models` cache TTL (seconds)                          |
| `CLAWCTL_NO_REDACT`          | `0`                             | Set to `1` to bypass redaction (debugging only)          |
| `CLAWCTL_JAEGER_UI`          | _unset_                         | Used by `clawctl trace` to print a working UI link            |

Store the token in Keychain once:

```bash
security add-generic-password \
  -s openclaw-gateway-token \
  -a "$USER" \
  -w "<your-bearer-token>"
```

Verify:

```bash
clawctl health
clawctl models | jq -r '.data[].id'
```

## Surface

| Command                                | Purpose                                              |
| -------------------------------------- | ---------------------------------------------------- |
| `clawctl health`                            | Gateway liveness (no auth)                           |
| `clawctl models`                            | List registered agents (60s cached)                  |
| `clawctl msg [-s SESSION] AGENT [TEXT]`     | One-shot chat; stdin if `TEXT` omitted               |
| `clawctl stream [-s SESSION] AGENT [TEXT]`  | Same, SSE-buffered + redacted                        |
| `clawctl raw METHOD PATH [curl-args]`       | Arbitrary `/v1/...` call with auth + traceparent     |
| `clawctl cli SUBCOMMAND...`                 | Run `openclaw …` over SSH on the gateway host        |
| `clawctl verify KIND ARGS`                  | Claim verification — `commit`, `pr`, `issue`, `file` |
| `clawctl trace TRACE-ID`                    | Print Jaeger UI link + first 30 spans for a trace    |

Exit codes: `0` ok, `2` usage, `6` DNS, `7` connection refused, `22` HTTP 4xx/5xx, `28` timeout.

## Recipes

The most common workflows live in [`docs/recipes.md`](docs/recipes.md). Highlights:

- _"Is the gateway alive and what's it serving?"_
- _"Talk to a specific agent and capture the trace-id."_
- _"Schedule a daily brief at 07:00 local time."_
- _"Investigate a stuck or failed run."_
- _"Rotate the gateway token without dropping traffic."_

A full openclaw CLI reference lives at [`docs/cli-reference.md`](docs/cli-reference.md).

## Use with Claude Code

This repo doubles as a Claude Code plugin. Once `clawctl` is on PATH, install the plugin from the same repo:

```
/plugin marketplace add tomstagl/clawctl
/plugin install clawctl
```

What ships with the plugin:

| Surface                | Name                | Purpose                                                                                  |
| ---------------------- | ------------------- | ---------------------------------------------------------------------------------------- |
| Slash command          | `/clawctl`          | Drive openclaw — health, models, msg, cli, verify, trace.                                |
| Slash command          | `/clawctl-recipes`  | Curated workflows (cron, sessions, debugging, redaction recovery, token rotation).       |
| Slash command          | `/clawctl-cli`      | Full openclaw CLI reference (every subcommand + flags + examples).                       |
| Skill                  | `openclaw-loopback` | Convention for openclaw agents that deliver work via GitHub: labels, YAML deliverable header, R-1..R-12 communication-layer rules, new-agent checklist. |

The slash commands enforce the same five rules as the CLI from the Claude side: read-only by default, JSON-first, trace every call, redact at the boundary, never bypass the wrapper.

## Design principles

These are non-negotiable. PRs that violate them will be rejected.

1. **Read-only by default.** Mutating commands must be explicit, named, and never invoked autonomously.
2. **No secrets on disk.** Tokens live in Keychain. Env-only fallback is forbidden — `clawctl` would rather fail than read a token from a dotfile.
3. **Trace every call.** A traceparent is generated per invocation and printed to stderr. Reporting an issue means citing a trace-id, not a body.
4. **Redact at the boundary.** Even if upstream agents leak, the wrapper masks before output ever reaches the terminal. The audit log is append-only.
5. **One binary, zero runtime deps.** Bash + `curl` + `jq` (optional) + `security` (macOS) + `openssl`. That's it.

## Contributing

Bug reports and PRs welcome. Before opening a PR:

1. Read `docs/design-principles.md`.
2. Test against your own openclaw gateway (`clawctl health` should still pass).
3. Add or update a recipe in `docs/recipes.md` if you introduce a new pattern.

## License

MIT — see [LICENSE](LICENSE).
tools

Comments

Sign in to leave a comment

Loading comments...