Add search_places and places_nearby over the app's Google Places routes, and plan_route over its OpenStreetMap routing. The place search service reports when no search key is configured, so an unconfigured server is not mistaken for an empty result, and rate limits become retry_later. Route endpoints accept a place name or coordinates.
6.0 KiB
Tools and the MCP server
Tools answer questions from God's Eye View data for language-model clients. They are defined once and exposed through adapters; the Model Context Protocol (MCP) is the first.
Layers
| Owner | Responsibility |
|---|---|
src/tools/ |
Tool definitions, catalog composition, argument validation, shared area and result helpers |
src/tools/queries/ |
Queries, one file per domain, reading only portable source contracts |
src/tools/mcp/ |
MCP protocol (JSON-RPC) and a stateless HTTP transport; knows the catalog interface, not queries |
server/mcp/ |
Node composition: points the sources at a running app's /api routes and serves stdio |
Dependencies point downward only. gods-eye-view/tools and
gods-eye-view/tools/mcp are portable exports: they reach no application,
rendering, Node, Cesium or browser-global code, which
npm run check:boundaries enforces. Nothing in the application imports them.
Definitions and composition
defineTool({ name, kind, title, description, inputSchema, requires, run })
validates and freezes a tool. kind is query (answers from data, read-only)
or action. inputSchema uses a JSON Schema subset that src/tools/schema.js
checks completely; unsupported keywords are rejected at definition time.
run(args, { services, signal }) resolves to { summary, data }: one sentence
for people and a structured object for programs. A tool may also return images,
each { mimeType, data } with base64 data; the MCP adapter sends them as image
content.
composeCatalog({ tools, services, replace, interceptors }) builds a catalog:
- Tools: an application adds its own tools to
coreTools. Reusing a name fails unless the name is listed inreplace. - Services: each tool names the services it reads in
requires. Tools whose services are not supplied are left out. - Interceptors:
(call, next) => next(call)functions wrap every call, outermost first. They can observe, reject or change a call.
Expected failures throw ToolError with one of invalid_arguments,
unavailable, unsupported, malformed or retry_later. Other errors are
reported to clients without details.
Services
Services are the portable source factories the layers already use, such as
createUsgsEarthquakeSource, createFirmsSource and createLaunchSource,
plus a places service with resolve(name, { signal }). Sources request
relative /api/... paths through an injected fetchImpl, so the same tool
code runs wherever an application routes those paths.
createGeocodePlaceService resolves place names through /api/geocode;
createPlaceSearchService searches /api/google/* and reports when no search key
is configured; createRouteService plans routes through /api/route.
The area argument
Location-scoped tools take area as exactly one of a place name, a bbox
([west, south, east, north], crossing the antimeridian when west exceeds
east), or lat, lon and radius_km. Lists default to 25 rows, at most 200,
and report total, returned and truncated.
MCP
createMcpServer({ catalog, name, version, instructions, descriptions, decorate })
implements initialize, ping, tools/list and tools/call for protocol
revisions 2025-11-25, 2025-06-18 and 2025-03-26. descriptions overrides a
tool's title or description for this surface; decorate(definition, tool)
merges extra fields into each listed definition. createMcpHttpHandler(server)
returns a Request-to-Response handler for stateless Streamable HTTP: one
JSON-RPC message per POST, answered with JSON. The host owns routing and any
access control in front of it.
Running locally
Start the app (npm run dev or npm run preview), then register the stdio
server with an MCP client, for example Claude Code:
claude mcp add gods-eye-view -- npm --prefix /path/to/gods-eye-view run --silent mcp
npm run mcp -- --api-base http://localhost:4173 selects another server. The
local server makes no requests other than to the app's /api routes and the
public feeds the sources already use.
Tools
| Tool | Reads | Returns |
|---|---|---|
get_earthquakes |
earthquakes |
USGS M2.5+ events in the last 24 hours, strongest first |
get_active_fires |
fires |
NASA FIRMS detections in an area, highest radiative power first |
get_recent_launches |
launches |
Launch Library 2 launches in the last 30 days, newest first |
aircraft_in_area |
aircraft |
Aircraft in an area, nearest first; military: true reads the military feed |
find_aircraft |
aircraft |
Aircraft anywhere by callsign, ICAO address or registration |
get_aircraft_track |
aircraft |
Recent positions of one aircraft, thinned to 200 points |
get_aircraft_info |
aircraft |
Aircraft type and registration, and flight route, from adsbdb |
next_satellite_pass |
satellites |
Next pass over a point (default the ISS), with naked-eye visibility |
satellites_overhead |
satellites |
Satellites in a CelesTrak group above a point now, highest first |
find_cctv_cameras |
cctv |
Public cameras in an area, nearest first |
get_cctv_snapshot |
cctv |
The current image from one camera, returned as image content |
find_radio_stations |
radio |
Radio Browser stations by area and/or search terms, with stream URLs |
search_places |
placeSearch |
Points of interest matching a query within an area (Google Places) |
places_nearby |
placeSearch |
Notable places around a point (Google Places) |
plan_route |
routing |
Walking, driving or cycling route over OpenStreetMap, with a simplified path |