Discovered 2026-05-27 while bringing up Mac mini as OpenClaw client of
PI231 OLP server: `openclaw plugins install ./olp-plugin/` fails with
package.json missing openclaw.extensions; update the plugin package to
include openclaw.extensions (for example ["./dist/index.js"])
OpenClaw v2026.5.22 enforces a stricter plugin-manifest validation than
earlier revisions. The olp-plugin/package.json still used the legacy
schema (`type: "plugin"` + `pluginManifest`) without the new
`extensions: [./index.js]` field that modern OpenClaw requires for the
gateway plugin-discovery loop.
Workaround until this fix lands: manually `cp -R olp-plugin
~/.openclaw/extensions/olp` (symlink also works per docs Option B).
Changes:
- olp-plugin/package.json: added `extensions: ["./index.js"]` to the
openclaw block. Keeps legacy fields (`type`, `id`, `pluginManifest`)
for backwards compat with pre-2026.5 OpenClaw revisions; the modern
loader only reads `extensions`.
- docs/integrations/openclaw.md:
- § 3 Configure: rewrote example to show the modern `plugins.allow` +
`plugins.entries.olp.{enabled, config}` schema. The previous shape
(`plugins.olp.{proxyUrl, apiKey}` at top level) doesn't match what
OpenClaw actually picks up.
- § Known issues: added a paragraph documenting the
`openclaw.extensions` schema-drift event + recovery path (pull latest
OLP, or symlink fallback).
Verified post-fix: `openclaw plugins install ./olp-plugin/` succeeds on
Mac mini OpenClaw v2026.5.22.
Authority:
- Reproduced live on Mac mini 2026-05-27 during PI231-as-server topology
bring-up
- OpenClaw stock plugin format (sample: `/opt/homebrew/lib/node_modules/
openclaw/dist/extensions/anthropic/package.json` uses `extensions:
["./index.js"]`)
Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
5.3 KiB
OpenClaw + OLP
OpenClaw is a multi-bot gateway
that exposes slash commands on Telegram, Discord, and other chat
surfaces. OLP ships olp-plugin/ as a native
OpenClaw plugin that registers a /olp slash command with read-only
parity to the local olp CLI.
Status: ✅ Supported.
What you get
After install, from Telegram or Discord:
| Slash command | Maps to | Tier |
|---|---|---|
/olp status |
GET /v0/management/status |
owner |
/olp health |
GET /health |
public |
/olp usage |
GET /v0/management/dashboard-data |
owner |
/olp models |
GET /v1/models |
public |
/olp cache |
GET /cache/stats |
owner |
/olp providers |
local registry view | public |
/olp chain show [model] |
local chain view | public |
/olp doctor |
informational (HTTP endpoint not yet shipped) | — |
/olp help |
usage text | — |
Mutating subcommands are deliberately not exposed via chat. keygen,
revoke, restart, logs are SSH-only. See
olp-plugin/README.md
for the rationale.
Quick setup
1. Install the plugin
Two install paths — either works.
Option A — OpenClaw CLI:
openclaw plugins install /path/to/olp/olp-plugin/
Option B — symlink:
mkdir -p ~/.openclaw/extensions/
ln -s /path/to/olp/olp-plugin/ ~/.openclaw/extensions/olp
2. Mint a bot owner key
Run on the OLP host (NOT in chat):
npx olp-keys keygen --owner --name=openclaw-bot
Capture the printed plaintext token — it is shown exactly once.
3. Configure
Edit ~/.openclaw/openclaw.json — register the plugin in both plugins.allow and plugins.entries (the modern OpenClaw schema; older revisions of this doc only listed plugins.olp, which is not picked up):
{
"plugins": {
"allow": ["...", "olp"],
"entries": {
"olp": {
"enabled": true,
"config": {
"proxyUrl": "http://127.0.0.1:4567",
"apiKey": "olp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}
}
}
}
4. Restart the gateway
openclaw gateway restart
The plugin is now active. Try /olp help in your bot's chat.
Known issues
-
openclaw gateway restartis required after install. OpenClaw caches plugin discovery at gateway start.openclaw plugins reloaddoes not guarantee a fresh import of the plugin module. -
OpenClaw v2026.5+ requires
openclaw.extensionsinpackage.json. OpenClaw versions ≥ 2026.5.22 enforce a stricter plugin-manifest validation atopenclaw plugins installtime. IfOption Afails withpackage.json missing openclaw.extensionsdespite recent OLP releases, your localolp-plugin/package.jsonmay predate the v0.5.x fix that adds"extensions": ["./index.js"]to theopenclawblock. Pull latest OLP main (git pullin your OLP clone) and retry, or fall through toOption Bsymlink which works against any plugin shape. (Original drift event: 2026-05-27, see commit history ofolp-plugin/package.json.) -
Owner key revocation kicks the plugin out immediately. If you revoke the bot's owner key (
npx olp-keys revoke --id=<id>), the next/olp statuswill return401 unauthorized. Mint a replacement key with a new name and edit~/.openclaw/openclaw.json; do NOT reuse the revoked key's UUID. -
Long responses are truncated. Telegram caps messages at ~4096 characters. The plugin truncates with a
... [truncated, use SSH for full]suffix when the rendered output would exceed ~3900 chars. Use SSH + the localolpCLI for full output.
OLP-specific notes
The plugin honours these env vars on the OpenClaw gateway process:
OLP_PROXY_URL— full URL, overrides plugin configproxyUrl.OLP_PORT— port only, localhost assumed; overridesproxyUrlwhenOLP_PROXY_URLis unset.
If you run the OpenClaw gateway under launchd or systemd with custom env
vars, set OLP_PROXY_URL there rather than editing the plugin config —
that way the same plugin install can serve multiple OLP hosts.
Per-bot vs maintainer key
Always create a dedicated bot key, never the maintainer's personal owner key. The bot key:
- Has its own
idso you can revoke it without affecting other clients. - Has its own audit-log entries so you can attribute
/v0/management/*traffic to the bot. - Can be rotated routinely (every 90 days etc.) without coordinating with the maintainer's daily-driver IDE configs.
Test it
After restart, in Telegram or Discord:
/olp health
/olp status
/olp models
Each should return a code-block-wrapped response within a few seconds.
If you see 401 unauthorized: the configured key is missing / wrong /
revoked. If you see 403 forbidden: the key is not owner-tier. If you
see OLP error: fetch failed or similar: the proxyUrl is unreachable
from the gateway host (test with curl http://<proxyUrl>/health from
that host).
Cross-references
olp-plugin/README.md— full plugin docs.- ADR 0010 § Phase 4 D71-D73 — the plugin's charter.
- OCP
/ocpplugin — the OCP predecessor (includes mutating subcommands that OLP deliberately drops).