CoMapper
Make maps multiplayer.
CoMapper is a WebMCP reference implementation for shared spatial work. Users and agents explore, filter, inspect, style, and export the same live map state.
Inspiration
Maps shape our world. We use them to navigate, predict, plan, and understand the world around us.
And yet, as the old saying goes:
Tabula non est terra. (The map is not the territory.)
For millennia, we've built tools for working with maps: the compass, sextant, surveying instruments, satellite imagery, GIS, spatial databases.
Now agents can use those same tools.
CoMapper asks: what happens when humans and agents collaborate on cartography?
What it does
CoMapper turns attributed GeoJSON into a shared spatial workspace. It validates mixed geometry, infers useful fields and controls, creates stable feature identifiers, and keeps the map, results, inspector, filters, and selection synchronized.
Its WebMCP tools reflect the current page state. Dataset discovery and workspace inspection are always useful. Result-level actions appear once a search produces visible features. Styling and filtering accept fields declared by the active dataset. Feature actions accept visible result IDs.
Agents can search, inspect, select, filter, style, and prepare CSV or GeoJSON exports. Their actions resolve into the same interface users are viewing. Prepared downloads appear as explicit controls in the workspace.
Demo Scenario
For the challenge demo, CoMapper includes a Toronto dataset with 269 features: 158 neighbourhoods, 86 technology-company locations, and 25 mobility, talent, and ecosystem anchors.
The scenario gives the collaboration loop a focused question: build a shortlist for a potential OpenAI office. The first pass surfaces a density-led set of candidates. Users broaden the search beyond downtown, ask for a shorter list, inspect the evidence, and request an export. Each prompt continues from the state already visible on the map.

The Toronto question is one worked example. The same interaction model applies wherever location, evidence, and human judgment meet: logistics, infrastructure, field operations, urban planning, environmental analysis, site selection, and emergency response.
The demo also surfaces the limits of its evidence. A real property decision would require current rents, vacancy, floorplates, zoning, incentives, employee origins, and travel-time analysis.
Why WebMCP
WebMCP lets the application expose the context it already understands. CoMapper registers page-bound tools with document.modelContext.registerTool(...) and refreshes the available surface as the workspace changes.
Each tool calls the same React action used by the interface. A search updates the result ledger and map. A selection opens the inspector. A filter changes the visible evidence. A prepared export reveals a download control. Users and agents remain synchronized around one state model.
CoMapper demonstrates four reusable principles:
- Page state determines capability. Tools appear when their inputs and effects are valid.
- The interface remains authoritative. Tool actions resolve into visible application state.
- Schemas enforce scope. Fields, result IDs, limits, and spatial frames are validated.
- Users retain control. Evidence gaps stay visible and downloads require an explicit action.
Stack
CoMapper uses React, TypeScript, Vite, MapLibre GL JS, Zod, Cloudflare Workers, and the OpenAI Sites Vite plugin.
The browser-side data pipeline accepts GeoJSON, validates its geometry, infers fields and controls, creates stable feature IDs, and normalizes the dataset into a shared search response. The bundled Toronto atlas follows the same path as an imported local dataset. The map, result ledger, inspector, and WebMCP tools all consume that response.
The tool layer uses narrow JSON Schemas with Zod validation. Searches accept one spatial frame: radius, visible bounds, or a drawn polygon. Feature actions are limited to visible result IDs. Styling and filtering use fields declared by the active dataset. Connected text carries an untrusted-content hint.
Tool registration follows page state and uses an AbortController for cleanup. Search calls receive the invocation cancellation signal. Tool results return updated visible state and provenance for the next step.
The public demo runs entirely in the browser with its bundled fixture. Evaluation requires no account, database, API key, or paid model call.
Challenges
Three details shaped the implementation.
First, tool state had to match page state. Result-specific tools need current rows, fields, and IDs, so registration changes as users move through the application.
Second, spatial datasets mix geometry types and overlapping evidence. CoMapper keeps points and polygons legible together, gives points click priority where geometries overlap, and preserves the camera while layer state changes.
Third, every agent action needed a visible and trustworthy boundary. Search limits, field allowlists, visible-ID checks, provenance, cancellation, and user-controlled download reinforce the same interaction model.
Accomplishments
- Users and agents work with the same live application state.
- Tools adapt to the active dataset and current results.
- Follow-up prompts revise the evidence within the active workflow.
- Imported GeoJSON and the bundled fixture share one data pipeline.
- Inspection keeps source fields, provenance, and evidence gaps visible.
- Agent-prepared downloads remain explicit user actions.
- The public demo is deterministic, attributed, and ready immediately.
Takeaways
WebMCP is especially effective when a website is already an instrument. The most useful tools expose a few high-confidence operations, inherit the application's constraints, and return their effects to the interface.
Shared state also changes the role of follow-up prompts. A correction becomes an input to the active workspace: users can see what changed, challenge the direction, and continue from the same evidence.
The broader opportunity is software where visual interaction and agent action form one inspectable loop.
What's next
The next step is to develop the reference implementation into a reusable spatial-workbench pattern:
- pluggable dataset adapters and validation profiles;
- saved workspaces and collaboration history;
- richer spatial operators, joins, and travel-time analysis;
- reusable tool contracts for other MapLibre applications; and
- review flows for teams working with consequential spatial decisions.
Try it
- Live project: https://sidetools.dev/comapper
- Public repository: https://github.com/mgd1984/comapper-webmcp
- Demo video: https://youtu.be/I5I-9khq2UY
- Architecture: https://github.com/mgd1984/comapper-webmcp/blob/main/docs/architecture.md
- WebMCP tool contract: https://github.com/mgd1984/comapper-webmcp/blob/main/docs/webmcp.md
Testing instructions
- Open https://sidetools.dev/comapper/#workspace in ChatGPT's in-app browser or Chrome 149+ with WebMCP testing enabled.
- Use the bundled Toronto Office Placement Decision Atlas, or import an attributed GeoJSON file to exercise the same data pipeline.
- Ask the site tools to inspect the workspace or search the current map.
- For the bundled scenario, ask: “Build a shortlist of candidate locations for a new OpenAI Toronto office using site tools.”
- Follow with: “You're over-indexing on downtown. Broaden the search scope.” Then request a shorter list and inspect a selected feature.
- Ask CoMapper to filter or style a declared field and confirm that the map and inspector update together.
- Ask CoMapper to prepare the visible candidates as GeoJSON. Confirm that the download control appears and waits for user action.
Built With
- cloudflare
- codex
- eslint
- maplibre
- node.js
- openai
- react
- typescript
- vite
- vitest
- webmcp
- wrangler
- zod
Log in or sign up for Devpost to join the conversation.