Skip to main content
Glama

emem, the verifiable memory protocol for the physical world

Ask a free-text question about a place

emem_ask
Idempotent

Single-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: Call when the question is about a specific place and the answer should carry its own evidence. Send the user's question verbatim as q plus a location as place (free text), cell (cell64), or lat+lng. One envelope comes back: answer, spatial_trace (the readings as primitives, each point indexing fact_cids), facts_summary, receipt and fact_cids at the ROOT, and caveats naming grid resolution and revisit cadence. Missing bands are materialised on demand. include: ["reasoning"] adds the ordered stages with their detail; include_image: true bundles a Sentinel-2 thumbnail. A question outside the corpus answers topic_routing.matched_topic: null with the inventory, so you can route elsewhere rather than guess.

Example arguments: {"q":"is this neighbourhood flood-prone for a flat purchase","place":"Ashok Nagar, Ranchi"}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qYesUser's natural-language question about the place (e.g. "is this neighbourhood flood-prone").
latNoWGS-84 latitude (paired with `lng`; alternative to `place` / `cell`).
lngNoWGS-84 longitude (paired with `lat`).
cellNocell64 string (alternative to `place`, use when you have one from a prior emem_locate / emem_recall response). Provide this OR `place` OR `lat`+`lng`.
modelNoOptional. Compose an EXTRA prose answer with a named model, returned as `model_answer` beside the deterministic `answer`. It does not replace it: `answer` is synthesised from the structured fields and never calls a model, so every number in it traces to a fact_cid, and asking for a model must not turn a checkable answer into an unchecked one. `model_answer` carries provenance.class = model_output. Name it by base_model (`nvidia/Cosmos3-Edge`), by family (`cosmos3_edge`, `gemma`), or by any fragment naming exactly one of them (`cosmos`); a fragment matching several is refused and names them; an unroutable name is refused with the list of routable ones, and a routable model whose service is not answering is refused as busy or down rather than silently substituted. Cosmos deliberates and typically takes 13-22 s.
placeNoFree-text place name (e.g. "Mount Fuji", "Ashok Nagar, Ranchi"). REQUIRED unless `cell` or `lat`+`lng` is provided. Extract the noun phrase from the user's turn; the responder geocodes via OSM Nominatim.
queryNoAlias for `q`.
includeNoOpt-in heavy response sections. Default response is slim (~5 KB): answer + algorithm key + fact_cids + caveats. Name specific sections to include them. Ignored when verbose=true (which includes everything).
verboseNoWhen true, return the full envelope: per-algorithm formula strings, temporal_recipe blocks, per-fact band_metadata duplicates, and the long _explanation prose. Default (since 2026-05-05) is false so the response fits MCP's 25 KB cap; the signed receipt + fact CIDs + algorithm keys + algorithms_cid are always retained. Pass true to get the full body when debugging.
questionNoAlias for `q`.
include_imageNoBundle a Sentinel-2 RGB scene URL for the resolved cell. Adds ~1-2 s on first call.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
cellNoThe cell64 the question resolved to: emem's address for the place.
_meansNo
answerNoThe prose answer. The same text is in the content block, which also carries the full envelope.
schemaYes
questionNoThe question as asked.
spatial_traceYesA spatial memory trace: what this responder has measured at this place, as primitives a model can reason over rather than a picture a person looks at.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedOutput schema / properties / spatial_trace / properties / layers / items / properties / points / items / properties / value / description
      Previous value: -"The measured value, in the band's own units."New value: +"The measured value, in the band's own units. `null` where the band was looked for and not found: an absence is a reading."
    • addedOutput schema / properties / spatial_trace / properties / layers / items / properties / points / items / properties / value / type
      Added value: +[
      +  "number",
      +  "string",
      +  "boolean",
      +  "null"
      +]
  2. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "_means": {
      +      "type": "string"
      +    },
      +    "answer": {
      +      "description": "The prose answer. The same text is in the content block, which also carries the full envelope.",
      +      "type": "string"
      +    },
      +    "cell": {
      +      "description": "The cell64 the question resolved to: emem's address for the place.",
      +      "type": "string"
      +    },
      +    "question": {
      +      "description": "The question as asked.",
      +      "type": "string"
      +    },
      +    "schema": {
      +      "const": "emem.ask_structured.v1",
      +      "type": "string"
      +    },
      +    "spatial_trace": {
      +      "description": "A spatial memory trace: what this responder has measured at this place, as primitives a model can reason over rather than a picture a person looks at.",
      +      "properties": {
      +        "absent": {
      +          "description": "Bands this responder looked for and did not find. Absence is evidence: without it a consumer infers coverage nobody measured.",
      +          "items": {
      +            "properties": {
      +              "band": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "at": {
      +          "description": "[lat, lng] of the cell, so a point has a position without a second call.",
      +          "items": {
      +            "type": "number"
      +          },
      +          "type": "array"
      +        },
      +        "cell": {
      +          "type": "string"
      +        },
      +        "counts": {
      +          "description": "Totals taken BEFORE any cap, so truncation can be seen rather than guessed.",
      +          "properties": {
      +            "absent": {
      +              "type": "integer"
      +            },
      +            "absent_shown": {
      +              "type": "integer"
      +            },
      +            "points_shown": {
      +              "type": "integer"
      +            },
      +            "present": {
      +              "type": "integer"
      +            }
      +          },
      +          "type": "object"
      +        },
      +        "layers": {
      +          "description": "Points grouped by what kind of evidence they are: surface (what the ground is), built (what stands on it), now (what is happening there), embedding (vectors for similarity). A layer absent from this list means the question never reached that kind of evidence; a band looked for and not found is in `absent` instead.",
      +          "items": {
      +            "properties": {
      +              "layer": {
      +                "enum": [
      +                  "surface",
      +                  "built",
      +                  "now",
      +                  "embedding",
      +                  "other",
      +                  "ground"
      +                ],
      +                "type": "string"
      +              },
      +              "points": {
      +                "description": "One per signed reading.",
      +                "items": {
      +                  "properties": {
      +                    "age_s": {
      +                      "description": "How old the reading was when this answer was written.",
      +                      "type": "integer"
      +                    },
      +                    "band": {
      +                      "type": "string"
      +                    },
      +                    "class": {
      +                      "description": "Provenance class: direct_sensor, deterministic_index, estimator, model_output, attested_execution, human_curated, unclassified. What KIND of claim this is.",
      +                      "type": "string"
      +                    },
      +                    "f": {
      +                      "description": "Index into the fact_cids array in this result's text block. Dereference it to get the signed bytes.",
      +                      "type": "integer"
      +                    },
      +                    "unit": {
      +                      "type": "string"
      +                    },
      +                    "value": {
      +                      "description": "The measured value, in the band's own units."
      +                    }
      +                  },
      +                  "required": [
      +                    "band",
      +                    "value"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              }
      +            },
      +            "required": [
      +              "layer",
      +              "points"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "schema": {
      +          "const": "emem.spatial_trace.v1",
      +          "type": "string"
      +        },
      +        "stage": {
      +          "description": "Which stage of the answer grounded these readings.",
      +          "type": "string"
      +        },
      +        "truncated": {
      +          "type": "boolean"
      +        }
      +      },
      +      "required": [
      +        "schema",
      +        "layers",
      +        "counts"
      +      ],
      +      "type": "object"
      +    }
      +  },
      +  "required": [
      +    "schema",
      +    "spatial_trace"
      +  ],
      +  "type": "object"
      +}
  3. Changed1 schema field changed
    • changedInput schema / properties / model / description
      Previous value: -"Optional. Compose an EXTRA prose answer with a named model, returned as `model_answer` beside the deterministic `answer`. It does not replace it: `answer` is synthesised from the structured fields and never calls a model, so every number in it traces to a fact_cid, and asking for a model must not turn a checkable answer into an unchecked one. `model_answer` carries provenance.class = model_output. Name it by base_model (`nvidia/Cosmos3-Edge`) or by family (`cosmos3_edge`, `gemma`); an unroutable name is refused with the list of routable ones, and a routable model whose service is not answering is refused as busy or down rather than silently substituted. Cosmos deliberates and typically takes 13-22 s."New value: +"Optional. Compose an EXTRA prose answer with a named model, returned as `model_answer` beside the deterministic `answer`. It does not replace it: `answer` is synthesised from the structured fields and never calls a model, so every number in it traces to a fact_cid, and asking for a model must not turn a checkable answer into an unchecked one. `model_answer` carries provenance.class = model_output. Name it by base_model (`nvidia/Cosmos3-Edge`), by family (`cosmos3_edge`, `gemma`), or by any fragment naming exactly one of them (`cosmos`); a fragment matching several is refused and names them; an unroutable name is refused with the list of routable ones, and a routable model whose service is not answering is refused as busy or down rather than silently substituted. Cosmos deliberates and typically takes 13-22 s."
  4. Changed1 schema field changed
    • addedInput schema / properties / model
      Added value: +{
      +  "description": "Optional. Compose an EXTRA prose answer with a named model, returned as `model_answer` beside the deterministic `answer`. It does not replace it: `answer` is synthesised from the structured fields and never calls a model, so every number in it traces to a fact_cid, and asking for a model must not turn a checkable answer into an unchecked one. `model_answer` carries provenance.class = model_output. Name it by base_model (`nvidia/Cosmos3-Edge`) or by family (`cosmos3_edge`, `gemma`); an unroutable name is refused with the list of routable ones, and a routable model whose service is not answering is refused as busy or down rather than silently substituted. Cosmos deliberates and typically takes 13-22 s.",
      +  "type": "string"
      +}
  5. Changed2 schema fields changed
    • addedInput schema / properties / query
      Added value: +{
      +  "description": "Alias for `q`.",
      +  "type": "string"
      +}
    • addedInput schema / properties / question
      Added value: +{
      +  "description": "Alias for `q`.",
      +  "type": "string"
      +}
  6. Changed1 schema field changed
    • changedInput schema / properties / cell / description
      Previous value: -"cell64 string (alternative to `place` — use when you have one from a prior emem_locate / emem_recall response). Provide this OR `place` OR `lat`+`lng`."New value: +"cell64 string (alternative to `place`, use when you have one from a prior emem_locate / emem_recall response). Provide this OR `place` OR `lat`+`lng`."
  7. Changed1 schema field changed
    • addedInput schema / properties / include
      Added value: +{
      +  "description": "Opt-in heavy response sections. Default response is slim (~5 KB): answer + algorithm key + fact_cids + caveats. Name specific sections to include them. Ignored when verbose=true (which includes everything).",
      +  "items": {
      +    "enum": [
      +      "band_observations",
      +      "algorithm_outcomes",
      +      "facts_full",
      +      "temporal_composition",
      +      "foundation_embeddings",
      +      "scene",
      +      "inventory"
      +    ],
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  8. Changed3 schema fields changed
    • addedInput schema / properties / cell / maxLength
      Added value: +23
    • addedInput schema / properties / cell / minLength
      Added value: +19
    • addedInput schema / properties / cell / pattern
      Added value: +"^(?:(?:[bcdfghjklmnpqrstvwxyz][aeiouAEIOU]){2}|z[0-9a-f]{4})(?:\\.(?:(?:[bcdfghjklmnpqrstvwxyz][aeiouAEIOU]){2}|z[0-9a-f]{4})){3}$"
  9. Changed1 schema field changed
    • addedInput schema / properties / verbose
      Added value: +{
      +  "default": false,
      +  "description": "When true, return the full envelope: per-algorithm formula strings, temporal_recipe blocks, per-fact band_metadata duplicates, and the long _explanation prose. Default (since 2026-05-05) is false so the response fits MCP's 25 KB cap; the signed receipt + fact CIDs + algorithm keys + algorithms_cid are always retained. Pass true to get the full body when debugging.",
      +  "type": "boolean"
      +}
  10. Changed4 schema fields changed
    • removedInput schema / anyOf
      Removed value: -[
      -  {
      -    "required": [
      -      "place"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "cell"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "lat",
      -      "lng"
      -    ]
      -  }
      -]
    • removedInput schema / description
      Removed value: -"Single-shot free-text answer about a real-world location. `q` is always required. Exactly one location form is also required: `place` (free text — extract the noun phrase from the user's turn), `cell` (cell64 from a prior call), or both `lat`+`lng`."
    • changedInput schema / properties / cell / description
      Previous value: -"cell64 string (alternative to `place` — use when you have one from a prior emem_locate / emem_recall response)."New value: +"cell64 string (alternative to `place` — use when you have one from a prior emem_locate / emem_recall response). Provide this OR `place` OR `lat`+`lng`."
    • changedInput schema / properties / place / description
      Previous value: -"Free-text place name (e.g. \"Mount Fuji\", \"Ashok Nagar, Ranchi\"). Use this when the user's turn names a place — extract the noun phrase yourself; the responder geocodes via OSM Nominatim."New value: +"Free-text place name (e.g. \"Mount Fuji\", \"Ashok Nagar, Ranchi\"). REQUIRED unless `cell` or `lat`+`lng` is provided. Extract the noun phrase from the user's turn; the responder geocodes via OSM Nominatim."
  11. Changed6 schema fields changed
    • addedInput schema / anyOf
      Added value: +[
      +  {
      +    "required": [
      +      "place"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "cell"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "lat",
      +      "lng"
      +    ]
      +  }
      +]
    • addedInput schema / description
      Added value: +"Single-shot free-text answer about a real-world location. `q` is always required. Exactly one location form is also required: `place` (free text — extract the noun phrase from the user's turn), `cell` (cell64 from a prior call), or both `lat`+`lng`."
    • changedInput schema / properties / cell / description
      Previous value: -"cell64 string (alternative to `place`)."New value: +"cell64 string (alternative to `place` — use when you have one from a prior emem_locate / emem_recall response)."
    • changedInput schema / properties / lng / description
      Previous value: -"WGS-84 longitude."New value: +"WGS-84 longitude (paired with `lat`)."
    • changedInput schema / properties / place / description
      Previous value: -"Free-text place name. One of `place`, `cell`, or (`lat`+`lng`) is required."New value: +"Free-text place name (e.g. \"Mount Fuji\", \"Ashok Nagar, Ranchi\"). Use this when the user's turn names a place — extract the noun phrase yourself; the responder geocodes via OSM Nominatim."
    • changedInput schema / properties / q / description
      Previous value: -"User's natural-language question about the place."New value: +"User's natural-language question about the place (e.g. \"is this neighbourhood flood-prone\")."
  12. First observed

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already provide readOnlyHint=false, openWorldHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is handled. The description goes well beyond that: it reveals the server-side locate→recall→algorithm chain, that "missing bands are materialised on demand," that the response is a single envelope with `caveats` naming grid resolution and revisit cadence, that verbose output "fits MCP's 25 KB cap," and that the optional `model` path never replaces the deterministic `answer` (provenance.class = model_output, with named latency 13–22 s). Without reading anything else, the agent is fully aware of what happens server-side, how long it takes to run, and what it will and won't return.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded (first sentence states the single-shot evidence-backed purpose), has a clearly signposted "When to use" section, and ends with a JSON example — excellent structure for an 11-parameter tool with a complex response envelope. It could be tightened: several sentences (e.g., the `model` and `verbose` behaviors, the alias list, part of the envelope enumeration) repeat what the input schema already documents in comparable detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool this complex — 11 params, an output schema, sibling tools like emem_locate/emem_recall — the description covers the critical context: the decision to call where to call, how to pick among place/cell/lat+lng, the shape of the output envelope, the caveats/inventory return, and the fallback routing behavior. An output schema covers the return-values, so those is not necessarily required here. Remaining gaps are minor (e.g., no mention of auth requirements or rate limits), but the main deficiencies are covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description does add meaning: it says to send the user's question "verbatim" as `q`, gives a concrete example argument mapping, clarifies that `place` only works as an alternative to `cell` (which must come from a prior emem_locate/emem_recall response, relative to lat/lng pairs), and frames disguised response sections ("added ordered stages" via include). It does not however describe the `query`/`question` aliases or add much over the schema for `lat`/`lng`/`include_image`, so the top of the 1–5 range isn't reached.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description leads with a specific verb+resource: "Single-shot free-text answer about a real-world location, backed by signed satellite/elevation/water/built-up receipts." It then makes the differentiation explicit by naming the server-side chain it runs ("locate → recall → algorithm chain") and by referencing sibling tools emem_locate and emem_recall as sources of `cell`. An agent can tell exactly what this tool does versus geocoding (emem_locate) or raw recall (emem_recall).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit when-to-use: "Call when the question is about a specific place and the answer should carry its own evidence," plus concrete instruction (send the user's question verbatim as `q` and a location via `place`/`cell`/`lat`+`lng`). It also defines the boundary condition ("A question outside the corpus answers... matched_topic: null with the inventory, so you can route elsewhere rather than guess"). It falls short of 5 because it never explicitly names a sibling as the alternative for out-of-scope questions or says when NOT to call this tool beyond the corpus-boundary case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.