Inspiration

I run e-commerce and paid media for apparel retail, so I have spent years on the ad-platform side of this problem. That machinery accumulates identity, infers intent from surveillance, and optimises for the conversion. It guesses at intent the shopper could simply have stated, and it never declines a discount because the discount would break the merchant's margin floor.

Promotional creative is where agents are most useful and most dangerous: a wrong percentage is a legal problem, not a bad impression. WebMCP made a different shape possible: rich page-local context, a deliberately tiny merchant-facing schema, and a human-only release. If a store does not need an identity to answer "no hoodie, size M", then do not send one, not even a hash.

The name comes from a hem loop: the small functional loop sewn inside a garment. Hidden, structural, load-bearing.

What it does

Hemloop is a shopper closet and a merchant studio on one origin, wired with WebMCP so ChatGPT works on live page state.

In under a minute: import a receipt into a private closet; the agent finds a gap such as hoodie, size M; you Approve once; the store only learns category, size, and need or want, with no name, account, hash, or wardrobe rows. The merchant agent proposes an offer inside locked margin rules, turns the same locked facts into a claim-safe promo, a human approves it, and the shopper alone can mark it Bought. The purchase sharpens the next cycle.

Twenty-one tools register: nine closet tools and twelve studio tools. The product is also what is missing: there is no tool for Approve, Lock facts, or Bought. Those presses are human-only by design.

Every promotional claim is checked against human-locked facts. "50% off" against a locked 25% is rejected atomically, and export refuses to exist while any claim is wrong.

How we built it

Registration targets document.modelContext, with a navigator.modelContext probe. Each tool has a name, description, closed input schema, optional annotations, and execute function. Every reader has readOnlyHint; user and catalog text is fenced and marked with untrustedContentHint.

The core is pure TypeScript: claim validator, composition exporter, wardrobe and fit logic, receipt parser, offer matcher, demand insight, and two WebMCP adapters. React surfaces own state and pass callbacks in, so the tool surface is testable without a browser.

The demo bridge is same-origin localStorage with exact-shape re-parse on every read, enough for judges to run both sides in one browser. Production would replace it with aggregation-before-disclosure and merchant-side intake; the structural tool absences and claim validator stay.

Stack: TypeScript, React 19, Vite through vinext, Cloudflare Workers, WebMCP, and a Shopify catalog snapshot as the demo connector.

Challenges we ran into

The hardest challenge was resisting the ad-platform instinct: just send an identifier, just let the agent optimise freely, just cache the shopper. Each of those would have made the build easier and erased the point.

The second was that a defensive re-parse is worthless if it is weaker than the parse it backs up, and that a tool result can exceed its output budget on ordinary data long before any attacker shows up. Both had to be fixed at the storage and tool-result boundaries.

Accomplishments that we're proud of

Structural human gates: there is no lock_facts, approve_offer, or approve_next_request tool. Those acts are absent by design, not "please don't".

matchOffer personalises discount depth, price, and validity inside the merchant's margin floor, and will trim or decline rather than break it.

One approval releases one demand event; the shopper sees the exact payload before and after; wardrobe rows cannot ride the outbound merchant tool.

What we learned

Privacy that depends on asking the model nicely is not a product. Boundaries that are missing tools and exact rebuilds at the storage edge are.

WebMCP is a strong fit when both sides need live page state in the person's own session, and when the outbound channel must be smaller than the local context the agent can reason over.

What's next

Aggregation before disclosure, so a demand cell becomes visible only after enough distinct shoppers contribute. Exportable consent receipts. Per-merchant sharing levels. Writing attributed outcomes into the merchant's own reporting rather than only displaying them on the demo page.

Built With

Share this project:

Updates

Submission history