AgentCart

Project Overview
- Name: AgentCart
- Type: Agentic e-commerce platform for clothing, footwear, and accessories
- Purpose: Pair a real boutique-style storefront with Maya, an AI shopping assistant that searches the catalog, manages a cart, walks a shopper through checkout, and generates a virtual try-on image - all through typed tools exposed by a Model Context Protocol (MCP) server, so the same tools drive Maya's embedded chat panel and any external MCP client (Claude Desktop, Claude.ai, or another agent)
- Live storefront: agentcart.mrutyunjaypatil.dev
- MCP endpoint:
https://mrutyunjaypatil.dev/agentcart/mcp(Streamable HTTP - connect any MCP client directly)
Overview
AgentCart is a full agentic storefront, not a chatbot bolted onto a demo catalog. A human clicking through the UI and an AI agent calling MCP tools drive the identical typed business logic against the same Cloudflare D1 database - the MCP server is just a second, protocol-level front door onto the same product, cart, checkout, and auth code the storefront's server actions call directly. Maya, the in-storefront assistant, is built with a salesperson persona rather than an assistant persona: she stays in character as a human associate on the shop floor, never breaks it to explain she's an AI, and reasons over exactly the tool calls an external MCP client would make.
Key Capabilities
Maya, the shopping assistant
- Seven typed MCP tools -
search_products,get_product_details,add_to_cart,get_cart,remove_from_cart,checkout, andvirtual_tryon- each with a JSON schema and a structured response, callable identically from the embedded chat panel or an external MCP client. - MCP Apps rich UI - every tool result declares
_meta.ui.resourceUri, so an MCP Apps-compatible client (Claude, Claude Desktop, ChatGPT, VS Code, Goose) renders a product grid, cart summary, order confirmation, or try-on image inline instead of raw JSON, built from single-file HTML resources served by the MCP server itself. - A persona that knows what it doesn't have. The system prompt gives Maya two mutually exclusive branches for whether a shopper's photo has already arrived, rather than one paragraph covering both, because the merged version told a shopper who had just attached a photo to attach a photo about a third of the time - the model has no way to check the image itself, since the picture deliberately never enters its context, only an opaque id it hands back to
virtual_tryon.
Semantic product search
- Cloudflare Vectorize behind keyword search. Plain keyword search ANDs every word in a query against the catalog's text columns, which returns nothing for the way a shopper actually talks to an agent ("office party outfit smart casual") because those words never appear verbatim in a product row. Embedding the query and the catalog into the same 768-dimension vector space (
@cf/baai/bge-base-en-v1.5) fixes exactly that case. - Merchandising-aware embeddings - each product's embedding text includes occasion, season, colour and gender, not just its name and description, so an intent like "something for a summer wedding" has real signal to match against.
- Resumable catalog indexing - an admin endpoint re-embeds the catalog in cursor-paginated batches of 50, because a single Worker invocation cannot embed a full catalog inside its CPU and subrequest budget.
- Semantic search degrades, never breaks. If Vectorize or the embedding model is unavailable, semantic ranking returns an empty result set rather than throwing, and the caller falls back to keyword-only search.
Virtual try-on
- Generates a try-on image from an uploaded photo or an image URL through a three-provider fallback chain: Azure FLUX.2 [pro], then Cloudflare Workers AI FLUX.2 [dev], then Gemini 2.5 Flash Image.
- The Workers AI tier requires both reference images under 512x512, resized through the Cloudflare Images binding before the call.
- Every response surfaces which provider actually served the request, for observability into the fallback chain rather than a black box.
Multiple Cloudflare accounts behind one interface
- Both AI fallback chains (chat and try-on/embeddings) attempt each provider in order and log which one served the request.
- Workers AI's free-tier daily neuron allowance is shared by chat, try-on, and embeddings, so semantic search silently degrading to keyword-only is often the first visible sign an account is out of budget - the fallback chain reaches a spare Cloudflare account's REST API for embeddings specifically to keep that half of search alive.
Architecture
Three deployable units share one Cloudflare D1 database:
- Storefront (Next.js,
apps/web) - deploys as theagentcart-webWorker on theagentcart.<domain>subdomain: App Router pages, server actions,/api/chat(the agent loop), and/api/tryon. - MCP server (
apps/mcp) - deploys as a separateagentcart-mcpWorker, routed at<domain>/agentcart/mcpon the root domain. Cloudflare Workers Custom Domains map a whole hostname to one Worker, so a path scoped onto the apex domain needs the classic Workers Routes mechanism instead of a Custom Domain - hence the dedicated Worker and route, deployed separately from the storefront. packages/core- shared business logic (products, cart, checkout, auth, the AI provider fallback chains) that both the storefront's server actions and the MCP server's tool handlers call directly, so there is exactly one implementation of "what a purchase is," not two that can drift.packages/db- Drizzle ORM schema, migrations, and the product/user seed script against Cloudflare D1 (SQLite), with product images rehosted to Cloudflare R2 at seed time.
Technical Stack
- Frontend: Next.js 16 (App Router), React 19, Astryx UI components (Stone theme) on StyleX
- Backend: Next.js Server Actions and Route Handlers plus a dedicated MCP Worker, both on Cloudflare Workers
- Database: Cloudflare D1 (SQLite), schema/migrations/seed as code via Drizzle ORM
- Vector search: Cloudflare Vectorize, embedded with Workers AI (
@cf/baai/bge-base-en-v1.5, 768-dim) - Image storage: Cloudflare R2
- Auth: custom email/password, PBKDF2-SHA256 (WebCrypto) password hashing, cookie sessions
- Agent/chat LLM: Azure OpenAI (
gpt-5.6-luna) with a Cloudflare Workers AI fallback - Virtual try-on: Azure FLUX.2 [pro] to Workers AI FLUX.2 [dev] to Gemini 2.5 Flash Image, a three-tier fallback chain
- MCP transport: Streamable HTTP via Cloudflare's
agents/mcp(McpAgent) and the official@modelcontextprotocol/sdk - Rich tool UI: MCP Apps (the MCP extension for inline tool-result UIs)
- Deployment: Wrangler CLI,
@opennextjs/cloudflare
Non-goals
No real payment processing - checkout is fully simulated. No admin or back-office UI. Not built for production-scale traffic - this is a demo-grade deployment optimized for correctness and polish, not for the volume a real storefront would see.