Tendero is a working WebMCP storefront for a Colombian corner store — Surtitienda La Milagrosa, Manrique, Medellín. It hands an AI agent the eleven tools a Colombian sale actually needs via document.modelContext.registerTool, and it closes the sale only in Wompi sandbox and only after a human's one-click authorization the agent structurally cannot bypass.
Why this is a strong fit for WebMCP
The default commerce tool set (search_products / add_to_cart / checkout) quietly exports US assumptions — a prepaid card, a street address, a self-serve checkout. A Colombian sale is none of those, and the correct action depends on local rules the agent cannot infer and only the page knows:
- Cash on delivery is the dominant rail — with a collection ceiling, partial carrier coverage, and towns no carrier will reach.
- VAT depends on the destination department — the same basket is VAT-excluded in Amazonas and San Andrés.
- Colombia has four VAT treatments plus consumption tax; exento and excluido differ in law.
- A statutory 5-business-day right of withdrawal, against the real holiday calendar.
- An e-invoice is rejected by DIAN without a valid document type and a correct NIT check digit.
How it creates a better UX
- The surface matches what's possible: an agent on a clean page sees 4 tools, not 11, and grows the surface 4 → 7 → 11 as the cart fills and a destination is set.
- Tools rewrite their own descriptions from page state — cash on delivery becomes "unavailable: Leticia has only air access" — firing
toolchangeso the agent re-reads the rules. - Refusals are recovery-shaped (the NIT check digit that should have been 8).
- Every
execute()calls the same render the human buttons call, so the person sees the machine work.
What people and agents can do together
The agent assembles the order and the page supplies the law — VAT treatment per line, cash-on-delivery reachability, the withdrawal deadline, whether the buyer's document survives e-invoicing. Then the split that makes it collaboration, not automation: a human's one-click authorization seals the sale; only then can the agent open the Wompi checkout and confirm the payment (sandbox — no real money). The human authorizes; the agent executes.
How we built it (WebMCP implementation)
- 11 tools, each
document.modelContext.registerTool({ name, description, inputSchema, execute })with full JSON Schema. - Progressive disclosure in three rungs, gated on page state; descriptions computed from state so a change forces genuine re-registration and a real
toolchangeevent. - MCP-shaped responses (
content[0].text+structuredContent); discriminateannotations(readOnlyHint,idempotentHint,destructiveHint,untrustedContentHint); host-portable teardown. - No backend at runtime — static files; the Colombian rule engine runs in the page, with a Python reference implementation pinned by parity tests.
- CI: ruff,
mypy --strict, pytest (99% coverage), and a headless harness that drives the real page with a mockmodelContextand asserts an agent can grow the surface and close the sale by itself.
Verified live
4 → 7 → 11 tools · cheapest freight to Leticia $86,435 · total $110,835 with VAT $0 (Amazonas excluded) · NIT 900123456-0 → invalid, check digit should be 8 · payment closes APROBADA in sandbox · zero console errors.
What's next
Colombia is the instance, not the point — swap the rule module for Brazil (NF-e), Mexico (CFDI), or India (GSTIN). MIT-licensed; adoption is one static file and a <script> tag.
Built With
- css
- document.modelcontext
- github
- github-actions
- html
- javascript
- python
- webmcp
- wompi
Log in or sign up for Devpost to join the conversation.