Handoff
A Kanban board where you and your AI agent manage the same tasks, in real time, on the same live page.
Inspiration
Every "agent + your app" story today follows the same pattern: the agent takes a screenshot, guesses which pixel is a button, clicks it, waits, screenshots again. It's slow, it's fragile, and it treats the agent like a human with a mouse instead of software that could just... call a function.
Task management felt like the clearest place to make that contrast obvious. A Kanban board is something people already share with teammates why not share it with an agent too, and let both act on the same live state at the same time?
What it does
Handoff is a collaborative Kanban board. A human drags cards between To Do, In Progress, and Done exactly like any other Kanban tool. An AI agent manages the same board through seven WebMCP tools registered directly on the page:
create_task,list_tasks,move_task,update_task,delete_taskthe core actions any task manager needsprioritize_tasksapplies a batch of priority changes the agent has already reasoned about (vialist_tasks), atomically, in one callsummarize_boarda natural-language rollup of what's open, in progress, and done
Both the human and the agent are working against the exact same Supabase-backed state, synced live over Supabase Realtime. When the agent creates or moves a card, it shows an "agent" badge and a brief highlight pulse, so at a glance you can see who did what. A live activity log underneath the board narrates the handoff as it happens: "You moved 'Fix login bug' to In Progress," "Agent created 'Update docs.'"
There's no chat window bolted onto the side. The agent works through the same UI you're looking at.
Why WebMCP fits this use case
Without WebMCP, an agent that wants to help manage your board has exactly two bad options: a bespoke backend API it has to be specifically integrated with, or screen-scraping a drag-and-drop UI that was never designed to be driven programmatically, inferring which <div> is a card, simulating a drag gesture, and hoping the DOM didn't change underneath it.
WebMCP replaces both of those with the page just telling the agent what it can do. document.modelContext.registerTool() exposes move_task with a typed schema (id, status) instead of forcing an agent to identify and drag a specific card. The agent doesn't need a separate integration, and it doesn't need to understand your UI, it needs to understand your tools, which you've defined precisely.
That's the UX improvement in one sentence: an agent can now say "reprioritize my sprint so the login bug is high priority" and it works, live, immediately reflected in the same board a human is looking at, without OpenAI, Anthropic, or anyone else needing to have built a Handoff-specific integration ahead of time. The website itself is the integration.
What's newly possible
Before WebMCP, "human and agent share a task board" basically meant the agent had its own separate interface (a chat window, a CLI) that happened to write to the same database, two disconnected experiences bolted together. WebMCP lets both parties act through the same page, the same session, the same state, at the same time. You can watch a card move because you dragged it, or because you asked an agent to move it, and the board doesn't care which, it just reacts. That's a genuinely different interaction model, not just a faster version of the old one.
How we built it
- Next.js / React, deployed on Vercel
- Supabase (Postgres + Realtime) for shared task storage; every client (human tab or agent-driven tab) subscribes to the same Realtime channel, so changes from either side propagate instantly
- WebMCP, implemented via direct
document.modelContext.registerTool()calls (seehooks/useWebMCPTools.js) each tool'sexecutefunction calls the exact same functions the drag-and-drop UI calls (hooks/useTasks.js), so there is one source of truth for board logic, not a parallel "agent path" that could drift out of sync with the human path - @hello-pangea/dnd for the human-facing drag-and-drop
- The activity log is derived from the same Realtime subscription that drives the board, no separate logging table, just an in-memory feed of what the subscription already sees
Challenges we ran into
WebMCP is genuinely early. I hit a real interoperability bug where a React wrapper library's handler callback wasn't being translated into the native execute property the browser's registerTool() implementation expects, which surfaced as execute is not a function only at call time, not at registration time, which made it harder to catch. We moved to calling the native imperative API directly rather than depending on a wrapper layer, which fixed it and also made the WebMCP usage more explicit in the codebase.
Accomplishments
A full round trip, human drags a card, agent calls a tool, board updates live for both working end to end, verified both through direct browser console calls to document.modelContext.executeTool() and through a real natural-language agent (Google's Model Context Tool Inspector) discovering and calling our tools correctly.
What's next
Multi-board support, authenticated multi-user boards, and finer-grained permissions per tool (e.g., a read-only list_tasks-only agent versus a full-access one)
Built with
Next.js, React, Supabase, Supabase Realtime, WebMCP (document.modelContext.registerTool), @hello-pangea/dnd, Vercel
Built With
- nextjs
- supabase
- supabaserealtime
- webmcp
Log in or sign up for Devpost to join the conversation.