Minimal installation kit for running BOTCTL_URL, BOTCTL_FILE, and BOTCTL lifecycle commands on another OpenClaw main agent.
This kit installs:
skills/botctl/SKILL.mdskills/openclaw-bot-lifecycle/SKILL.mdscripts/openclaw-bot-lifecycle/botctl_local.py
Use this when developer needs to control another OpenClaw instance with the smallest possible remote footprint.
The remote side only needs:
- the two skills
- the local helper script
- Python 3
- local filesystem access to its own OpenClaw state
Run:
./install.sh \
--workspace "/path/to/openclaw-workspace" \
--main-agent-id "dev"If --state-root is omitted, the installer defaults to the workspace parent directory.
Example:
./install.sh \
--workspace "$HOME/.openclaw/workspace" \
--main-agent-id "main"If you want to pass it explicitly, use the same state root your gateway is actually reading:
./install.sh \
--workspace "$HOME/.openclaw/workspace" \
--state-root "$HOME/.openclaw" \
--main-agent-id "main"Recommended internal usage:
- push this repository to GitHub
- create tags such as
v0.1.0 - let teammates download a fixed tag or release zip instead of the moving default branch
After install, the target OpenClaw instance will contain:
<workspace>/skills/botctl/SKILL.md
<workspace>/skills/openclaw-bot-lifecycle/SKILL.md
<workspace>/scripts/openclaw-bot-lifecycle/botctl_local.py
The developer service should send one of:
BOTCTL_URL: <signed-bundle-url>BOTCTL_FILE: <payload-file>BOTCTL: <inline-json>
BOTCTL_URL is preferred.
- This kit does not create a database.
- Bundles downloaded through
--bundle-urlare unpacked into a temporary directory and deleted after execution. - The
developerside is still responsible for generating signed bundle URLs and lifecycle payloads. - Running
install.shwill overwrite the installed skill and helper files at the target paths. --state-rootmust point to the same OpenClaw state root your gateway is using, typically~/.openclaw.- The lifecycle helper should be executed directly as
.../botctl_local.py <payload>or.../botctl_local.py --bundle-url <url>. Do not wrap it withpython3, otherwise script-path allowlists may not match. - For Zapry /
openapibots,createnow provisionschannels.zapry.accounts.<botId>and the matchingbindingsroute so polling can start before later publish/activate steps. - For Zapry /
openapibots,createandactivatenow fail if the expected account/route wiring is not present after writingopenclaw.json, anddeletefails if the target account/route still remains after cleanup.
After installation, ask the remote OpenClaw main agent to process a BOTCTL_URL: message. If the helper runs and returns:
Action: activate
Bot: <botId>
Status: activated
then the bridge is wired correctly.
For Zapry / openapi bots, you can also validate after create that:
channels.zapry.accounts.<botId>exists inopenclaw.json- a
bindingsroute exists from account<botId>to agent<tenantId>-<botId>