An AI shopping assistant that demonstrates the Open Commerce Protocol (OCP) — a standardized protocol enabling AI agents to transact with merchants through structured APIs instead of brittle browser automation.
Today's AI shopping agents rely on scraping web pages and clicking buttons — slow, fragile, and error-prone. OCP (Open Commerce Protocol) proposes a better way: merchants expose a standard API endpoint, and AI agents interact with it directly.
Every OCP transaction follows three phases:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Discovery │ ──▶ │ Intention │ ──▶ │ Deal │
│ │ │ │ │ │
│ Does this │ │ Search & │ │ Checkout, │
│ merchant │ │ select │ │ pay & │
│ support OCP? │ │ products │ │ confirm │
└─────────────┘ └─────────────┘ └─────────────┘
Phase 1 — Discovery: The agent probes /.well-known/ocp on the merchant's domain. If the merchant returns an OCP profile, the agent uses native API transport. Otherwise, it falls back to browser automation.
Phase 2 — Intention: The agent searches for products and presents options to the user. With OCP, this is a structured API query; without OCP, it navigates the website via browser.
Phase 3 — Deal: The agent creates a checkout session, fills in shipping and payment details, and completes the order — all through a state-machine-driven API flow.
The checkout session progresses through well-defined states:
┌──────────────┐
│ incomplete │ ← session created, needs more data
└──────┬───────┘
│ update (add address, promo, etc.)
▼
┌─────────────────────┐
│ ready_for_complete │ ← all fields satisfied
└──────────┬──────────┘
│ complete (submit payment)
▼
┌──────────────┐
│ completed │ ← deal_id returned
└──────────────┘
Special states:
requires_escalation → browser fallback needed (3D Secure, CAPTCHA, etc.)
failed / cancelled → terminal states
AgentCart seamlessly handles both OCP-enabled and traditional merchants:
| OCP Native | Browser Fallback | |
|---|---|---|
| Discovery | GET /.well-known/ocp |
— |
| Product Search | GET /ocp/products?keyword=... |
Navigate site, type in search box |
| Checkout | POST /ocp/checkout → state machine |
Fill forms, click buttons |
| Payment | POST /checkout/{id}/complete |
Fill card fields, submit |
| Speed | Fast (API calls) | Slow (page loads + rendering) |
| Reliability | High (structured data) | Fragile (DOM changes break it) |
- Node.js >= 18
- Google Chrome
- Anthropic API Key
git clone https://github.com/Arxtect/agentcart-ai-assistant.git
cd agentcart-ai-assistant
npm installCreate ~/.agentcart/config.json:
mkdir -p ~/.agentcart
cat > ~/.agentcart/config.json << 'EOF'
{
"env": {
"ANTHROPIC_API_KEY": "sk-ant-xxx"
},
"email": "you@example.com",
"email_provider": "resend",
"resend_api_key": "re_xxx",
"allowed_domains": ["amazon.com", "localhost:4000"]
}
EOFFull configuration reference
npm run devOpens http://localhost:3000 automatically. Start chatting — e.g., "Buy me a pair of running shoes on amazon.com".
A built-in mock merchant server lets you test the full OCP flow locally:
# Terminal 1: Start the mock OCP merchant (port 4000)
npx tsx src/ocp/mock-server.ts
# Terminal 2: Start AgentCart
npm run devThen ask the agent: "Buy a Classic White T-Shirt from localhost:4000"
The agent will:
- Discover OCP support on
localhost:4000 - Query products via the OCP API
- Create a checkout session
- Request your payment confirmation (OTP email)
- Complete the deal — all without touching a browser
User → Chat UI (localhost:3000) → POST /chat
↓
Agent Loop (Claude Agent SDK)
↓
┌─────────────────┼─────────────────┐
↓ ↓
OCP Native Transport Browser Transport
(structured API calls) (Playwright CDP → Chrome)
↓ ↓
Merchant OCP API Merchant Website
↓ ↓
└─────────────────┬─────────────────┘
↓
Payment Confirmation (OTP Email)
WebSocket → Real-time UI Updates
A merchant implements these endpoints to support OCP:
| Endpoint | Method | Purpose |
|---|---|---|
/.well-known/ocp |
GET | Discovery — returns merchant profile & capabilities |
/ocp/products |
GET | Product search with filters (keyword, category, price) |
/ocp/checkout |
POST | Create a checkout session with line items |
/ocp/checkout/{id} |
GET | Check session status |
/ocp/checkout/{id} |
PATCH | Update session (add address, shipping method, promo) |
/ocp/checkout/{id}/complete |
POST | Submit payment credential to finalize the deal |
| Module | Role |
|---|---|
src/ocp/types.ts |
OCP type definitions (profile, session states, credentials) |
src/ocp/client.ts |
OCP API client (discovery, products, checkout operations) |
src/ocp/mock-server.ts |
Reference OCP merchant implementation for testing |
src/agent/ocp-tools.ts |
OCP tools exposed to the AI agent via MCP |
src/agent/tools.ts |
Browser automation tools (navigate, click, type, snapshot) |
src/agent/loop.ts |
Agent orchestration — drives the three-phase OCP flow |
src/payment/otp.ts |
OTP generation & verification for payment security |
npm run dev # Run with tsx (no build needed)
npm run dev:ui # Frontend hot reload (proxies API to localhost:3000)
npm run build # Production build (tsc + vite)- AI Agent: Claude Agent SDK + Claude Opus
- Backend: Fastify + TypeScript
- Frontend: Vanilla TS + Tailwind CSS + Vite
- Browser Automation: Playwright (CDP mode)
- Email: Resend / Nodemailer
MIT
{ // Required: Anthropic API Key "env": { "ANTHROPIC_API_KEY": "sk-ant-xxx" }, // Required: Email for OTP payment verification "email": "you@example.com", // Required: Email provider — "resend" or "smtp" "email_provider": "resend", "resend_api_key": "re_xxx", // Or use SMTP: // "email_provider": "smtp", // "smtp": { "host": "smtp.example.com", "port": 587, "secure": false, "user": "...", "pass": "..." }, // Required: Domains the agent is allowed to visit "allowed_domains": ["amazon.com", "localhost:4000"], // Optional: Payment info (can also be set in the web UI) "payment": { "card": { "number": "4111111111111111", "expiry": "12/28", "cvv": "123", "name": "Your Name" }, "address": { "first_name": "Jane", "last_name": "Doe", "street": "123 Main St", "city": "San Francisco", "state": "CA", "zip": "94105", "country": "US" } }, // Optional: Defaults shown "cdp_port": 9222, "server_port": 3000 }