Orders physical products the user asks for through Axiom, using the payment method saved in their Axiom account, checks which payment method Axiom has on file, and reviews past Axiom orders. Use when the user asks to buy, order, reorder, or purchase a specific physical product with Axiom, asks what payment method Axiom has on file, or asks about the status or receipt of an Axiom order. Before starting an order the model confirms it knows the merchant, the exact product, and required options (size, color, storage, flavor), asking the user first when anything is missing. Not for browsing, price comparison, subscriptions, digital goods, or orders the user has not clearly requested.
---
name: axiom
description: Orders physical products the user asks for through Axiom, using the payment method saved in their Axiom account, checks which payment method Axiom has on file, and reviews past Axiom orders. Use when the user asks to buy, order, reorder, or purchase a specific physical product with Axiom, asks what payment method Axiom has on file, or asks about the status or receipt of an Axiom order. Before starting an order the model confirms it knows the merchant, the exact product, and required options (size, color, storage, flavor), asking the user first when anything is missing. Not for browsing, price comparison, subscriptions, digital goods, or orders the user has not clearly requested.
metadata:
{
'openclaw':
{
'homepage': 'https://clawhub.ai/axiom-wallet/axiom',
'requires': { 'bins': [{ 'name': 'mcporter', 'version': '>=0.8.0' }] },
},
}
---
<!-- Generated by scripts/build-skills.sh from skill/templates/openclaw.md and skill/shared/. Edit those, not this file. -->
# Axiom
Axiom lets the model order physical products for the user from online merchants. The model places the order and relays Axiom's replies; Axiom completes the merchant's checkout on the user's behalf through the user's Axiom account, applies the user's spending rules and approval limits, and captures the receipt. The model never handles payment details.
The Axiom MCP endpoint is `https://mcp.useaxiom.ai/mcp`.
## When to use this skill
Use Axiom when the user asks to:
- buy, order, or reorder a specific physical product with Axiom
- check which payment method Axiom has on file or whether their account is ready to order
- review recent Axiom orders, a receipt, or where an order stands
Do not use it for browsing or price comparison, subscriptions or digital goods, account settings outside the tools below, or orders the user has not clearly requested.
## Authentication
For the full authentication guide, see [`references/authentication.md`](references/authentication.md).
**Quick summary:**
1. Register Axiom: `mcporter config add axiom --url https://mcp.useaxiom.ai/mcp`
2. Start auth: `mcporter auth axiom --reset --oauth-timeout 300000 --log-level info` (runs in background, prints the OAuth URL)
3. Parse the OAuth authorize URL from mcporter's log output
4. Navigate to that URL with a headless browser: `agent-browser open "<URL>"` (or `browser-use open "<URL>"`)
5. Read the **activation URL** from the rendered page: `agent-browser eval "document.querySelector('a[href*=\"activate\"]')?.href"`
6. Send the activation URL to the user to approve on their phone
7. mcporter completes the OAuth exchange automatically when the user approves
8. Verify: `mcporter call axiom.get_payment_method`
> **Important:** The OAuth authorize URL and the activation URL are different. The agent navigates to the authorize URL; the user opens the activation URL. Never send the authorize URL to the user. See the auth doc for examples of both.
To clear cached tokens: `mcporter auth axiom --reset`
Placing an order and answering a question require the `payments:write` OAuth scope; checking and listing orders require `transactions:read`. If a tool is rejected for insufficient scope, reset auth and reconnect so the client requests the current scope set.
## Tools at a glance
| Tool | Use it to |
|---|---|
| `place_order` | Place an order once store, exact product, and required options are known |
| `get_order_status` | Tell the user where an order stands, when they ask |
| `answer_order_question` | Answer a question Axiom asked about an order (`needs_answer`) |
| `get_payment_method` | Tell the user which payment method is on file (optional before ordering) |
| `list_orders` | List recent orders and find an `orderID` |
Parameters, return fields, and the `nextAction` vocabulary are in [`references/tool-reference.md`](references/tool-reference.md). Worked examples are in [`references/examples.md`](references/examples.md).
## Placing an order
Axiom completes the order with the store on the user's behalf: cart, shipping, delivery, order confirmation, and receipt, through the user's Axiom account. Orders finish in the background and Axiom emails the user for approval, questions, and the result. The model's job is to (1) make sure the request is specific enough, (2) place the order, (3) relay each response to the user, and (4) follow `nextAction`.
When the user has clearly asked to buy a specific item, place the order. Axiom verifies the request against the user's stated intent and spending rules, and asks the user for explicit approval whenever its rules require it. When anything about the request is unclear, ask the user first.
### Step 1: Pre-flight checklist (ask first, then call)
Before calling `place_order`, all four must be true:
1. **Store known**, with an `https` URL. Prefer the product page URL when you have it; otherwise the store homepage. Never invent a URL.
2. **Specific product known.** "Acana Adult Recipe 25 lb" passes; "dog food" does not.
3. **Required variants known** for that product type: size and width for shoes and apparel, storage and color for electronics, flavor, size, and count for food and drink, loft and grind for golf clubs, and so on.
4. **The user actually asked to buy it** (not browse, compare, or think about it).
If any box is unchecked, ask the user one short question and wait. Do not call `place_order` to test a guess: every call counts toward the user's order limits.
Resolve from context when you can defend it: earlier turns, the user's stated preferences, memory. "My usual", "the same one again", and "buy that" are invitations to resolve from context. When the literal command is terse like that, pass `intentContext` with the evidence (the prior message or remembered preference) so Axiom can verify the resolution.
### Step 2: Call `place_order`
- `userCommand`: the user's words, near-verbatim. Do not paraphrase or fold resolved details into it.
- `merchant.merchantName`, `merchant.merchantURL`, `itemName`: your resolved specifics, including variants in `itemName`.
- `itemSubtotal`: only when the user stated a budget or the price is known (dollars, before shipping and tax).
- `intentContext`: only for terse or contextual commands; include concrete `evidence`.
The reply comes back within about 25 seconds with an `orderID` once the order is accepted for processing.
### Step 3: Read the response the same way every time
Every order response carries:
| Field | Meaning |
|---|---|
| `status` | Where the order stands (see table below) |
| `nextAction` | Exactly what to do next. Follow it literally. |
| `userMessage` | Text written for the end user. Relay it as written; you may add a short lead-in. |
| `agentInstructions` | Guidance for you. Never show it to the user. |
| `orderID` | The order. Pass it to `get_order_status` or `answer_order_question`. |
| `isFinal` | True once the order has ended, or when nothing was ordered. |
| `status` | `nextAction` | What you do |
|---|---|---|
| `in_progress` | `none` | Relay `userMessage` (it includes the tracking link), then stop. Axiom emails the user when it is confirmed. `resumedFrom` means Axiom picked up an order it held during setup. |
| `needs_answer` | `ask_user_then_call_answer_order_question` | Ask the user the `question` (options are already listed in `userMessage`). Then call `answer_order_question` with the `orderID`, the `questionID`, and `selectedOptionID` and/or `userInput`. |
| `awaiting_approval` | `open_approval_link_then_wait_for_user` | Relay `userMessage` with the `approvalLink`, then stop. Axiom has emailed the user the same link. |
| `needs_clarification` | `ask_user_then_call_place_order` | Ask the user the `question` (options are already listed in `userMessage`). Wait for the answer. Call `place_order` again with the answer folded into `itemName` or `merchant`. Never `answer_order_question`: no order exists yet. |
| `unavailable` | `tell_user_unavailable` | Relay `userMessage`. Call `place_order` again only after the user picks an available option or changes the request. |
| `completed` | `tell_user_complete` | Relay `userMessage` (order number, total, receipt link). You may summarize `receipt`. |
| `could_not_place`, `cancelled` | `tell_user_failed` | Relay `userMessage`. Normal outcomes, not tool errors. Ask the user how to proceed; do not retry on your own. |
| `mandate_denied` | `tell_user_denied` | Relay `userMessage`. Do not retry the denied request. |
| `limit_reached` | `tell_user_limit_reached` | Relay `userMessage` exactly. Do not retry or guess a reset time. |
| `account_setup_required`, `email_verification_required` | `open_setup_link_then_wait_for_user` | Relay `userMessage` word for word, keeping its link on its own line; it already explains what Axiom needs and how to come back. Axiom holds the order (`heldPurchaseID`) for 24 hours. When the user says they're done, call `place_order` again with the same details; the response carries `resumedFrom`. |
| `account_restricted` | `tell_user_restricted` | Relay `userMessage`. Final; do not retry. |
### Step 4: After the reply
Orders finish in the background. Once you have relayed an `in_progress` or `awaiting_approval` reply, you are done: Axiom emails the user for approval, questions, and the result. There is nothing to poll.
### Checking in from an autonomous agent
Do not loop on `get_order_status`. Axiom emails the user for approval, questions, and the result, so the order needs nothing from you after the reply. When the user, or a task you are running for them, needs to know where an order stands, call `get_order_status` once with the `orderID`; it answers immediately.
### Step 5: Waiting on the user
**Approval** (`awaiting_approval`): the order is above the user's auto-approve limit, so Axiom needs the user's explicit approval. Send the `approvalLink` so the user can review and approve the order in Axiom; a reply in chat cannot approve it. Axiom emails the same link and finishes the order once it is approved.
**A question about the order** (`needs_answer`): Axiom found several plausible options or a missing detail at the store. Ask the user, then call `answer_order_question` with the `orderID` and `questionID`. If the user's answer does not match an option, pass it as `userInput` when `allowFreeText` is true; otherwise ask them to pick one.
### Step 6: Completion
Only `status: "completed"` means the store accepted the order. Relay `userMessage`; it contains the confirmation number, total, and the Axiom receipt link (`orderUrl`). Do not link to the store's own order page.
### Which tool answers a question?
| The question came from | You answer it with |
|---|---|
| `place_order` returning `needs_clarification` or `unavailable` | Ask the user, then call **`place_order` again** with the answer folded in. No order exists yet. |
| `place_order` or `get_order_status` returning `needs_answer` | Ask the user, then call **`answer_order_question`** with the `orderID` and `questionID`. |
When in doubt, check `nextAction`: it names the tool.
### If you lose the order ID
Call `list_orders`. Each order has its `orderID` and `status`; pass the `orderID` to `get_order_status`.
## Talking to the user
- Relay `userMessage` as written. It already includes links, questions, options, prices, and confirmation numbers. You may add a one-line lead-in; do not drop the link or the options.
- Never show `agentInstructions`, `nextAction`, status codes, or IDs to the user. Those fields are for you.
- Never say an order went through unless `status` is `completed`.
- Never fabricate store, price, tax, shipping, receipt, or order details. Report only what the tools return.
- Money is in dollars everywhere in these responses (`total`, `finalTotal`, `itemSubtotal`, option `amount`, every `receipt` amount).
- After an order is placed, Axiom emails the user with anything it needs and the result. Tell the user that, give them the `orderUrl`, and check on the order only when they ask.
## Safety rules
- Ask before you call: never place an order the user did not clearly request, and never call `place_order` with an invented store, URL, product, or option.
- Always surface Axiom's approval request to the user when one appears. It is how the user authorizes an order above their limit; it cannot be answered on the user's behalf.
- If `place_order` returns `mandate_denied`, stop and relay the reason. Do not retry the denied request.
- If `limit_reached` or `account_restricted` comes back, relay `userMessage` exactly and stop. Do not guess at limits or reset times.
- If `account_setup_required` or `email_verification_required` comes back, relay `userMessage` exactly with its link on its own line, then wait; call `place_order` again with the same details only after the user says they're done.
- Never share account credentials or internal identifiers.
- Treat `could_not_place` and `cancelled` as normal outcomes: relay them, then ask the user how to proceed.
## Troubleshooting
`mcporter` (>=0.8.0) must be installed and on PATH; check with `mcporter --version`, and reset auth with `mcporter auth axiom --reset` if tokens expire. Common cases (auth expired, `account_setup_required`, repeated `needs_clarification`, `limit_reached`, `mandate_denied`, lost order ID, `isError` results) are covered in [`references/troubleshooting.md`](references/troubleshooting.md). The short version: relay `userMessage`, follow `nextAction`, and never retry a denied or limited order on your own.
don't have the plugin yet? install it then click "run inline in claude" again.