Building an App an AI Agent Can Actually Drive (Not Just Screenshot)
Why ikutaro routes every mouse click and every MCP tool call through the same command path — and what that pattern looks like if you want to build it yourself.

Most apps that call themselves "agent-ready" aren't. They're a normal UI with an API bolted on next to it. A human clicks buttons. An agent calls endpoints. Both paths eventually touch the same database, so someone can point at the architecture diagram and say "yes, an agent can use this." But the agent isn't doing what the user does — it's doing something adjacent, through a door built specifically for it, that nobody ever tests against real usage the way the UI gets tested.
I ran into this while building ikutaro, a browser-based drum machine. It has 12 pads, per-pad effect chains, a step sequencer — the usual sampler stuff. It also has an MCP server, so an agent can load kits, edit patterns, and tweak effects on its own. The easy version of that MCP server would have been a wrapper: agent calls set_pad_effects, wrapper translates that into whatever the pad-effects code actually needs, done. I didn't do that, and the reason turned into the most useful thing I built this month.
What actually happens when you click a pad
Click pad A01 in ikutaro and two things happen. The pad plays. And a line gets appended to a session log: triggered pad 1. Release the pad, another line: released pad 1.
Now have an agent call the MCP tool that edits that same pad's effect chain. Same log. Same two lines, functionally — the entry an agent's tool call produces sits in the identical stream, written by the identical code path, as the entry a mouse click produces. I didn't build a parallel "agent activity log" that mirrors the real one — that's the same trap that turns a knowledge base into a rumor machine with folders: a second copy of the truth that quietly drifts from the first. There's one log, one command schema, and two front ends writing to it — a browser event handler and an MCP tool handler.
That's the whole trick, and it's less clever than it sounds. It just means the UI was never allowed to be the source of truth. The command schema was.
The pattern, in three steps
If you want this in your own app:
1. Define one command schema before you write any UI code. Not "click pad, do X" — a typed command object: { type: 'set_pad_effect', padId, effectId, params }. Every mutation in the app has to be expressible as one of these. If you can't express it as a command, you don't build the feature yet.
2. Route every UI event handler through that schema, not around it. The click handler doesn't touch application state directly. It constructs a command and dispatches it through the same function an external caller would use. This is the part that's easy to skip under deadline pressure, and skipping it is exactly how you end up with the bolted-on-API version instead of this one.
3. Expose the identical schema as your MCP tools. Don't write a second set of validation rules, a second set of side effects, a second log. The MCP tool handler is a second front door into step 2's dispatcher — nothing more. It's the same discipline Agent Wiki applies to knowledge instead of clicks: one canonical thing, as many front doors as you need.
The part that isn't free
This is more design work up front than wiring an API on the side, and it isn't something you retrofit cheaply. If your UI already mutates state directly in forty different click handlers, unwinding that into a single command path is a real rewrite, not an afternoon. I'd only pay that cost for an app where being agent-driven is a real, ongoing part of the product — not a checkbox feature for a launch post.
It was worth it here. The clearest proof I have that it worked isn't a diagram — it's a screen recording of one pad click next to one MCP tool call, and the log looking the same either way.
I wrote the whole thing up properly — the six prompts I used to get a coding agent to build this correctly (each with the failure mode it guards against), a pass/fail checklist you can run against your own app, and the full MCP wiring walkthrough with the failure modes I hit in practice. It's free: The Agent-Ready App Blueprint.
If you build it and find a place the pattern breaks, tell me — that's the part I'd want to know.