Observed since 20 Oct, 17:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
0xai-openclaw-guardian
Real-time cost tracking, security monitoring, and settings dashboard for OpenClaw AI agent deployments
Real-time observability, cost tracking, kill-switches and configuration dashboard for OpenClaw AI agent deployments.
http://localhost:3847 with tabs: Spend · Calls · Crons · Limits · Settings · Securitycalls.db for live queries and aggregations
Real-time spend breakdown by agent, model, and source. API-equivalent cost is displayed even for subscription (Claude Max) calls, so you always see the economic value consumed.
Zero setup if you just want to run it:
# Global CLI
npm install -g openclaw-observability
openclaw-obs
# Or without install
npx openclaw-observability
Then open http://localhost:3847 in your browser.
The proxy starts automatically on http://127.0.0.1:18801 the first time it detects Claude credentials at ~/.claude/.credentials.json.
Edit ~/.openclaw/openclaw.json so each provider's baseUrl points at the local proxy. That makes every call route through observability, pricing, kill-switches, and the logger.
{
"models": {
"providers": {
"anthropic": { "baseUrl": "http://127.0.0.1:18801" },
"openai": { "baseUrl": "http://127.0.0.1:18801/openai/v1" },
"google": { "baseUrl": "http://127.0.0.1:18801/google" },
"openrouter":{ "baseUrl": "http://127.0.0.1:18801/openrouter/v1" },
"groq": { "baseUrl": "http://127.0.0.1:18801/groq/openai/v1" },
"cerebras": { "baseUrl": "http://127.0.0.1:18801/cerebras/v1" },
"xai": { "baseUrl": "http://127.0.0.1:18801/xai/v1" },
"ollama": { "baseUrl": "http://127.0.0.1:18801/ollama", "api": "ollama" }
}
}
}
Restart the OpenClaw gateway so the new baseUrls take effect.
All optional.
| Variable | Default | Description |
|---|---|---|
OPENCLAW_DIR | ~/.openclaw | Path to your OpenClaw directory |
OBS_PORT | 3847 | Dashboard server port |
OBS_HOST | 0.0.0.0 | Bind address |
OBS_LIMITS_FILE | $OPENCLAW_DIR/observability/limits.json | Spend + rate limit config |
OBS_BILLING_PROXY_AUTOSTART | 1 | Start the proxy on boot when Claude creds are present |
OBS_BILLING_PROXY_PORT | 18801 | Proxy port (all providers multiplex here) |
OBS_BILLING_PROXY_HOST | 127.0.0.1 | Proxy bind address |
Historical spend aggregated by agent / model / source / day / cron. Reads from session JSONL files. Works even for subscription calls (API-equivalent cost is always computed).
Every single call captured by the proxy, live. Filters: provider, model, billing mode (SUB/API). Columns:
| Col | Meaning |
|---|---|
| Time | local timestamp |
| Provider / Model | who served the call |
| Agent | derived from request body / openclaw.json whitelist |
| Query | last user message (tooltip has full text) |
| In / Out / Cache / Total | token counts |
| Cost / $/1k | API-equivalent USD |
| Lat | round-trip latency |
| Billing | SUB (subscription plan) or API (pay-per-token) |
List every OpenClaw cron with schedule, agent, last-run status, consecutive errors. Enable/disable or permanently delete any cron from the UI.
Edit ~/.openclaw/observability/limits.json with a form. Proxy hot-reloads on mtime change.
callsPerMinute, callsPerHour, callsPerDay, tokensPerDay.Example limits.json:
{
"enabled": true,
"paused": false,
"global": { "dailyUsd": 10, "weeklyUsd": 50, "monthlyUsd": 200 },
"perAgent": { "anhelo": { "dailyUsd": 3 } },
"perModel": { "claude-opus-4-6": { "dailyUsd": 5 } },
"rateLimits": {
"perProvider": {
"ollama": { "callsPerMinute": 120, "callsPerHour": 2000, "tokensPerDay": 50000000 }
}
},
"loopDetector": { "enabled": true, "windowSec": 60, "maxCalls": 30 }
}
Select each agent's model. Toggle crons. Inspect provider connectivity.
Audit: exposed secrets in config files, file permissions, encryption status.
All endpoints are local, no auth needed (bind to loopback by default).
| Method | Path | Purpose |
|---|---|---|
| GET | /api/dashboard | Spend aggregate for range/filters |
| GET | /api/calls?from&to&provider&agent_id&model&limit&offset | Paginated call log |
| GET | `/api/calls/aggregate?by=provider | model |
| GET | /api/limits | Current limits + spend snapshot |
| POST | /api/limits | Atomic write to limits.json |
| GET | /api/crons | List every cron, enabled or not |
| POST | /api/crons/:id/toggle | `{enable:true |
| DELETE | /api/crons/:id | Permanent delete |
| GET | /api/billing-proxy | Proxy health + guard snapshot |
| GET | /api/security | Security audit |
Every tab and section has a hash slug. Hover any heading to reveal a 🔗 icon — click to copy a shareable URL.
#spend
#calls #calls/filters
#crons
#limits #limits/caps #limits/loop #limits/rates
#settings
#security
When the proxy blocks a request it returns HTTP 429 with a structured payload. Useful for debugging and alerting:
| Code | Trigger |
|---|---|
paused | Emergency switch is ON |
global_daily_cap · global_weekly_cap · global_monthly_cap | Global USD cap reached |
agent_daily_cap · model_daily_cap · provider_daily_cap | Per-dimension USD cap |
loop_detected | Session fired too many calls too fast |
provider_rpm_cap · provider_rph_cap · provider_rpd_cap | Rate-limit for zero-cost provider |
provider_tpd_cap · agent_id_tpd_cap · model_tpd_cap | Token-budget cap |
@mariozechner/pi-ai generated catalog, ~45 models) plus a small fallback table.uncached = input − cacheRead.Copy the 3 hook handlers into your OpenClaw hooks directory to automate startup and spend enforcement:
mkdir -p ~/.openclaw/hooks/{observability,spend-guard,model-guard}
cp node_modules/openclaw-observability/hooks/observability/handler.ts ~/.openclaw/hooks/observability/
cp node_modules/openclaw-observability/hooks/spend-guard/handler.ts ~/.openclaw/hooks/spend-guard/
cp node_modules/openclaw-observability/hooks/model-guard/handler.ts ~/.openclaw/hooks/model-guard/
| Hook | Trigger | Effect |
|---|---|---|
| observability | Gateway startup | Launches the dashboard server |
| spend-guard | Before each agent turn | Rejects the call if caps are breached |
| model-guard | Before each agent turn | Prevents drift to more expensive models |
127.0.0.1) by default. Do not expose it publicly — it relays OAuth tokens.~/.claude/.credentials.json is read in-memory; never logged or echoed.limits.json and calls.db live inside ~/.openclaw/observability/. The repo .gitignore excludes every user-specific directory.git log -p against this repo to verify: zero secrets committed.git clone https://github.com/<your-org>/openclaw-observability
cd openclaw-observability
npm install
node bin/cli.mjs
Source layout:
src/
├── server.mjs # Dashboard HTTP + REST API
├── billing-proxy.mjs # Anthropic proxy (OAuth rewriting)
├── multi-provider.mjs # Generic router for OpenAI/Google/Ollama/etc
├── usage-parser.mjs # Per-provider token extractor
├── logger.mjs # SQLite call log (better-sqlite3, JSONL fallback)
├── guards.mjs # Kill-switch evaluator (caps + rate + loop detector)
├── pricing.mjs # noosphere-backed cost calculator
└── dashboard.html # Single-file SPA, Tailwind + vanilla JS
MIT
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
noosphereEnvironment{
"local_name": "noosphere",
"alias": false,
"peer_metadata": null
} | * | runtime |
better-sqlite3Environment{
"local_name": "better-sqlite3",
"alias": false,
"peer_metadata": null
} | ^11.10.0 | runtime |
Source distribution
{
"shasum": "15e6b9d8d95d7727aa536b1f0e7778b6e9033706",
"tarball": "https://registry.npmjs.org/0xai-openclaw-guardian/-/0xai-openclaw-guardian-2.0.0-alpha.0.tgz",
"fileCount": 15,
"integrity": "sha512-HeibV6Bh54FUFDgCMUGH6zf0ywni5faq4GrG82nNMagETuErc/HforY3SyPEI+MKJLkIEF9Z3Th6dORxR4bvDQ==",
"signatures": [
{
"sig": "MEYCIQCXRYFwAXPtafKlN7WeUEUbRU5fLpRT5jqEsSYqtQDRDQIhAMhefoRuFbwF0CO1Xwx4SOPURFjJeYvjGewnQ6RsjC7h",
"keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
}
],
"unpackedSize": 240453
}Shared repository data · GitHub
Observed since 20 Oct, 17:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:a63b01e3a27c1f6224e2041d21998c8e744dd0baceebd2c3a0839cfaea09ed0e