Built for agents.
Designed around real people.
Two agent entry points, one commerce service: authenticated hosted MCP and REST fallback. Humans set intent, connect agents and consent to signed intents. The website is not a parallel catalog browser. This concrete proposed v1 contract makes no compatibility claim for unavailable historical v2 interfaces or unverified assistant platforms.
A real connection, not a copied brief
New to agent shopping? Start with the human setup guide. Build your brief, then use an agent client that accepts a hosted MCP endpoint and a Bearer credential, or call REST from your agent integration. Copying a brief does not connect or authorize an assistant. Client features, subscriptions and account permissions vary; no consumer-assistant compatibility is claimed as tested here.
Service capability verification has not been loaded.
Use the actual origin you are visiting:
/mcp — hosted MCP/api/v1/search — REST search- Create a short-lived delegated key in this shopper browser.
- Configure your trusted agent client with
Authorization: Bearer <key>. - List tools to verify transport. Query only for an explicit shopper need.
- Preserve exact variant IDs, quantities, currencies and unknown facts. Create the intent and give its
review_urlto the human. - The originating shopper browser reviews and authorizes handoff. An agent's
approval:truealone is not human consent.
Hosted MCP endpoint: /mcp Authorization: Bearer <delegated-key> Client syntax is client-specific; copying this is not a connection.
REST example — agent only
Set CARTRELAY_KEY securely. Never paste raw keys into shared logs.
POST /api/v1/search
Authorization: Bearer <delegated-key>
Content-Type: application/json
{"query":"laundry refill","context":{"country":"CA","currency":"CAD"},"limit":3}Browser session & CSRF
GET /api/session with credentials included and X-CartRelay-Client: browser returns {csrf_token,expires_at}. Browser mutations include X-CartRelay-CSRF. Opaque cookies are HttpOnly and secure on HTTPS; CSRF stays in memory. These cookies authorize scoped key management, support and review of an agent-issued intent owned by that browser. They do not authorize /mcp or any /api/v1 commerce route. Open CartRelay directly if embedded cookies are blocked.
A key for your own agent
Guest-scoped delegated keys last two hours and can be revoked earlier. Guest sessions last 24 hours; intent tokens last ten minutes. A key holder can act within its permitted scope until expiry or revocation. Trust your client and keep the key private. Keys are not operator credentials.
No keys loaded. Load or create keys for this guest session.
Confirm delegated-key revocation
Only hashes and metadata are retained. Raw keys are revealed once and never stored in localStorage or sessionStorage by this page. Keep the originating browser cookie for key management and review ownership; changing browsers does not transfer the intent.
Reference hosted MCP client
Node ESM example for the pinned SDK2 client package. It connects and lists tools; it does not query a catalog or order products. Run it against your actual service and inspect current capability status. Transport discovery is not proof of live source negotiation, browser-consent validation, or consumer-platform approval. Published source-profile verification remains a separate release condition.
pnpm add @modelcontextprotocol/client@2.4.0 # Save as client.mjs, set CARTRELAY_KEY privately, # and run: node client.mjs
import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
const client = new Client({name: 'cartrelay-reference', version: '1.0.0'});
// Complete origin-derived example appears with JavaScript enabled.Use only documented transport modes reported by the service. See MCP protocol documentation ↗.
Five tools. Two agent entry points.
Every commerce route requires delegated Bearer authentication; browser cookies cannot substitute. Success envelope: {ok:true,data:{…}}. Context: {country:"CA",currency:"CAD",postal_code?:string}. CAD is a preference, not a conversion. Prices are {amount:integer_minor,currency:string} or null; preserve their currency exponent.
| Tool / REST route | Request | Response data |
|---|---|---|
cartrelay_searchPOST /api/v1/search | {query,context,max_price_minor?,limit?} | {products,pagination:{cursor,has_next_page},notices,source,fetched_at} |
cartrelay_detailPOST /api/v1/detail | {id,context,selected?:[{name,label}]} | Same discovery envelope with exact offers. |
cartrelay_price_stockPOST /api/v1/price-stock | {ids:[id],context} | Same envelope with current permitted offer facts. |
cartrelay_cart_createPOST /api/v1/cart | {lines:[{id:exact_variant_id,quantity:1..12}],context} | {cart_token,review_url,expires_at,items:[{id,quantity,product_title,offer|null}],notices,not_a_reservation:true} |
cartrelay_checkout_handoffPOST /api/v1/handoff | {cart_token,approval:true}; requires recorded human approval for the reviewed token. | {review_required,groups:[{merchant|null,items,links}],notices,commission_tracked:false,purchase_completed:false} |
Product and exact-offer shape
{
id, title, url, image_url,
offers: [{
id, title, price: {amount, currency} | null,
available: true | false | null, availability_status,
options: [{name, label}],
merchant: {name, id, domain, url, policy_links} | null,
retailer_url, quantity_link_support, missing_facts
}],
options: [{name, values: [string]}],
description_inferred, missing_facts
}Cart and handoff offers, and group merchants, can be null. Preserve unresolved exact references visibly; do not silently remove or substitute them. Group items add changed and unavailable. Group links are {id,url,label,quantity,quantity_link_support:"one_item_only"|"unknown"}. Support defaults to unknown: a link may open one item only and may not set your quantity; no support is asserted as proven.
GET /api/contracts is public metadata: no delegated key, browser cookie or operator login is required. It exposes concrete input and output schemas for the proposed v1 contract. Current live schemas, authentication and owner/consent checks are authoritative.
Human consent, not browser commerce
The agent-created review_url uses /review#cart=<token>. The fragment keeps the intent out of HTTP URL logs. Open it in the browser whose shopper cookie owns the delegated agent key. The page reads the fragment into memory and immediately erases it using history replacement. A new agent link that changes the fragment in the same open document clears the old local review, cancels pending browser requests and loads the new token with fresh unchecked consent; prior local consent does not transfer. Cancellation does not undo consent already processed by the service for an older intent. Never persist tokens, put them in query parameters or share them with support.
POST /api/review/open
# Browser cookie + X-CartRelay-CSRF
{"cart_token":"<agent-issued-token>"}
{ok:true,data:{
cart_token, expires_at,
items:[{id,quantity,product_title,offer|null}],
notices, not_a_reservation:true
}}The returned token represents freshly resolved exact offers. Human approval must use that new returned token, not the original fragment token. The page has no discovery, manual variants, quantity editing, new product IDs or generic cart creation. Its explicit checkbox authorizes retailer handoff, not a purchase.
POST /api/review/approve
# Same owning browser cookie + X-CartRelay-CSRF
{"cart_token":"<new-returned-token>","approval":true}
{ok:true,data:{
review_required,
groups:[{merchant:null|{…},items:[{id,quantity,product_title,
offer:null|{…},changed,unavailable}],
links:[{id,url,label,quantity,quantity_link_support}]}],
notices, commission_tracked:false, purchase_completed:false
}}Tokens are independently signed with a server-held secret, not derived from a guest cookie. The server records an opaque human approval hash scoped to owner and expiry, then rechecks source price, availability, exact variants, merchant and link fingerprints. Changed fingerprints require renewed review. Changed, missing or unknown current selections withhold all retailer action links. Ask the agent to revise and send a new review link; no source fallback or manual shopping is offered. Wrong browser, missing token and expired intents remain locked. Successful consent only releases permitted source-returned retailer links. Confirm exact variant, quantity, currency, final price, taxes, shipping and payment there. Leaving the review page clears token/response memory and rendered source details; refresh requires a fresh agent link.
Live source. No copied catalog.
The homepage has one explicit limited-preview exception: GET /api/showcase resolves four fixed references with a fresh batch lookup and no query/ref/cursor parameters. It returns source-listed titles, variants, direct merchant-image URLs, seller attribution and actual-currency prices; no checkout/action links. Responses are no-store and globally limited to ten requests per minute to preserve source capacity for agents. Images render in real time with their related listings and are not downloaded or rehosted. The card CTA starts a local agent brief; commerce, intent creation and retailer handoff still require authenticated agent tools and independent human consent.
Shopify Global Catalog is the first outbound provider. Agents query a bounded live source for a current shopper intent; CartRelay retains no permanent product index, retailer descriptions, image copies, source-result bodies or price snapshots. Source imagery, when used by clients, must be externally hosted and accompanied by merchant attribution. The human review page displays text facts only and releases retailer navigation only after consent and recheck.
Catalog and credential responses use Cache-Control: no-store. Do not cache or persist provider payloads, bulk harvest, log raw keys or tokens, or export a copied catalog. Keep offer details request-local or transient. Four stored homepage references are configuration for fresh lookup, not a retained catalog. CartRelay-owned storage includes hashed credentials, rates, minimal operational outcomes, opaque approval hashes and submitted support requests, not catalog tables.
Unknown stock, shipping, ingredients, certifications and pack sizes stay unknown; inferred descriptions are not verified evidence. Preserve currencies; never relabel USD as CAD, invent FX or total mixed currencies as a single quote. Retailers handle checkout, payment, fulfillment and returns. No stock is reserved, no universal merchant cart is created and no commission tracking is enabled.
Expired credential and approval state is removed by daily cleanup. Application-database support and operational records are deleted after 30 days on the next daily run (up to 31 days). App cleanup does not delete email/message copies delivered in owner notifications; owner inboxes and Manus notification systems follow separate retention policies. Request operator help for those copies through a privacy request. Native retention registration and own-profile source verification follow deployment; documentation is not evidence that they succeeded.
Shopify source documentation ↗ · CartRelay public capability profile · Privacy · Terms
Errors, management & limits
Error envelope: {ok:false,error:{code,message,retry_after?}}. Application errors use JSON, including 401 with WWW-Authenticate: Bearer realm="CartRelay". A plain-text/HTML unauthorized response without the application envelope is not evidence of a CartRelay key-scope error; capture your client/runtime, exact method/path, response Content-Type and response headers (never keys/tokens) for support. Successful standard Node REST checks do not establish support for every proxy or runtime. Statuses: 400 invalid input, 401 unauthenticated/expired, 403 forbidden/CSRF/wrong owner, 404 missing resource, 409 conflict/changed state, 429 rate limited, 502 source failure, 503 unavailable. Honor retry_after; no aggressive retries or unattended catalog polling. Limits and current tool input schemas are enforced by the service.
POST /api/agent-keys {label} reveals {id,raw_key,prefix,expires_at} once. GET /api/agent-keys lists {keys:[{id,label,prefix,expires_at,revoked,last_used_at,calls}]}. DELETE /api/agent-keys/:id revokes only the owning guest's key. Browser mutations require CSRF.
POST /api/support {email,message,kind:"support"|"privacy"} returns {reference,notification_accepted}. GET /api/status reports configuration and verification, not retail coverage or product discovery. The locked operator area requires real Manus identity and separate exact owner authorization. Missing source data is never replaced with demo products. Use support when setup is unavailable.