Your agents ship. You stay in the loop.
How it works
See it, say it, ship it, sign off.
- 01
Record
Narrate the bug in the app where it happens. Draw on the page. Record it again if you fluff it — every take lands end to end on one timeline you can trim, reorder and re-word before anyone sees it.
0:000:301:001:34take 20:19and nothing. No error, no discount, the total is still…
one timeline · 2 takes · drag across the seam - 02
Route
Gripes land in one inbox and file themselves to the right project by the site they were recorded on. Nobody triages a queue of untitled screen recordings.
- open2m
Promo code applies to nothing at checkout
shop.northwind.test
- in review1h
Order confirmation email never arrives
shop.northwind.test
- resolvedTue
Admin search returns deleted customers
admin.northwind.test
/app · auto-filed by recorded origin - open
- 03
Fix
Your coding agent pulls the brief over MCP — sheets, transcript, the errors that fired while you were talking — and opens the fix against it.
▸ list_gripes() → 3 open
▸ get_gripe("promo-code-checkout")
← report.md · 5 sheets · 41 frames · transcript · 3 errors
▸ set_gripe_status("in_review")
claude code · inloop mcp server - 04
Sign off
The reviewer puts the frame you complained about next to the same screen on the fixed build. It either changed or it didn’t.
SIGNED OFF0:22 · what you recorded build #418 · the same screen
The hard part
Video is the worst thing you can hand a model.
Ninety seconds of screen capture is thousands of pictures of almost the same thing. Inloop throws away the frames that say nothing, keeps the ones that do — and it decides while you’re still recording.
What you recorded
1:34 of screen capture · ~2,800 frames · almost all of them identical
The 41 frames that say something
Each one carries the position it was taken at, why it survived, and the pointer drawn into the picture — so a still is never a still with the subject missing.
0:04
moved
0:08
clicked
0:11
typed
0:14
clicked
0:15
moved
0:17
moved
0:19
moved
0:22
marked
0:31
clicked
- Compared against every frame it already kept
- Not just the one before it. A page that drifts a little at a time can’t slip through as “nothing changed” — the oldest thing still on screen is still being watched.
- Your clicks and keystrokes force a frame
- The instant you act is never an instant it threw away, even when the screen barely moved. A tooltip, a focus ring, a field that silently rejects you — all kept.
- Survivors are spread across the whole take
- A busy first minute doesn’t get to eat the budget. What’s kept stays even across the recording, so the end is covered as well as the opening.
Nine to an image, in order
A model reading consecutive frames side by side follows what happened. The same frames handed over one at a time, it doesn’t.
So the report leads with the sheets and the flow comes after. The first coding agent to read a real bundle called these the highest-value thing in it — and they cost a fraction of the tokens the same frames would have burned separately.
The full-size stills are still there. The report inlines one only where the narration is pointing at something, and names the rest by filename so an agent can open exactly the one it wants.
41 keyframes → 5 sheets → 9 tiles per image
One gripe
Everything you’d have had to write down.
You talked for ninety seconds. This is what came out of it — collected while you were speaking, so there was nothing to remember to do afterwards.
Everything you said
Timestamped, editable, and tied to the frames it’s about — people narrate what just happened, so each line knows the moment it’s describing.
- 0:06
Okay, so this is the checkout — I'm on the cart with three items.
- 0:11
I paste in SAVE20, which is the code we emailed out this morning.
- 0:14
Hit apply…about 0:14–0:17
- 0:19
and nothing. No error, no discount, the total is still a hundred and twenty-eight.about 0:17–0:22
- 0:24
It doesn't tell you it failed, which is the part that's killing us — people just assume it worked and bail at the total.
- 0:31
Second try, same thing. Watch the total.about 0:31–0:38
The moment you pointed at
Draw on the page mid-sentence. The stroke is captured into the recording, so “this number, right here” survives the trip to a model.
What broke underneath
The console and network failures that fired while you were talking. You didn’t open devtools; you didn’t know to.
- 0:15network
POST /api/coupons/apply → 500 (118 ms) - 0:15console
TypeError: Cannot read properties of null (reading 'id') - 0:31network
POST /api/coupons/apply → 500 (104 ms)
The recording itself
The one thing in the bundle that’s for you rather than the agent — for when a reviewer wants to watch it happen.
Promo code applies to nothing at checkout
2026-07-29-1215-promo-code-checkout · pushed as one unit, replaced wholesale if you record it again
The handoff
What your agent actually gets.
Not a link to a video. Not a ticket with a screenshot stapled to it. One tool call, and the whole ninety seconds arrives as something it can read.
▸ get_gripe("promo-code-checkout")
- ← report.md
- ← 5 contact sheets
- ← 41 keyframes, pointer drawn in
- ← transcript.txt · 24 lines
- ← recording.json · frames, events, windows
- ← walkthrough.webm · 1:34
▸ reading sheets 1–5…
Three tools
- list_gripes
- what’s open, and for which project
- get_gripe
- the brief, plus a signed link to every file in it
- set_gripe_status
- hand it back for review when the fix is up
Wired in once, from any repo:
$ claude mcp add inloop --env INLOOP_TOKEN=ilp_… -- bun cli/mcp.tsGripe — Promo code applies to nothing at checkout
walkthrough 1:3441 keyframes24 spoken lines1 marked3 errors capturedrecorded 29 Jul 2026 12:15–12:17 · shop.northwind.test
You are reading a gripe — a bug report recorded by a human using the running app. Everything below sits on one timeline, in the order it happened. Read the images: they are the primary evidence, and the words are shorthand that assumes you looked.
Contact sheets — read these first
41 keyframes across 5 sheets, nine per image, in order, each tile labeled with its filename.
0:14 — "Hit apply…"
POST /api/coupons/apply → 500 · 0:15
TypeError: Cannot read properties of null (reading 'id') · 0:15
01-0017.jpg · 01-0019.jpg · 01-0022.jpg
"and nothing. No error, no discount, the total is still a hundred and twenty-eight." — 0:19, about 0:17–0:22
Pricing