Every location on Earth gets a 64-bit cell identifier and a cryptographically signed answer for elevation, land cover, climate, or one of 46 remote sensing bands. Ask for a fact at a cell and emem fetches the tile, signs it with ed25519, persists it, and returns a content-addressed receipt you can verify at /verify without trusting the server. The MCP interface exposes locate, recall_bands, memory_create, memory_search, and memory_contradictions. Cold reads take 180ms, warm reads under 10ms, no API keys required. Four foundation models (Clay, Prithvi, Tessera, Galileo) run server-side for consensus scoring on deforestation, wetland change, and disaster anomaly. Reach for this when your agent needs a stable, auditable handle for real-world coordinates instead of hallucinating numbers.
claude mcp add --transport http emem https://emem.dev/mcpRun in your terminal. Add --scope user to make it available in every project.
Review the command, arguments, and environment values before installing — MCP servers run with your local permissions.
Verified live against the running server on Jun 10, 2026.
emem_locateResolves a place mention (free-text name, address, or lat/lng) to the protocol's cell64 identifier, and returns the topic-grouped inventory of bands and algorithms available at that location. When to use: Use whenever the input refers to a real-world location and the next step...4 paramsResolves a place mention (free-text name, address, or lat/lng) to the protocol's cell64 identifier, and returns the topic-grouped inventory of bands and algorithms available at that location. When to use: Use whenever the input refers to a real-world location and the next step...
qstringlatnumberlngnumberplacestringemem_askSingle-shot free-text answer about a real-world location, backed by signed satellite/elevation/water/built-up receipts. Forwards a place mention plus a question; runs the locate → recall → algorithm chain server-side; returns one packaged envelope. When to use: Use when the qu...8 paramsSingle-shot free-text answer about a real-world location, backed by signed satellite/elevation/water/built-up receipts. Forwards a place mention plus a question; runs the locate → recall → algorithm chain server-side; returns one packaged envelope. When to use: Use when the qu...
q*stringlatnumberlngnumbercellstringplacestringincludearrayverbosebooleaninclude_imagebooleanemem_huntEvent-discovery sweep: pick an event keyword (algal_bloom, deforestation, flood_extent, wildfire, urban_heat_island, methane_plume, landslide, drought, soil_salinity, crop_stress, water_turbidity, oil_slick) plus a region (free-text name or polygon_bbox). The responder geocode...3 paramsEvent-discovery sweep: pick an event keyword (algal_bloom, deforestation, flood_extent, wildfire, urban_heat_island, methane_plume, landslide, drought, soil_salinity, crop_stress, water_turbidity, oil_slick) plus a region (free-text name or polygon_bbox). The responder geocode...
event*stringalgal_bloom · deforestation · flood_extent · wildfire · urban_heat_island · methane_plumeregionstringpolygon_bboxobjectemem_eudr_ddsProduce a Due Diligence Statement per Regulation (EU) 2023/1115 for one or more plots. Each plot carries operator-supplied geometry (GeoJSON Polygon for >4 ha, Point for ≤4 ha non-cattle per Article 2(28)), country of production (ISO3), Combined Nomenclature code (HS-6+), and...6 paramsProduce a Due Diligence Statement per Regulation (EU) 2023/1115 for one or more plots. Each plot carries operator-supplied geometry (GeoJSON Polygon for >4 ha, Point for ≤4 ha non-cattle per Article 2(28)), country of production (ISO3), Combined Nomenclature code (HS-6+), and...
plots*arrayoperatorobjectcut_off_datestringlegality_modulestringmax_cells_per_plotintegerforest_baseline_overridestringemem_spiCompute the Standardized Precipitation Index (McKee et al. 1993) at a cell: fit a gamma distribution to the same-window precipitation-accumulation history, then standardize the current accumulation to a z-score and map it to a drought class (extreme/severe/moderate drought … n...4 paramsCompute the Standardized Precipitation Index (McKee et al. 1993) at a cell: fit a gamma distribution to the same-window precipitation-accumulation history, then standardize the current accumulation to a z-score and map it to a drought class (extreme/severe/moderate drought … n...
cell*stringwindow_daysintegerprecip_history_mmarraycurrent_accumulation_mmnumberemem_burn_severityCompute the differenced Normalized Burn Ratio (dNBR = NBR_pre − NBR_post; Key & Benson 2006) and map it to the USGS burn-severity classes (unburned / low / moderate-low / moderate-high / high). Supply `nbr_pre` + `nbr_post` (pin the scenes bracketing the fire date) for a corre...3 paramsCompute the differenced Normalized Burn Ratio (dNBR = NBR_pre − NBR_post; Key & Benson 2006) and map it to the USGS burn-severity classes (unburned / low / moderate-low / moderate-high / high). Supply `nbr_pre` + `nbr_post` (pin the scenes bracketing the fire date) for a corre...
cell*stringnbr_prenumbernbr_postnumberemem_rice_ch4Estimate seasonal CH4 emissions from rice cultivation per IPCC 2019 Refinement Eq 5.1: integrate the daily emission factor over the cultivation period with water-regime scaling (SFp pre-season, SFo organic amendment) and an optional Yan-2005 Q10 temperature modifier. `cultivat...7 paramsEstimate seasonal CH4 emissions from rice cultivation per IPCC 2019 Refinement Eq 5.1: integrate the daily emission factor over the cultivation period with water-regime scaling (SFp pre-season, SFo organic amendment) and an optional Yan-2005 Q10 temperature modifier. `cultivat...
sfonumbersfpnumbercell*stringt_paddy_cnumberndwi_seriesarrayefc_kg_ch4_ha_day*numbercultivation_period_days*numberemem_deforestation_alertComposite deforestation-alert score: `alert_score = 0.5·clamp01(ndvi_drop/0.30) + 0.5·clamp01(embedding_change/0.20)`, where `ndvi_drop = max(0, ndvi_modis_baseline − ndvi_now)` and `embedding_change = 1 − cos(tessera_latest, tessera_prev)`. Each half degrades INDEPENDENTLY an...1 paramsComposite deforestation-alert score: `alert_score = 0.5·clamp01(ndvi_drop/0.30) + 0.5·clamp01(embedding_change/0.20)`, where `ndvi_drop = max(0, ndvi_modis_baseline − ndvi_now)` and `embedding_change = 1 − cos(tessera_latest, tessera_prev)`. Each half degrades INDEPENDENTLY an...
cell*stringemem_sar_forest_disturbanceCloud- and night-independent Sentinel-1 C-band confirmation of forest disturbance. Intact forest scatters VV strongly + stably (canopy volume scattering); clearing collapses that term so VV backscatter DROPS ~3-5 dB. Samples VV at a baseline-year July-1 anchor and the latest s...2 paramsCloud- and night-independent Sentinel-1 C-band confirmation of forest disturbance. Intact forest scatters VV strongly + stably (canopy volume scattering); clearing collapses that term so VV backscatter DROPS ~3-5 dB. Samples VV at a baseline-year July-1 anchor and the latest s...
cell*stringbaseline_yearintegeremem_triple_consensusThree-encoder change ensemble: compute the cosine change between the two most-recent DISTINCT vintages for each of the Clay, Prithvi, and Tessera embeddings at the cell, then vote each encoder's change against `consensus_threshold` (registry default 0.15). Returns each encoder...2 paramsThree-encoder change ensemble: compute the cosine change between the two most-recent DISTINCT vintages for each of the Clay, Prithvi, and Tessera embeddings at the cell, then vote each encoder's change against `consensus_threshold` (registry default 0.15). Returns each encoder...
cell*stringconsensus_thresholdnumberemem_terrainCompute three standard DEM terrain indices from one 3×3 Copernicus-DEM (copdem30m.elevation_mean) neighbourhood at a cell: Horn (1981) slope in degrees, Riley (1999) Terrain Ruggedness Index (TRI = sqrt(Σ(Z_centre−Z_i)²)), and Weiss (2001) Topographic Position Index (TPI = Z_c...2 paramsCompute three standard DEM terrain indices from one 3×3 Copernicus-DEM (copdem30m.elevation_mean) neighbourhood at a cell: Horn (1981) slope in degrees, Riley (1999) Terrain Ruggedness Index (TRI = sqrt(Σ(Z_centre−Z_i)²)), and Weiss (2001) Topographic Position Index (TPI = Z_c...
cell*stringstep_cellsintegeremem_region_similarityAnswer 'how alike are these two places?' Mean-pool the 128-D GeoTessera embedding across each region's cells to get a centroid, then return the cosine similarity in [-1,1] (+1 = identical landscape, 0 = unrelated). Each region is {place} | {polygon_bbox} | {cells}. CPU-fetched...3 paramsAnswer 'how alike are these two places?' Mean-pool the 128-D GeoTessera embedding across each region's cells to get a centroid, then return the cosine similarity in [-1,1] (+1 = identical landscape, 0 = unrelated). Each region is {place} | {polygon_bbox} | {cells}. CPU-fetched...
region_a*objectregion_b*objectmax_cellsintegeremem_embedding_centroidMean-pool the 128-D GeoTessera embedding over a region's cells: centroid = (1/N) Σ v_i, plus the L2-normalised centroid and a content-addressed centroid_cid. The building block region_similarity composes. Region is {place} | {polygon_bbox} | {cells}. NaN dims are averaged over...4 paramsMean-pool the 128-D GeoTessera embedding over a region's cells: centroid = (1/N) Σ v_i, plus the L2-normalised centroid and a content-addressed centroid_cid. The building block region_similarity composes. Region is {place} | {polygon_bbox} | {cells}. NaN dims are averaged over...
cellsarrayplacestringmax_cellsintegerpolygon_bboxobjectemem_embedding_diversityQuantify how varied a region's landscape is: diversity = (1/(N(N-1))) Σ_{i<j} (1 − cosine(v_i, v_j)), the mean pairwise cosine distance over the region's GeoTessera embeddings. 0 = perfectly uniform; higher = more heterogeneous land cover (a determinantal-point-process / k-med...4 paramsQuantify how varied a region's landscape is: diversity = (1/(N(N-1))) Σ_{i<j} (1 − cosine(v_i, v_j)), the mean pairwise cosine distance over the region's GeoTessera embeddings. 0 = perfectly uniform; higher = more heterogeneous land cover (a determinantal-point-process / k-med...
cellsarrayplacestringmax_cellsintegerpolygon_bboxobjectemem_neighborhood_consistencyScore how much a cell looks like its surroundings: consistency = (1/8) Σ cosine(centre, neighbour_i) over the 8 immediate cell64 neighbours, plus outlier_score = 1 − consistency. High consistency = the cell blends in (Tobler's First Law); high outlier_score = it stands out — a...1 paramsScore how much a cell looks like its surroundings: consistency = (1/8) Σ cosine(centre, neighbour_i) over the 8 immediate cell64 neighbours, plus outlier_score = 1 − consistency. High consistency = the cell blends in (Tobler's First Law); high outlier_score = it stands out — a...
cell*stringemem_stateGet one dense numeric fingerprint that summarises everything known about a place — ready to feed into similarity search, a classifier, or clustering. Two views: `encoder` returns a single AI-model embedding (128-D Tessera, 1024-D Clay, 1024-D Prithvi); `cube` returns the full...9 paramsGet one dense numeric fingerprint that summarises everything known about a place — ready to feed into similarity search, a classifier, or clustering. Two views: `encoder` returns a single AI-model embedding (128-D Tessera, 1024-D Clay, 1024-D Prithvi); `cube` returns the full...
cell*stringviewstringencoder · cubetslotintegerencoderstringfamiliesarrayas_of_tslotintegermaterializebooleanas_of_signed_atstringinclude_reservedbooleanemem_state_multiGet the place's fingerprint from several AI models at once (`geotessera`, `clay_v1`, `prithvi_eo2`, `galileo`) in one call, returned as a per-model map. Each model is tried independently; any that can't produce a vector here show up under `missing` with a reason instead of fai...5 paramsGet the place's fingerprint from several AI models at once (`geotessera`, `clay_v1`, `prithvi_eo2`, `galileo`) in one call, returned as a per-model map. Each model is tried independently; any that can't produce a vector here show up under `missing` with a reason instead of fai...
cell*stringtslotintegerencodersarrayas_of_tslotintegeras_of_signed_atstringemem_state_diffVector delta between the same cell at two tslots: returns the per-element residual, its L2 norm (scalar change-magnitude), the cosine between the two source vectors (orientation drift), and both source fact CIDs so the agent can quote both attestations as evidence. When to use...4 paramsVector delta between the same cell at two tslots: returns the per-element residual, its L2 norm (scalar change-magnitude), the cosine between the two source vectors (orientation drift), and both source fact CIDs so the agent can quote both attestations as evidence. When to use...
cell*stringencoderstringtslot_a*integertslot_b*integeremem_memory_tokenCompose a `memt:<cell64>:<fact_cid>` (or `memt:<cell64>:<state_cid>`) citation handle. Validates both components are non-empty and do not contain the outer separator `:`. When to use: Call when the agent wants a single rebindable string to cite a place + attested fact across m...2 paramsCompose a `memt:<cell64>:<fact_cid>` (or `memt:<cell64>:<state_cid>`) citation handle. Validates both components are non-empty and do not contain the outer separator `:`. When to use: Call when the agent wants a single rebindable string to cite a place + attested fact across m...
cell*stringfact_cid*stringemem_memory_token_resolveParse a `memt:<cell64>:<fact_cid>` citation handle and return the signed fact body the cid binds. Saves the agent from string-splitting the token and chaining `GET /v1/facts/<cid>` manually. When to use: Call when an agent receives a memory_token from another agent (or out of...1 paramsParse a `memt:<cell64>:<fact_cid>` citation handle and return the signed fact body the cid binds. Saves the agent from string-splitting the token and chaining `GET /v1/facts/<cid>` manually. When to use: Call when an agent receives a memory_token from another agent (or out of...
token*stringemem_memory_bundleCompose N (cell, band, tslot?) triples into ONE signed envelope. Each triple runs through the standard auto-materialize recall path; the resulting fact_cids are bundled into a content-addressed envelope and the responder signs over the full receipt. The composed `bundle_token`...2 paramsCompose N (cell, band, tslot?) triples into ONE signed envelope. Each triple runs through the standard auto-materialize recall path; the resulting fact_cids are bundled into a content-addressed envelope and the responder signs over the full receipt. The composed `bundle_token`...
purposestringtriples*arrayemem_memory_bundle_resolveParse a `memb:<bundle_cid>` token and return the signed bundle envelope: every citation (cell, band, resolved_tslot, fact_cid, memory_token), the receipt, the responder pubkey, and the deduped flat cells[] / fact_cids[] arrays. Returns 404 with a typed code when the responder...1 paramsParse a `memb:<bundle_cid>` token and return the signed bundle envelope: every citation (cell, band, resolved_tslot, fact_cid, memory_token), the receipt, the responder pubkey, and the deduped flat cells[] / fact_cids[] arrays. Returns 404 with a typed code when the responder...
token*stringmemory_viewRead the contents of a memory file at `/memories/<path>` or list a directory when the path ends with `/`. Optional `view_range: [start, end]` slices a 1-indexed inclusive line range out of the file. Mirrors the `view` verb in Anthropic's context-management-2025-06-27 memory to...4 paramsRead the contents of a memory file at `/memories/<path>` or list a directory when the path ends with `/`. Optional `view_range: [start, end]` slices a 1-indexed inclusive line range out of the file. Mirrors the `view` verb in Anthropic's context-management-2025-06-27 memory to...
kindstringepisodic · semantic · procedural · resourcepath*stringview_rangearrayvault_capabilitystringmemory_createWrite a memory file at `/memories/<path>` with the supplied `file_text`. Overwrites if the file exists. Persists to sled, content-addresses the bytes (`file_cid`), and signs the write so the operation carries a verifiable receipt. Mirrors the `create` verb in Anthropic's conte...4 paramsWrite a memory file at `/memories/<path>` with the supplied `file_text`. Overwrites if the file exists. Persists to sled, content-addresses the bytes (`file_cid`), and signs the write so the operation carries a verifiable receipt. Mirrors the `create` verb in Anthropic's conte...
kindstringepisodic · semantic · procedural · resource · vaultpath*stringattesterobjectfile_text*stringmemory_str_replaceReplace `old_str` with `new_str` in the named memory file. Fails (no partial write) when `old_str` is absent or matches more than once. Writes a new content-addressed `file_cid` and signs the receipt. Mirrors the `str_replace` verb in Anthropic's context-management-2025-06-27...5 paramsReplace `old_str` with `new_str` in the named memory file. Fails (no partial write) when `old_str` is absent or matches more than once. Writes a new content-addressed `file_cid` and signs the receipt. Mirrors the `str_replace` verb in Anthropic's context-management-2025-06-27...
kindstringepisodic · semantic · procedural · resourcepath*stringnew_str*stringold_str*stringattesterobjectmemory_insertInsert `new_str` after the given 1-indexed line in the named memory file. `insert_line: 0` inserts at the top. Writes a new `file_cid` and signs the receipt. Mirrors the `insert` verb in Anthropic's context-management-2025-06-27 memory tool spec. When to use: Call when the LLM...5 paramsInsert `new_str` after the given 1-indexed line in the named memory file. `insert_line: 0` inserts at the top. Writes a new `file_cid` and signs the receipt. Mirrors the `insert` verb in Anthropic's context-management-2025-06-27 memory tool spec. When to use: Call when the LLM...
kindstringepisodic · semantic · procedural · resourcepath*stringnew_str*stringattesterobjectinsert_line*integermemory_deleteDelete a memory file at `/memories/<path>`. When the path ends with `/`, every file beneath the directory is removed. Updates the path index but leaves prior content-addressed blobs in place (the audit history is append-only). Mirrors the `delete` verb in Anthropic's context-m...2 paramsDelete a memory file at `/memories/<path>`. When the path ends with `/`, every file beneath the directory is removed. Updates the path index but leaves prior content-addressed blobs in place (the audit history is append-only). Mirrors the `delete` verb in Anthropic's context-m...
path*stringattesterobjectmemory_renameMove (rename) a memory file from `old_path` to `new_path`. Both paths must stay under `/memories/`; `new_path` must not already exist. The file_cid is preserved (no re-sign) so the prior receipt still binds the bytes. Mirrors the `rename` verb in Anthropic's context-management...3 paramsMove (rename) a memory file from `old_path` to `new_path`. Both paths must stay under `/memories/`; `new_path` must not already exist. The file_cid is preserved (no re-sign) so the prior receipt still binds the bytes. Mirrors the `rename` verb in Anthropic's context-management...
attesterobjectnew_path*stringold_path*stringmemory_list_by_kindList memory files by their typed `kind` (episodic | semantic | procedural | resource). Optional path prefix narrows the scan; results are sorted by signed_at descending. The kind taxonomy follows the CoALA / LangMem / MIRIX agent-memory ontology: `episodic` = observations of e...3 paramsList memory files by their typed `kind` (episodic | semantic | procedural | resource). Optional path prefix narrows the scan; results are sorted by signed_at descending. The kind taxonomy follows the CoALA / LangMem / MIRIX agent-memory ontology: `episodic` = observations of e...
kind*stringepisodic · semantic · procedural · resourcelimitintegerprefixstringemem_memory_searchSemantic search over /memories/* file contents using BGE-base-en-v1.5 (768-D, L2-normalised) backed by a Lance partition (`memory_text_index_d768.lance`). Matches paraphrases — "rainfall in March" finds "precipitation observed in spring" without an exact substring match. Retur...5 paramsSemantic search over /memories/* file contents using BGE-base-en-v1.5 (768-D, L2-normalised) backed by a Lance partition (`memory_text_index_d768.lance`). Matches paraphrases — "rainfall in March" finds "precipitation observed in spring" without an exact substring match. Retur...
kintegerq*stringkindstringpath_prefixstringattester_pubkey_b32stringemem_corpus_state_statsSigned snapshot of corpus liveness: distinct_cells, distinct_bands, facts_scanned, top per-band counts, manifest CIDs. Same payload that backs /v1/stream's corpus.state tick (signed). Use this for a one-shot poll instead of holding an SSE connection. When to use: Call when an...Signed snapshot of corpus liveness: distinct_cells, distinct_bands, facts_scanned, top per-band counts, manifest CIDs. Same payload that backs /v1/stream's corpus.state tick (signed). Use this for a one-shot poll instead of holding an SSE connection. When to use: Call when an...
No parameters — call it with no arguments.
emem_benchmarkHand-verified evaluation items for grading an agent against the responder. Returns {items[], grader_url}. Submit answers (cell64 or fact_cid per item) to POST /v1/benchmark/grade for per-item scores. Items today: elevation recall, NDVI, find_similar neighbours. When to use: Ca...Hand-verified evaluation items for grading an agent against the responder. Returns {items[], grader_url}. Submit answers (cell64 or fact_cid per item) to POST /v1/benchmark/grade for per-item scores. Items today: elevation recall, NDVI, find_similar neighbours. When to use: Ca...
No parameters — call it with no arguments.
emem_recallRecall facts about a cell — auto-materializes on miss for any band with a registered materializer. When to use: Call after `emem_locate` (or with a known cell64). Returns every Primary fact stored at that (cell, band, tslot). IMPORTANT: if the cell has no fact yet for a reques...7 paramsRecall facts about a cell — auto-materializes on miss for any band with a registered materializer. When to use: Call after `emem_locate` (or with a known cell64). Returns every Primary fact stored at that (cell, band, tslot). IMPORTANT: if the cell has no fact yet for a reques...
bandstringcell*stringbandsarrayscopeobjecttslotintegeras_of_tslotintegeras_of_signed_atstringemem_recall_polygonRecall facts across every cell inside a place's polygon (single signed envelope). Closes the place-name-drift gap for wide features (parks, lakes, regions). When to use: Call when the user names a wide feature (national park, river basin, country, large urban area) where one c...8 paramsRecall facts across every cell inside a place's polygon (single signed envelope). Closes the place-name-drift gap for wide features (parks, lakes, regions). When to use: Call when the user names a wide feature (national park, river basin, country, large urban area) where one c...
bandsarrayplacestringtslotintegerincludearraymax_cellsintegeras_of_tslotintegerpolygon_bboxobjectas_of_signed_atstringemem_field_boundariesPer-field agricultural-boundary polygons from the Fields of The World global product (~3.17B fields, 241 countries, 10 m resolution, CC-BY-4.0). Returns a GeoJSON FeatureCollection with the polygon geometries, FIBOA-compatible properties, and a planar `area_m2` per field — plu...3 paramsPer-field agricultural-boundary polygons from the Fields of The World global product (~3.17B fields, 241 countries, 10 m resolution, CC-BY-4.0). Returns a GeoJSON FeatureCollection with the polygon geometries, FIBOA-compatible properties, and a planar `area_m2` per field — plu...
zoomintegerplacestringpolygon_bboxobjectemem_query_regionQuery facts over a region (single cell or list of cells), optionally aggregated per band. When to use: Call when the user asks 'how does region X look', 'what's the average NDVI here', or wants a region-level summary. Use `agg=mean|median|p90|vector_centroid` to fold per-band...5 paramsQuery facts over a region (single cell or list of cells), optionally aggregated per band. When to use: Call when the user asks 'how does region X look', 'what's the average NDVI here', or wants a region-level summary. Use `agg=mean|median|p90|vector_centroid` to fold per-band...
aggstringmean · median · p90 · vector_centroidbandsarraygeometry*stringas_of_tslotintegeras_of_signed_atstringemem_compareCompare two cells: cosine similarity over shared vector bands + per-band scalar deltas. When to use: Call when the user asks 'how similar is X to Y', 'compare these two places', or wants a difference vector. Returns a single cosine score and per-band deltas.3 paramsCompare two cells: cosine similarity over shared vector bands + per-band scalar deltas. When to use: Call when the user asks 'how similar is X to Y', 'compare these two places', or wants a difference vector. Returns a single cosine score and per-band deltas.
a*stringb*stringfamilystringemem_compare_bandsCompare two bands at the same cell. Scalar pair → metric=delta, value=b-a. Vector pair (equal dim) → metric=cosine + per-dim delta. Returns a signed receipt naming both source fact CIDs. When to use: Call when the user wants cross-source consistency at one place ('does Cop-DEM...6 paramsCompare two bands at the same cell. Scalar pair → metric=delta, value=b-a. Vector pair (equal dim) → metric=cosine + per-dim delta. Returns a signed receipt naming both source fact CIDs. When to use: Call when the user wants cross-source consistency at one place ('does Cop-DEM...
a*stringb*stringcell*stringtslot_aintegertslot_bintegerpredicateobjectemem_find_similark-NN over the corpus by cell embedding or inline vector. When to use: Call when the user asks 'find places like X', 'where else looks like this', or hands an embedding to find neighbours. `key` is either a cell64 or `inline:[x,y,...]`. Default band is `geotessera` (128-D Tesse...6 paramsk-NN over the corpus by cell embedding or inline vector. When to use: Call when the user asks 'find places like X', 'where else looks like this', or hands an embedding to find neighbours. `key` is either a cell64 or `inline:[x,y,...]`. Default band is `geotessera` (128-D Tesse...
kintegerkey*stringbandstringmodestringcosine · hamming · hamming_then_rerankdefault: cosineas_of_tslotintegeras_of_signed_atstringemem_trajectoryTime series for one (cell, band) over an inclusive [start, end] tslot window. Returns only what's already attested — does NOT trigger materialization. For historical backfill use `emem_backfill`. When to use: Call when the user asks 'how did X change over time' for a band that...5 paramsTime series for one (cell, band) over an inclusive [start, end] tslot window. Returns only what's already attested — does NOT trigger materialization. For historical backfill use `emem_backfill`. When to use: Call when the user asks 'how did X change over time' for a band that...
band*stringcell*stringwindow*arrayas_of_tslotintegeras_of_signed_atstringemem_diffCompute a DerivativeFact (delta) between a band's values at two tslots. When to use: Call when the user asks 'what changed between t1 and t2', 'give me the delta'. Returns a signed DerivativeFact + receipt — the delta itself is content-addressed and citable.4 paramsCompute a DerivativeFact (delta) between a band's values at two tslots. When to use: Call when the user asks 'what changed between t1 and t2', 'give me the delta'. Returns a signed DerivativeFact + receipt — the delta itself is content-addressed and citable.
band*stringcell*stringtslot_a*integertslot_b*integeremem_memory_contradictionsSurface where the corpus DISAGREES with itself. When two or more independent sources signed different values for the same place + band + time, this returns that disagreement with a 0–1 severity score and citations to every disputed fact — instead of silently picking one value...5 paramsSurface where the corpus DISAGREES with itself. When two or more independent sources signed different values for the same place + band + time, this returns that disagreement with a 0–1 severity score and citations to every disputed fact — instead of silently picking one value...
bandstringlimitintegercell_prefixstringmin_severitynumberwindow_unix_sarrayemem_edges_recallRead temporal knowledge-graph edges (subj --pred--> obj, valid over [valid_from, valid_to)), bi-temporally filtered, in EITHER direction. Forward (`subj`, direction="out", the default): edges originating at a subject fact. Reverse (`obj`, direction="in"): edges pointing AT a f...6 paramsRead temporal knowledge-graph edges (subj --pred--> obj, valid over [valid_from, valid_to)), bi-temporally filtered, in EITHER direction. Forward (`subj`, direction="out", the default): edges originating at a subject fact. Reverse (`obj`, direction="in"): edges pointing AT a f...
objstringpredstringsubjstringlimitintegerdirectionstringout · inas_of_tslotintegeremem_fetchFetch a fact by its content-address (CID). Returns the full signed Primary or Absence fact — the same body served by REST `/v1/facts/{cid}`. Closes the citation loop: any fact_cid surfaced by recall, materialize, attest, or verify can be re-resolved by another agent without RE...1 paramsFetch a fact by its content-address (CID). Returns the full signed Primary or Absence fact — the same body served by REST `/v1/facts/{cid}`. Closes the citation loop: any fact_cid surfaced by recall, materialize, attest, or verify can be re-resolved by another agent without RE...
cid*stringemem_backfillMaterialize and sign every per-tslot fact for one (cell, band) inside a [start_unix, end_unix] window. Returns a signed list of (tslot, fact_cid, status) for each step. Slow but possible — one upstream fetch per tslot, capped by `max_facts`. When to use: Call when the user wan...5 paramsMaterialize and sign every per-tslot fact for one (cell, band) inside a [start_unix, end_unix] window. Returns a signed list of (tslot, fact_cid, status) for each step. Slow but possible — one upstream fetch per tslot, capped by `max_facts`. When to use: Call when the user wan...
band*stringcell*stringend_unixintegermax_factsintegerstart_unixintegeremem_heat_solveForward-step 2-D explicit finite-difference solver for the heat equation ∂u/∂t = α∇²u over a 3×3 cell stencil centred on `cell`. Reads `modis.lst_day_8day` (Land Surface Temperature) at the centre and 8 cell64 neighbours, integrates N hours ahead under a CFL-stable timestep, r...3 paramsForward-step 2-D explicit finite-difference solver for the heat equation ∂u/∂t = α∇²u over a 3×3 cell stencil centred on `cell`. Reads `modis.lst_day_8day` (Land Surface Temperature) at the centre and 8 cell64 neighbours, integrates N hours ahead under a CFL-stable timestep, r...
cell*stringhours_aheadnumberdiffusivity_m2_per_snumberemem_wave_solveForward-step 1-D explicit finite-difference solver for the shallow-water wave equation ∂²u/∂t² = c²∂²u/∂x² with c² = g·h, where depth h comes from `gmrt.topobathy_mean` along the seaward gradient. Models how an offshore swell of height H_s and period T propagates toward `coast...4 paramsForward-step 1-D explicit finite-difference solver for the shallow-water wave equation ∂²u/∂t² = c²∂²u/∂x² with c² = g·h, where depth h comes from `gmrt.topobathy_mean` along the seaward gradient. Models how an offshore swell of height H_s and period T propagates toward `coast...
period_s*numbercoastal_cell*stringn_offshore_cellsintegeroffshore_height_m*numberemem_jepa_predictPredict next-month NDVI at a cell using a constrained JEPA-pattern AR(2) seasonal predictor. Reads up to 24 past months of `indices.ndvi`, fits a closed-form predictor `y_{t+1} = α·(lag-12 NDVI or recent mean) + β·(last + slope) + γ·recent_mean`, returns the prediction clamped...4 paramsPredict next-month NDVI at a cell using a constrained JEPA-pattern AR(2) seasonal predictor. Reads up to 24 past months of `indices.ndvi`, fits a closed-form predictor `y_{t+1} = α·(lag-12 NDVI or recent mean) + β·(last + slope) + γ·recent_mean`, returns the prediction clamped...
bandstringcell*stringlookback_monthsintegerforecast_horizon_monthsintegeremem_jepa_predict_v2Predict the next-step value of 4 environmental scalars at a cell — `indices.ndvi`, `modis.lst_day_8day`, `modis.lst_night_8day`, `cams.pm25` — using a small learned dynamics MLP. Reads up to K=6 most-recent attested lags per band, runs them through an ONNX dynamics head (~200k...1 paramsPredict the next-step value of 4 environmental scalars at a cell — `indices.ndvi`, `modis.lst_day_8day`, `modis.lst_night_8day`, `cams.pm25` — using a small learned dynamics MLP. Reads up to K=6 most-recent attested lags per band, runs them through an ONNX dynamics head (~200k...
cell*stringemem_verifyVerify a structured claim against a cell's facts. Returns verdict + evidence CIDs + signed receipt. When to use: Call when the user asks a yes/no question about a cell ('is the NDVI > 0.7 here', 'has this been deforested'), or when downstream code wants citable evidence for a...3 paramsVerify a structured claim against a cell's facts. Returns verdict + evidence CIDs + signed receipt. When to use: Call when the user asks a yes/no question about a cell ('is the NDVI > 0.7 here', 'has this been deforested'), or when downstream code wants citable evidence for a...
cell*stringmodestringfast · resolvedefault: fastclaim*objectemem_bandsActive band ontology (offsets, dims, tempo, privacy). When to use: Call once at session start to learn the band registry — every other primitive's `band` argument MUST come from this list.Active band ontology (offsets, dims, tempo, privacy). When to use: Call once at session start to learn the band registry — every other primitive's `band` argument MUST come from this list.
No parameters — call it with no arguments.
emem_functionsActive function registry (derivation recipes). When to use: Call when you need to know which derivative ops are available for `emem_diff` or how a band is computed from upstream sources.Active function registry (derivation recipes). When to use: Call when you need to know which derivative ops are available for `emem_diff` or how a band is computed from upstream sources.
No parameters — call it with no arguments.
emem_sourcesActive source-connector registry (URL templates, providers, licenses). When to use: Call when you need to inspect which upstream EO providers are wired (Copernicus DEM, JRC GSW, ESA WorldCover, etc.) — useful for license attribution in agent answers.Active source-connector registry (URL templates, providers, licenses). When to use: Call when you need to inspect which upstream EO providers are wired (Copernicus DEM, JRC GSW, ESA WorldCover, etc.) — useful for license attribution in agent answers.
No parameters — call it with no arguments.
emem_schemaActive CDDL/JSON schema bundle by CID. When to use: Rarely needed at chat time. Useful for offline verification of receipts / attestations against the exact schema version a responder used.Active CDDL/JSON schema bundle by CID. When to use: Rarely needed at chat time. Useful for offline verification of receipts / attestations against the exact schema version a responder used.
No parameters — call it with no arguments.
emem_errorsStable error code catalog. When to use: Call to enumerate the wire-stable error codes — useful when the LLM wants to programmatically branch on responses.Stable error code catalog. When to use: Call to enumerate the wire-stable error codes — useful when the LLM wants to programmatically branch on responses.
No parameters — call it with no arguments.
emem_manifestsActive manifest CIDs (bands / functions / sources / schema). When to use: Call to learn which exact registry versions a responder is serving. Cite these CIDs alongside any answer where reproducibility matters.Active manifest CIDs (bands / functions / sources / schema). When to use: Call to learn which exact registry versions a responder is serving. Cite these CIDs alongside any answer where reproducibility matters.
No parameters — call it with no arguments.
emem_capabilitiesLive capability snapshot of the responder's GPU sidecar — extensions[] (e.g. gpu, clay-v1.5, prithvi-eo2), cuda_available, models_loaded[], healthy, last_polled_unix_s. Refreshed every 30 s by a background poller; reads are constant-time. When to use: Call before scheduling a...Live capability snapshot of the responder's GPU sidecar — extensions[] (e.g. gpu, clay-v1.5, prithvi-eo2), cuda_available, models_loaded[], healthy, last_polled_unix_s. Refreshed every 30 s by a background poller; reads are constant-time. When to use: Call before scheduling a...
No parameters — call it with no arguments.
emem_grid_infoActive grid encoding: cell64 ground resolution, lat/lng axis sizes, DGGS lineage. When to use: Call once at session start (or when the user asks about cell resolution / 'how big is a cell'). Returns the actual ground resolution today (~9.54 m × 9.55 m square at the equator (la...Active grid encoding: cell64 ground resolution, lat/lng axis sizes, DGGS lineage. When to use: Call once at session start (or when the user asks about cell resolution / 'how big is a cell'). Returns the actual ground resolution today (~9.54 m × 9.55 m square at the equator (la...
No parameters — call it with no arguments.
emem_coverage_matrixPer-band live status — what data is alive AND auto-materializable, with history bounds, tempo cadence, and the responder pubkey that signs the band. When to use: Call BEFORE `emem_recall` when you don't know which bands answer at this responder. For each band returns `has_mate...Per-band live status — what data is alive AND auto-materializable, with history bounds, tempo cadence, and the responder pubkey that signs the band. When to use: Call BEFORE `emem_recall` when you don't know which bands answer at this responder. For each band returns `has_mate...
No parameters — call it with no arguments.
emem_materializersAuto-fetch registry: which bands the responder will materialize on a recall miss, the upstream provider, license, value shape, and history bounds. When to use: Call once at session start (alongside `emem_bands` and `emem_coverage_matrix`) to learn which bands answer for ANY ce...Auto-fetch registry: which bands the responder will materialize on a recall miss, the upstream provider, license, value shape, and history bounds. When to use: Call once at session start (alongside `emem_bands` and `emem_coverage_matrix`) to learn which bands answer for ANY ce...
No parameters — call it with no arguments.
emem_data_availabilityTemporal catalog: for every materializable band the upstream-of-record window the data genuinely covers, the temporal `kind` (static | annual_snapshot | annual_stack | time_series | now_only | per_release), tempo seconds, upstream wire path, and whether `emem_backfill` is mean...Temporal catalog: for every materializable band the upstream-of-record window the data genuinely covers, the temporal `kind` (static | annual_snapshot | annual_stack | time_series | now_only | per_release), tempo seconds, upstream wire path, and whether `emem_backfill` is mean...
No parameters — call it with no arguments.
emem_algorithmsContent-addressed dictionary of composition recipes — formulas that fuse attested band facts (and embeddings) into derived scores, classifications, and similarity metrics. When to use: Call when the user's question is COMPOSITE (flood risk, urban density, water consensus, chan...Content-addressed dictionary of composition recipes — formulas that fuse attested band facts (and embeddings) into derived scores, classifications, and similarity metrics. When to use: Call when the user's question is COMPOSITE (flood risk, urban density, water consensus, chan...
No parameters — call it with no arguments.
emem_explain_algorithmPer-key drill-down on a single composition recipe — full body (kind, inputs, formula, output, citation, references) for ONE algorithm key. Companion to `emem_algorithms` (which is the catalog). When to use: Call when you already know the algorithm key (from `emem_algorithms`'s...1 paramsPer-key drill-down on a single composition recipe — full body (kind, inputs, formula, output, citation, references) for ONE algorithm key. Companion to `emem_algorithms` (which is the catalog). When to use: Call when you already know the algorithm key (from `emem_algorithms`'s...
key*stringemem_topicsTopic-grouped registry of every band and algorithm at this responder, plus visual surfaces and the `declared_but_no_materializer_at_this_responder` block (cube slots reserved without a live connector). Single source of truth shared with `/v1/locate`'s `data_at_this_cell` block...Topic-grouped registry of every band and algorithm at this responder, plus visual surfaces and the `declared_but_no_materializer_at_this_responder` block (cube slots reserved without a live connector). Single source of truth shared with `/v1/locate`'s `data_at_this_cell` block...
No parameters — call it with no arguments.
emem_coverage_mapLive SVG render of the responder's corpus density, returned as a proper MCP EmbeddedResource content block (image/svg+xml) — multimodal MCP agents can render it natively. When to use: Call when the user asks 'where do you have data?', 'show me the coverage', or wants a visual...Live SVG render of the responder's corpus density, returned as a proper MCP EmbeddedResource content block (image/svg+xml) — multimodal MCP agents can render it natively. When to use: Call when the user asks 'where do you have data?', 'show me the coverage', or wants a visual...
No parameters — call it with no arguments.
emem_cell_scene_rgbTrue-colour Sentinel-2 L2A RGB thumbnail centred on a cell. PNG returned as a native MCP ImageContent block (mimeType image/png). Pure-Rust pipeline: STAC search + HTTP-Range COG reads + 2-98 percentile stretch + PNG encode. When to use: Call when the user wants a VISUAL of a...3 paramsTrue-colour Sentinel-2 L2A RGB thumbnail centred on a cell. PNG returned as a native MCP ImageContent block (mimeType image/png). Pure-Rust pipeline: STAC search + HTTP-Range COG reads + 2-98 percentile stretch + PNG encode. When to use: Call when the user wants a VISUAL of a...
cell*stringdatetimestringmax_cloudnumberemem_cell_geojsonCell polygon as a native MCP EmbeddedResource (mimeType application/geo+json). Properties carry centre lat/lng, bbox, approx size in metres, and the 8-cell neighbourhood — drop straight into Mapbox / Leaflet / Deck.gl / QGIS without a GIS pipeline. When to use: Call when the a...1 paramsCell polygon as a native MCP EmbeddedResource (mimeType application/geo+json). Properties carry centre lat/lng, bbox, approx size in metres, and the 8-cell neighbourhood — drop straight into Mapbox / Leaflet / Deck.gl / QGIS without a GIS pipeline. When to use: Call when the a...
cell*stringemem_recall_manyRecall facts across a list of up to 256 cell64 strings in one signed envelope. Server fans out per-cell recalls in parallel, then aggregates the response. Auto-materializes any cell with a missing fact whose band has a registered materializer — same contract as emem_recall. Wh...4 paramsRecall facts across a list of up to 256 cell64 strings in one signed envelope. Server fans out per-cell recalls in parallel, then aggregates the response. Auto-materializes any cell with a missing fact whose band has a registered materializer — same contract as emem_recall. Wh...
bandstringbandsarraycells*arraytslotintegeremem_elevationOne-shot elevation answer that fuses Cop-DEM 30 m (land), GMRT (ocean topobathy), and ESA WorldCover (water mask) into a single signed scalar at a place or coordinate. Returns `elevation_m`, the source actually used, and a `coherence_note` when the two surfaces disagree at the...4 paramsOne-shot elevation answer that fuses Cop-DEM 30 m (land), GMRT (ocean topobathy), and ESA WorldCover (water mask) into a single signed scalar at a place or coordinate. Returns `elevation_m`, the source actually used, and a `coherence_note` when the two surfaces disagree at the...
latnumberlngnumbercellstringplacestringemem_fleetPer-band satellite-and-sensor fleet inventory — names the upstream platform (e.g. Sentinel-2A/B, MODIS Aqua/Terra, Landsat-8/9), revisit cadence, native resolution, and license for every materialized band. Lets an agent attribute imagery products correctly and pick the right b...Per-band satellite-and-sensor fleet inventory — names the upstream platform (e.g. Sentinel-2A/B, MODIS Aqua/Terra, Landsat-8/9), revisit cadence, native resolution, and license for every materialized band. Lets an agent attribute imagery products correctly and pick the right b...
No parameters — call it with no arguments.
emem_temporal_routeTurn a time-shaped question into a ready-to-run recall plan: it figures out WHICH bands to pull at WHICH past time windows (e.g. 'the year before the flood', 'last growing season', 'two vintages to compare') so you don't have to compute tslot offsets by hand. Returns the band...5 paramsTurn a time-shaped question into a ready-to-run recall plan: it figures out WHICH bands to pull at WHICH past time windows (e.g. 'the year before the flood', 'last growing season', 'two vintages to compare') so you don't have to compute tslot offsets by hand. Returns the band...
cell*stringbandsarraylimitintegerintentstringquery_timeintegeremem_verify_receiptVerify a signed receipt envelope server-side: recomputes the canonical preimage (`request_id | served_at | primitive | cells, | fact_cids,`), runs ed25519 over the embedded pubkey + signature, and returns `{valid, reason, pubkey_b32}`. Use when the in-browser /verify path is b...2 paramsVerify a signed receipt envelope server-side: recomputes the canonical preimage (`request_id | served_at | primitive | cells, | fact_cids,`), runs ed25519 over the embedded pubkey + signature, and returns `{valid, reason, pubkey_b32}`. Use when the in-browser /verify path is b...
receipt*objectpubkey_b32stringemem_atOne-shot multi-band recall at a place (or lat/lng). Defaults to emem's standard at-a-glance band set; pass `band` / `bands` to override. Polygon-resolved places stay at the centroid by default (`n_cells: 1`) to keep multi-band calls cheap — pass `n_cells: 2..=64` to fan out. W...8 paramsOne-shot multi-band recall at a place (or lat/lng). Defaults to emem's standard at-a-glance band set; pass `band` / `bands` to override. Polygon-resolved places stay at the centroid by default (`n_cells: 1`) to keep multi-band calls cheap — pass `n_cells: 2..=64` to fan out. W...
latnumberlngnumberbandstringbandsstringplacestringtslotintegerincludearrayn_cellsintegeremem_ndviRecall Sentinel-2 NDVI (indices.ndvi, 10 m native) at a point or place. Composes locate → cell64 → recall in one call; auto-materializes on miss. When to use: Use when the user names a place (or lat/lng) and just wants the NDVI number. Polygon-resolved places default to a 16-c...8 paramsRecall Sentinel-2 NDVI (indices.ndvi, 10 m native) at a point or place. Composes locate → cell64 → recall in one call; auto-materializes on miss. When to use: Use when the user names a place (or lat/lng) and just wants the NDVI number. Polygon-resolved places default to a 16-c...
latnumberlngnumberbandstringbandsstringplacestringtslotintegerincludearrayn_cellsintegeremem_airRecall Copernicus CAMS air-quality bands at a place: PM2.5 + NO2 + O3. Composes locate → recall → aggregate. When to use: Use when the user names a place and asks about air quality, pollution, or emissions exposure. CAMS is the European reanalysis — global coverage, ~0.4° nati...8 paramsRecall Copernicus CAMS air-quality bands at a place: PM2.5 + NO2 + O3. Composes locate → recall → aggregate. When to use: Use when the user names a place and asks about air quality, pollution, or emissions exposure. CAMS is the European reanalysis — global coverage, ~0.4° nati...
latnumberlngnumberbandstringbandsstringplacestringtslotintegerincludearrayn_cellsintegeremem_lstRecall MODIS land surface temperature day-8day + night-8day composites at a place. 1 km native, 8-day composite. When to use: Use when the user asks about surface heat, urban heat island, thermal anomalies, or wants day/night LST. Returns both fluxes so the agent can derive da...8 paramsRecall MODIS land surface temperature day-8day + night-8day composites at a place. 1 km native, 8-day composite. When to use: Use when the user asks about surface heat, urban heat island, thermal anomalies, or wants day/night LST. Returns both fluxes so the agent can derive da...
latnumberlngnumberbandstringbandsstringplacestringtslotintegerincludearrayn_cellsintegeremem_soilRecall SoilGrids 250 m profile at a place: SOC, pH, clay/sand/silt fractions, bulk density, nitrogen — all at 0–30 cm depth. When to use: Use when the user asks about soil quality, agricultural suitability, or carbon stocks at a location. Six bands returned in one envelope.8 paramsRecall SoilGrids 250 m profile at a place: SOC, pH, clay/sand/silt fractions, bulk density, nitrogen — all at 0–30 cm depth. When to use: Use when the user asks about soil quality, agricultural suitability, or carbon stocks at a location. Six bands returned in one envelope.
latnumberlngnumberbandstringbandsstringplacestringtslotintegerincludearrayn_cellsintegeremem_waterRecall surface-water signals at a place: JRC Global Surface Water recurrence (1984–2021) + Sentinel-1 SAR backscatter (current). Pair detects standing water through clouds. When to use: Use when the user asks about flooding, wetlands, surface-water dynamics, or wants a robust...8 paramsRecall surface-water signals at a place: JRC Global Surface Water recurrence (1984–2021) + Sentinel-1 SAR backscatter (current). Pair detects standing water through clouds. When to use: Use when the user asks about flooding, wetlands, surface-water dynamics, or wants a robust...
latnumberlngnumberbandstringbandsstringplacestringtslotintegerincludearrayn_cellsintegeremem_forestRecall forest signals at a place: Hansen Global Forest Change (tree cover 2000 baseline + year-of-loss) + ESA WorldCover 2021 land class. When to use: Use when the user asks about deforestation, canopy cover, forest loss, or wants a forest-vs-not classification. Hansen gives y...8 paramsRecall forest signals at a place: Hansen Global Forest Change (tree cover 2000 baseline + year-of-loss) + ESA WorldCover 2021 land class. When to use: Use when the user asks about deforestation, canopy cover, forest loss, or wants a forest-vs-not classification. Hansen gives y...
latnumberlngnumberbandstringbandsstringplacestringtslotintegerincludearrayn_cellsintegeremem_weatherRecall the standard met.no/CAMS weather bundle at a place: 2 m temperature + total cloud cover + precipitation + 10 m wind speed. When to use: Use when the user names a place and asks 'what's the weather' or wants a now-cast snapshot. weather.* bands are now-only (no backfill)...8 paramsRecall the standard met.no/CAMS weather bundle at a place: 2 m temperature + total cloud cover + precipitation + 10 m wind speed. When to use: Use when the user names a place and asks 'what's the weather' or wants a now-cast snapshot. weather.* bands are now-only (no backfill)...
latnumberlngnumberbandstringbandsstringplacestringtslotintegerincludearrayn_cellsinteger
Earth as memory, for real-world agents.
Hosted · Docs · Spec · OpenAPI · Try it · /verify · Gallery · HF Space
Ask an AI agent what is on the ground at 19.07° N, 72.87° E and it will guess. It has no fixed handle for that patch of Earth, and no way to prove whatever number it returns. emem is the handle. It is a shared memory of the planet that an agent can read, write, and cite, where every answer is signed so anyone can check it later without trusting the server that produced it.
The planet is cut into fixed cells about 9.55 m across, the way a page is cut into words. One measurement at one cell is a fact: an elevation, a rainfall total, this year's forest loss, a satellite embedding. Every fact is signed. When an agent asks about a place nobody has measured yet, the responder pulls the value from a real satellite source, signs it, and hands it back in the same response. Nothing is pre-seeded. Every cell on Earth answers from the first request.
emem is a protocol. A fact is named by the blake3 hash of its own bytes, so the name carries the data's fingerprint and means the same thing on every machine. The responder signs that name with an ed25519 key, the kind that secures SSH and HTTPS. Any responder can serve a fact and any client can verify it offline, with no account and no key to manage. Paste a fact id into a chat and a colleague pulls the same bytes from any node and checks the signature in their own browser at /verify. The hosted node is https://emem.dev. The same binary self-hosts with one docker run, and the same handlers answer both MCP and plain REST. Run enough nodes and you get a federation: independent responders that resolve the same ids byte for byte and write down where they disagree. The memory gets more trustworthy as more agents use it.
A cell64 addresses a place the way a token addresses text in an LLM. Every patch of ground about 9.55 m wide gets a 64-bit id, and ids that look alike sit physically near each other. A fact is one measurement at that cell, keyed by (cell, band, time) and packed in a fixed byte order (canonical CBOR) so the same reading hashes the same way on every machine. That blake3 hash is the fact's content id. Change one byte and the id changes, so the id proves the bytes. The responder signs it. The signed envelope it returns is the receipt, and the receipt checks out offline against the responder's public key without any trust in the server.
When an agent asks for a band at a cell that has no signed fact yet, the responder fetches the underlying tile through one of its 46 upstream sources, signs the result under its own key, persists it, and returns it in the same response. A cold read takes about 180 ms. A warm read is under ten. Five of the 46 schemes are declared but not yet wired (openet.30m.daily, dynamic_world.v1, tropomi.s5p.ch4, tropomi.s5p.no2, viirs.dnb.monthly); they answer with a typed Absence. When a band genuinely has no value at a cell, because the place is outside coverage or the upstream is unreachable, the answer is still a signed absence with a reason you can read. An empty answer is a citable receipt. The catalog never promises more than it can sign.
# Geocode a place to a cell64.
curl -s -X POST https://emem.dev/v1/locate \
-H 'content-type: application/json' \
-d '{"q":"Bengaluru"}' | jq .cell64
# "defi.zb493.xuqA.zcb5f" # (geocoder result, may drift)
# Recall a band at that cell (auto-fetched if cold).
curl -s -X POST https://emem.dev/v1/recall \
-H 'content-type: application/json' \
-d '{"cell":"defi.zb493.xuqA.zcb5f","bands":["weather.temperature_2m"]}' \
| jq '.facts[0]'
# Ask a free-text question; the foundation-embedding fan-out fires
# automatically on "find places like" / "what changed" intents.
curl -s -X POST https://emem.dev/v1/ask \
-H 'content-type: application/json' \
-d '{"q":"find places like Yellowstone","place":"Yellowstone National Park"}' \
| jq '.answer'
# Hunter mode: discover event hotspots over a named region. The same
# classifier reads "find <event> in <region>" from /v1/ask and routes
# here; structured callers can hit /v1/hunt directly.
curl -s -X POST https://emem.dev/v1/hunt \
-H 'content-type: application/json' \
-d '{"event":"algal_bloom","region":"Lake Erie"}' \
| jq '.hotspots[0]'
The receipt's fact_cid is a durable handle. Re-fetching it from any responder, in any year, returns the same bytes.
The pitch lives or dies on this flow. Every recall response carries a receipt with fact_cids[], a merkle_proof, and an Ed25519 signature over a domain-separated, length-prefixed preimage: blake3("emem.preimage.v1" ‖ "receipt" ‖ tagged(request_id, served_at, [scope], [as_of], [edges], [manifest], primitive, cells[], fact_cids[])). Tagging every field and prefixing its length means no two distinct responses can ever share signed bytes; the receipt's preimage_version selects the rule, and pre-v1 receipts still verify under the original one. The signer's public key is stable; the receipt verifies offline against any copy of the responder pubkey. The merkle tree uses RFC 6962 leaf/node domain separation and rejects duplicate leaves.
Here is a real one. Ask https://emem.dev for the elevation under Denver and it returns the city's nickname as a signed number, mile-high at 1609 m, which anyone can re-check without trusting the server:
// POST /v1/recall {"cell":"defi.zb5c4.guxe.nuxe","bands":["copdem30m.elevation_mean"]}
{
"facts": [{ "cell": "defi.zb5c4.guxe.nuxe", "band": "copdem30m.elevation_mean",
"value": 1609.0, "unit": "m", "source": "copernicus.dem.glo30" }],
"receipt": {
"primitive": "emem.recall",
"fact_cids": ["72wdchiyurfrjxz7zat6kor7gjnvsn564fbrzjkmlhagoy4rrh4a"],
"responder_pubkey_b32": "777er3yihgifqmv5hmc2wwmy…",
"preimage_version": 1,
"signature": "…ed25519 over the canonical preimage…"
}
}
Paste that fact_cid into /verify and the page re-derives the hash and checks the signature in your browser. The four curls below do the same from a shell:
# 1. Resolve a place to a cell64.
CELL=$(curl -s -X POST https://emem.dev/v1/locate \
-H 'content-type: application/json' \
-d '{"q":"Golden Gate Park, San Francisco"}' | jq -r .cell64)
# 2. Recall a band and capture the receipt envelope.
curl -s -X POST https://emem.dev/v1/recall \
-H 'content-type: application/json' \
-d "{\"cell\":\"$CELL\",\"bands\":[\"indices.ndvi\"]}" > /tmp/recall.json
jq '.receipt | {primitive, served_at, responder_pubkey_b32, fact_cids, merkle_proof: .merkle_proof.root}' \
/tmp/recall.json
# 3. Ask the responder to verify its own signature (server-side check).
jq '{receipt: .receipt}' /tmp/recall.json > /tmp/receipt.json
curl -s -X POST https://emem.dev/v1/verify_receipt \
-H 'content-type: application/json' --data @/tmp/receipt.json
# {"valid":true,"preimage_blake3_hex":"…","fact_cids_count":1,"signer_pubkey_b32":"…",…}
# 4. Reproduce: pull the same fact_cid from any responder, on any day.
# The cell, band, tslot, and derivation.fn_key are content-addressed, so
# the bytes you receive will hash to the same fact_cid.
jq '.facts[0].derivation' /tmp/recall.json
For a browser-only verify, open /verify/<fact_cid>; the page does the same Ed25519 check in WebCrypto + @noble/ed25519 so you never have to trust the responder you got the receipt from. A guided walk lives at /demos/signed-answer.
One binary. The same handlers answer MCP and plain REST, reads need no auth, and every write lands in an append-only signed log. Four content-addressed manifests (bands_cid, algorithms_cid, sources_cid, schema_cid) pin exactly what produced each answer. The full deployment suite lives at /docs/diagrams.
A cache hands back a tile. A memory remembers what it saw, links it to what it saw before, and says so when two sources disagree. emem gives an agent that second thing on top of the fact store, and the agent owns it.
An agent's memory of Earth, drawn as an engram. Each cell is a node and each edge a synapse that relates, supersedes, or disagrees. Recall draws signed facts inward to the lotus where the shared memory consolidates, and every node carries its own signature.
Writes land in /memories/ as content-addressed, signed files. memory_create makes one, memory_str_replace and memory_insert edit it, and memory_search runs a BGE-768 embedding query over the contents through a LanceDB IVF_PQ index, so an agent finds a note it wrote last week by meaning instead of by filename. Each file carries a kind from the CoALA taxonomy: episodic for what happened, semantic for what holds true, procedural for how to do a thing, resource for a pointer out. A write under /memories/by_attester/<pubkey>/ is capability-bound, so a path owned by one key turns away every other signer. The signature that proves a Sentinel-2 reading is the same signature that proves the agent's own notes are untouched.
The memory connects facts and notices when they fight. memory_bundle folds N facts into one signed envelope, memb:<bundle_cid>, that resolves to identical bytes on any peer, so an agent hands over a single citation for a whole finding instead of a list of loose ids. memory_contradictions walks the cases where two attesters signed different values at the same (cell, band, tslot) and scores the gap by band kind: normalised spread for a scalar, mean cosine for a vector, mode-share for a category. A second node that read the same Sentinel scene on a cloudier day leaves a trace the agent can weigh instead of a silent overwrite.
Every read takes a bi-temporal bound. as_of_tslot asks what the world looked like at a past moment. as_of_signed_at asks what the system knew at a past moment. Set both and both hold. The receipt records the bound, so an auditor in 2027 takes a 2026 receipt to any peer and replays the exact same query.
The memory is live, and you can watch it. GET /v1/stream is a Server-Sent Events heartbeat. Every few seconds the responder signs a snapshot of corpus state and pushes it, so a dashboard or an agent follows the shared memory growing without polling for it. The tick is signed like everything else, captured here straight off https://emem.dev:
event: state
data: {
"type": "corpus.state",
"served_at": "2026-06-12T16:17:30Z",
"corpus": { "distinct_cells": 8147, "distinct_bands": 75, "facts_scanned": 32768 },
"responder": { "pubkey_b32": "777er3yihgifqmv5hmc2wwmy…", "key_epoch": 0 },
"signature": {
"alg": "ed25519",
"preimage": "emem.stream.tick|v0.1.0|epoch0|2026-06-12T16:17:30Z|registry:3pbqnyni…|cells:8147",
"signature_b32": "xk2hiluwmfywwnfj…"
}
}
GET /v1/memory/sse?path_prefix=&kind=&attester= is the narrow stream. It pushes one event the moment a memory write commits, filtered server-side, so a compliance subscriber sees a write to a watched path the instant its sled commit lands rather than on the next poll.
The MCP endpoint is https://emem.dev/mcp. Drop a config snippet into your client.
| Client | Config |
|---|---|
| Claude Desktop | examples/claude-desktop.json |
| Claude Code | examples/claude-code.mcp.json |
| Cursor | examples/cursor.mcp.json |
| Cline (VS Code) | examples/cline.mcp.json |
| Gemini CLI | gemini extensions install https://emem.dev/gemini-extension.json |
| ChatGPT (Custom GPT) | examples/openai-gpt-action.json |
| LangChain (Python) | examples/langchain.py |
| LangChain MCP agent | examples/langchain/ |
| LlamaIndex (Python) | examples/llamaindex.py |
| LlamaIndex MCP agent | examples/llamaindex/ |
| Agno MCP agent | examples/agno/ |
| Pydantic AI MCP agent | examples/pydantic-ai/ |
| AutoGen MCP agent | examples/autogen/ |
| CrewAI MCP agent | examples/crewai/ |
| Mastra MCP agent | examples/mastra/ |
Python (ememdev) and TypeScript (@emem/client) SDKs live under sdks/ (PyPI / npm publication pending; install from the repo today).
81 MCP tools (10 core, 71 extended), 93 documented REST paths under /v1/*, surfaced through /openapi.json. Every tool carries a when_to_use string written for LLM tool-selection, and four MCP behavioural annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint). A no-param tools/list returns all 81 tools (so every MCP client discovers the full surface); pass {"tier":"core"} for just the 10 essentials. Tools are callable via tools/call regardless of tier.
cell64. Five-layer cascade: wide-bbox table → embedded gazetteer → GeoNames cities-5000 (68 581 places, in-process) → sled cache → Photon → Nominatim. Polygon geometry from Overture divisions/division_area. District-level queries reroute through Overture when Nominatim returns a POI courthouse.POST /v1/state returns a signed dense per-place embedding (view=encoder default 128-D, view=cube full 1792-D). POST /v1/state_multi fans across geotessera + clay_v1 + prithvi_eo2 + galileo. POST /v1/state_diff returns residual + L2 + cosine between two vintages. POST /v1/memory_token composes memt:<cell64>:<fact_cid>. POST /v1/memory_bundle composes a signed envelope memb:<bundle_cid> over N (cell, band, tslot) triples. Six MCP file-op verbs (memory_view, memory_create, memory_str_replace, memory_insert, memory_delete, memory_rename) conform to Anthropic's memory-tool spec; every write is ed25519-signed and content-addressed. Paths under /memories/by_attester/<pubkey>/... enforce capability binding (ed25519 signature over blake3("emem.memory_write|" + verb + "|" + path + "|" + body_hash)). Each file carries a kind from the CoALA taxonomy (episodic / semantic / procedural / resource). POST /v1/memory/search does BGE-768 semantic search over file contents via a LanceDB IVF_PQ partition. POST /v1/memory_contradictions walks a parallel multi-attester index and scores disagreement per band kind (scalar / vector / categorical). GET /v1/memory/sse?path_prefix=&kind=&attester= streams write events with server-side filter. Every read primitive accepts as_of_tslot + as_of_signed_at for bi-temporal queries (valid-time + transaction-time); the receipt carries an as_of block when set. See docs/memory.md for the full reference.hamming_then_rerank triages with Hamming then re-orders by cosine; the over-sampling factor is EWMA-adaptive.emem_edges_recall reads a fact's signed connections of type disagrees_with, supersedes, or relates_to, bounded by valid-time), multi-attester contradiction scoring (memory_contradictions, per band kind), and a deterministic refinement loop that re-derives a fact when a newer attestation or a disagrees_with edge lands. All three ship in 0.1.0./v1/heat_solve (2-D explicit FTCS heat, MODIS LST stencil), /v1/wave_solve (1-D shallow-water along seaward bathymetry gradient), /v1/jepa_predict (closed-form NDVI AR(2) seasonal), /v1/jepa_predict_v2 (Tessera embedding dynamics; short-circuits to last-vintage identity baseline while the trained head is pending, receipt carries untrained_baseline).find places like / what changed / deforestation / anomaly (cross-encoder consensus over Clay + Prithvi + Tessera), corpus-meta intents on where do you have data / how fresh is your corpus (redirect to coverage surfaces), and hunter-mode discovery on find <event> in <region> (routes to /v1/hunt).POST /v1/hunt and MCP emem_hunt for open-world event discovery. Twelve event keywords (algal_bloom, deforestation, flood_extent, wildfire, urban_heat_island, methane_plume, landslide, drought, soil_salinity, crop_stress, water_turbidity, oil_slick) each map to a registered detection algorithm. The responder samples up to 32 cells from the named region (8 for slow primary bands such as MODIS LST), recalls the algorithm's primary scalar plus any configured gate band (e.g. NDWI > 0 for water-mask events), and returns the top 8 hotspots with cell64, lat/lng, recalled value, gate value, fact CID, and a Sentinel-2 scene URL. A Tessera embedding rerank fires when at least three candidate cells have a geotessera vector available, re-ordering by cosine similarity to the cluster centroid. oil_slick returns status: not_yet_implemented with pointers at flood_extent_sar_threshold@1 and water_turbidity_red_band@1 instead of fabricating detections.POST /v1/eudr_dds and MCP emem_eudr_dds produce a signed Annex II-shaped DDS under Regulation (EU) 2023/1115. The per-cell algorithm eudr_compliance@1 implements Article 2(4) as written: >0.5 ha, >5 m height, >10 % canopy cover, excluding land predominantly under agricultural or urban use. The verdict is the consensus of two static baselines read with one windowed COG sample per band over the plot: JRC GFC2020 V3 (the Commission's expected non-binding baseline) for forest-at-cut-off, and Hansen GFC v1.12 loss-year for clearing strictly after the 31 December 2020 cut-off. A cell cleared on or before the cut-off is not_in_scope, never a pass. Plot aggregation applies the Article 2(4) 0.5 ha minimum-mapping-unit floor, and the Article 2(28) dispatch picks POINT (≤4 ha non-cattle) vs POLYGON (>4 ha or any cattle plot under HS 0102/0201/0202). Each plot also carries a loss_year_histogram, the per-year distribution of Hansen loss-year over its sampled cells, signed as its own forest_change.lossyear_histogram derivative whose id is folded into the receipt, so the loss-year breakdown is a verifiable figure rather than an unsigned summary. JRC TMF, Sims et al. 2025 driver attribution, and RADD Sentinel-1 alerts sit off the verdict hot path (their upstreams do not honour HTTP Range); each stays available as an explicit band request, and the responder will not fabricate a value for a connector it cannot read. Two disclaimers keep the scope honest: legality_disclaimer for Article 9(1)(b) (land tenure, FPIC, country-of-origin law, structurally out of EO scope), and degradation_disclaimer for Article 2(7) forest degradation (the verdict measures deforestation, not degradation). The JSON Schema at /v1/schemas/eudr_dds.json cites the exact EUR-Lex paragraph each field maps to; regulation_status_note tracks the application deferral (Regulations 2024/3234 and 2025/2650 → 30 December 2026 for large operators, 30 June 2027 for micro and small).emem_at, emem_ndvi, emem_air, emem_lst, emem_soil, emem_water, emem_forest, emem_weather. Collapse locate → recall → polygon-aggregate into one call by place name.source.coop./v1/coverage_map.svg (1440×720 plate-carrée of attested cells, log-scale density) and /v1/places/scene_overlay.svg?place=…&band=… (per-place value-painted bbox grid; band-aware ColorBrewer ramps, horizontal legend, km scale bar, signed source line). The MCP equivalents return the same SVG as an EmbeddedResource block. The full set, plus the 32-diagram protocol/industry suite, lives at /docs/gallery and /docs/diagrams.
One use case, end to end. A geolocated plot is checked against the forest baseline and the Hansen loss-year over the 2020 cut-off, the verdict and its per-year loss histogram are signed into one Due Diligence Statement, and that 26-character handle is what clears customs. This is what eudr.dev runs on.
160 named composition recipes (flood_risk@2, walkability_score@1, heat_index@2, carbon_sink_score@1, eudr_compliance@1, forest_carbon_loss_co2_flux@1, enteric_ch4_dairy_tier1_ipcc2019@1, n2o_synthetic_fertilizer_ef1_ipcc2019@1, ...) live in a content-addressed registry. Each carries:
formula: plain math the agent can read and apply.inputs: band keys with role + explanation.when_to_use: agent-targeted trigger guidance.citation: peer-reviewed source.accuracy_band: honest precision estimate, not marketing.parameters: typed tunable thresholds (gate, k, timeout, ...).learned_from: citation provenance for every tuned number. An auditor can trace any gate threshold back to a referee.Algorithms with an evaluation: Expr AST are also re-executable in-process: the responder walks the AST against the snapshot recall and returns a signed composite scalar that any third party with matching algorithms_cid and input fact CIDs reproduces deterministically.
Browse at GET /v1/algorithms or per-key at GET /v1/algorithms/<key>.
Designed for agents to read, not for humans to remember:
GET /openapi.json OpenAPI 3.1 of every REST route
GET /v1/agent_card live capability snapshot + manifest CIDs
GET /v1/tools 81 MCP tools (10 core, 71 extended) with when_to_use + annotations
GET /v1/algorithms?summary=true 160 algorithm keys + categories
GET /v1/topics 27 topic-grouped bands + algorithms (router brain)
GET /v1/manifests bands_cid, algorithms_cid, sources_cid, schema_cid
GET /v1/schemas/eudr_dds.json Annex II JSON Schema with EUR-Lex paragraph citations
GET /.well-known/{emem,agent,mcp,ai-plugin}.json
POST /v1/state signed dense state vector at any cell (view=encoder | view=cube)
POST /v1/state_multi fan-out across geotessera + clay_v1 + prithvi_eo2 with typed missing[]
POST /v1/state_diff vintage delta at one cell: residual vector + L2 + cosine
POST /v1/memory_token compose memt:<cell64>:<fact_cid> citation handle
POST /v1/memory_token/resolve single round-trip dereference back to signed fact body
GET /v1/stream Server-Sent Events corpus heartbeat, signed every 5-300 s
GET /v1/corpus_state_stats signed snapshot of corpus liveness (one-shot equivalent of /v1/stream)
GET /v1/benchmark hand-verified eval items; pair with POST /v1/benchmark/grade
POST /v1/hunt structured event-discovery sweep (12 events × region)
POST /v1/eudr_dds EUDR Due Diligence Statement (Regulation EU 2023/1115)
POST /mcp JSON-RPC 2.0 (Streamable HTTP)
GET /llms.txt /llms-full.txt plaintext catalog for LLM ingestion
GET /humans /humans.json interactive try-it surface + machine twin
GET /verify /verify/<fact_cid> in-browser ed25519 receipt verifier
GET /docs/gallery live coverage map + hunter case studies + 32 diagrams
GET /docs/diagrams/ 32 SVGs of protocol + industry deployments
The operator_attestation block in /.well-known/emem.json binds the running binary's BLAKE3 hash to its git_commit + build_timestamp and signs the triple under the responder's ed25519 key, so a verifier can confirm the live binary corresponds to the published source tree without trusting the operator.
Every receipt pins four content-addressed registry CIDs (bands_cid, algorithms_cid, sources_cid, schema_cid). A peer that recomputes a fact under matching CIDs produces the same bytes. A peer with drifted registries returns a different bands_cid on /health and the divergence is visible before any data flows.
cargo run --release --bin emem-server
# Or via container.
docker run -p 5051:5051 ghcr.io/vortx-ai/emem:latest
No required env vars. EMEM_BIND overrides the listener (default 0.0.0.0:5051). EMEM_DATA overrides the data directory (default ./var/emem; pass :memory: for ephemeral). For TLS, systemd, ACME on :443, and the HuggingFace Space wrapper, see docs/operators/operating.md.
| field | bits | wire form | example |
|---|---|---|---|
cell | 64 | four base-1024 bigrams, dot-sep | defi.zb493.xuqA.zcb5f |
tslot | 64 | base32-nopad-leb128, t. prefix | t.aaaaagy |
cid | 32 B BLAKE3 | base32-nopad-lowercase, 26 chars | qi3jo4sqcg…l2hgjtwm |
vec | 1792-D fp16 | 12-byte prefix in receipts | full vector via recall |
The active grid is ~9.54 m × ~9.55 m at the equator (lat 21 bits × lng 22 bits, asymmetric to match the 360°/180° ratio). Above the equator, longitude pitch narrows with cos(lat). The Hilbert-ordered base-1024 alphabet keeps adjacent cells string-prefix-similar, so an LLM that emits defi.zb493… already lands in roughly the right place. GET /v1/grid_info declares the active resolution honestly; the spec target is a hierarchical migration toward H3-equivalent res-13 (~3.4 m).
emem/
├── crates/ # 16 workspace crates, MSRV 1.91, version 0.1.0
│ ├── emem-core/ # bands, algorithms, functions, sources, topics, schema
│ ├── emem-codec/ # cell64, cid64, vec64, hilbert, geo, alphabet
│ ├── emem-fact/ # canonical CBOR; fact, receipt, attestation
│ ├── emem-claim/ # claim predicates (Op enum)
│ ├── emem-cache/ # sled cache wrapper
│ ├── emem-fetch/ # 16 data connectors + 13 utility modules
│ ├── emem-storage/ # sled hot cache + append-only merkle log
│ ├── emem-cubes/ # 1792-D voxel cube handle
│ ├── emem-primitives/ # recall, find_similar, trajectory, compare, diff, verify, query_region
│ ├── emem-attest/ # merkle root over fact CIDs
│ ├── emem-intent/ # rule-based intent → plan planner
│ ├── emem-mcp/ # MCP tool descriptor registry (81 tools, core + extended)
│ ├── emem-api-rest/ # axum router, physics solvers, foundation fan-out
│ ├── emem-cli/ # binaries: emem-server, emem-livedemo, emem-realdemo, emem-demo, emem-ask-eval
│ ├── emem-membench/ # memory-substrate benchmark harness
│ └── emem-sleep-agent/ # offline refinement loop over contradictions + edges
├── sdks/
│ ├── emem-py/ # Python client (httpx, sync + async)
│ └── emem-ts/ # TypeScript client (zero runtime deps, native fetch)
├── python/ # FastAPI sidecar over UDS: Prithvi-EO-2.0, Galileo, Clay v1.5, JEPA-v2
├── examples/ # MCP configs + LangChain / LlamaIndex
├── ops/ # systemd units, journald retention
└── web/ # SSR HTML, humans, verify, llms.txt, agent.json
The 16 data connectors back 46 declared source schemes and 124 live materializer registrations. Five of the 46 schemes are declared-but-unwired (openet.30m.daily, dynamic_world.v1, tropomi.s5p.ch4, tropomi.s5p.no2, viirs.dnb.monthly); they return a typed Absence, not data. Most wired schemes route through cog.rs, the universal STAC + COG sampler, plus bespoke modules for chirps (rainfall), dmsp_ols (nightlights), esa_cci_biomass (above-ground biomass, CEDA), firms (active fire), ftw (Fields of The World), geonames (gazetteer), gmrt (topobathymetry, PointServer + GridServer), hansen_gfc (forest change), jrc_gfc2020 (EUDR forest baseline, JEODPP single-COG), jrc_tmf (tropical moist forest, pull-and-cache), koppen (climate classification), overture (places / buildings / divisions), radd_alerts (Sentinel-1 disturbance), terraclimate (climate), wdpa (protected areas), worldpop (population), wri_gdm_drivers (Sims et al. 2025 driver attribution).
The GPU sidecar (Python FastAPI over Unix domain socket) co-resides four encoders on a 20 GB VRAM budget:
vit_large_patch14_reg4_dinov2.lvd142m) pre-staged at boot so HF_HUB_OFFLINE=1 holds.base in production; tiny / nano selectable via EMEM_GALILEO_VARIANT): S2-only modality wired (S1 / ERA5 / SRTM / VIIRS / Dynamic-World / WorldCover / LandScan / location zero-masked; the scaffold is multimodal but only S2 is connected today). The advertised capability is galileo-<variant> in /v1/capabilities.extensions[].is_trained() check short-circuits to last-vintage identity; receipt carries untrained_baseline and via: "short_circuit_untrained". Training is upstream-bottlenecked on multi-vintage Tessera availability.Sidecar crash does not cascade. The REST router degrades to scalar bands and signs the GPU-anchored algorithms as Absence with gpu_unavailable. See docs/developers/inference.md.
emem is built to be a protocol, not a single service. Because every fact is content-addressed and signed, any responder can serve it and any client can verify it offline, without trusting the source. Today that runs as one hosted responder plus self-hosted nodes. The design target is a federation of independent responders that resolve the same content ids byte-for-byte, cross-cite each other's attestations, and record where they disagree, so the shared memory gets more trustworthy the more agents read and write against it. None of the multi-host federation routing ships in 0.1.0. What ships today is the substrate that makes it possible: content addressing, signed receipts, typed temporal edges, multi-attester contradiction scoring, and a deterministic refinement loop.
The end state: many responders, one address space. A content id means the same bytes everywhere, every responder signs under its own key, and a client trusts the signature instead of the server. Where two responders disagree, the network records it.
declared_but_no_materializer_at_this_responder.geotessera (Tessera 128-D) has a wired materializer and auto-fetches on miss. clay_v1 and prithvi_eo2 are seed-only at this responder: the GPU sidecar runs both models, but the auto-materialise path that fans out to upstream tile archives is not wired today. Recall against either returns whatever has already been signed; the hunter-mode envelope discloses this per request under materializer_status[].dl2.geotessera.org reliably serves 2024 vintages today; historical backfill across all eight vintages (2017–2024) is partial. The Tessera-coherence rerank in hunter mode gracefully degrades to primary-scalar order when the upstream is unreachable, surfacing the reason under embedding_rerank.reason.modis.lst_day_8day materialises through the NASA/ORNL REST API at roughly 30 s per cell. Hunter mode caps the per-region fan-out for the LST family to 8 cells (env override EMEM_HUNTER_SLOW_BAND_CAP) so urban-heat queries return inside the gateway timeout./humans (try-it drawer, manifest grid, ontology SVG); for analytics, drive from a notebook against the REST or MCP endpoint.| Agent loop | https://emem.dev/agents.md |
| Wire spec | https://emem.dev/spec.md |
| llms.txt | https://emem.dev/llms.txt |
| OpenAPI 3.1 | https://emem.dev/openapi.json |
| MCP | https://emem.dev/mcp |
| Verify | https://emem.dev/verify |
| Container | ghcr.io/vortx-ai/emem:latest (multi-arch, anonymously pullable) |
| HF Space | huggingface.co/spaces/vortx-ai/emem |
| MCP Directory | docs/mcp-directory.md |
| Issues / PRs | github.com/Vortx-AI/emem/issues |
| Security | SECURITY.md, avijeet@vortx.ai |
Apache-2.0. See LICENSE and NOTICE.
Default-build data sources are open: Copernicus DEM, JRC GSW (CC-BY 4.0), Hansen GFC, ESA WorldCover (CC-BY 4.0), Overture Maps (places, buildings, transportation, divisions/division_area; ODbL / CDLA-Permissive), Fields of The World (CC-BY 4.0), GeoNames cities-5000 (CC-BY 4.0), OSM (ODbL), met.no, Open-Meteo, Tessera. No API keys, no operator credentials, no SaaS lock-in.
EMEM_BINDBind address for the HTTP server. Defaults to 0.0.0.0:5051 inside the container.
EMEM_DATAPath to the persistent data directory (sled cache + ed25519 identity). Mount a volume here.
EMEM_PUBLIC_URLOptional canonical origin for self-referencing URLs in MCP responses (e.g. https://emem.dev). When unset the server falls back to urn:emem.
EMEM_TLS_DOMAINSComma-separated hostnames for built-in Let's Encrypt ACME (TLS-ALPN-01). When set, the server binds 0.0.0.0:443 instead of EMEM_BIND.
io.github.ericm1018/skillfm-llm-cost-optimizer-openai-anthropic-usage
io.github.mikerawsonnz/llm-orchestration-agent
io.github.mikerawsonnz/authenticated-llm-agent
labforgedev/copilot-memory-mcp
csoai-org/agent-prompt-injection-firewall-mcp
io.github.mikerawsonnz/authenticated-multi-llm-agent