Skip to main content

Overview

This guide will walk you through using the Clawdot Gateway to build a complete local life Agent from scratch. By following best practices and handling edge cases, you will be able to create a robust, user-friendly application. The Gateway exposes its capabilities as MCP (Model Context Protocol) tools — once you connect, you see 24 tools and chain them, from binding/consent through finding shops and picking items, all the way to preview, order, and signing. Every example below is given as a tool name + JSON arguments (every business tool carries consent_grant_id, except the binding tools).

Architecture Design

A complete local life Agent consists of the following modules:
The delivery gateway exposes 24 MCP tools over Streamable HTTP, covering the full local-life flow from binding/consent to ordering and payment. The connection, grouping, and ordering sequence of the tools are in the MCP Overview.

Step 1: Get API Key and Connect to MCP

1

Create an Agent in the console

Visit Clawdot Console, create an Agent and enable the delivery capability for it. Agents and API Keys are both managed in the console.
2

Copy API Key

System generates an API Key (starting with clw_), displayed only once — immediately copy and save to a secure location. The server only stores a hash; if lost, you must regenerate it.
3

Configure the API Key in your MCP client

The gateway serves MCP over Streamable HTTP (FastMCP), with the endpoint https://eleme-gateway.hicaspian.com/mcp/v1. Put the API Key into your MCP client’s connection headers:
Do not commit the API Key to a Git repository or hard-code it into your source; inject it via environment variables or a secrets manager.
The API Key identifies the Agent, passed at the connection layer via the Authorization: Bearer clw_... header — required on every MCP request. To act on user resources, you also need the user consent grant obtained in the next step, which is passed as the consent_grant_id tool argument (not a header). See Authentication.

Acting on user resources (search shops, place orders, query addresses, etc.) requires two-layer authentication: the connection-layer API Key identifies the Agent, and the user consent grant identifies the authorized delivery user. After a user completes a binding flow once, you get a consent_grant_id (prefixed cg_) and pass it as an argument on every subsequent business tool call. Binding supports two modes: sms (sends a verification code to the phone) and h5 (returns an authorization link the user logs in through). The binding tools request_user_bind / verify_user_bind are the entry point for obtaining consent — they only need the Agent identity (connection-layer API Key) and take no consent_grant_id. The example below uses sms.

Binding Flow

First, initiate binding; the gateway sends a verification code to the user’s phone:
Second, after the user tells you the code, confirm the binding to mint the consent_grant_id:
Once you have the consent_grant_id, keep it safe — its plaintext is returned only once and only a hash is stored. Pass it as an argument on every subsequent business tool call.
H5 mode is also supported: request_user_bind(auth_type="h5") returns an h5_url (valid for ~300s); hand the link to the user to open and authorize. Then poll with verify_user_bind(auth_type="h5", request_id=...) — pending means not yet done, and bound=true returns the consent_grant_id. You may also pass callback_url to request_user_bind, and the gateway will POST a callback (event=user_bind) once authorization completes. Full fields in Initiate Binding and Confirm Binding.
The expires_at returned on success is the consent expiry (ISO 8601). Re-authorization rotates the grant: each successful binding for the same user mints a new consent_grant_id and immediately invalidates the old one. Consent can be revoked any time via revoke_user_bind, after which the old consent_grant_id is invalidated immediately.

Step 3: Core Business Flow

Implement the complete chain from preparing the delivery address, finding shops and picking items, quoting, previewing, to placing the order. The whole chain is stateful: each step’s returned ID must be passed verbatim to the next — never fabricate one or mix IDs across chains. Prepare the delivery address first, then search deliverable shops by that address, so downstream tools all get the delivery coordinates.
All amount fields are in cents (integer), not yuan. For example payable_price: 1500 means ¥15.00.
Password-free payment signing is an account-level, one-time prerequisite (see “Password-Free Payment Signing” below); it is not part of any single order’s chain and is not bound to a specific order — do not treat it as a step in the order chain.
Every business tool call below carries the consent_grant_id argument (from Step 2).

Phase 1: Prepare Delivery Address

First pin down “where to deliver”. The address flow = search POIs for a single-use token → register for an address_id. First search addresses:
saved_addresses[] are already-saved addresses whose address_id can be reused directly; for a new address, take a suggestions[].token and pass it as select_address’s suggestion_token to register it:
You can also call select_address directly with an existing address’s address_id. This address_id is used both to search shops next and for the later quote / preview. See Search Addresses and Select/Register Address; edit door number / label with update_address (the address_id stays the same).

Phase 2: Search Shops

Use the address_id from the previous step to search deliverable shops. Without keyword it is browse mode (up to 20 shops near that address) with distance, rating, delivery fee, min-order and other decision fields; with keyword (shop name / category / item name) it is precise search (~5 shops). Browse mode accepts offset for paging: pass offset: 0 first, keep paging with the returned next_offset until shops is empty. Each result carries a shop_id and a cart_id: the cart_id already encapsulates that shop plus the delivery coordinates, and is the entry point for the later get_shop_menu / quote_cart / preview_order — pass it verbatim, so downstream tools need not pass coordinates. Full fields in Search Shops.

Phase 3: View Menu Details

Menus can be very large (100+ items); use keyword or limit / offset for progressive disclosure and check has_more for more. To order, you MUST use the item_id / sku_id returned by get_shop_menu (plus ingredient_option_ids for specs / add-ons). Full fields in Shop Menu; the spec / attribute / add-on system is in Item Specs.

Phase 4: Quote Cart

items is an array (NOT a JSON string); each item’s item_id / sku_id comes from get_shop_menu. can_checkout indicates whether min-order and other ordering conditions are met, and payable_price is the estimated payable (in cents). Full fields in Quote Cart.

Phase 5: Preview Order (Pre-Order Confirmation)

Always validate and show the final price with preview_order before creating the order to avoid mistakes. The preview_id + confirmation_token it produces are the credentials required to actually place the order.
preview_id + confirmation_token must be used as a pair, are produced by the same preview, and are valid for about 10 minutes. Coupons take effect at the preview stage, and the coupons actually usable for the current order are whatever is in the returned available_coupons (coupon_ids tri-state: omitted = auto-pick best; [] = no coupon; ["<coupon_id>"] = specific coupon). To switch coupons, pick a available_coupons[].coupon_id and re-call preview_order with coupon_ids=[...] to re-price:
The account-level coupon list can be queried with list_coupons, but what’s actually usable for the current order is the available_coupons from preview_order. Full fields and the coupon_ids tri-state are in Preview Order.

Phase 6: Create Order

Place the order with the preview_id + confirmation_token from the same preview:
This tool uses confirmation_token as the idempotency key: a token can place only one order; re-ordering requires a fresh preview for a new token. Returns order_id, status, and (when payment is needed) payment_action. You may pass callback_url; every status change on the order POSTs a callback (body carries order_id, seq, status; the payment-outcome one adds event=order_payment and ispay, status, etc.) — otherwise poll get_order_status yourself. Full fields in Create Order.

Step 4: Password-Free Payment Signing (Account-Level, One-Time)

Password-free signing lets the user authorize password-free payment: sign once, and later password-free orders are charged automatically. It is an account-level, one-time prerequisite that is not bound to any single order and is not done per order — so it stands apart from the order chain above. Before you need password-free payment, check with get_sign_status whether already signed, and only initiate when not:
When action_type=open_h5, direct the user to action_url (the H5 sign page) to sign; once done the browser returns to return_url. none means already signed. Then poll the signing result with get_sign_status:
Full fields in Initiate Password-Free Signing and Query Signing Status; the order chain and payment sequence are in Order Flow.

Step 5: Handle Edge Cases

Robust Agents gracefully handle edge cases and provide friendly error messages. Gateway errors return a uniform {"error": {"code", "message"}} structure (every MCP tool returns this shape on failure).

Error Handling

Branch on error.code to show friendly messages:
Any business tool returning CONSENT_GRANT_INVALID / CONSENT_GRANT_EXPIRED means re-authorization is needed (or proactively compare the recorded expires_at). Just run the binding flow again — re-authorization rotates the grant, so you get a new consent_grant_id; replace the stale value in local storage with it.

Shop Closed Handling

The available / unavailable_reason in search_shops browse results let you pre-check whether a shop is open. If the order chain hits a closed shop mid-way, prompt the user to choose another shop and go back to search_shops to re-select.

Order Query with Retry

get_order_status is a read-only query and is safe to retry on timeout:
Use bounded backoff retries (e.g. up to 3) for read-only tools like get_order_status, but do not blindly retry order-creation tools — rely on the confirmation_token idempotency key to avoid duplicate orders.

Best Practices

Reuse Saved Addresses

search_addresses returns saved_addresses[]; prefer reusing their address_id instead of re-registering a new address.

Progressive Menu Disclosure

Menus can have 100+ items. Use keyword or limit / offset on get_shop_menu to page, following has_more / next_offset until done.

Logging and Monitoring

Record critical tool calls (argument summaries, returned order_id / error codes, etc.) for debugging and monitoring. Be sure to redact sensitive fields like consent_grant_id.

Rate Limit Handling

Respect rate limits (create order 10/min, others 60/min, per Agent). On limit a tool returns RATE_LIMITED; use exponential backoff.

Amounts Are in Cents

All amount fields are cents (integer). Divide by 100 when showing to users — never treat cents as yuan. payable_price: 1500 is ¥15.00.

Graceful Degradation

When upstream is unavailable (ELEME_ERROR), provide alternatives (show cached results or ask the user to retry later).

The Full Chain at a Glance

Chaining the tool calls from each step above gives one complete order:
Prepare the delivery address first, then search deliverable shops by that address, so downstream tools all get the delivery coordinates. All cross-step IDs (address_id / shop_id / cart_id / preview_id / confirmation_token …) are issued by the gateway and must be passed verbatim — never fabricate them or mix across chains. confirmation_token is the order idempotency key, and the consent_grant_id minted during binding is the user-consent argument carried by every subsequent business tool call. Password-free payment signing (get_sign_action) is an account-level, one-time prerequisite, independent of this order chain (see Step 4).

Next Steps

  • See the MCP Overview for the 24 tools’ connection, grouping, and complete inputs / outputs
  • Read Order Flow to master the full stateful order chain and payment sequence
  • Read Security Model to learn data protection best practices
  • Explore Supported Platforms to integrate with your Agent app