My Etsy shop, Cuttlefish Boutique, now has a small team of AI agents running behind it — one checks the shop and reconciles shipping every morning, one drafts replies to customer messages, one builds new listings with real product mockups, one keeps an eye on trends, one handles social content ideas. When I mention this, the assumption is always the same: I typed one really good prompt and it just... works.
It doesn't work that way. Here's the actual build, including the parts that broke.
It's not a prompt. It's a loop.
A prompt is one message in, one message out. What's running my shop is a tool-use loop: Claude gets a real set of tools — get_order_detail, search_listings, generate_mockup, create_draft_listing — decides which ones it needs, calls them against real APIs, reads what comes back, and decides what to do next. Sometimes that's four or five calls chained together before it ever writes a word back to me. That loop is hosted as a small serverless function per agent, not a chatbot wrapper sitting on top of a single response.
The difference matters in practice, not just in architecture. Ask a single-prompt system "did my last few orders actually ship?" and it can only answer from whatever you fed it in the prompt. Ask my shop-audit agent the same question and it goes and checks Printful's real order data against Etsy's real receipt data, live, and tells you what it actually found — including when the two don't agree.
Real accounts, not simulated ones
Every credential behind this is real and mine. Etsy's API uses OAuth2 with PKCE — a full authorization flow, not a simple key you paste in — and the scopes grew as the agents needed more access: read-only at first, then transaction data for shipping reconciliation, then delete permission once a listing-builder agent existed that could need to remove one. Printful uses a personal API key. AnyList, which has no official public API at all, gets accessed through a reverse-engineered community package — I read its actual source before trusting any of its method names, because a package name tells you nothing about what a function really does.
None of that is simulated for a demo. It's the actual shop, the actual orders, the actual customer messages.
Every agent that can take a real action is scoped on purpose, not by default. The message-drafting agent never sends — it drafts, and I get an email to review it. The listing-builder agent always creates listings in draft state, never published. Deleting a listing requires me to say so explicitly; it's never inferred from context. That boundary got asked and re-confirmed more than once during the build, specifically so "it's just my own shop, it's fine" pressure never quietly widened it.
The bugs a single prompt would never catch
This is the part that actually took the time, and it's the part "vibe coding" skips entirely — because vibe coding tests the happy path once, sees it work, and stops.
- Etsy's listing-creation API kept 400ing with no useful reason. It turned out to silently require a
shipping_profile_id, then — after fixing that — areadiness_state_id, neither one documented anywhere in Etsy's own listing-creation docs for this shop type. I only found both by reading the raw fields off a listing that already existed in the shop and matching the shape. - A shipping reconciliation check was flagging real orders as "not shipped" when they had shipped. The cause was a reshipped order's ID carrying a
-RESHIPsuffix that didn't match Etsy's numeric receipt ID format, which made the lookup error — and the original code was treating any lookup error as "not shipped." The fix wasn't a smarter prompt, it was making the code skip anything it couldn't verify instead of guessing. - The meal-planning agent returned empty recipes and an empty calendar for weeks of testing until I read the actual AnyList wrapper's source and found two methods that have to be awaited before their data is populated — an async bug invisible from the outside, only visible by reading real library code instead of trusting the interface it appeared to offer.
- An agent confidently answered a "what's for dinner this week" question with the wrong week, because nothing in the system told it what day it actually was. The fix was computing the real date fresh on every request and feeding it into the prompt at call time — not something you'd think to build until an agent has already gotten it wrong in front of you.
None of these show up if you're only ever testing the demo case. They show up from using the real thing against real data and watching it fail in a way you have to actually trace back to a root cause.
Making it run without me
Once the agents were solid, I added a second, separate layer: three of them now run on a schedule with no one asking. A morning meal-plan digest, a weekly content-idea batch, and a daily shop health check — all emailed to me automatically.
The shop health check is the one I'm proudest of, because it's built to shut up. It's told to prefix its own answer with the literal word ALLCLEAR or ATTENTION, and the code only sends an email on ATTENTION. A daily check that emails you every single day, clear or not, gets ignored by week two. One that only speaks up when something's actually wrong gets read every time.
What "vibe coding" actually can't do
Vibe coding, as I understand the accusation, is iterating on vibes — does it look right, does the demo work, ship it. Nothing about that process finds an undocumented required field two calls deep in a real API, or an async bug hiding inside a reverse-engineered wrapper, or decides that a message-drafting agent should never be allowed to hit send even though it technically could. Those aren't prompt problems. They're engineering judgment calls, made one at a time, usually because something real broke first.
I'm self-taught — no CS degree, no dev team. What made this work wasn't a better prompt. It was treating Claude Code as a real build tool: testing against live data instead of trusting docs, reading actual source instead of guessing from a package name, and deciding — explicitly, more than once — what this system is and isn't allowed to do on its own.
this is the same tool-use pattern behind the AI team running Three Seven's client work — built a second time, on completely separate infrastructure, specifically to prove it wasn't a one-off.