Inspiration
“I thought you were taking Mum.”
That sentence captures the problem behind Handshake. When relatives and carers coordinate across different locations, asking someone to help can easily be mistaken for confirming that they will.
A message can be delivered without being accepted. A calendar can show someone as free without knowing whether they are willing to take responsibility.
Handshake began with a simple rule: a request is not a handoff.
What it does
Handshake is a simulated Alexa+ experience that helps families and carers transfer practical responsibilities, starting with appointment transport for an older adult.
Maya owns the task. When her plans change, the coordinator checks another person’s availability and sends a request. Maya remains the recorded owner until the recipient explicitly accepts and the transfer passes validation.
If Arun declines, Handshake can check Elena, a visiting carer. Automatic fallback requires the organizer’s permission; otherwise, the organizer chooses when to approach the next candidate. If nobody accepts, the task stays with its current owner and the application clearly records that another arrangement is needed.
The prototype makes three things visible throughout: who owns the task, who has been asked, and whether they have actually agreed.
Why is it worth checking out?
Availability without opening everyone’s calendar
Each participant has a personal MCP endpoint backed by a separate SQLite store. The coordinator asks a scoped question about a specific time window and receives availability and relevant conditions. Private event titles stay out of those availability responses. The coordinator can learn that someone cannot cover a task without needing to know what their conflicting commitment is. The Privacy Wall inspector shows the actual permitted information exchanged during coordination.
Acceptance that can be checked
An explicit recipient approval produces an Ed25519 receipt bound to the request, task version, recipient, original owner, expiry, and decision. The coordinator checks the receipt against the participant’s pinned public key before recording the transfer. The interface lets viewers verify a receipt and alter a copy to see signature verification fail. This provides a verifiable record of the application’s acceptance event. It does not claim to establish legal responsibility or independently verify a person’s identity.
A workflow built for changed plans
The most revealing demonstration is a failed transfer. If a recipient signs while available but becomes unavailable before finalization, the coordinator’s shared validation path rechecks availability and blocks the transfer. The original owner remains recorded. Expired requests, duplicate acceptance, stale browser responses, and altered receipts are also handled explicitly. Candidates who have already declined are not repeatedly contacted in the same handoff cycle.
How we built it
Handshake uses JavaScript, Node.js, Express, native SQLite, and the official MCP JavaScript SDK.
Three personal endpoints communicate with the coordinator through MCP Streamable HTTP, negotiating protocol version 2025-11-25. A separate browser SSE channel keeps connected views updated.
The coordinator database is the single source of truth for task ownership. SQLite transactions update ownership and request resolution together. Personal stores hold synthetic calendars, proposals, and signing material.
The current local prototype runs these endpoint instances within one Node process. Its conversational interface uses a clearly labeled deterministic intent router, while the MCP calls, scheduling checks, signatures, and state transitions are real.
Challenges we ran into
One important challenge was putting validation in the right place. A check performed only by a browser route could be bypassed by another coordinator caller. Moving the availability recheck into finalization made it part of the shared acceptance path.
Another was persistence. Early startup seeding reset the demo every time the server restarted. The corrected application seeds empty state and preserves accepted ownership, history, and keys across normal restarts.
Fallback also needed a clear stopping rule. Tracking attempted candidates prevents a refusal from creating an endless cycle of requests.
Accomplishments that we're proud of
The corrected build passes 37 automated tests, covering real MCP interactions, ownership retention, signature verification, expiry, replay protection, bounded fallback, restart persistence, and post-signing availability changes.
Browser verification exercised proposal, decline, fallback, acceptance, receipt verification, tamper rejection, refresh, and updates across two windows.
What we learned
What's next for Handshake
Next steps include a flexible LLM conversation layer, stronger identity and session management, richer travel constraints, and integrations with existing calendars and notification channels.
The principle will stay the same: help people coordinate while keeping the final acceptance in their hands.
Built With
- css3
- express.js
- html5
- javascript
- mcp
- node.js
- sqlite
- sse
- tailwind
Log in or sign up for Devpost to join the conversation.