Inspiration

Everyone is talking about agentic commerce, but almost nobody is comfortable with it. Would you hand an AI your credit card and walk away? Today's agents either scrape websites blind, clicking through UIs they were never meant to understand or they get access with no visibility and no control for the person they're acting for.

We built Tandem to prove there's a third option: a storefront designed for both audiences at once the human who owns the money, and the agent who does the work. WebMCP makes this possible because the app can speak to the agent in structured tools instead of hoping it guesses the UI correctly.

What it does

Tandem is an agent-native grocery store where you and your AI shop together:

  • Give your agent a mission, not clicks: "Dinner for 4, gluten-free, under $60." It searches the catalog, reads product details, and builds a cart using its WebMCP tools.
  • Guardrails are enforced by the app, not the prompt. add_to_cart refuses items that break the budget or dietary rules. The agent can't prompt its way past policy, the store itself is the policy layer.
  • Every agent action is visible. Each tool call renders as a human-readable card in a shared Activity Timeline. Shopping with an agent stops being a black box.
  • You can talk back. Drop a note like "no cilantro" — the agent reads it via get_shopper_notes and re-plans. Async human→agent communication, inside a web app.
  • Nothing is bought until you tap Approve. request_checkout returns a pending_human_approval card. The agent fills the cart; only you can greenlight it.
  • Swaps, not surprises. When the agent wants to replace an item (out of stock, over budget), it calls propose_swap and you accept or reject in one tap.

How we built it

  • The storefront is a React (Vite) app with a product catalog, cart, notes panel, activity timeline, and approval flow.
  • We registered 7 WebMCP tools using the standard browser API:

document.modelContext.registerTool({ name: "add_to_cart", description: "Add a product to the shopper's cart. Enforces budget and dietary guardrails.", inputSchema: { /* JSON Schema / }, execute: async (input) => { / validate policy, mutate cart, log to timeline */ }});

  • Full tool set: search_products, get_product_details, add_to_cart, get_cart, get_shopper_notes, propose_swap, request_checkout.
  • Each execute() returns structured JSON (prices, remaining budget, refusal reasons) so the agent can plan its next move and also updates the UI so the human sees the same story in real time.
  • Guardrails (budget cap, dietary exclusions) live in app code, evaluated inside tool executions, the same rules apply no matter what the agent's prompt says.
  • A built-in Dev Tools panel can invoke any registered tool manually, a fallback demo path and a debugging aid.
  • Deployed on Vercel; tested in ChatGPT's in-app browser and Chrome with chrome://flags/#enable-webmcp-testing.

Challenges we ran into

  • Tool descriptions are the agent's entire documentation. We rewrote them repeatedly; vague descriptions produced hesitant agents, precise ones with explicit constraints produced confident, correct plans.
  • One action, two audiences. Every execute() must mutate UI state for the human and return clean structured data for the agent. Getting that dual contract right was the core design problem.
  • Policy vs. persuasion. The agent would "ask" to exceed the budget. We learned to encode refusals as first-class structured responses ({ added: false, reason: "over_budget", remaining: 4.50 }) so the agent recovers gracefully instead of failing.
  • Testing across two WebMCP surfaces (ChatGPT's in-app browser and Chrome's flag) surfaced small schema strictness differences we had to normalize.

Accomplishments that we're proud of

  • In testing, the agent completed a full mission 11 items, gluten-free, $58.40 of a $60 budget on its first attempt, with zero unauthorized purchases. Not because we asked nicely, but because the app makes it impossible.
  • The human's Activity Timeline is generated from the exact same tool-call events the agent generates one source of truth, two audiences.
  • A pattern we believe generalizes across the web: propose → enforce → approve, applicable to expenses, bookings, emails, and deploys.

What we learned

  • Designing tools is designing an API for a new kind of user. Schema and description quality mattered more than anything else we wrote.
  • The best agent UX isn't full automation, it's delegation with visibility. Humans stay sovereign; agents do the labor.
  • Rich structured responses (remaining budget, reasons, alternatives) make agents dramatically more capable than bare success/fail returns.

What's next for Tandem

  • Real payments behind the approval gate (Stripe), making the pattern production-safe.
  • A roaming agent that shops across multiple WebMCP-enabled stores in one mission.
  • Shared household carts with per-person budgets.
  • A spec proposal: a standard human-consent / approval tool pattern for WebMCP, so every agent-native app can implement trustworthy checkout the same way.

Built With

Share this project:

Updates

Submission history