Why this use case is a strong fit for WebMCP

Seating a room is a two-brain problem.

One brain holds context no form can capture: who is divorced, which sponsor is feuding with whom, which aunt needs to sit near the exit. The other has to satisfy a combinatorial pile of constraints: table capacities, conflicts, introductions, dietary needs, accessibility, company-mixing rules, and table balance.

Humans are great at the first and bad at the second. Agents are the opposite.

Before WebMCP, neither interface worked well. A drag-and-drop floor plan is a terrible surface for an agent to operate through pixels, while moving the task into chat throws away the human's spatial judgment.

Duet lets both work on the same live state, in the same tab: the human drags, pins, and visually evaluates the room while the agent uses structured tools such as seat_guest, add_constraint, set_group_rule, and a real constraint solver.

How it creates a better user experience

Duet gives human-agent collaboration an explicit contract, enforced in code.

Pins are law. Any guest placed manually is pinned 📌. The solver plans around those decisions, and agent tools are refused if they attempt to move or remove a pinned guest.

Agents propose; humans decide. The preferred agent tool, propose_arrangement, does not mutate the room. It displays the reasoning and complete move list first. Only the human can Accept or Dismiss it.

The tool surface follows human attention. Selecting a table dynamically exposes table-scoped tools such as seat_at_selected_table and clear_selected_table. Deselecting it removes them. The agent's available capabilities therefore reflect what the human is currently focused on.

Everything is visible and reversible. Agent actions appear as a violet cursor on the board, every action enters a shared activity feed labeled ✳ agent or ● you, and undo/redo works across both human and agent actions.

What becomes possible — together — that wasn't before

Load a 120-guest fundraising gala.

The human manually places two important guests, pinning them in place. The agent records "press away from the board", applies "maximum two people from the same company per table", and proposes a complete arrangement for the remaining 118 guests.

The solver honors every constraint without touching the human's pins. The human reviews the proposal visually and accepts it in one click.

Create a conflict deliberately and Duet pans to the affected table, identifies who conflicts and why, and lets the agent call explain_seating to justify individual placements.

Then ask: "Give me the caterer's brief." The agent calls export_plan and returns dietary counts by table.

That loop — human judgment steering an agent and a constraint solver through conversation, directly on a shared visual surface — is what WebMCP makes possible.

The same engine includes five scenarios: wedding, fundraising gala, corporate networking dinner, office seating, and classroom seating.

How we implemented WebMCP

Duet exposes 21 base tools through document.modelContext.registerTool, covering:

  • guest and table CRUD
  • pair constraints with notes
  • group spread and cluster rules
  • solver execution
  • arrangement proposals
  • pins
  • dietary reports
  • Markdown export
  • template loading
  • undo
  • explain_seating
  • get_activity_log, allowing a returning agent to understand what the human changed while it was away

It also exposes 4 dynamic selection-scoped tools registered and removed with AbortController as the user's selection changes. The WebMCP tool surface itself therefore mirrors the human's current focus.

Tool results return structured JSON, including the conflicts an action would create, so agents can reason about consequences before modifying state.

Guardrails are enforced at the tool layer: pinned guests cannot be moved by agents, and propose_arrangement is explicitly presented as the preferred workflow so agents default to human review rather than silent mutation.

The constraint solver is dependency-free and combines greedy assignment, local search, targeted repair, and three-way relocation. A 120-guest room solves in roughly 75 ms while respecting pins, pair constraints, group rules, accessibility requirements, and table balance.

Duet is built with React, Vite, and TypeScript and has no backend. The entire collaborative state lives in the browser tab — exactly where WebMCP operates.

Built With

Share this project:

Updates

Submission history