15 April 2026
I turned 5 million Shopify stores into Claude apps
I’d been building an MCP widget against the new Apps spec: a Cloudflare Worker that turns any Shopify store into something Claude can shop from. All five-million-plus of them: most of the online shops that aren’t Amazon. Last Tuesday I used it to buy a bag of coffee.
I asked for fruity filter roasts under $30. Claude came back with two product cards rendered inline in the chat: photo, roaster, price, tasting notes, dropdowns for weight and grind. I picked the 250g bag of Peruvian Merly León (a washed Yellow Caturra) from Rocket Coffee, a roaster in Hamilton. One click and I was on their checkout with Merly in my cart.
Most people don’t know you can do that yet. These are MCP widgets: tools whose response is a rendered interface instead of a wall of text. MCP is how models like Claude plug into external services (your calendar, a weather feed, a coffee shop). Web search is the one most people have already used without realising.
Most MCP tools still return walls of text
The normal shape of an MCP tool response is a blob of structured text (JSON). You ask a weather tool for tomorrow’s forecast and it sends back a paragraph. You ask a calendar tool what’s on this week and it sends back a bulleted list. Web search hands back a list of links and snippets. The model reads the text, summarises it, and you read the summary. That has been the whole experience since the protocol shipped.
Walls of text are fine for questions with short answers. They fall over the moment the answer is a choice. Picking a coffee out of twelve options with photos, price, tasting notes and variants does not compress well into prose. The model does its best and you still end up finishing the job on the website. The coffee render skips that last mile.
Tools can return interfaces now
The Model Context Protocol picked up a spec extension called MCP Apps. A tool response can now carry a small HTML-and-JS bundle, which the host (Claude, in my case) mounts in a sandboxed iframe inside the chat with a messaging channel back to the server.
What the model sees is still text: a short summary of what the widget is showing. What the human sees is the widget itself. Click events and form state stay inside the iframe, so the model’s context stays clean even when I’m spinning through twelve product variants. The sandbox is also the security story: the widget can’t touch the host, the rest of the chat, or the other tools on the thread. Everything it wants to do has to go back through the MCP server, and the server decides what’s allowed.
In the Rocket Coffee flow, the widget is a small React app that mounts product cards with variant pickers. What makes it feel considered is that the model decides, on the fly, what belongs on the card. It noticed the products had tasting notes and roast levels, so it surfaced those. It saw that each bag came in 250g and 1kg variants, so it wired up a variant selector instead of dumping both as separate cards.
When you hit “add to cart” the widget calls back into the MCP server with the selection, and Claude hands back a Shopify cart link. One click lands you on the merchant’s real checkout.
The model wrote the integration live
The other half of this works because of Cloudflare’s Code Mode. Instead of registering a dozen tools like search_products, get_collection and get_variants, the server registers one code tool. The model writes a snippet of JavaScript against a typed proxy and the Worker runs it in a V8 sandbox. I wrote up the pattern in more depth in a separate piece on Code Mode.
When I asked for a bright, fruity single-origin, Claude wrote something like this in the moment: fetch the full product list, filter for washed single-origins with berry or floral notes in the description, trim the payload down to title, price, image, tasting notes and variant ids, return the result. The sandbox called Rocket Coffee’s /products.json under the hood, and only the fields the model actually asked for came back into context.
The upshot is that the server does not have to pre-specify every question a shopper might ask. A coffee store has an endless tail (single origin under $25, something bright and citrusy, a washed natural with berry notes) and you can’t write a tool for each one. With Code Mode you don’t have to. The model writes the query, the server runs it, and a render tool turns the result into a widget.
Any Shopify store is already a Claude storefront
Every Shopify store exposes its full catalogue at /products.json. No auth, nothing to install. Try it on any DTC brand right now.
The endpoint was built to feed themes and third-party integrations: a public catalogue, not a storefront. MCP Apps and Code Mode let it act like one. Over 5 million Shopify stores are readable right now with a single fetch.
Every Shopify store is already a Claude storefront. The merchants don’t know yet.
The bigger shift underneath all this: people are opening fewer websites. They ask the chat and act on whatever comes back. If your brand isn’t reachable from inside the conversation, it stops being reachable at all. An MCP widget is how you stay in the room when the room is Claude.
The server I built is shopfront-ui-mcp, a single Cloudflare Worker. Point it at any Shopify URL and it works, because the store is the integration.
Same pattern, different store
A few days later I tried it on Ishinomaki Lab, a Japanese furniture maker. Same shape, different store: Claude pulled the catalogue, clocked the yen pricing, converted my $600 budget, and surfaced only the wood variants that fit.
Where this goes next
Shopify is the obvious unlock because its catalogue feed sits in public. The pattern doesn’t care about that. Anywhere there’s a system with a workable API, the same shape works: a property portal, a booking calendar, a quote engine, a clinic’s appointment system. Credentials stay in the Worker, the model writes queries against it, and a widget renders whatever comes back. If the client already has the system, the MCP server goes in front of it and the agent experience comes out the other side.
Checkout is the last step that still kicks me out of the chat, and that won’t last long. Stripe, Shopify and the agent platforms are all circling agentic payments. Soon enough the “buy” button resolves inside the conversation and I never leave the thread.
The first generation of MCP tools dressed up the chat with better answers. The next one cuts out the clicking. The model does the thinking, a widget does the last mile, and a loop that used to take ten tabs and a dozen clicks finishes in seconds.
The server is public. Paste https://shopfront-ui-mcp.iraritchiemeek.workers.dev/mcp into Claude’s connector settings (Settings → Connectors → Add custom connector on claude.ai), then ask Claude to find you something from any Shopify store.
Feel free to explore the codebase on GitHub and set it up locally.
