Tools
Available MCP tools for AI agent interaction.
These are the tools available to AI agents connected to Axiom via MCP. Each tool requires specific scopes, allowed when the user connects the agent.
Axiom runs the entire store checkout server-side. An agent places an order and Axiom finishes it in the background, emailing the user for approval, questions, and the result; the agent never sees card details, drives the store's site, or polls. See How It Works for the full flow.
Every order is identified by one public ID, orderID. Each order tool takes or returns it, and orderUrl links to the order in the Axiom app.
The order response contract
Order responses (place_order, get_order_status, answer_order_question) share one shape so an agent never over-reports success:
status: where the order stands. Onlycompletedmeans the order went through. An agent must not tell the user an order succeeded on any other status.isFinal(boolean): true once the order has ended, or when nothing was ordered.userMessage: ready-to-relay text for the user. Relay it as written.agentInstructions: guidance for the agent. Never shown to the user.nextAction: what the agent should do next:none,ask_user_then_call_answer_order_question,ask_user_then_call_place_order,tell_user_unavailable,tell_user_complete,tell_user_failed,tell_user_denied,tell_user_limit_reached,open_setup_link_then_wait_for_user, ortell_user_restricted.
Order statuses
status | Meaning |
|---|---|
in_progress | Axiom is placing the order, by browser or by Axiom's team. Relay userMessage and stop; Axiom emails the result. |
awaiting_approval | A spending rule requires approval. Send the user the approvalLink, then stop; Axiom emails the same link. nextAction is none. |
needs_answer | Axiom has a question about the order. Ask it, then call answer_order_question. |
completed | The store confirmed the order. The response carries the receipt. |
could_not_place | The order ended without going through; reason says why. |
cancelled | The order was cancelled. |
limit_reached / mandate_denied | The order never started: a spending limit was hit, or the request was denied. |
Account Tools
get_payment_method
Returns the payment method on file (brand and last 4 digits only) and whether the user has finished the account setup needed to order: confirmed email, payment method, phone number, and shipping address. It is optional before an order: place_order performs the same checks and reports the payment method it will charge.
- Scope:
account:read - Parameters: None
- Returns:
hasPaymentMethod,card(brand,last4),accountSetupComplete,missingRequirements,setupUrl, anduserMessage. When setup is incomplete, alsoagentInstructionsandnextAction(open_setup_link_then_wait_for_user). Once setup is complete,heldPurchaseIDnames an order Axiom is holding for the user; this tool never starts it.
Order Tools
place_order
Places an order. Axiom validates the request against an LLM intent mandate (purchase intent + prohibited-merchant screening) and the user's spending rules, then completes the store's checkout in the background with the payment method on file. Replies within about 25 seconds: long enough for a question about the product to come back in the same reply. The order finishes in the background and Axiom emails the user the result.
- Scope:
payments:write - Parameters:
userCommand(string, required): The user's original instruction, near-verbatim. This is the audit/intent record; don't paraphrase or fold resolved specifics into it.merchant(object, required):merchantName(string): Resolved brand name (e.g.Chewy), not a category.merchantURL(string): Store URL the checkout starts from. Prefer the product detail page; fall back to the store homepage.
itemName(string, required): The specific resolved product (include variants like size/color/quantity when known), not a category.intentContext(object, optional): Context for terse or elliptical commands ("same one", "buy that", "try again") when the order is justified by conversation context rather than the literaluserCommand:resolvedUserIntent(string): Concise, audit-safe interpretation of the intended order.evidence(string[], 1–5 entries): Concrete supporting evidence: short prior-message summaries, visible app state, or a remembered preference. Without evidence, Axiom may ask for clarification instead of placing the order.resolutionSummary(string, optional): Concise rationale mapping the evidence to this order.
itemSubtotal(number, optional): Line-item subtotal in dollars the user approved (pre-shipping/tax/fees). Caps the line-item total at payment time.preferences(object, optional):fulfillment(shipping|pickup|delivery),substitutionsAllowed(boolean),maxTipCents(number),notes(string).
- Returns: A
status, plusorderIDandorderUrlonce an order exists andpaymentCard(brand,last4) when known. Status is one ofin_progress,needs_answer,awaiting_approval,completed,needs_clarification,unavailable,mandate_denied,limit_reached,account_setup_required,email_verification_required, oraccount_restricted. Responses also carry the order response contract fields. Onneeds_clarificationorunavailableno order exists yet: the agent asks the user, then callsplace_orderagain.
Account setup and held orders
When an order is blocked because the user's account is not ready, the response is success-shaped (no isError) so the agent relays it instead of retrying:
status | nextAction | Extra fields |
|---|---|---|
account_setup_required | open_setup_link_then_wait_for_user | setupUrl, missingRequirements (email_verification, payment_method, phone_number, shipping_address), heldPurchaseID |
email_verification_required | open_setup_link_then_wait_for_user | setupUrl, heldPurchaseID |
account_restricted | tell_user_restricted | None; final, do not retry |
in_progress (resumed) | none | resumedFrom: the heldPurchaseID this order picked up |
setupUrl is the Axiom setup page for this user (https://app.useaxiom.ai/setup?from=<client>); the page reads what is missing live, so the URL never carries the list. userMessage already contains the URL on its own line and tells the user how to continue, and agentInstructions asks the agent to relay it verbatim. Axiom holds the blocked order (heldPurchaseID) for 24 hours, scoped to the user and the connecting client. The next place_order from that user and client after setup completes places the held order, whatever arguments the new call carries, and returns the normal response with resumedFrom set.
get_order_status
Returns where an order stands, by the orderID from place_order or list_orders. Answers immediately. Call it when the user asks about an order, not on a schedule: Axiom emails the user for approval, questions, and the result.
- Scope:
transactions:read - Parameters:
orderID(string, required): Fromplace_orderorlist_orders.
- Returns: The same shape as
place_order, withstatusone of the order statuses. PlusapprovalLinkanddeadlinewhenawaiting_approval;questionID,question,options(each withoptionID,label,description,amount,imageUrl,productUrl),allowFreeText, anddeadlinewhenneeds_answer; thereceipt(items, taxes and fees, discounts, shipping, total, order number) andfinalTotalwhencompleted; andreasonwhen the order ended without going through.
orderUrl links to the order page in the Axiom app; it's the canonical link agents should surface to users. The store's own order-confirmation URL is intentionally omitted; users reach it through the Axiom app. deadline is when the order times out if nobody approves or answers; userMessage already states it in hours.
answer_order_question
Sends the user's answer when place_order or get_order_status returns needs_answer, and continues the same order. Not for needs_clarification or unavailable from place_order: no order exists yet, so the agent asks the user and calls place_order again.
-
Scope:
payments:write -
Parameters:
orderID(string, required)questionID(string, required): From theneeds_answerresponse.selectedOptionID(string, optional): AnoptionIDfromoptions.userInput(string, optional): Free-text answer whenallowFreeTextis true.
Provide
selectedOptionID,userInput, or both. -
Returns: The same shape as
get_order_status; usuallyin_progress, orneeds_answerwhen another question follows.
list_orders
Returns the user's recent orders, most recent first. Use it when the user asks about their orders, or to find the orderID of an order to check with get_order_status.
- Scope:
transactions:read - Parameters:
limit(number, optional): Maximum number of orders to return (1–100, default 20)
- Returns:
orders(each withorderID,status,merchant,description,totalin dollars,currency,createdAt, andorderUrl), pluscount(returned) andtotal(available)