Docs / For Agents

Geographic data for
agents and MCP clients.

Remote MCP server and hosted API for deterministic geography-aware queries. Free discovery. Free and paid execution lanes. 12 live packs in one catalog.

What you get

12 live packs across disasters, FX rates, and global indicators. All packs share a common location model and query contract.

  • Free: currency, floods, un_sdg, world_bank_wdi, volcanoes
  • Paid via x402 on Base USDC: earthquakes, hurricanes, tornadoes, tsunamis, wildfires, world_factbook, worldpop
  • Free geography tools: reverse geocode lat/lon to loc_id, fetch boundaries, and walk the loc_id hierarchy - the /mcp/geography family

Browse all packs

Connect your agent

New here: if your client supports remote MCP, start with MCP. Use plain HTTP when you want the raw request/response flow or when your runtime does not support MCP yet. Both paths hit the same hosted backend.

  • Remote MCP client: https://app.daedalmap.com/mcp
  • Plain HTTP: /api/v1/catalog, /api/v1/packs/{pack_id}, /api/v1/query/dataset
  • Free cross-disaster helpers for supported hazard packs - same helper, two lanes: HTTP /api/v1/disaster-links/event/{event_id}, /api/v1/disaster-links/chain/{event_id}, /api/v1/disaster-links/search; MCP tools get_disaster_links_for_event, get_disaster_link_chain, search_disaster_links on the umbrella /mcp and on the earthquakes, tsunamis, volcanoes, wildfires, floods, hurricanes, and tornadoes facades. Exact-event lookup (get_disaster_links_for_event, get_disaster_link_chain) only works for earthquakes, tsunamis, volcanoes, and wildfires; search_disaster_links works everywhere and takes event-type filters, not a pack_id.
  • Free earthquake-native aftershock helper: /api/v1/earthquakes/aftershocks/{event_id}
  • Free geography tools on the loc_id spine: /mcp/geography - resolve_point (lat/lon -> loc_id chain), get_boundary, loc_id_hierarchy, loc_id_info; also on the umbrella /mcp
  • Pack-specific registry entry: narrow facades at /mcp/currency, /mcp/earthquakes, etc.

This is a structured machine lane, not the human chat lane. Send explicit pack_id, source_id, metrics, region_ids, and time filters so the backend can execute direct deterministic DuckDB/parquet queries without an LLM in the execution path.

request_id is optional but recommended for tracing and idempotency.

Which path to use

  • Browse what exists: call GET /api/v1/catalog, then GET /api/v1/packs/{pack_id}.
  • Run a normal data query: call POST /api/v1/query/dataset or MCP query_dataset. Use this for counts, rankings, time series, and filtered rows.
  • Fetch one exact event: call GET /api/events/exact/{event_id}?pack_id=.... Use this when you already know the exact earthquake, tsunami, tornado, flood, volcano, or wildfire event id.
  • Resolve a place or click to geography: call resolve_point, then pass the returned loc_id into filters.region_ids.
  • Follow event relationships: use /api/v1/earthquakes/aftershocks/{event_id} for same-pack earthquake sequences, or the disaster-links helpers for cross-hazard chains.

Keep the identifiers straight. event_id identifies one exact event for lookup helpers. loc_id scopes a structured data query. Exact-event records also return a canonical event-shaped loc_id, and that value can be reused in filters.region_ids when you want to query around that same event through the dataset lane.

MCP quickstart

If you already have an MCP-capable client, point it at https://app.daedalmap.com/mcp, list tools, then call one narrow tool. Include request_id when you want easier tracing across logs, examples, or retries. If you want to inspect the raw HTTP request/response flow as well, go to Agent Examples after the MCP probe works.

curl https://app.daedalmap.com/mcp

curl -X POST https://app.daedalmap.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-06-18" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'
  • get_catalog - list every published pack
  • get_pack - full pack schema: metric inventory with stats, query rules, and a paste-ready example body. Call this before any query.
  • query_dataset - generic structured query against any pack (matches POST /api/v1/query/dataset). Start here for packs without a dedicated narrow tool, such as floods, hurricanes, tornadoes, wildfires, world_factbook, worldpop, and most multi-source comparisons.
  • get_earthquake_events, get_volcanic_activity, get_tsunami_events, get_fx_rates - narrow canonical tools with sensible defaults. Use these when the question maps cleanly onto one pack and a normal region/time filter shape.
  • get_live_earthquake_events, get_live_volcano_events - preliminary upstream wrappers. Use these only when the caller explicitly wants live or not-yet-canonical updates. They are not the enriched canonical history lane.
  • resolve_point, get_boundary, loc_id_hierarchy, loc_id_info - free geography utilities on the loc_id spine. Use these to turn a raw lat/lon or admin name into a loc_id before querying any data pack, or to fetch a boundary/hierarchy for a loc_id you already have.
  • get_disaster_links_for_event, get_disaster_link_chain - resolve or expand cross-hazard links for one exact event id. Pass the pack_id hint (earthquakes, tsunamis, volcanoes, or wildfires) only when the event id is ambiguous.
  • search_disaster_links - discover linked-event chains by event type (e.g. start_event_type: "wildfire") instead of looking up one event id. No pack_id argument; filter by start_event_type/via_event_type/end_event_type and year range instead.

Pack detail is the contract. Do not assume every field visible on an exact-event record is a queryable metric. Read quick_start.first_query_template, filterable_fields, and sortable_fields before you build a query body.

Tool map

  • Discovery: get_catalog, get_pack
  • Canonical pack query: query_dataset, plus narrow canonical tools such as get_fx_rates, get_earthquake_events, get_volcanic_activity, and get_tsunami_events
  • Preliminary live wrappers: get_live_earthquake_events, get_live_volcano_events
  • Geography spine: resolve_point, get_boundary, loc_id_hierarchy, loc_id_info
  • Exact-event relationships: get_disaster_links_for_event, get_disaster_link_chain, search_disaster_links, and /api/v1/earthquakes/aftershocks/{event_id}

One question, every pack

Every pack returns rows keyed on the same loc_id. Earthquakes in Japan, the population of Japan, and Japan's currency timeline all come back with loc_id=JPN. Cross-pack joins are a client-side zip on a single column. No country-name normalization. No fuzzy matching. No per-source dictionaries.

# 1. Earthquake counts for Japan, last 25 years
curl -X POST https://app.daedalmap.com/api/v1/query/dataset \
  -H "Content-Type: application/json" \
  -d '{"source_id":"earthquakes_events",
       "metrics":["event_count"],
       "filters":{"region_ids":["JPN"],
                  "time":{"start":"2000-01-01","end":"2025-12-31"}}}'

# 2. Poverty headcount ratio for Japan, same window
curl -X POST https://app.daedalmap.com/api/v1/query/dataset \
  -H "Content-Type: application/json" \
  -d '{"source_id":"01",
       "metrics":["ind_1_2_1"],
       "filters":{"region_ids":["JPN"],
                  "time":{"start":2000,"end":2025}}}'

# Both responses key on loc_id=JPN. Join in five lines.

This is the differentiator vs single-source MCP wrappers. One geographic key across every domain - disasters, demographics, economics, climate, currency.

Learn loc_id / Geometry tools

Client setup

Expand your client below.

Claude Code
claude mcp add --transport http daedalmap https://app.daedalmap.com/mcp

claude mcp list

JSON config equivalent:

{
  "mcpServers": {
    "daedalmap": {
      "type": "http",
      "url": "https://app.daedalmap.com/mcp"
    }
  }
}
Codex
codex mcp add daedalmap --url https://app.daedalmap.com/mcp

codex mcp list
ChatGPT developer mode
  • Enable developer mode in ChatGPT settings.
  • Add a remote MCP connector.
  • Use https://app.daedalmap.com/mcp as the server URL.
Gemini SDK
from google import genai

client = genai.Client()

mcp_server = {
    "type": "mcp_server",
    "name": "daedalmap",
    "url": "https://app.daedalmap.com/mcp",
}

interaction = client.interactions.create(
    model="gemini-2.5-flash",
    input="List the published DaedalMap packs and suggest one first query.",
    tools=[mcp_server],
)
Mistral SDK

If your Mistral runtime supports a remote MCP client, point it at https://app.daedalmap.com/mcp. Otherwise use the hosted HTTP API at /api/v1/ directly.

Local and open-weight runtimes

If your agent framework supports remote MCP, use https://app.daedalmap.com/mcp. Otherwise call /api/v1/catalog, /api/v1/packs/{pack_id}, and /api/v1/query/dataset directly.

First flow

  1. Call GET /api/v1/catalog - see all live packs at a glance.
  2. Call GET /api/v1/packs/{pack_id} for each pack you plan to use. This is the workhorse endpoint. It returns the complete metric inventory with per-metric statistics, a quick_start block with step-by-step rules and a paste-ready query body, temporal and geographic coverage, and the list of countries missing from each metric. Read quick_start.important_rules before writing any query.
  3. If a disaster pack exposes related_disaster_links.supported=true, you can take one exact event id from that pack's event rows and inspect cross-disaster links or a bounded related-event chain - HTTP GET /api/v1/disaster-links/event/{event_id} / /chain/{event_id}, or the MCP tools get_disaster_links_for_event / get_disaster_link_chain. Exact-event lookup only covers earthquakes, tsunamis, volcanoes, and wildfires. To discover chains without an event id, use a type-filtered search instead: HTTP GET /api/v1/disaster-links/search?start_event_type=volcano&via_event_type=earthquake&end_event_type=tsunami, or the MCP tool search_disaster_links with the same filters as JSON arguments ({"start_event_type": "volcano", "via_event_type": "earthquake", "end_event_type": "tsunami"}) - this one works across all hazard packs, including floods, hurricanes, and tornadoes.
  4. Earthquake aftershocks are a native same-pack sequence, not a shared cross-disaster link. Use /api/v1/earthquakes/aftershocks/{event_id} for that case.
  5. Copy quick_start.first_query_template, optionally keep or add request_id, and modify region_ids, time, and metrics to match your question.
  6. Call POST /api/v1/query/dataset. Free packs return rows directly. Paid packs return a 402 challenge with the exact price; retry with payment.
  7. For questions that cross two packs, run step 4 once per pack and join rows on loc_id client-side.

The metric stats block (min, median, max) in the pack response is a diagnostic tool, not just a description. If a max value looks like a year or an implausible number, that signals a data quality edge case worth checking before building on that metric.

Public disaster-link methodology and confidence rules

Copyable request shapes for every pack

Common Query Mistakes

  • Do not invent metric ids. Use the exact metric names shown in GET /api/v1/packs/{pack_id}, including case.
  • Do not guess filter names. Copy machine-readable fields from the pack detail, especially each source's filterable_fields, sortable_fields, and quick_start.first_query_template.
  • Do not treat every returned property as a metric. Exact-event endpoints may show helper fields such as source, source_url, or event_subtype even when the dataset query lane does not expose them as metrics.
  • Do not assume count metrics combine with raw event metrics. Some event sources require event_count on its own. The pack detail tells you when this applies.
  • Do not mix up event_id and loc_id. Exact-event helpers take event_id. Structured data queries take filters.region_ids, which means loc_id.
  • Do not start with a broad global multi-year event scan. Event packs often need a bounded geography, a shorter time window, or a simpler aggregation first.
  • Do not guess the time shape. Some packs expect numeric years; others expect ISO date strings. Follow the pack's starter template.
  • Do not assume all yearly metrics are dense. Start yearly sources with one stable metric first so you can verify the returned year row shape before widening the request.
  • Do not pass pack_id to search_disaster_links - it has no such argument and returns an error. Filter by start_event_type/via_event_type/end_event_type instead. pack_id is only a valid (and optional) argument on get_disaster_links_for_event and get_disaster_link_chain, where it disambiguates an event id.
  • Generate a fresh request_id for each real call when you want clean tracing in analytics, logs, and examples.

If a query returns a typed error, treat it as a contract hint. Re-read quick_start.important_rules, then retry with a narrower or more exact request instead of inventing a new shape.

Canonical first, live second

Agent callers should prefer DaedalMap's hosted canonical pack tools first. For earthquakes and tsunamis, that means using the published pack lanes and their processed event history before considering any upstream wrapper.

  • Preferred: get_earthquake_events and /api/v1/query/dataset against the earthquakes pack.
  • Routing hint: use get_pack as the source of truth for canonical_available_through, preferred_tool, and any live_fallback_tool guidance.
  • Fallback only: live wrapper tools for preliminary upstream data when the caller explicitly asks for live/preliminary updates or needs a window not yet present in the canonical hosted lane.
  • Explore mode: the human Explore chat should stay on DaedalMap canonical data and should not silently switch to an upstream live wrapper.

This keeps cross-pack joins, loc_id alignment, enriched fields, and published artifact behavior stable by default.

Pricing

Base price is $0.01 for up to 100 rows, then $0.0001 per additional row. The 402 challenge shows the exact amount before any charge. Requests above the pack row limit are rejected rather than charged.