Inspiration

Splitting a restaurant bill is a nightmare.

Five friends can sit around one table with different diets, different arrival times, shared dishes, tax, tip, and a receipt nobody can quite remember. The app can give you checkboxes for all of it, but eventually someone is doing mental bookkeeping at 11 PM just to answer a simple question: who actually owes what?

And when the perfect split is too much work, people take the easy way out: split it evenly.

Tabby started from a simple idea: what if you could tell the app what happened in the same way you'd tell a friend?

That's where WebMCP became interesting. Instead of building another chat interface around an expense database, we wanted an agent that could actually work inside the expense app, alongside the person using it.


What it does

Tabby is a complete shared expense app: groups, receipts, itemised bills, multiple currencies, balances, settle-up, and an audit trail.

You can use it entirely with a mouse. Nothing about the app requires an agent.

When an agent is present, WebMCP lets it work with the same interface and the same live state.

Give it a receipt. Tell it that Ravi is vegetarian, Meera arrived late, or that someone remembered something after the split. The agent can reason about those facts, propose changes, and navigate the page to show you what it means.

The model handles perception and reasoning. The page handles the money.

This division is deliberate. A model is good at understanding a messy receipt or a sentence like "Ravi didn't eat the prawns." The application is better at calculating exactly how much everyone owes. Tabby never asks the model to calculate a per-person monetary amount.

Most importantly, the agent never silently takes control. Changes that matter are staged as proposals with a visible diff and require the human to accept them.


Why WebMCP is the right primitive

We could have built an agent directly into Tabby. But that would make the agent another feature of Tabby, tied to our UI, backend, and product architecture.

WebMCP lets us do something more powerful: Tabby remains a normal expense app, while any compatible agent can become a participant in it.

The same Tabby interface can be used normally by a person, or augmented by an agent when the task benefits from it. The agent gets access to Tabby's existing capabilities and live state without requiring a separate agent-specific workflow.

This also means the human stays in control. The agent can reason, propose, and act through the application's existing operations, while Tabby remains responsible for state, validation, and money.

WebMCP turns an existing web application into something an agent can participate in, rather than requiring every application to build its own agent.


How we built it

The central architectural decision was simple:

There is one app, one state, and one set of operations.

A button in the UI and a WebMCP tool call the same underlying store action. There is no separate agent backend and no special code path built only for AI.

WebMCP exposes those existing operations to an agent.

We deliberately split responsibilities:

  • The model perceives and reasons. It can read a receipt photo, understand natural-language constraints, and reason about who ate what.
  • The page computes. Tabby performs every allocation deterministically using integer minor units and largest-remainder arithmetic.
  • The human decides. Every consequential write becomes a proposal with a visible diff before anything is committed.

This means assign_items can say who ate which items, but it cannot tell Tabby how many rupees each person owes. The page calculates that.

The same principle extends to settlement. Tabby computes the minimum-transfer plan rather than asking a language model to do the arithmetic.

WebMCP tools are registered through document.modelContext.registerTool(), with a navigator.modelContext fallback for client compatibility. Registration is also tied to application state, so the page only exposes tools that are actually usable at that moment.

For consequential actions, Tabby uses a propose → diff → accept flow. The commit operation can wait for a human to confirm in an in-page sheet. The agent cannot bypass that interaction.


What became possible

For humans, Tabby replaces tedious checkbox-by-checkbox bookkeeping with natural collaboration.

You can say:

"Ravi's vegetarian and doesn't drink. Meera arrived after the starters. Split tax and service based on what people actually ate."

The agent can turn that context into a proposed item-level split. If the user remembers something later, they can simply edit the bill directly and ask the agent to incorporate the correction.

For agents, Tabby provides something more useful than a database API: a live application they can reason about.

The agent can read receipts, inspect expenses and balances, navigate to the relevant part of the page, propose changes, see human edits, and amend its own pending proposal.

This creates a workflow that was difficult to achieve before:

The human provides judgment and memory. The agent handles context and reasoning. The application handles state and computation.


Challenges we ran into

The hardest part wasn't registering tools. It was deciding what an agent should be allowed to do.

Money is a particularly unforgiving domain. A language model can be excellent at understanding "Ravi didn't eat the prawns" and still be the wrong component to calculate 17% of a ₹4,381.27 bill.

So we designed the tool surface around that distinction.

We also had to make the WebMCP surface reflect the actual state of the application. Tools appear and disappear as capabilities become available. A receipt-reading tool shouldn't exist when there is no receipt to read. A commit operation shouldn't exist when there is no draft to commit.

We also had to handle the reality of an evolving WebMCP implementation. Clients currently differ in API support, iframe discovery, and image content handling, so Tabby uses feature detection and keeps its registration at the top level.


Accomplishments we're proud of

We built a real expense application, not an agent demo wearing an expense-app costume.

Every feature works without an agent.

We made the agent share the application's state rather than mirror it.

Human edits are immediately part of what the agent can reason about.

We made arithmetic impossible for the model to get wrong.

Money is represented as integer minor units throughout the system. Largest-remainder allocation guarantees that every split sums exactly to the original amount.

We made human approval a system property, not a prompt instruction.

Consequential operations follow a propose → diff → accept flow. The agent cannot simply decide to move money.

We tested the actual WebMCP boundary.

61 unit tests cover money, splitting, settlement, and parsing. 73 Playwright tests exercise the WebMCP surface, including dynamic registration, human cancellation, two-browser collaboration, hand edits beneath open drafts, amendment chains, and malformed input.


What we learned

The interesting question isn't:

"What can an agent do?"

It's:

"What should the agent do, and what should the application do?"

WebMCP made that boundary surprisingly clear.

Models are good at ambiguity, context, perception, and language.

Applications are good at state, arithmetic, validation, permissions, and consequences.

The best experience isn't necessarily an agent replacing the interface. In many cases, it's an agent that can join the interface without taking it away from you.


What's next for Tabby

The next step is making that collaboration more configurable.

We want per-group agent permissions, so you could let an agent read your ledger without giving it permission to propose changes.

We want receipt processing that explicitly surfaces uncertainty instead of guessing when a line cannot be read.

And we want to extend the same model beyond expense splitting. Wherever an application already has a rich interface but the task contains too much context for a human to manage comfortably, an agent should be able to join the workflow without becoming the owner of it.

Tabby started with a restaurant bill. The bigger idea is giving agents a place inside the interfaces people already use.

Built With

Share this project:

Updates

Submission history