- Runtime is the default story. It is for worker agents using a prepared wallet and the governed fetch / approval / receipt loop.
- Operator/manage is a separate advanced surface. It is for trusted developer and admin automation, and it requires an org-wide operator credential.
One key = one surface. A wallet-scoped runtime key belongs on the runtime entry. An org-wide operator key belongs on the operator/manage entry. If a workflow needs both, mount both surfaces as two separately named MCP servers.
Before you start
Before changing any config, figure out which surface each of your existing keys is already on.GET /v1/me returns a surface field that is authoritative:
The legacy “mixed” key shape no longer exists — every key currently in
api_keys resolves to exactly one surface. If a key that used to drive control-plane actions still returns surface: "runtime", that is the expected state: the key kept its wallet binding, and it can no longer mint wallets or move treasury. Mint a new operator key from the dashboard or axon-op for those workflows.
What changed
Older setups often used one MCP server for everything:- worker-agent spending
- approvals and receipt checks
- wallet creation
- treasury movement
- emergency freeze actions
Migration map
Runtime-surface error remediation
If you send a wallet-scoped runtime key to a control-plane tool, AXON returns a runtime-surface error with codeTOOL_NOT_AVAILABLE_IN_RUNTIME_SURFACE and details.required_surface = "operator".
What that means:
- you are on the right product, but the wrong surface
- the request belongs on the operator/manage path
- the fix is to move the workflow, not to broaden the runtime key
- Keep the worker-agent config on the runtime surface.
- Move the admin action to the operator/manage surface or to
axon-op. - Mint or reuse an org-wide operator key if the workflow needs MCP automation.
- Retry the action on the correct surface.
Step-by-step migration
If your current config has one MCP server driving both spend and admin work, take it in this order:- Identify each credential’s surface with the
GET /v1/merecipe above. - Keep the runtime entry intact. Your existing wallet-scoped runtime key continues to drive
governed_fetch, approvals, and receipts onPOST /v1/mcp(or stdio without--surface=). - Mint an operator key if admin work used to flow through the same MCP server. Dashboard → Settings → API Keys → Create operator key, or
axon-op keys create --name "<name>"from the terminal with--walletomitted. Never reuse a wallet-scoped key for control-plane work. - Add a second MCP entry named
axon-operator(or similar) pointing athttps://api.axon402.com/v1/operator/mcpor, if you self-host,--surface=operator. Paste from IDE Setup → Advanced: Operator / manage surface. - Verify the surfaces. The runtime
tools/listshould return the runtime tools only, including provider-search tools on both hosted HTTP and self-hosted stdio runtime. The operatortools/listshould return control-plane tools only: wallets, treasury, offers, API keys, mandates, approvals, ledger/earnings, and organization introspection. Any overlap means the wrong key landed on the wrong entry. - Retire operator work from the runtime entry. Remove any runtime-side scripts that call control-plane tool names — they will return
TOOL_NOT_AVAILABLE_IN_RUNTIME_SURFACEon current builds.
axon-op. Mount the operator/manage surface only when IDE-native automation is actually required.
Operator/manage setup
The operator/manage surface is explicit and opt-in. Recommended pattern:- runtime server entry: default MCP server, wallet-scoped runtime key
- operator server entry: separate MCP server, org-wide operator key,
--surface=operatoror/v1/operator/mcp
@axon402/cli (axon-op) instead of mounting the operator/manage surface everywhere.
Support guidance
When triaging a migration issue:- Ask which surface the user is on.
- Check
GET /v1/meand look at thesurfacefield. - If
surface = "runtime"and the user is trying to manage wallets, treasury, or emergency controls, point them to the operator/manage setup. - If a runtime key is hitting operator-only tools, tell them to move the action rather than broaden the runtime key.
surface: "runtime"means the credential is wallet-scoped.surface: "operator"means the credential is org-wide, static operator, or platform-session backed.TOOL_NOT_AVAILABLE_IN_RUNTIME_SURFACEmeans the request belongs on the operator/manage surface.
Rollback posture
If migration needs to pause, keep the two surfaces separate.- Do not revert to a mixed default surface. The product default stays runtime-only; the mixed model was a transitional accident, not a fallback.
- The
AXON_MCP_SURFACE_SPLIT_ENABLEDfeature flag toggles the runtime-side enforcement ofTOOL_NOT_AVAILABLE_IN_RUNTIME_SURFACE. Disabling it is a rollback of enforcement, not a revert of the product model — the runtime registry still ships the runtime-only tools, and operator work still belongs on the operator/manage surface. - If a temporary compatibility bridge is truly required for a specific integration, treat it as a bounded, explicitly non-default path with an expiry date — never as the canonical way AXON is configured.
FAQ
I had one key that did everything. Where did it go?
I had one key that did everything. Where did it go?
The key still exists and still authenticates. What changed is which tools are reachable with it. Run
GET /v1/me — the surface field tells you whether it is a runtime (wallet-scoped) or operator (org-wide) credential today. If you need the other surface as well, mint a second key from the dashboard or axon-op; do not try to broaden the existing one.Why can't my wallet-scoped key call create_wallet anymore?
Why can't my wallet-scoped key call create_wallet anymore?
Wallet creation, treasury movement, key rotation, offer mutations, and org-wide emergency stops are control-plane actions. They belong on the operator/manage surface with an org-wide operator key. Sending a wallet-scoped runtime key to these workflows returns
TOOL_NOT_AVAILABLE_IN_RUNTIME_SURFACE with details.required_surface = "operator". The fix is to move the workflow, not to escalate the runtime key.Does every IDE need both entries?
Does every IDE need both entries?
No. Most worker agents only need the runtime entry. Add the operator/manage entry only when IDE-native admin automation is genuinely required. Day-to-day operator work belongs in the dashboard or
axon-op.Can I put both surfaces behind one MCP server name?
Can I put both surfaces behind one MCP server name?
No. Mount them as two separately named MCP servers (e.g.
axon + axon-operator). The stdio entrypoint dispatches on --surface=; the HTTP path uses POST /v1/mcp for runtime and POST /v1/operator/mcp for operator. Collapsing them recreates the mixed-surface confusion this split was designed to remove.Will my existing automation stop working at cutover?
Will my existing automation stop working at cutover?
Anything already scoped correctly — runtime keys on runtime entrypoints, operator keys on operator entrypoints or
axon-op — continues to work unchanged. The split tightens the runtime surface’s rejection of control-plane tool names. If your automation depended on the legacy mixed default, use the step-by-step migration above to add an operator-surface entry.