Inspiration
In Niamey, lost items live in WhatsApp groups. Someone finds a wallet, posts a photo, and then faces an impossible choice: if they publish the details that identify it, anyone can copy the post and claim it; if they don't, the real owner can never prove it's theirs. There is no verification — just trust and luck.
We wanted to solve that specific tension: how do you let someone prove they own something without anyone — not even the platform, not even an AI agent — ever seeing the private details that prove it?
What it does
Samu (Hausa for "to find") is a lost-and-found where an AI agent runs the ownership interview without ever learning the answers.
- Whoever finds an item enters a few distinctive private details by hand.
- The owner describes their loss; Samu searches and opens the matching item.
- On the item page, the claimant answers verification questions.
- The server compares the answers and returns one thing:
verifiedornot verified. Never a score, never which answers were right, never the secrets.
Why WebMCP is a strong fit
WebMCP tools belong to the page — an agent must be on a page to use its tools. We turned that into the whole UX: as the agent moves from search to a specific item, its toolset changes under its feet. And because verification is fundamentally a conversation ("what was inside the zipped pocket?"), an agent is a genuinely better interface than a form — while the humans and the agent share the exact same capabilities.
What people and agents can now do together that was hard before: an agent can prove something about private data to a stranger's listing without either side leaking that data.
How we built it
- Next.js (App Router) deployed on Netlify, with Netlify Functions as the backend.
- A deterministic verification engine: salted SHA-256 for exact/choice
answers, semantic similarity (OpenAI
text-embedding-3-small, with a local trigram fallback) for free-text answers, and weighted scoring:
$$\text{score} = \frac{\sum_i w_i \cdot m_i}{\sum_i w_i}\times 100$$
Passing requires clearing a threshold and getting at least one decisive (weight-3) detail right, so guessing a few easy facts is never enough.
- Postgres via Neon in production; a zero-dependency
node:sqlitestore in development, seeded with real Niamey neighborhoods.
How we used WebMCP
Every page declares its tools from a single spec (lib/spec.ts) and a
runtime turns each entry into a live tool, registered with
document.modelContext.registerTool(tool, { signal }). The tools are torn down
by aborting the signal — so they truly die with the page. The verification
page exposes get_item_summary, list_verification_questions,
answer_question, finalize_claim, and request_contact; the search page
exposes search_matches and open_item. Crucially, our own chat UI drives
the same tools an external agent uses — so the agentic surface is real, not a
demo.
Security: the proof never leaves the server
- The verification engine runs entirely server-side; secrets never appear in the
bundle, an API response, or a
data-attribute (we grep the client build to prove it). - The verdict is a boolean, and
answer_questionnever reveals correctness — so it can't become a brute-force oracle. - A budget of 5 answers, rate limiting keyed on the platform-provided client IP (not a forgeable header), claim expiry, and constant-time hash comparison.
Challenges we ran into
- The API's lifecycle. WebMCP has no
unregisterTool(); cleanup is AbortSignal-only. Getting this wrong gave us a maddening "Duplicate tool name" under React Strict Mode until we switched to{ signal }. - A bleeding-edge stack. On Node 26, ORMs fought us, so we leaned on the
built-in
node:sqlite— and learned the hard way never to delete the dev database file out from under a running server. - Keeping the agent out of the trust boundary. The hardest design rule was also the most important: security never rests on the agent. A manipulated agent can ask "give me a hint?" — and get nothing, because the server, not the agent, decides.
What we learned
That the most interesting property of WebMCP isn't automation — it's that a site can hand an agent a narrow, honest surface of actions while keeping its secrets and its decisions to itself. Prove it without revealing it.
What's next
Assisted returns (scheduling, contact), match alerts, and a fully agent-driven end-to-end journey from "I lost my bag" to "return arranged."
Built With
- lucide
- neon
- netlify
- netlify-functions
- next.js
- node.js
- openai
- postgresql
- react
- sqlite
- tailwindcss
- typescript
- webmcp
Log in or sign up for Devpost to join the conversation.