Skip to content
Conduit

mcp server

axonflow-openclaw-plugin

AxonFlow governance for OpenClaw agents — block dangerous tools, govern MCP access, and keep audit trails for production agent workflows

getaxonflow/axonflow-openclaw-plugincommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

Before you start

  • Node.js 20 or newer
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "axonflow-openclaw-plugin": {
      "command": "npx",
      "args": [
        "-y",
        "@axonflow/openclaw"
      ]
    }
  }
}

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Oct 25, 2026

@axonflow/openclaw

Governance for OpenClaw agents: block dangerous tool calls, require human approval on high-risk actions, redact PII from outbound messages, and keep a compliance-grade audit trail — without changing a single line of your agent code.

npm ClawHub License: MIT

→ Full integration walkthrough: docs.getaxonflow.com/docs/integration/openclaw — architecture, hook coverage, policy examples, and troubleshooting.

Upgrade strongly recommended. AxonFlow ships substantial monthly security and quality hardening; staying on the latest major is the security-supported release line. Latest release · Security advisories

Rolling this plugin out for a real team or production workflow?

Choose the path that fits:

  • Self-serve hosted: $9.99/month Hosted Starter after registration, with published usage limits
  • Free self-hosted: Community Edition on infrastructure you operate
  • Paid production program: Design Partner or Confidential Pilot - one scoped workflow over 60 or 75 days, founder-led rollout support, upfront conversion pricing, and a fixed decision date; public track from $2,000 or confidential track from $4,000

The paid program requires a dated forcing event, written controls, an executive sponsor, and a technical owner. Prices are subject to eligibility and a signed agreement.


Why this plugin exists

OpenClaw is a strong agent runtime. It is also a serious production security problem the moment you take it past a prototype:

OpenClaw handles agent runtime, MCP connectivity, channels, and tool execution. It was never intended to be the place you enforce governance. This plugin adds the governance layer on top, so OpenClaw keeps doing what it does well and AxonFlow takes over the "is this allowed, should this redact, who approved, where is the audit record" questions.

AxonFlow governs. OpenClaw orchestrates. OpenClaw still makes every LLM call; AxonFlow only evaluates policies and records audit trails. LLM provider keys never leave your machine. Where the rest of your data goes — tool inputs, message bodies — depends on which deployment mode you pick. See Where your data goes below.


Where your data goes

The plugin governs tool calls and outbound messages by sending each one to an AxonFlow endpoint for policy enforcement and audit. Pick the deployment mode that fits your workload:

Privacy notice — read before installing. AxonFlow Community SaaS at try.getaxonflow.com is the zero-config endpoint the plugin uses if no other endpoint is configured. In that mode, governed tool inputs (tool name + arguments) and outbound message bodies are checked by AxonFlow's policy enforcement endpoint. Community SaaS is for early exploration only — not for production workloads, regulated environments, real user data, personal data, or any other sensitive information. It is offered "as is" on a best-effort basis with no SLA, no warranties, and no commitment to retention, deletion, or incident-response timelines.

For any serious use, choose one of the following instead:

  1. Self-host AxonFlow Community Edition — runs entirely on your infrastructure and keeps data within your boundary. Recommended for any real workload.
  2. Community Edition with an Evaluation License — for production use with real users or clients on the open core; adds production-fit limits and license-gated features. Free 90-day evaluation license.
  3. AxonFlow Enterprise — production-grade governance, regulatory-grade controls, SLOs, and contractual commitments suitable for regulated industries. Contact hello@getaxonflow.com.

To skip Community SaaS entirely: set pluginConfig.endpoint to a self-hosted AxonFlow URL. That alone flips the plugin into self-hosted mode — the Community SaaS auto-bootstrap is not attempted, and no env var is required. Get the AxonFlow platform from getaxonflow/axonflow and follow the Getting Started guide for the Docker Compose setup. For air-gapped environments where AxonFlow is not yet reachable but you want to suppress the bootstrap attempt, set AXONFLOW_COMMUNITY_SAAS=0; set AXONFLOW_TELEMETRY=off to also disable the 7-day usage heartbeat.

Self-hosted (recommended for any real use)

Point the plugin at an AxonFlow instance you run. Nothing leaves your network except the usage heartbeat (which can also be disabled). Configure three values in pluginConfig:

  • endpoint — the URL of your AxonFlow agent gateway (for example https://axonflow.your-corp.example.com).
  • clientId — the AxonFlow tenant identifier issued to your deployment.
  • clientSecret — the matching secret. Never commit this to source control or paste it into a config file checked into a repository. Resolve it from a secret manager (Vault, AWS Secrets Manager, GCP Secret Manager, or your CI provider's secret store) and inject the value via your OpenClaw config templating, an environment variable consumed by your config loader, or your platform's secret-injection sidecar.

For production with real users or clients: run Community Edition with a free 90-day Evaluation License for production-fit limits and license-gated features, or AxonFlow Enterprise for regulated industries with SLOs and contractual commitments.

See the Self-Hosted Deployment Guide for prerequisites and production options, or the OpenClaw Integration Guide for architecture and the full pluginConfig schema.

Community SaaS hosted starter

Install the plugin without setting pluginConfig.endpoint and it registers an account with try.getaxonflow.com on first load. Registration is free. Hosted governance becomes active after the dedicated $9.99/month checkout completes. The plugin creates Checkout from the authenticated account, so there is no tenant ID to copy and no license token to paste. Auto-registration credentials persist at $AXONFLOW_CONFIG_DIR/try-registration.json (mode 0600).

Use only for early exploration of the plugin's behaviour. Not for production workloads, regulated environments, real user data, personal data, or any other sensitive information.

What goes to try.getaxonflow.comWhat does NOT
Tool name + arguments before each governed callLLM provider API keys
Outbound message bodies before delivery (PII/secret scan)OpenClaw conversation history outside governed tools
Usage heartbeat (plugin version, OS, runtime, instance ID)Files outside the OpenClaw runtime

Hosted Starter includes the governance foundation plus limited FinCrime, payment exception, support refund, and secure Customer Portal access. The exact governed-event, case, seat, integration, retention, and burst limits are shown before purchase and by the billing status API. Higher volume, additional integrations, longer retention, production financial actions, and contractual controls follow the paid Enterprise PoC or design-partner path. Read the Community SaaS documentation for the data boundary and current limits.

Air-gapped: zero outbound

If you need the plugin to make no outbound calls at all — air-gapped lab, regulated network, etc. — set both:

export AXONFLOW_COMMUNITY_SAAS=0   # disable auto-bootstrap
export AXONFLOW_TELEMETRY=off      # disable 7-day heartbeat

…and configure pluginConfig.endpoint to a self-hosted AxonFlow on the same network. With these set, no traffic leaves your environment.

Environment variables

The plugin recognizes the following environment variables. All are optional with safe defaults; the plugin runs unmodified if none are set.

VariableEffect
AXONFLOW_ENDPOINTOverride the AxonFlow agent gateway endpoint. Wins over pluginConfig.endpoint when both are set. Setting this selects self-hosted mode: all governed traffic targets this endpoint and the Community-SaaS auto-registration never runs. When unset and AXONFLOW_COMMUNITY_SAAS is not opted out, the plugin auto-bootstraps against https://try.getaxonflow.com. For self-hosted deployments, set this (or pluginConfig.endpoint) to your AxonFlow URL.
AXONFLOW_TELEMETRY=offDisables the 7-day usage heartbeat to checkpoint.getaxonflow.com. Accepted off-values: off, 0, false, no.
AXONFLOW_COMMUNITY_SAAS=0Disables auto-registration with try.getaxonflow.com. You must then set pluginConfig.endpoint (or AXONFLOW_ENDPOINT) for the plugin to enforce policy. Accepted off-values: 0, false, off, no.
AXONFLOW_CACHE_DIROverrides the per-user cache dir (telemetry stamp, rate-limit backoff, free-tier throttle + upgrade-prompt stamps). Defaults to $XDG_CACHE_HOME/axonflow (Linux), ~/Library/Caches/axonflow (macOS), %LOCALAPPDATA%\axonflow (Windows).
AXONFLOW_CONFIG_DIROverrides the per-user config dir (Community-SaaS registration file, disclosure stamp, plugin runtime-state record read by axonflow-openclaw-status). Defaults to OS conventions: $XDG_CONFIG_HOME/axonflow (Linux), ~/Library/Application Support/axonflow (macOS), %APPDATA%\axonflow (Windows).
AXONFLOW_LICENSE_TOKENLegacy prepaid plugin-claim token. Existing 90-day purchases remain valid through their paid term. New monthly hosted subscriptions are resolved from the registered account and require no token.
AXONFLOW_USER_TOKENPer-user authorization token forwarded on every governed request via the X-User-Token header, giving this developer a validated {identity, role} on the AxonFlow fleet plane: role-scoped reads return the developer's own rows, and audit attribution keys on the token's canonical email — beating the forgeable userEmail label — on the planes that consume the header (the MCP tools at /api/v1/mcp-server and the audit/decisions/overrides REST surface; the check-input/check-output hook plane keeps client-scoped attribution on current platforms). Minted by an org admin via the AxonFlow user-token mint API; delivered via managed settings/MDM. Resolution order: pluginConfig.userToken wins over this env var, which wins over the 0600 provisioning file ~/.config/axonflow/user-token.json (a cross-plugin path shared with the other AxonFlow plugins). A malformed value is dropped with a warning — never sent — and resolution falls through to the next source. Unset (default): no header is sent; requests are byte-identical to v2.6.x.
AXONFLOW_PEP_AUDIENCEThe audience your AxonFlow decision proofs are bound to. Set it and this plugin declares what it can enforce on every governed call (ADR-065 PEP capability handshake, sent as X-Axonflow-PEP-Handshake): a platform running v10.4.0 or later then refuses to hand this plugin a mandatory obligation it has declared it cannot discharge, rather than assuming it will. The plugin presents two declarations under separate names, because its request and response paths discharge different obligations. A malformed value throws at construction rather than silently disabling the handshake. Unset (default): no header is sent and requests are byte-identical to v2.8.x.
AXONFLOW_RECOVERY_TIMEOUT_MSPer-HTTP-request timeout in milliseconds for the bundled axonflow-openclaw-recover CLI's calls to /api/v1/recover and /api/v1/recover/verify. Default 10000 (10s). Increase for high-latency networks; decrease for fail-fast CI environments.
AXONFLOW_UPGRADE_URLOverrides the authenticated hosted checkout endpoint surfaced by axonflow-openclaw-status. Defaults to https://try.getaxonflow.com/api/v1/billing/checkout.
AXONFLOW_TRY=1Forces the v1 telemetry deployment_mode classifier to report community_saas even when the configured endpoint is a custom hostname proxying try.getaxonflow.com. No effect outside the heartbeat payload.

The same set is the authoritative declaration in openclaw.plugin.json envVars block — both surfaces ship in the published artifact and stay in lockstep via the manifest-envvars-coverage CI gate.

Activate Hosted Starter

Hosted Starter starts at $9.99 USD per month. It includes the governance foundation plus limited FinCrime, payment exception, support refund, and secure Customer Portal access. The dedicated checkout shows the current governed-event, case, seat, integration, retention, and burst allowances before purchase.

To activate an installed plugin:

  1. Register and check status. Run the plugin once, then run:

    npx @axonflow/openclaw axonflow-openclaw-status
    

    The status output confirms the registered client identity and the authenticated checkout endpoint. You do not copy that identity into Stripe.

  2. Make the first governed call. If the account is unpaid, OpenClaw blocks the action, creates a tenant-bound Checkout session, and logs one actionable Checkout URL.

  3. Complete Checkout. Stripe webhook activation applies to the same registered tenant. Reload OpenClaw and retry the call. No emailed license token is required.

Existing 90-day prepaid tokens continue working until their recorded expiry. Renewals, failed payments, cancellation, invoices, and recovery are available through the billing status and secure billing portal endpoints.

Check status

Use the status command to confirm the registered identity, endpoint, deployment mode, legacy prepaid token state, and authenticated checkout endpoint:

# Installed via OpenClaw plugin install:
npx @axonflow/openclaw axonflow-openclaw-status

# Or directly from a clone:
node bin/axonflow-openclaw-status.mjs

# Machine-readable JSON, suitable for piping into jq:
axonflow-openclaw-status --json

Sample output (hosted account registered):

AxonFlow OpenClaw plugin status

  client_id:  cs_demo_tenant_abc123  (formerly tenant_id)
              (authenticated identity; hosted checkout binds it automatically)
  endpoint:   https://try.getaxonflow.com  (mode=community-saas)
  tier:       Hosted Starter (payment status checked by AxonFlow)
  checkout:   POST https://try.getaxonflow.com/api/v1/billing/checkout
              The first unpaid governed call opens the dedicated $9.99/month checkout.

Sample output (self-hosted):

AxonFlow OpenClaw plugin status

  client_id:  acme-prod  (formerly tenant_id)
              (from pluginConfig.clientId; the identity governed requests authenticate with)
  endpoint:   https://axonflow.acme.internal  (mode=self-hosted)
              (from pluginConfig, as recorded by the plugin load at
              2026-07-28T11:02:14.881Z; reload OpenClaw after changing it)
  tier:       Self-hosted Community

Sample output (legacy prepaid term active):

AxonFlow OpenClaw plugin status

  client_id:  cs_demo_tenant_abc123  (formerly tenant_id)
              (authenticated identity; hosted checkout binds it automatically)
  endpoint:   https://try.getaxonflow.com  (mode=community-saas)
  tier:       Prepaid Pro (expires 2026-10-14, 78 days remaining)
  license:    ...XYZ9 (redacted; last 4 chars only)

The license token is never printed in full — only the last four characters are shown so you can confirm the token is the one you expect without exposing it via screen-share, copy-paste, or shell history. If client_id is missing, the CLI points you at axonflow-openclaw-recover to re-issue credentials against your registered email. JSON output (--json) populates BOTH client_id and the legacy tenant_id key with the same value so v2.4.x consumers keep working unchanged.

Self-hosted installs. The CLI runs as its own process. It can see neither OpenClaw's pluginConfig nor the environment the OpenClaw runtime was started with, so through v2.8.4 it reported the Community-SaaS default endpoint and the cached Community-SaaS client_id even when governed traffic was going to a self-hosted stack (#167).

It now resolves the endpoint, mode and identity through the same helper the governance runtime uses. To give that helper the inputs it otherwise could not see, every plugin load records them at $AXONFLOW_CONFIG_DIR/openclaw-plugin-runtime-state.json (mode 0600): the endpoint override the runtime resolved — from either AXONFLOW_ENDPOINT or pluginConfig.endpoint — plus the configured clientId. No credentials are written: clientSecret, licenseToken and userToken are excluded.

What is recorded is your input, not the resolved answer. AXONFLOW_ENDPOINT is still read live from whatever shell you run the CLI in, and still wins, so a recorded value only ever fills a gap and can never override your current environment. Three consequences worth knowing:

  • The mode= suffix on the endpoint line, and the mode / identity_source keys in --json, tell you which deployment the answer describes.
  • When a recorded value contributed, the CLI names the channel it came from and the timestamp of the load that recorded it. When nothing was recorded, or nothing contributed, that line is absent rather than decorating an environment-only answer with a timestamp that would suggest otherwise.
  • If your shell exports a different AXONFLOW_ENDPOINT than the runtime was started with, the CLI reports what a fresh load would resolve and adds a NOTE: naming the endpoint the running plugin is still governing against until it reloads.

Change pluginConfig or the runtime's environment and reload OpenClaw, and the record is rewritten to match.

One record exists per config directory. If you run two OpenClaw hosts with different plugin configurations against the same AXONFLOW_CONFIG_DIR, the last one to load wins the record, and the CLI will report that configuration to both. Give them separate AXONFLOW_CONFIG_DIRs if you need their status surfaces to stay independent — the runtimes themselves are unaffected, since each governs from its own in-process configuration.

The same values are available to the agent through the axonflow_get_tenant_id tool, which runs inside the runtime and reads the live config directly.

Recover lost Community-SaaS credentials

If you registered with Community SaaS, lost the auto-bootstrapped credential file ($AXONFLOW_CONFIG_DIR/try-registration.json), and want your tenant + audit history back:

# Installed via OpenClaw plugin install:
npx @axonflow/openclaw axonflow-openclaw-recover you@example.com

# Or directly from a clone:
node bin/axonflow-openclaw-recover.mjs you@example.com

The CLI:

  1. Posts your email to /api/v1/recover (the platform always returns 202 — anti-enumeration, no signal whether the email is bound or not).
  2. Prompts you to paste the magic-link token (or the full magic-link URL) from the email you receive.
  3. Posts the token to /api/v1/recover/verify, which returns a freshly-issued tenant_id + secret bound to the original email.
  4. Persists the new credentials at $AXONFLOW_CONFIG_DIR/try-registration.json (mode 0o600).

Reload OpenClaw and the plugin picks up the recovered registration on the next init — no other config change required. Magic-link tokens are one-shot and short-lived; replays return 401.


What you get

CapabilityWhat it means in practice
Pre-execution policy checkEvery tool call is scored against 80+ built-in policies (reverse shells, SSRF, credential access, SQLi, prompt injection, path traversal, PII in arguments) before it runs
Approval gatesAny tool in highRiskTools pauses execution and posts a native OpenClaw approval request with policy severity surfaced as approval priority
Outbound message scanningEvery message to Telegram/Discord/Slack/webhook is scanned for PII and secrets before delivery — redacted, blocked, or passed through per policy
Compliance-grade audit trailEvery tool call and LLM interaction records the input, output summary, matched policies, decision, and duration
Decision explainabilityBlocked calls return a decision_id the agent can pass to explainDecision() to see exactly which policy family triggered and why
Session overridesOperators can request a time-bounded, audit-logged exception when policy allows it — without leaving the agent
Per-user identityconfig.userEmail threads the actual human operator through to every explain/override call, so shared chat agents still produce attributable audits

How it plugs in

┌──────────────────────────────────────────────────────────────┐
│                        OpenClaw Agent                        │
│                                                              │
│  User Message → LLM Call → Tool Execution → Response → User  │
│        │           │             │                       │   │
│        ▼           ▼             ▼                       ▼   │
│  ┌────────────────────────────────────────────────────────┐  │
│  │            @axonflow/openclaw                          │  │
│  │                                                        │  │
│  │  GOVERNANCE (can block / modify):                      │  │
│  │  before_tool_call   (priority 10) → check_input        │  │
│  │  message_sending    (priority 10) → check_output       │  │
│  │                                                        │  │
│  │  AUDIT (observe-only, non-blocking):                   │  │
│  │  after_tool_call    (priority 90) → audit_tool_call    │  │
│  │  llm_input          (priority 90) → record prompt      │  │
│  │  llm_output         (priority 90) → record response    │  │
│  └────────────────────────┬───────────────────────────────┘  │
└───────────────────────────┼──────────────────────────────────┘
                            │
                            ▼
                    ┌───────────────────┐
                    │     AxonFlow      │
                    │  ┌─────┐ ┌─────┐  │
                    │  │Policy│ │Audit│  │
                    │  │Engine│ │Trail│  │
                    │  └─────┘ └─────┘  │
                    │  ┌─────┐          │
                    │  │ PII │          │
                    │  │Scan │          │
                    │  └─────┘          │
                    └───────────────────┘

What stays the same: your OpenClaw agent config, ClawHub skills, MCP connectors, and channel integrations are unchanged. The plugin only adds lifecycle hooks.


The production problems this solves

These are the three questions that reliably surface the moment an OpenClaw agent hits real users or regulators.

1. "The tool that phones home"

A web_fetch skill is installed from ClawHub. An agent uses it to look up product docs. Then a user asks, "Summarize my customer list" — the agent calls web_fetch with customer emails in the URL. The data leaves your infrastructure. OpenClaw executed the tool correctly; nobody checked what it was sending.

What the plugin does: check_input fires before web_fetch runs, scans the URL arguments against PII and exfiltration policies, and blocks the call with a decision ID.

2. "The MCP response full of PII"

An MCP connector queries your CRM for "recent support tickets." The MCP server returns 50 rows with names, emails, phone numbers. All of it flows into the LLM context. OpenClaw managed the connection; SecretRef protected the credentials; the data itself was never inspected.

What the plugin does: check_output fires on message_sending before anything reaches the user channel, and scans every outbound message for SSN, credit card, API key, and other 80+ policy matches — redacting or blocking per policy.

3. "The compliance question nobody can answer"

Six months later, a regulator asks: "For this interaction on March 14, which tools were called, what data did they access, which policies were in effect, and why was the response allowed?" OpenClaw's execution logs show a tool was called and succeeded. The decision context does not exist.

What the plugin does: every governed call emits a structured audit record with tool, input, output summary, matched policies, decision, and duration. Search via searchAuditEvents() or the Customer Portal.


Take a governed plugin rollout into production

Solo developers and self-serve teams can use the free 90-day Plugin Evaluation License to validate hook behavior, policy packs, and override workflows.

Organizations with a dated production requirement, written controls, an executive sponsor, and a technical owner can use AxonFlow's paid Production Program. It takes one scoped workflow into production over 60 or 75 days with Enterprise access, founder-led rollout support, upfront conversion pricing, and a fixed decision date.

Public Design Partner pricing starts at $2,000; the Confidential Paid Pilot starts at $4,000. Prices are subject to eligibility and a signed agreement.

See AxonFlow in Action

Videos covering different angles of the platform:

Plugin Evaluation Tier (Free 90-day License)

Outgrown Community on a real plugin install? Evaluation unlocks the capacity and features that matter for plugin users — without moving to Enterprise yet:

CapabilityCommunityEvaluation (Free)Enterprise
Tenant policies2050Unlimited
Org-wide policies05Unlimited
Audit retention3 days14 daysUp to 10 years
HITL approval gates—25 pending, 24h expiryUnlimited, 24h
Evidence export (CSV/JSON)—5,000 records · 14d window · 3/dayUnlimited
Policy simulation—300/dayUnlimited
Session overrides (self-service unblock)——Enterprise-only

Org-wide policies and session overrides are Enterprise-only — those are the actual upgrade triggers for plugin users.

Get a free Plugin Evaluation license


Install

This is a three-step install: stand up the AxonFlow platform, add the plugin to OpenClaw, then point the plugin at the platform. The plugin alone does not enforce policy — it is a thin client that talks to an AxonFlow agent gateway. If the platform is not installed and reachable, governed tool calls have nothing to evaluate against. Skipping Step 3 is the most common mistake: the platform is running locally but the plugin still falls back to Community SaaS because no endpoint is configured.

Step 1: install the AxonFlow platform

For any real workload, run AxonFlow on your own infrastructure via Docker Compose:

git clone https://github.com/getaxonflow/axonflow.git
cd axonflow && docker compose up -d

# verify
curl -s http://localhost:8080/health | jq .

Follow the Getting Started guide for prerequisites (Docker Engine or Desktop, Docker Compose v2, 4 GB RAM, 10 GB disk) and the Self-Hosted Deployment Guide for production options. For production with real users or clients, run Community Edition with a free 90-day Evaluation License or AxonFlow Enterprise.

Skipping Step 1 makes the plugin fall back to the Community SaaS endpoint at try.getaxonflow.com for early exploration only. Do not skip Step 1 for any real workload — see the Privacy notice above.

Step 2: install the plugin

Requires OpenClaw 2026.4.15 or later (CVE floor). Strongly recommended: 2026.5.7 or later — see hash-mismatch workaround below. Upgrade with npm install -g openclaw@latest.

openclaw plugins install @axonflow/openclaw@latest --accept-capabilities

Since 2.9.0 the install needs --accept-capabilities. The plugin now declares the capabilities it exercises (the ADR-065 enforcement-point handshake), and the OpenClaw CLI refuses to start a plugin that declares capabilities until you consent once at install or enable time. Without the flag the install completes and then the CLI reports Plugin "axonflow-governance" requires capability consent.

We recommend the npm-spec form as our primary install path. npm is our source-of-truth registry — every release is published there first, with the long track record and stability you'd expect from a mature package registry. The CLI resolves the npm spec and downloads the latest tarball directly.

To pin a specific version (recommended in production / CI):

openclaw plugins install @axonflow/openclaw@2.10.0 --accept-capabilities

The clawhub:@axonflow/openclaw form is also supported and pulls from the ClawHub mirror, which we publish to alongside npm on each release.

OpenClaw CLI versions before 2026.5.7 can hit a regression in the ClawHub install path's integrity check (confirmed on 2026.4.27). openclaw plugins install @axonflow/openclaw fails with:

ClawHub archive integrity mismatch for "@axonflow/openclaw@2.X.Y":
expected sha256-..., got sha256-...

The published artifact is byte-correct on both npm and ClawHub (they serve identical bytes that match the manifest's pinned hash). The CLI computes a different hash internally and fails the comparison. Fixed in OpenClaw 2026.5.7.

npm install -g openclaw@latest
openclaw plugins install @axonflow/openclaw@latest --accept-capabilities

If you cannot upgrade the CLI, fall back to a local-tgz install — the same path used for the older ENOENT bug below — which bypasses the broken integrity check:

TGZ=$(npm pack @axonflow/openclaw 2>/dev/null | tail -1)
openclaw plugins install "./$TGZ"

OpenClaw versions before 2026.4.14 had a bug (openclaw/openclaw#66618) that made scoped packages fail with ENOENT .../openclaw-clawhub-package-XXXXXX/@axonflow/openclaw.zip — both forms of the install command hit it. The fix shipped in 2026.4.14. If you cannot upgrade, install from npm directly:

# Captures the exact tgz filename so a stale tgz in CWD doesn't get picked up
TGZ=$(npm pack @axonflow/openclaw 2>/dev/null | tail -1)
openclaw plugins install "./$TGZ"

Step 3: point the plugin at the platform

Without this step the plugin auto-registers with Community SaaS regardless of whether you ran Step 1 — it does not auto-detect a locally-running AxonFlow. Set pluginConfig.endpoint (and clientId / clientSecret if you have them):

# openclaw.config.yaml
plugins:
  "@axonflow/openclaw":
    endpoint: http://localhost:8080  # or your remote AxonFlow URL
    # clientId + clientSecret are required for Evaluation License or Enterprise tenants

Every plugin init logs a one-line canary on stderr confirming the active mode:

[AxonFlow] Connected to AxonFlow at http://localhost:8080 (mode=self-hosted)

If the canary says mode=community-saas after you ran Step 1, the plugin is still hitting try.getaxonflow.com because Step 3 was skipped or pluginConfig.endpoint is unset. Fix Step 3 and reload.

See Configure below for the full pluginConfig schema (highRiskTools, governedTools, onError, userEmail, etc.).


Configure

Step 3 above covers the minimum config (endpoint + optional clientId / clientSecret). The full pluginConfig schema is below.

Full configuration reference

OptionRequiredDefaultDescription
endpointNohttps://try.getaxonflow.com (Community SaaS) when unset; http://localhost:8080 when self-hosted with no endpoint specifiedAxonFlow agent gateway URL
clientIdNo"community" (self-hosted) or auto-bootstrapped cs_<uuid> (Community SaaS)Tenant identity for data isolation. Override for Evaluation License or Enterprise tenants.
clientSecretNo"" (self-hosted) or auto-bootstrapped (Community SaaS)Basic-auth secret paired with clientId. Required for self-hosted Community Edition with an Evaluation License or AxonFlow Enterprise; auto-populated for Community SaaS; can be left unset for self-hosted Community Edition without a license.
licenseTokenNoprocess.env.AXONFLOW_LICENSE_TOKEN if setLegacy prepaid plugin-claim token. Existing 90-day purchases remain valid through expiry. New monthly hosted subscriptions need no token. Env var wins over pluginConfig.licenseToken.
userEmailNo—Per-user identity forwarded on explain/override calls. Shared agents should set this from session context.
userTokenNoprocess.env.AXONFLOW_USER_TOKEN, else ~/.config/axonflow/user-token.json (mode 0600)Per-user authorization token, sent as X-User-Token on every governed request. Yields a validated {identity, role} on the platform's fleet plane — role-scoped reads return this developer's own rows (a token-less caller gets zero rows on those read tools against current platforms), and audit attribution keys on the token's canonical email rather than the forgeable userEmail label on the header-consuming planes (MCP tools + audit/decisions/overrides REST; the check-input/check-output hook plane keeps client-scoped attribution on current platforms). Minted by an org admin via the platform's user-token mint API. This config value wins over the env var, which wins over the provisioning file; a malformed candidate at any source is dropped with a warning (never sent) and resolution falls through to the next source. Unset: header omitted, wire behavior unchanged.
highRiskToolsNo[]Tools that require human approval even when policy allows
governedToolsNo[] (all)Tools to govern. Empty = all tools.
excludedToolsNo[]Tools to exclude from governance. Takes precedence over governedTools.
defaultOperationNo"execute"Operation type for check_input ("execute" or "query")
onErrorNo"block"Governs behavior on auth/config errors only (401/403). "block" denies the tool call with a message telling the operator to fix configuration; "allow" lets the call through ungoverned. Does not apply to network/transient errors — see Fail behavior below.
requestTimeoutMsNo8000Timeout for policy checks, output scans, audit writes, and health checks

Fail behavior

The plugin classifies errors from the AxonFlow client into two buckets and applies different rules per hook.

| Hook | Transient network error (timeout, DNS, connection refused, 5xx) | Auth/config error (401 / 403) | Payment required (402) | |---|---|---| | before_tool_call | Always fail-open. The tool call proceeds regardless of onError. | Respects onError. The default blocks. | Always blocks, creates authenticated checkout, and surfaces one URL. | | message_sending | Respects onError. The default cancels the message. | Same as network error. | Always cancels, regardless of onError. | | after_tool_call, llm_input, llm_output (audit) | Always silently caught. Governance was already enforced on the pre-execution hook. | Always silently caught. |

The before_tool_call network fail-open is not silent. The first time a governed tool call proceeds because the governance check failed for a non-auth reason — the endpoint was unreachable, timed out, or answered 5xx — the plugin emits one warning on the same channel as the auth-failure notice (console.warn, so it lands in the OpenClaw plugin log and in the terminal running the session), naming the endpoint, the underlying error, and the fact that the call ran with no policy evaluated:

[AxonFlow] Governance check against http://localhost:8080 failed (fetch failed). This tool
call ran UNGOVERNED — no policy was evaluated, nothing was blocked, and no decision was
recorded. Tool calls continue to run ungoverned until the endpoint answers again; restore
it to resume enforcement. Shown once per process.

It appears once per process rather than once per tool call, mirroring the auth-failure notice, so a long outage does not flood the transcript.

Auth errors do not trigger this notice — they take the onError path above. With the default onError: "block" nothing runs ungoverned, so there is nothing to announce, and a 401 additionally trips the client's own one-time authentication warning. One gap remains: with onError: "allow", an HTTP 403 proceeds ungoverned and emits nothing (only 401 trips the client warning). Tracked in #170; until it is closed, treat onError: "allow" as a posture that can go quiet.

If you need tool-execution itself to fail-closed during an AxonFlow outage (for example on a production infrastructure agent), pair the plugin with an OpenClaw-side health check or a front-door liveness gate — the plugin alone will not achieve that for before_tool_call.


Use-case recipes

DevOps / coding agent — heavy exec usage

plugins:
  @axonflow/openclaw:
    endpoint: http://localhost:8080
    highRiskTools: [exec, process]
    excludedTools: [get_current_time, list_models]
    onError: block

Customer support agent — Slack/Discord/Telegram

plugins:
  @axonflow/openclaw:
    endpoint: http://localhost:8080
    highRiskTools: [message, execute_sql, send_email]
    onError: block

Social automation agent — reviewed live actions

Use this pattern when an OpenClaw social plugin separates local catalog or discovery tools from live account actions. Keep free/local lookup tools outside approval gates, but require review for tools that can publish content, send direct messages, spend credits, export audience data, create monitors or webhooks, or run recurring workflows.

plugins:
  @axonflow/openclaw:
    endpoint: http://localhost:8080
    highRiskTools: [social_post, social_dm, social_export, social_monitor]
    excludedTools: [social_catalog]
    onError: block

Self-healing infrastructure agent — highest risk

plugins:
  @axonflow/openclaw:
    endpoint: http://localhost:8080
    highRiskTools: [exec, process, web_fetch]
    onError: block  # auth-error path and message_sending fail-closed; see Fail behavior above

More examples — content/social agents, data analysts, RAG pipelines, and named ecosystem plugin recipes — in the integration guide.


MCP tools available to your agent

Beyond the lifecycle hooks, OpenClaw agents can call 15 MCP tools via the agent's MCP server at /api/v1/mcp-server. These are served by the platform (not the plugin), so new tools become available to every plugin without a code change.

Governance (6): check_policy, check_output, audit_tool_call, list_policies, get_policy_stats, search_audit_events

Explainability & overrides (4): explain_decision, create_override, delete_override, list_overrides

Tenant identity and hosted capability (5):

ToolHosted Starter
axonflow_get_tenant_idReturns tenant identity, endpoint, tier state, and authenticated checkout endpoint
axonflow_list_pro_featuresLists the capabilities reported by the current platform
axonflow_request_approvalAvailable within the published hosted limits
axonflow_create_tenant_policyAvailable within the published hosted limits
axonflow_get_cost_estimateAvailability follows the server plan response

OpenClaw also registers axonflow_get_tenant_id locally as a plugin agent tool. It returns tenant_id, tier, checkout_url, checkout_method, and legacy prepaid expiry fields.

When a tool call is blocked, the agent can surface the decision_id to the operator, call explain_decision to reveal the triggering policy family, and — if the decision is overridable — call create_override with mandatory justification for a short-lived, audit-logged exception. Operators never leave the OpenClaw session.

See Decision Explainability and Session Overrides.

Hosted payment and limit prompts

An unpaid hosted call receives HTTP 402. The plugin creates authenticated Checkout, blocks the governed action even when onError is allow, and logs one actionable URL. A paid account that reaches a published allowance receives a structured limit response with its reset or Enterprise PoC path.

[AxonFlow] Hosted governance needs an active plan. Complete checkout: https://checkout.stripe.com/...

The plugin also stamps a local back-off file from the response's Retry-After header so subsequent governed calls fall through immediately (no thundering herd against the agent) until the cap clears. The upgrade nudge is shown at most once per UTC day.


What's covered today, and what's not

Protected today:

  • Tool inputs before execution
  • Outbound messages before delivery
  • Tool and LLM audit trails (including search & explainability)
  • Decision-level overrides with per-user attribution

Not protected yet:

  • Tool results written into the session transcript (OpenClaw's tool_result_persist hook is synchronous and cannot call AxonFlow's HTTP APIs)

PII in tool results is still caught by message_sending before it reaches the end user, but it is visible to the LLM. When OpenClaw adds async support for tool_result_persist, this plugin will add transcript scanning immediately. Upstream issue: openclaw/openclaw#58558.


Latency

OperationTypical overhead
Policy pre-check2–5 ms
PII / secrets detection1–3 ms
SQL-injection scan1–2 ms
Audit write (async)0 ms (non-blocking)
Total per-tool overhead3–10 ms

Imperceptible for interactive agents.


Starter policies

The policies directory ships research-backed starter policies addressing the top 10 OpenClaw security risks — reverse shells, SSRF, credential exfiltration, path traversal, agent config poisoning, prompt injection, and more. Ready-to-use SQL INSERT statements and setup instructions included.


Telemetry

The plugin sends a usage heartbeat once every 7 days so AxonFlow can understand adoption and environment shape. Includes plugin version, OS/arch, Node.js version, AxonFlow platform version, the licence tier, edition and deployment mode that platform reports about itself, this plugin's own deployment-mode and endpoint-type classification, org_id, and hook configuration summary. Also includes a persistent per-machine instance ID (UUID v4). Never includes message contents, tool arguments, or policy data.

The licence tier sent is whatever the platform reported about itself, relayed verbatim. The plugin does not normalise, map, or restrict the value, so a transient state such as starting, or a tier name introduced after this plugin shipped, reaches the wire unchanged rather than being flattened into a fixed list. What is never read or sent: no licence key, no expiry date, no seat count, and no customer or organisation name. It is read from the tier field of the same /health response the heartbeat already fetches to detect the platform version, so it costs no additional request, and it is omitted entirely whenever that probe does not answer with one.

Two further values are relayed on the same terms, from the same response: the platform's edition and the deployment mode the platform reports about itself. The second is deliberately separate from the deployment_mode above, which is this plugin's own classification of the endpoint it was pointed at — they answer different questions and routinely differ, so neither is written over the other. Both are omitted entirely whenever the platform does not report them — whether the member is missing or present as null, both of which mean not-learned — which is the case for every platform released before they existed. Any relayed value longer than 64 bytes is dropped whole rather than truncated, since a truncated value would be something the platform never said.

The heartbeat refuses HTTP redirects on both legs. A redirected /health teaches the plugin nothing rather than reading values from a host you did not configure, and a redirected checkpoint POST is not treated as a delivery — fetch would otherwise re-issue it as a bodyless GET whose success advanced the 7-day stamp on a ping that was never received, silencing this machine for a week.

Opt out: set AXONFLOW_TELEMETRY=off in the environment OpenClaw runs in.

Scope of AXONFLOW_TELEMETRY=off

AXONFLOW_TELEMETRY=off disables the usage heartbeat described above. On self-hosted and in-VPC deployments, that heartbeat is the only data the plugin sends to AxonFlow, so setting =off means we receive nothing. On Community SaaS (try.getaxonflow.com) the hosted service also processes operational data — registrations, audit logs, policy enforcement records, workflow state, plan data, and request-header metadata aggregated for usage analytics — as part of running the platform; that operational data flow is governed by the Privacy Policy, not by AXONFLOW_TELEMETRY.

Network calls this plugin makes

CallWhenWhat is sentOpt out
Governance checkEvery governed tool call / outbound messageTool name + arguments, message bodyCore functionality
Audit logAfter each tool execution / LLM callTool name, result summary (truncated), prompt summary (first 500 chars), token usage, latencyCore functionality
Health checkOn plugin initNothing (GET request)Fire-and-forget
Usage heartbeatOnce per 7 daysPlugin version, OS, arch, Node version, platform version, the platform's licence tier, edition and own deployment mode, this plugin's deployment-mode and endpoint-type classification, org_id, hook config summary, persistent instance IDAXONFLOW_TELEMETRY=off (also accepts 0, false, no)
Platform version, licence tier, edition + platform deployment mode probeDuring heartbeat (if not opted out)Nothing (one GET to /health; all four fields are read from the same response, and redirects are refused)Disabled when AXONFLOW_TELEMETRY=off
Version compatibility checkOn plugin initPlugin versionFire-and-forget
Community SaaS registrationFirst run (community-saas mode only)Machine label (plugin version + OS)AXONFLOW_COMMUNITY_SAAS=0 or self-hosted endpoint
Credential recoveryOnly when you run axonflow-openclaw-recoverThe email address you pass on the command line, then the magic-link token you paste backDon't run the CLI — it never fires from the plugin runtime

Testing

Unit tests (jest, mock fetch — no live stack needed):

npm test

Smoke E2E (requires a live AxonFlow stack at localhost:8080):

npm ci && npm run build
# Start a local AxonFlow stack first — `docker compose up -d` in
# the axonflow repo, or point AXONFLOW_ENDPOINT at an existing one.
node tests/e2e/smoke-block-context.mjs

The smoke scenario uses AxonFlowClient.mcpCheckInput to fire a SQLi-bearing statement against a running platform and asserts the response carries richer-context fields (decision_id, risk_level, policy_matches). Exits 0 with a SKIP: message if no stack is reachable.

For the broader validation story — explain-decision, override lifecycle, audit-filter parity, cache invalidation — see the OpenClaw integration guide.


Links

License

MIT

↑↓ navigate openesc close