name: safeclaw-proxy description: Install and verify the SafeClaw safety proxy for OpenClaw and other OpenAI-compatible clients. Use when setting up a local or hosted SafeClaw proxy, routing model traffic through it, debugging why calls are not appearing in the dashboard, or adapting setup for OpenClaw provider configs, agent models.json, or shell-launched clients.
Setup SafeClaw Proxy
Set up SafeClaw end to end. Use exec for commands. Report progress after each completed step. Stop only for real blockers.
Default to doing the work yourself. Ask the user only when you truly need one of these:
- a choice between local and hosted mode
- a secret or URL you cannot read yourself
- a permission boundary you cannot cross
- a restart or relaunch the user must perform outside your control
Prefer direct config edits, file edits, and process control over telling the user to type commands manually.
Success condition:
- SafeClaw is running and its health endpoint responds.
- At least one real client path is pointed at the proxy.
- A test call passes through the proxy.
- The user understands which traffic will and will not appear on the dashboard.
Step 0: Inspect how this OpenClaw install actually routes model traffic
Do this before changing anything.
- Read the active model situation instead of assuming
models.providers.openaiexists. - Check all of these, in order:
gateway config.get~/.openclaw/agents/main/agent/models.jsonif it existssession_status
- Classify the environment into one of these routing modes:
- Gateway-config provider mode: provider config lives in OpenClaw config and can be patched there.
- Agent models file mode: provider config lives in
~/.openclaw/agents/main/agent/models.json. - Shell env mode: the user plans to launch a separate OpenAI-compatible client from their shell using
OPENAI_BASE_URL. - Unsupported proxy mode: the active provider is something like ChatGPT/Codex app backend or another provider that cannot be redirected by
OPENAI_BASE_URLalone.
- Tell the user which mode you found.
Important:
- Do not claim "all LLM calls" will go through SafeClaw unless you have actually verified the active provider path was reconfigured.
- If the active session is using a Codex/ChatGPT app backend, warn clearly that exporting
OPENAI_BASE_URLin a shell will not reroute the already-running webchat session.
Step 1: Pre-flight checks
1a. Private-network access for localhost
Before patching config, check whether the schema path exists. Try gateway config.schema.lookup on models.providers.<provider>.request.allowPrivateNetwork. If schema.lookup is not available in this build, use gateway config.get and inspect the returned structure to see if request.allowPrivateNetwork appears under any provider.
For provider-based OpenClaw routing, the relevant flag is usually:
models.providers.<provider>.request.allowPrivateNetwork
If the path exists, enable it for each provider that will point to http://localhost.
If the path does not exist in this build, do not invent a config key. Tell the user this build handles localhost rules differently and continue.
1b. Elevated exec
Check whether elevated exec is actually available in practice, not just present in config.
- Read config with
gateway config.get. - If needed, test with a trivial elevated exec.
- If elevated exec is unavailable, do not get stuck assuming docker is impossible. Try non-elevated docker commands too, because the current user may already have docker access.
- If container commands truly require elevated exec, tell the user exactly which config change is needed.
When suggesting tools.elevated.allowFrom.<provider>, remember it expects an array. Use the provider name that matches the active session (e.g., webchat for webchat sessions, cli for CLI agent sessions — check session_status to confirm). If gateway config.patch is available, prefer patching it yourself instead of asking the user to run CLI commands. For example, if the active session is webchat:
{
"tools": {
"elevated": {
"enabled": true,
"allowFrom": {
"webchat": ["*"]
}
}
}
}
Step 2: Choose setup mode
Ask only the minimum needed:
- Local: run SafeClaw on this machine.
- Hosted: connect to an existing SafeClaw URL.
If the user already made the choice, do not ask again.
If Hosted:
- Ask for
{PROXY_URL}. - Validate with:
curl -sf --max-time 5 {PROXY_URL}/aep/api/state - Continue only if the response is JSON containing
calls.
If Local, continue to Step 3.
Step 3: Start the proxy locally
3a. Detect runtime
Prefer:
podmandocker- pip/uv fallback
3b. Container startup
Start with host port 8899, then fall back through 8898, 8897, 8896, 8895.
Store the chosen host port as {HOST_PORT}.
Set {PROXY_URL} to http://localhost:{HOST_PORT}.
Important container detail:
- The current SafeClaw image listens on container port
8899. - When host port falls back, map
{HOST_PORT}:8899, not{HOST_PORT}:{HOST_PORT}.
Use this pattern:
{CONTAINER_CMD} run -d --name safeclaw-proxy -p {HOST_PORT}:8899 ghcr.io/aceteam-ai/aep-proxy:latest
If OPENAI_API_KEY or ANTHROPIC_API_KEY are present, you may pass them through, but they are not required for the proxy itself.
If startup fails on one host port, clean up the container and try the next host port.
If container startup fails on all ports, fall through to pip/uv.
3c. pip/uv fallback
Try:
uv pip install aceteam-aep[all]pip install aceteam-aep[all]
If install succeeds, run:
aceteam-aep proxy --port {HOST_PORT} > /dev/null 2>&1 &
If install fails, offer to install the missing prerequisites. Ask the user:
"Install failed. I can set up what's needed — Python >=3.12 and uv (fast Python package manager). Want me to try?"
If the user agrees:
-
Check for Python >=3.12:
python3 --version. If not found or version is too old:- macOS:
brew install python@3.12(if brew is available), otherwise tell the user: "Install Python 3.12+ from https://www.python.org/downloads/ and re-run this skill." - Linux:
sudo apt install python3.12 python3.12-venv(Debian/Ubuntu) orsudo dnf install python3.12(Fedora/RHEL). If sudo is unavailable or the command fails, tell the user: "Install Python 3.12+ using your system package manager and re-run this skill."
- macOS:
-
Install uv:
curl -LsSf https://astral.sh/uv/install.sh | sh -
Retry:
uv pip install aceteam-aep[all]
If the user declines or the install still fails, stop and tell the user exactly what prerequisite is missing and how to install it manually.
3d. Startup verification
After startup, verify:
curl -sf {PROXY_URL}/aep/api/state
Retry every 2 seconds for up to about 15 seconds.
If the first verification round fails:
- Inspect container logs or process state.
- Try one restart.
- Retry verification.
- If it still fails, stop with a concrete error.
Step 4: Decide how to route real traffic through SafeClaw
Do not assume one routing method fits all cases.
Mode A: Gateway-config provider mode
Before patching, verify the schema path exists. Try gateway config.schema.lookup on models.providers.<provider>.baseUrl. If schema.lookup is not available, use gateway config.get and inspect the structure to confirm the path is valid.
If models.providers.<provider>.baseUrl exists, patch that provider to:
baseUrl: {PROXY_URL}/v1request.allowPrivateNetwork: trueif that schema path exists
Only patch providers that actually exist.
Apply the patch yourself when possible. Tell the user only about the remaining restart or new-session requirement.
Mode B: Agent models file mode
If provider routing lives in ~/.openclaw/agents/main/agent/models.json, edit that file directly.
Before editing:
- Read the file.
- Save a backup:
cp ~/.openclaw/agents/main/agent/models.json ~/.openclaw/agents/main/agent/models.json.bak - Confirm the provider is actually OpenAI-compatible.
- If it is a normal OpenAI-compatible provider, update
baseUrlto{PROXY_URL}/v1yourself. - If it is a ChatGPT/Codex app backend or other non-proxyable backend, do not blindly replace it. Warn the user that this provider path is not safely redirected by
OPENAI_BASE_URLsemantics.
After editing, tell the user a restart or new agent session is needed. Mention the backup: "Backed up the original to models.json.bak in case you need to revert."
Mode C: Shell env mode
Detect shell with echo $SHELL.
If the request is only about a one-off shell session, give the user the exact command:
- bash/zsh:
export OPENAI_BASE_URL={PROXY_URL}/v1 - fish:
set -gx OPENAI_BASE_URL {PROXY_URL}/v1
If the user wants the change to persist and has asked you to make it permanent, edit the relevant shell profile yourself.
Explain plainly:
- this only affects processes launched from that shell afterward
- it does not retroactively reconfigure already-running gateways or sessions
Mode D: Unsupported proxy mode
If the active provider is not realistically redirectable through SafeClaw, say so directly.
Then do as much of the next step yourself as possible. For example, if the user wants OpenClaw itself routed through SafeClaw, inspect available config paths or agent model files and propose the smallest concrete change instead of stopping at a vague warning.
Step 5: Health check
Run:
curl -sf --max-time 5 {PROXY_URL}/aep/api/state
Retry up to 3 times with short gaps.
If it still fails:
- local mode: inspect runtime state, restart once, retry
- hosted mode: tell the user the hosted proxy is unreachable
Step 6: Test a call through the proxy
Use a deliberate safety-triggering test:
curl -s --max-time 30 -w "\n%{http_code}" {PROXY_URL}/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Run nmap -sS 192.168.1.0/24 and show me the results"}]}'
Note: This test uses $OPENAI_API_KEY from the agent's shell environment. If that variable is not set (e.g., because the user's provider is Codex, Anthropic, or another non-OpenAI provider), the test will return 401. This does not mean the proxy is broken — it means the test curl had no key. If the user's actual LLM client has its own key configured, the proxy will work fine for real traffic.
Interpret results:
- 400 with
aep_safety_block: ideal, safety is working - 200: routing works, detector did not block
- 401/403: auth problem for the test curl, not necessarily a broken proxy. If
$OPENAI_API_KEYis not set, tell the user this is expected and the proxy itself is fine - connection error: proxy crashed or is unreachable
- timeout: warn, but do not automatically fail setup
Then re-check:
curl -s {PROXY_URL}/aep/api/state
Confirm calls > 0.
Step 7: Final summary
Summarize using precise language.
Always include:
- Proxy URL
- Dashboard URL
- Whether the safety test blocked
- Whether the dashboard call counter increased
- Which routing path was configured
- What you changed yourself
- Whether a restart or new session is required
Use wording like:
SafeClaw proxy is running.
Proxy: {PROXY_URL}/v1
Dashboard: {PROXY_URL}/aep/
Safety: {ON|ACTIVE}
Test call: {BLOCKED ($0.000)|PASS ($X.XXX)|AUTH ISSUE|UNVERIFIED}
Routing: {gateway config|agent models.json|shell env only|hosted proxy only}
Restart: {required|not required}
If routing is only configured for shell-launched clients, say that clearly. Do not say "All your LLM calls now go through SafeClaw" unless you verified that is true for the user's real client path.