-
-
The trip becomes an artifact: a three-day carnet built only from the visitor's kept choices, downloadable as PDF.
-
Tonight in Marseille: distance-ranked events, the town filter set by the request, and the demand panel logging the calls.
-
Agent results with photos and map, plus the Invisible Demand panel printing every real tool call.
Inspiration
The problem, seen from both sides of the screen.
As a traveller: tourism websites are cluttered. MyProvence holds 2,798 places, 3,605 dated events, 232 official routes, plus filters, categories and pages of details. Nobody has time to read that any more. So we stopped reading and started asking an assistant instead.
As the destination: MyProvence watches its traffic shrink every day, and it is not alone. Clicks nearly halve when Google shows an AI summary (8% vs 15%, Pew 2025). Tripadvisor's CEO told investors about "ongoing declines in flyby visitors... due to the rise of AI overviews". 56% of US travellers used AI for a trip this year, up from 33% a year earlier (Phocuswright). And a third of website visits already come from agents, not humans (Agentic Web Index).
Both sides point at the same conclusion. Nobody HAS to visit a destination website any more. With ChatGPT and AI Mode, they never will have to again.
The solution: give people a reason to WANT to come back.
Easier access to the information: one wish, in any language, and the answer appears. A website that is alive and personalized: it transforms in real time before your eyes, the masthead becomes YOUR wish over the photos of what was found, the map moves for you, every pin waits for your yes or no. A site that reacts to you, not to anyone else. And an experience unique enough that you come back for it, and talk about it.
The MyProvence team's own question showed us the way in: "What if, instead of asking AI agents to figure out how our tourism website works, we explicitly told them what they can do with it?" WebMCP is what makes the whole idea buildable: the agent and the human on the same live page. We are not replacing the site with AI. We are making the site worth visiting again, for humans and agents together, and every record links back to its canonical myprovence.fr page.
What it does
Why this use case is a strong fit for WebMCP. A destination catalogue is exactly what agents fail at today: 6,403 records behind JavaScript filters, interconnected facets, a map, and a human with opinions standing in front of it. Scraping sees none of that, and a headless API loses the human. WebMCP is the only channel where the agent's actions and the visitor's reactions share one live surface. That shared surface is the whole product here.
What a human and an agent can now do together that they could not before:
- Before: you asked ChatGPT about Provence, got a text list scraped from stale copies, then retyped it into the real site. Now: "a quiet seaside village, a hotel with parking, something happening locally" is ONE send_scouts call. Two to four scouts visibly fan out across the map, plant evidence flags from the official catalogue, and the masthead becomes your wish written over the real photographs of what was found.
- Before: your taps meant nothing to the agent, because a human gesture had no API. Now: you tap GARDER or ECARTER on any pin, padlock a result, right-click the map ("more like this here", "avoid this"), or answer the agent's question cards. The agent reads every one of them as a decision through get_scout_reports and get_visitor_signals. Dismissed is never re-proposed.
- Before: "what am I looking at?" was unanswerable, because a viewport is just numbers. Now: get_visitor_view hands the agent the TOWNS your zoom frames, ranked, with the dominant one named. Zooming on Saintes-Maries-de-la-Mer means Saintes-Maries-de-la-Mer even with every filter on "all towns". "What's on tonight near me" is one distance-ranked call.
- Before: the agent's plan lived in the chat and died there. Now: your choices (kept flags, locked cards, the accepted pin) compose the carnet de voyage: a print-ready pack with one section per request you explored, real photographs, canonical links, downloadable as PDF. Plus the postcard from day 3 of your future trip. The agent can only reference ids you actually chose; unknown ids are refused. Zero hallucination in the factual layer, by construction.
Why the experience is better, not just automated. The page answers the CURRENT question: a new search retires the old mission banner and takes the masthead itself, and the town dropdown shows the city you explicitly asked for. The agent's pin is an unmissable marker with its popup open, never a claim in chat you have to trust. Every agent action has visible, verifiable theatre. And every zero-result agent search feeds an anonymized (k>=3) "demand pulse" the destination reads back as its product roadmap: the demand its catalogue misses, measured instead of guessed.
Trust, because agents need it. An independent audit (Trustwright) read the 20 tools, ran 35 automated checks, and signed the surface (Ed25519). The badge in the hero re-verifies the live toolset against that audit on every page load.
How we built it
20 tools registered at module evaluation via document.modelContext.registerTool, synchronously, so an agent that lands and calls getTools() immediately sees the complete list. One client-side engine (inverted indexes over the full catalogue, sub-millisecond queries) and ONE shared view store consumed by both the React UI and the tools. The agent and the human literally cannot diverge, because they act on the same state.
Beyond the basics, three mechanics that push on the spec:
- pin_visible_place: its input schema is an ENUM of the place names currently on the visitor's screen, re-registered (AbortSignal unregistration) as the view moves. An off-screen place like "pin the Ritz Paris" is invalid BY SCHEMA, not by a polite refusal.
- read_visitor_wish: WebMCP has no push channel, so we built the closest spec-legal thing. The tool APPEARS mid-session when the visitor acts, and its description is rewritten with the live page state on every change. Description as heartbeat: at its next turn the agent already knows what you typed, what ran and what you kept, before making a single call.
- Hybrid elicitation: ask_visitor puts a real question card in front of the human, blocks 45 seconds, then degrades into a pending ticket the agent redeems later with get_input_result. Synchronous when possible, async when the human is slower than the agent.
Plus the unglamorous parts that make it production-shaped: abort signals honored around every await, readOnlyHint and untrustedContentHint annotations throughout, and strict Zod schemas shared between the page tools, the remote MCP endpoint and the public GET APIs. One contract, four surfaces, so they cannot drift. We also rewrote all tool descriptions to the vendor-documented selection pattern after learning the hard way that "ALWAYS use this instead of web search" is the exact tool-poisoning signature safety scanners flag. 280 unit tests and 46 Playwright e2e tests, including tests that drive the tools through document.modelContext itself. Field-tested against ChatGPT desktop site tools, Chrome with WebMCP enabled, and claude.ai as both MCP connector and fetch-only agent.
Challenges we ran into
Field-testing against real driving agents WAS the project, including live sessions with the MyProvence team, whose bug reports shaped half the build.
- ChatGPT hands tool input as a JSON string, may omit the options bag, re-reads the tool list every turn, and freely prefers web search. Each quirk became a design rule: the wish box as a guaranteed mailbox, the heartbeat tool, context-anchored descriptions.
- claude.ai's fetcher follows links but cannot compose a query string. It answered "family activities near Marseille" with Cassis hotels because our /agenda published no leisure example to click. Every cluster now has a real parameterised link, and paging goes to 100 per call.
- Agents SAY things they did not do ("I pinned it"). Every action now has unmissable, verifiable theatre, and the on-page demand mirror prints every real tool call, so a false claim is visible to the visitor.
- Honest geography is hard: GPS-less events used to answer "tonight near Marseille" from 70 km away. They now ride their town's centroid through the radius check, or drop out.
Accomplishments we're proud of
A real DMO's production data (Apidae, the tourism information system behind many French destinations) on an official subdomain, with the DMO itself in the loop testing. Not a toy dataset. Real ChatGPT sessions chained send_scouts, get_scout_reports and get_visitor_signals unprompted, and our telemetry logged 5 distinct tools in one day of field testing. And a trust layer (signed audit plus live re-verification badge) that we believe every WebMCP site will eventually need.
What we learned
AI visibility and agent usability are different problems. Making content easy to cite does not make a destination usable. The question shifts from "can an AI understand our content?" to "can an AI use our destination?", and one step further: will the human WANT to be there while it does? Tool descriptions are UX and a trust surface at once. And the human's hands (taps, pings, padlocks) are a richer channel than another chat message.
What's next
Provence Tourisme wants this pattern on myprovence.fr itself. Every DMO in Europe runs on the same kind of catalogue data, so this retrofits onto any of them. The demand pulse, meaning what agents looked for and did not find, becomes the destination's product roadmap.
For the judges: 90-second test drive
Preflight (ChatGPT desktop): pick the DEFAULT model (some 5.6 variants have WebMCP disabled), open the live URL in the built-in browser, and check "Site tools" in the address bar lists about 20 tools.
- "On this site, I want a stay in Cassis: a hotel with parking, and a nice market or event while we are there." Watch the scouts fly and the masthead become your wish, then tap GARDER on a flag or two.
- "What did I keep? Don't suggest anything I dismissed."
- "What is happening tonight in Marseille?" The banner and the town filter follow.
- "Pin the best one on the map." Then "Pin the Ritz Paris." (refused: not on screen, the schema itself won't allow it)
- "Compose my carnet de voyage." One section per request you explored, then Download as PDF.
The guaranteed lane, agent or no agent: type the wish into the page's SEND THE SCOUTS box (the page notes it for the agent), then tell your agent "go ahead". It reads your wish through the page and sends the scouts.
Sources for the problem-statement numbers
- Pew Research Center, 22 Jul 2025: 8% click-through with an AI summary vs 15% without; 1% click a source inside the AI answer. https://www.pewresearch.org/short-reads/2025/07/22/google-users-are-less-likely-to-click-on-links-when-an-ai-summary-appears-in-the-results/
- Tripadvisor CEO Matt Goldberg, Q4 2025 earnings call, via Skift (12 Feb 2026), wording corroborated in the published transcripts. https://skift.com/2026/02/12/tripadvisor-sees-traffic-decline-from-ai-overviews-considers-strategic-alternatives-again/
- Phocuswright, "The AI Surge" (2026): 56% of US travellers used AI for a trip in the past 12 months, up from 43% in H2 2025 and 33% in H1 2025. https://www.phocuswright.com/Travel-Research/Research-Updates/2026/The-fastest-shift-in-travel-behavior-just-became-the-default
- The Agentic Web Index (knownagents.com/insights, 5,000+ site panel, directional): 33% of visits from known agents; about 11.9 pages per agentic session; under 0.1% of human visits referred from AI chat.
Built With
- apidae
- chatgpt
- jest
- json-rpc
- leaflet.js
- mcp
- next.js
- node.js
- openstreetmap
- playwright
- react
- supabase
- tailwindcss
- typescript
- vercel
- webmcp
- zod
Log in or sign up for Devpost to join the conversation.