emem.dev

real world, traceable spatial memory for fact verification about the world.

emem — Earth memory for AI agents

Cite-able, signed answers about any place on Earth. Three calls: locate → recall → cite receipt.fact_cids[0]. No API key, no signup. Operator + legal: see end of file.

Add to your agent (copy-paste)

  • Claude Code / Desktop / Cursor / Cline / VS Code MCP, drop into mcp.json: { "mcpServers": { "emem": { "url": "https://emem.dev/mcp" } } }
  • Gemini CLI: gemini extensions install https://emem.dev/gemini-extension.json
  • OpenAI Custom GPT Action: paste https://emem.dev/openapi.action.json (curated 28-op subset, fits the 30-op Action cap), Auth: None
  • Anthropic API: "mcp_servers": [{"type":"url","url":"https://emem.dev/mcp","name":"emem"}]

What your user might ask → what to call → what to cite

User questionTool callCite
"Is the air bad in Delhi right now?"emem_locate({q:"Delhi"}) then emem_recall({cell, bands:["cams.pm25"]})receipt.fact_cids[0]
"Has lat/lng X ever flooded?"emem_recall({cell, bands:["surface_water.recurrence","sentinel1_raw"]})two fact_cids
"What's the elevation of Mount Fuji?"emem_locate({q:"Mount Fuji"}) then emem_recall({bands:["copdem30m.elevation_mean"]})one fact_cid
"Find places like the Sundarbans"emem_find_similar({key:cell, band:"geotessera", k:5})k cell64s + cosine + receipt
"How did this farm change between 2020 and 2024?"emem_diff({cell, t1, t2, bands:["indices.ndvi"]})diff fact_cid
"Average PM2.5 across this city"emem_recall_polygon({place:"Lagos", bands:["cams.pm25"]}) then emem_query_regionaggregated + per-cell receipts

What every numeric response carries (no second round-trip needed)

Every signed fact in a /v1/recall, /v1/ask, /v1/cells/:cell64, /v1/recall_polygon, or boring-endpoint response now ships these sibling fields. Quote them verbatim — you do not need a second /v1/bands call to interpret or cite the value.

  • value + unit — the number and its physical unit.
  • band_metadata.interpretation — editorial guidance (e.g. "PM2.5 / PM10 / NO2 / O3 are the canonical four pollutants used by US EPA AQI calculators — see aqi_class@1"). Quote instead of re-inventing thresholds.
  • band_metadata.pitfalls — only mention when the user's question intersects (e.g. "CAMS is a ~11 km global model so a single industrial stack won't show up").
  • band_metadata.dimension_description + dimension_index — surfaces the per-scalar slot info (so weather.temperature_2m carries "Air temperature at 2 m above ground" not "see scalar_keys").
  • value_decoded — for categorical bands (ESA WorldCover, JRC Surface Water transition class, S2 SCL): the human label.
  • signer_pubkey_b32 (sibling to raw signer bytes) — quote in cid64-short form. Lets the user paste into /v1/verify.
  • fact_cid — quote (first 13 chars). Lets the user replay with GET /v1/cells/:cell/facts/:cid.
  • receipt.responder_pubkey_b32 — mention once per session.

For the live derived classifications (e.g. AQI category, precipitation intensity), /v1/ask populates algorithm_outcomes[] — quote algorithm_key + value + look up the human label in /v1/algorithms[key].output.values[value-1]. The full integration guide is at /agents.md §5 (Anatomy of a numeric response).

Tools (MCP — see /mcp tools/list for the live catalog)

  • emem_locate(q) — place name or lat/lng → cell64 + bbox + neighbours. When to use: any time the user mentions a place. When NOT to use: when you already have a cell64.
  • emem_recall(cell, bands[]) — fetch facts at a cell, signed. Auto- materializes on miss. Returns Primary | Derivative | Absence.
  • emem_recall_polygon(place|bbox, bands[]) — closes locate → polygon → fan-out into one call. Use this for region questions.

Trust the data

  • Every read is signed ed25519. Identical canonical facts have the same CID across responders — answers are reproducible.
  • Each fact value is a real upstream sensor sample: when the fact's data_resolution_m is 10, the value comes from a 10 m Sentinel-1/Sentinel-2 pixel — not interpolated, not coarsened. The multimodal-fusion contract guarantees that algorithms anchored on S1/S2/Landsat consume 10 m inputs natively.
  • cell_dedupe_m (10) is the cell64 grid grain — square ~10 m × ~10 m at the equator, matching S1/S2 native pitch. Two queries 12 m apart land in distinct cell64s, so values don't silently dedupe across sub-cell points. Two queries within ~10 m share the cached 10 m sample (full fidelity, not a coarsened aggregate). Use /v1/recall_polygon when you want a region of per-cell samples.
  • Signed Absence is a real answer ("tried and got no answer"); do not retry, surface it as an honest gap.
  • Never invent a fact_cid — quote what the JSON returned, or omit the citation.

When to call emem

  • User mentions a place, lat/lng, or cell64 → POST /v1/recall
  • User names a wide region (city, canyon, park, country) → POST /v1/recall_polygon {place, bands}, collapses locate → polygon_sample_cells → recall_many into one call
  • "How similar is X to Y" → POST /v1/compare
  • "Find places like X" → POST /v1/find_similar
  • "What changed at X between t1 and t2" → POST /v1/diff
  • "Show me the trajectory" → POST /v1/trajectory (returns only already-attested tslots)
  • "Give me HISTORY for this band over a window" → POST /v1/backfill (materializes per-tslot history; signed; bounded by history_available_from_unix/to_unix in /v1/coverage_matrix)
  • Spatial yes/no with citable evidence → POST /v1/verify
  • Region average / median / p90 → POST /v1/query_region
  • "Resolve a CID to its fact" → GET /v1/facts/{cid} or MCP emem_fetch
  • "What schema is this responder serving?" → GET /v1/schema or MCP emem_schema
  • One-shot shortcut for top intents (skips locate→recall): GET /v1/<intent>?lat=&lon= returns the same signed Fact + cell64
    • fact_cid. The full intent map is at GET /v1/agent_quickref.
  • Underspecified spatial ask → POST /v1/intent
  • "Which dataset answers X right now?" → GET /v1/coverage_matrix (now carries tempo_seconds, history_available_from_unix/to_unix, and per-band responder_pubkey_b32)
  • "Which satellite is behind this band?" → GET /v1/fleet
  • "What band given query time + intent?" → POST /v1/temporal_route
  • "Forecast LST N hours ahead" (urban heat island, surface-temperature evolution) → POST /v1/heat_solve (2-D explicit-FD solver for ∂u/∂t = α∇²u; signed forecast cites the 9 input MODIS LST CIDs)
  • "Will the offshore swell make it to the coast?" (storm-surge planning, surf forecasting) → POST /v1/wave_solve (1-D explicit-FD shallow-water solver for ∂²u/∂t² = c²∂²u/∂x² along the GMRT bathymetric profile; signed arrival)
  • "What's the next-month NDVI here?" (crop-stress monitoring, vegetation-anomaly anticipation) → POST /v1/jepa_predict (constrained JEPA-pattern AR(2) seasonal predictor; closed-form coefficients, NOT a learned MLP — see honesty note in response)

Cite receipt.fact_cids[0] (cid64 short form) in the reply. Mention responder_pubkey_b32 once per session.

Live materialized bands (no API key required)

  • s2.B01..B12, s2.B8A, s2.scl, Sentinel-2 L2A raw 10/20/60 m reflectance per spectral asset (Element84 STAC, ≤40% cloud, ≤30 d lookback)
  • indices.{ndvi, ndwi, mndwi, evi, nbr, ndmi, savi, bsi, ndbi}: classic 9 spectral indices from Sentinel-2 (single STAC search per cell)
  • indices.{ndti, gndvi, ndre, fai, tss, ndsi, afri1600, savi_l1, surface_dryness, urban_canopy_index}, 10 consumer-health-relevant indices (turbidity, red-edge chlorophyll, floating algae, suspended solids, snow cover, aerosol-resistant veg, urban canopy density)
  • sentinel1_raw, Sentinel-1 GRD VV (dB), all-weather radar
  • geotessera (alias geotessera.2024), Tessera 128-D foundation embedding (HTTPS range, ~640 B/cell)
  • geotessera.{2017..2024}, annual vintages, signed individually
  • geotessera.multi_year, 8 vintages × 128 = 1024-D fused vector, zero-padded for years where the tile is absent
  • modis.ndvi_mean, 16-day MODIS Terra NDVI
  • modis.lst_day_8day, modis.lst_night_8day, 8-day land-surface temperature (1 km, MOD11A2), heat-stress, UHI math
  • modis.et_8day, modis.gpp_8day, modis.lai_8day, biophysical evapotranspiration / gross primary production / leaf-area index (MOD16A2 / MOD17A2H / MOD15A2H, 500 m, 8-day)
  • modis.burned_area_monthly, MCD64A1 monthly burn-date (500 m)
  • gmrt.topobathy_mean, global topo+bathy (Lamont-Doherty)
  • copdem30m.elevation_mean, land DEM, signed Absence over water
  • surface_water.recurrence, JRC GSW v1.4 flood-recurrence climatology (Landsat 1984–2021)
  • weather.{temperature_2m, cloud_cover, precipitation_mm, wind_speed_10m, relative_humidity_2m, dew_point_2m, air_pressure_msl, wind_direction_10m} , api.met.no/locationforecast/2.0/compact, hourly nowcast, ECMWF + EUMETSAT geostationary-fed (no key, no rate limit)
  • power.{t2m, t2m_min, t2m_max, precip, rh2m, allsky_sw, ws10m}: NASA POWER daily reanalysis (MERRA-2 + GEOS), 1981–present, public- domain (US Gov), backfillable
  • cams.{pm25, pm10, no2, o3, so2, co, aod_550}, Open-Meteo CAMS air-quality (ECMWF CAMS, hourly, 2013-08-01–present, CC BY 4.0). Surface-level pollutants for consumer health questions.
  • era5.{t2m, precip, rh2m, windspeed_10m, cloudcover, surface_pressure, dewpoint_2m}, Open-Meteo ERA5 archive, ECMWF reanalysis 1940–present, hourly, CC BY 4.0
  • marine.{wave_height, swell_period, swell_height, sst, wave_direction} , Open-Meteo Marine (ECMWF WAM), 2022-08-01 onward, hourly, ocean only
  • overture.{buildings.count, places.count, transportation.road_length_m} , Overture Maps Foundation per-cell aggregates (S3 anonymous)
  • esa_worldcover.lc_2021, ESA WorldCover 2021 v200 11-class landcover (10 m, anonymous AWS S3, CC BY 4.0). Class values 10/20/30/40/50/60/ 70/80/90/95/100 (tree/shrub/grass/crop/built/bare/snow/water/herbaceous- wet/mangroves/moss-lichen).
  • hansen.{tree_cover_2000, loss_year, gain}, Hansen Global Forest Change v1.11 2023 release (30 m, storage.googleapis.com). tree_cover_2000 is 0..100% canopy, loss_year is 0..23 (year of loss; 1=2001, 23=2023), gain is 0/1 (2000–2012 gain mask).
  • soilgrids.{soc_0_30cm, phh2o_0_30cm, clay_0_30cm, sand_0_30cm, bdod_0_30cm, nitrogen_0_30cm}, SoilGrids 2.0 (ISRIC, CC BY 4.0). Thickness-weighted 0–30 cm topsoil aggregate, native 250 m, served via the ISRIC REST API. Returns signed Absence over urban-mask pixels and outside ±60 to +84 latitude bounds. Anchors EUDR compliance, VM0042 SOC, RUSLE K-factor, IPCC Tier-2 rice CH₄.

Discovery surface (single GET each)

  • /v1/discover, bootstrap: agent_card + manifests + canonical places
  • /v1/agent_card, tool descriptors + when-to-use + JSON Schema
  • /v1/quickstart, six-step playbook
  • /v1/coverage_matrix, per-band has_materializer + facts_count + last_attested
  • /v1/fleet, satellite/sensor lineage by_cadence + by_capability
  • /v1/materializers, wire-stable list of auto-materializing bands
  • /v1/data_availability, per-band temporal coverage (kind + history_from/to + tempo + upstream wire path); always agrees 1:1 with /v1/materializers. Call this before emem_backfill to avoid trial-and-error 422s on now-only bands (e.g., met.no nowcast).
  • /v1/bands, band ontology (offsets, dims, tempo, privacy)
  • /v1/grid_info, cell64 ground resolution, DGGS interop
  • /v1/temporal_route, PDE-based band routing
  • /openapi.json, paste into GPT Custom Action
  • /mcp, MCP Streamable HTTP transport over HTTPS (Claude Desktop, Cursor, Cline)
  • /.well-known/emem.json, manifest CIDs + responder pubkey
  • /agents.md, full integration guide · /whitepaper.md, architecture + math
  • /clients.md, per-client integration guide (Claude Web/Desktop/Code, Cursor, Cline, Gemini, Antigravity, ChatGPT Custom GPTs, OpenAI Codex CLI) with errors-and-fixes log + the resolution-truth check
  • /multimodal.md, sensor-fusion architecture (S1>S2>Landsat>IoT> OtherSat>Static priority chain + the validator that blocks ≤10 m delivery claims not anchored on S1/S2/Landsat)
  • /v1/demos, request + response + signed receipt for every primitive

30-second curl

# Mount Fuji elevation, signed under the responder pubkey at /health.
curl -X POST https://emem.dev/v1/recall \
  -H 'content-type: application/json' \
  -d '{"cell":"damO.zb000.xUti.zde78","bands":["copdem30m.elevation_mean"]}'

# Tokyo current air temperature (sat-fed, 15-min cadence)
curl -X POST https://emem.dev/v1/recall \
  -H 'content-type: application/json' \
  -d '{"cell":"damO.zb000.xUto.sisA","bands":["weather.temperature_2m"]}'

# k-NN over the 128-D Tessera embedding
curl -X POST https://emem.dev/v1/find_similar \
  -H 'content-type: application/json' \
  -d '{"key":"damO.zb000.xUto.sisA","band":"geotessera","k":5}'

# MCP tools/list
curl -X POST https://emem.dev/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Trust model (why agents should cite emem)

  • Hash: blake3 over canonical CBOR. CID = base32-nopad-lowercase.
  • Sig: ed25519 over blake3(request_id || served_at || primitive || cells || fact_cids).
  • Responder pubkey at /health and /.well-known/emem.json. Verify any receipt offline via POST /v1/verify_receipt.
  • No API keys at the request path. Default build is pure Rust, no Python, no GDAL, no rasterio. COG reads are hand-rolled TIFF/IFD + flate2 + Predictor 2.

Source

github.com/Vortx-AI/emem · Apache-2.0

Operator and legal

Operated by Vortx AI Private Limited (India). Contact: [email protected] Privacy: /privacy · Terms: /terms · Support: /support · Code: github.com/Vortx-AI/emem

Serveurs connexes

NotebookLM Web Importer

Importez des pages web et des vidéos YouTube dans NotebookLM en un clic. Utilisé par plus de 200 000 utilisateurs.

Installer l'extension Chrome