AI agent · MCP · voice
A London pottery studio run by talking to an agent that changes nothing without approval
Two brands of one company, two backends, one agent. The owner types or talks, the agent reads the data, proposes a change on a card and executes it only after “Approve”. The same agent is available inside Claude as an MCP connector.
- Status
- Pre-launch: replacing a closed SaaS, testing with the owner
- Period
- October – November 2026
- from an empty repo to a system with an agent and MCP (329 commits)
- 17 dnifrom an empty repo to a system with an agent and MCP (329 commits)
- API endpoints; the server checks access: customer, staff, owner or agent (OAuth)
- 304API endpoints; the server checks access: customer, staff, owner or agent (OAuth)
- tables in two PostgreSQL databases
- 72tables in two PostgreSQL databases
- correct in the photo-recognition eval
- 24/24correct in the photo-recognition eval
The problem
The studio ran on a closed SaaS built for barbers: a course was a single event with a start date, there was no attendance, no kiln queue, no student accounts, and content loaded by JavaScript was invisible to Google. The owner runs two brands and has no time for panels with forty tabs.
What I built
- Two FastAPI backends (Studio Rhei and Sway) with separate PostgreSQL databases, a shared library and a secret-signed bridge, so one brand's agent can safely read and change the other's data.
- Keramos: an agent with dozens of tools. Every write is a proposal with the exact description, amount and e-mail text. The server executes it through the same services as the panel. A daily cost limit and a history of every action.
- Voice: Whisper locally on the server, ElevenLabs for speech. Dates, amounts and codes are rewritten by rules behind markers, because without them the model garbled codes.
- A remote MCP server with OAuth 2.1 + PKCE: the owner connects Keramos to their own Claude. Sensitive changes (money, e-mails, prices) are approved on a panel page.
- AI for photos of pieces: a model recognises type, stage and size (with an A4 reference sheet), and the kiln planner arranges pieces in 3D on the shelves.
- Brand sites prerendered to HTML (React Router 7) with schema.org, sitemap and hreflang. Stripe with signed webhooks, Resend with a queue and retries, Parcel2Go, Google Merchant, Meta.
Architecture
The interesting part is underneath
Pick a flow to see data move through the system. Click any part for details.
← swipe the diagram →
Flows
Voice → proposal → approval → Stripe. The model never writes on its own.
Click a part of the diagram for details.
- hardware
- edge / network
- service
- data
- AI
- third party
- people / apps
- radio
- tunnel
- HTTPS
- local
- event
Every element, described
- Owner · panel, voice
- Types or talks to Keramos in the panel, on a phone or a computer. Approves proposals with one click.
- Claude.ai · MCP connector
- The same agent in the owner's Claude (web, desktop, phone). OAuth sign-in, owner accounts only.
- Customer · booking, shop
- A student or buyer: books classes, pays, follows their piece by QR code, gets e-mails.
- Pages · prerendered HTML
- Brand sites built to static HTML at deploy time; a product change in the panel rebuilds the site after 30 s.
- Tunnel · the only way in
- The APIs listen on localhost only. The tunnel is the only path in from the internet, and SSH works only over Tailscale.
- rhei-mcp · OAuth 2.1, PKCE
- The MCP server: client registration (CIMD/DCR), tokens stored as SHA-256, refresh-token rotation, 600 calls an hour. 14 tests and 16 live checks.
- Studio Rhei API · courses, kiln, pieces
- Courses with attendance and make-ups, firings, pieces with QR, gift cards, enquiries, e-mail. Plus Whisper for voice.
- Sway API · shop, gallery
- Shop and gallery of the artist brand: orders, shipping, refunds, a Google Merchant feed.
- Keramos · agent loop
- Context: a cached fixed part, a small snapshot of the studio's state and the latest messages. The agent pulls the rest with tools that resolve names to IDs. Step and cost limits.
- PostgreSQL · 2 databases, 72 tables
- A database per brand. Translatable content in JSONB. Alembic migrations run on deploy.
- jobs · timers, 5 min
- E-mail queue with retries, reminders, SEO, catalogues. Same code and database as the API, a separate process.
- Anthropic · Sonnet · Haiku
- Sonnet runs multi-step writes, Haiku checks photos (eval 24/24, about 2 cents a run) and smooths text for speech.
- Stripe · payments, refunds
- PaymentIntents and signed webhooks: payments, failures, refunds (including ones made in the Stripe dashboard) and disputes.
- Supabase Auth · e-mail code
- Authentication only (OTP or magic link). People and roles live in our database; tokens are verified via JWKS.
- ElevenLabs · agent voice
- Speech for answers, with a daily character limit. Past it, the browser's own voice takes over.
- Resend · Parcel2Go · e-mail, couriers
- Queued e-mail with retries; courier labels and tracking.
Decisions that make the difference
Every write is a proposal
The model has no direct write. The server executes after the click, through the same services and rules as the manual panel. Nothing is deleted: things are hidden or cancelled.
Recreate functions, not code
A closed SaaS can't be exported. First a 1:1 demo on a snapshot of the public API; the screens produced the contract, and only then the database schema.
Zero open ports
APIs bind to 127.0.0.1, traffic comes in through a tunnel, SSH only over Tailscale, secrets at 640. The architecture review is written up in the repo for a security audit.
Models matched to the job
Sonnet for multi-step writes (Haiku was too weak), Haiku for photos and speech. Each job has an eval and a known cost.
How it works
Studio, shop and agent in one system
A studio panel with twenty sections, the artist brand's shop, the student account and Keramos, which uses all of it. The descriptions come from the guide the owner received with the system.
Courses, attendance, firings, pieces with QR codes, money and people, with no outside SaaS.





An agent that reads both brands' data, asks when unsure and proposes a change on a card. Nothing happens until the owner approves.





A shop and gallery with its own panel: listing a piece from the phone, orders, couriers, Etsy and eBay.




An account with no password: bookings, make-up classes, card payment, firing their own piece and its status.





Data on the screens is fictional.
Stack
Service lines
Got a process that should run itself?
30 minutes, free. I'll tell you if it makes sense, how I'd build it and what it would cost to run.