Geology AI query box over boreal forest and lakes, drawn from four EPSG:4326 coordinates with no map, beside panels for the bounds check, earthquake and fault results and warnings
Four coordinates and no map: the server checks the box’s syntax, not its place

Key Takeaways

  • The task today: To list recorded earthquakes and active faults for an area, the map workflow ties a scan to coordinates with ground control points and draws the results back on it, so a box in the wrong place looks wrong. Stratigraphic Amenity, an open-source MCP server (a tool server that AI agents call), can also run the query from four EPSG:4326 coordinates with no map at all.
  • The problem: Without a map, nothing confirms what the four numbers mean: the server checks only that they are valid degrees in the right order, so a swapped latitude and longitude anywhere between 90°W and 90°E, or minutes typed as decimals, pass without an error. An empty result then carries two doubts, that nothing was recorded or that the box is somewhere else, and by default the earthquake data is a single USGS file named for magnitude 4.5 and above since 1970.
  • What the tool does: geomap_query_knowledge validates the box, runs the default earthquake and fault providers on local data and returns records, counts, warnings and a saved bundle in seconds. It cannot know whether the box is where you meant, so that check moves to the caller: place names in the records, coverage warnings that name a region, and something you already know about the place before you trust an empty answer.

TL;DR

When you need recorded earthquakes and active faults for an area but have no map, Stratigraphic Amenity, an open-source MCP server for AI agents, can run the query from four EPSG:4326 coordinates in seconds. The map workflow had a built-in check that the box sat in the right place; a bare box only has to be valid, so a swapped pair of coordinates can land in Antarctica and come back empty without an error. The server returns records, counts and warnings, but deciding that the box is the intended place falls to the caller, through place names, coverage warnings and a known fact about the area.

What Does a Geology AI Query Need Without a Map?

Someone sends you four numbers: -80.2, 46.1, -79.8, 46.4. There is no scan and no shapefile, only a line in a message and a question: what has been recorded around here? An agent connected to Stratigraphic Amenity can answer in seconds.

It passes the numbers to the knowledge query tool, geomap_query_knowledge, as an EPSG:4326 box. Then the default earthquake and active-fault providers search the area. No map, no detector and no georeference ever enter the conversation.

In the map workflow, the box is the output of a procedure. Ground control points go in and an affine fit comes out. With four or more well-spread points, the fit reports a residual in metres and a holdout error that say how far to trust it.

Then the overlay puts each record back on the scan, where a point in the wrong place looks wrong to anyone who glances at it. Each of those steps is a witness that the box sits where the map says it does. A knowledge-only query has none of them. The four numbers arrive alone, and whatever they claim about place, the server has to take on trust.

What a Geology AI Server Checks in a Bounding Box

The server does check the box, and it pays to be exact about what that check covers. The values must be numbers. Longitudes must lie within ±180 and latitudes within ±90. On neither axis may the minimum exceed the maximum. The only reference systems accepted are EPSG:4326 and its alias OGC:CRS84, and the server treats a box with no label as EPSG:4326. It refuses anything else with a typed error before a single provider runs.

These are checks of syntax. They catch the box that cannot exist, not the box that exists somewhere else. For example, a corner copied from an old sheet in NAD27 geographic coordinates and labelled EPSG:4326 passes, carrying a datum offset that can reach tens of metres. A latitude of 46°30′ typed as 46.30 passes too, about 22 km south of where it was meant. Even a coordinate the agent recalled from memory rather than read from the user passes, because nothing in four floats distinguishes a remembered number from a surveyed one.

The swapped latitude and longitude

The swapped pair is the most instructive case, because whether the server notices depends on where you work. Put the latitudes in the longitude fields of a box around San Francisco Bay and the call fails at once: -122 cannot be a latitude. Do the same with the Ontario box and nothing fails. 46 is a perfectly good longitude and -80 a perfectly good latitude, so the swapped request is valid, and it lands on the East Antarctic ice sheet.

In short, the server catches the swap only where the true longitudes lie beyond 90 degrees east or west. Everywhere between those meridians, a swap goes through silently. That band includes Europe, Africa, mainland South America and North America east of the 90th meridian west.

The western hemisphere adds a smaller trap. There, the minimum longitude is the more negative number. Write the Ontario longitudes from east to west, -79.8 then -80.2, and the server does refuse the box. However, the message points somewhere else: “Antimeridian-crossing bounds are not supported in this phase.”

Why a Wrong Bounding Box Is Worse Than a Crash

A rejected box costs a retry. A valid wrong box costs an answer. The providers do exactly what they should: they search the place they were given, find little or nothing, and say so honestly. “No GEM active-fault features intersected the bounds; this is not evidence that no active faults exist.” The warning is correct, and it is about the wrong place.

Without a map, then, an empty result carries two doubts instead of one. Perhaps nothing has been recorded here. Or perhaps “here” is not where anyone meant. The defaults narrow the first doubt further than most readers assume. By default, the earthquake lookup reads the USGS catalogue only. Its default file is named for magnitude 4.5 and above since 1970, and its default live request to USGS asks for exactly that. So an empty earthquake list is a statement about that slice of one catalogue, in one box, which may be in the wrong hemisphere.

Where the Witnesses Went

The witnesses do not vanish entirely. Instead, they move into the bundle, and a geology AI agent has to know to look for them.

Place names in the records

The first witness is the records themselves. Earthquake records keep the catalogue’s place description, and fault records keep their names. When something does come back, those strings act as a rough gazetteer. If the place names belong to the region you meant, the box is probably where you think.

Warnings that say where the box is

The second witness is the warnings, which carry more geography than they seem to. The active-fault provider checks every box against coarse rectangles drawn around documented gaps in the GEM database. A box that overlaps the rectangle drawn around Canada gets a caveat that names the country: “GEM active-fault coverage has a documented coarse gap near canada”. The Ontario box triggers it. The swapped box in Antarctica does not. The rectangle is broad, though, and also covers the northern United States.

Likewise, when you include mineral occurrences, the provider routes each box by the coverage rectangles of its two shipped example sources, Ontario and Quebec. It warns when a box falls outside them. Read as a location report, those warnings say where the server believes the box is. On hosts that only show text, they may be the only geography the model sees at all, since the text summary of a knowledge query repeats every count and warning but not the box itself.

A positive control for geology AI

The third witness is one the agent has to supply: a positive control. A laboratory runs a sample whose answer it already knows before trusting a negative result. A knowledge-only query can borrow the habit. Before reading an empty list as absence, look for something you can predict about the intended place: a caveat you expect to see, an event you know happened there, a fault you know crosses the area. If the predictable thing is missing, doubt the box before you doubt the ground.

What the Map Was For

It is tempting to think of the scanned map as the slow part of the pipeline, the thing you are glad to skip when you already have coordinates. But the map was never only a picture to annotate. It was the evidence that the coordinates meant a place.

A geology AI query without one is fast and often exactly right: for a desk study, a screening pass, or a question asked before anyone has found the right sheet. It also moves the burden of place from a procedure to whoever typed four numbers. Before trusting an empty answer, the useful question is not only “is anything here?” It is “what tells me this is here?”

None of this calls for new tooling. The fast part already exists in open source: a server that takes four numbers, runs the default providers and writes a bundle you can open again. What it cannot do is decide whether those numbers mean the place you had in mind, and the clearest way to see that boundary is to read the few lines that stand between a request and the providers.

They are short, and knowing exactly what they refuse also tells you what they let through. The same codebase shows where the accidental witnesses come from.

What the Bounds Check Can and Cannot See

Every knowledge-only call passes through one small class before any provider runs. geomap_query_knowledge turns the request’s bounds object into a Bounds (mcp/adapter.py:486-487, 1225-1230). Apart from converting each value to a float, these lines are the whole check:

python
        normalized_crs = str(self.crs).upper()
        if normalized_crs == "OGC:CRS84":
            normalized_crs = "EPSG:4326"
        if normalized_crs != "EPSG:4326":
            raise InvalidBoundsError(
                f"Unsupported bounds CRS {self.crs!r}; only EPSG:4326 is supported."
            )
        self.crs = normalized_crs

        if not -180 <= self.min_lon <= 180 or not -180 <= self.max_lon <= 180:
            raise InvalidBoundsError("Longitude bounds must be between -180 and 180 degrees.")
        if not -90 <= self.min_lat <= 90 or not -90 <= self.max_lat <= 90:
            raise InvalidBoundsError("Latitude bounds must be between -90 and 90 degrees.")
        if self.min_lon > self.max_lon:
            raise InvalidBoundsError(
                "Antimeridian-crossing bounds are not supported in this phase."
            )
        if self.min_lat > self.max_lat:
            raise InvalidBoundsError("min_lat must be less than or equal to max_lat.")

The code refuses rather than repairs. It rejects a CRS label other than EPSG:4326 or OGC:CRS84 instead of reprojecting the box, and a missing label falls back to the class default, "EPSG:4326" (line 17). So convert a box in UTM or NAD27 coordinates to EPSG:4326 degrees before you send it. The MCP layer applies the same ranges first, in the tool’s JSON Schema (mcp/schemas.py:343-353). As a result, an out-of-range value fails as invalid_arguments, while an inverted box or a foreign CRS label reaches this class and fails as invalid_bounds (mcp/adapter.py:497-499).

Nothing here asks whether the box is the place you meant, and nothing could: four floats carry no other information. That is the whole gap, in nineteen lines. The class checks syntax and leaves place to the caller.

The witnesses live elsewhere in the same package. The caveat that names a country comes from GEM_GAP_BBOXES and coverage_caveats_for_bounds in knowledge/sources/gem_faults.py:24-49, which the active-fault provider runs on every query (knowledge/providers/faults.py:163-164). The mineral provider writes its out-of-coverage warning in knowledge/providers/minerals.py:144-152. Finally, the evidence digest that text-only hosts read prints every warning (mcp/digest.py:114-115) but prints bounds only for georeference results (mcp/digest.py:90-91).

Running a geology AI query from four coordinates

To try it, install Stratigraphic Amenity from a source checkout. A knowledge-only server can leave out the detector stack and the assets extra, which only downloads the detector weights. Live sources such as mineral occurrences also need the knowledge-network extra:

bash
git clone https://github.com/EigenformAI/stratigraphic-amenity.git
cd stratigraphic-amenity
uv sync --group dev --extra mcp --extra geo --extra knowledge-network

Without the assets extra, the client can still install the knowledge base itself through geomap_prepare_knowledge, after the user agrees.

Launch stratigraphic-amenity-mcp from the checkout through your MCP host, with GEOMAP_DATA_ROOT="$PWD/data" and GEOMAP_CACHE_ROOT="$PWD/.cache". Then call the capability check, geomap_list_capabilities, and confirm that earthquake_history and active_faults are ready. Finally, send the box to geomap_query_knowledge:

json
{
  "bounds": {"min_lon": -80.2, "min_lat": 46.1, "max_lon": -79.8, "max_lat": 46.4, "crs": "EPSG:4326"},
  "include": ["earthquake_history", "active_faults"],
  "max_records": 25
}

What comes back is a knowledge/v2 bundle. It holds the box in bounds and in each item’s provenance, per-provider record_counts, total_records_found against total_records_returned, truncated, the warnings and a bundle_uri of the form geomap://bundles/<bundle-id>.json that you can read again later. For this box, the warnings include the GEM caveat naming canada. Until you sync a source mirror, both providers also warn that they are “using legacy local asset because no source mirror was found.”

Before anything else, repeat the structured bounds to the user in words, latitude and longitude named: a latitude of -80 reads as Antarctica to anyone who sees it. Adding "mineral_occurrences" to include makes the call live. It sends the box over HTTP to the shipped Ontario and Quebec example services it intersects, so do it only with the operator’s authorization.

What to Watch For When Geology AI Starts From a Box

A few more traps apply to every query that starts from a box:

  • Default providers only. Without include, only earthquake_history and active_faults run on a box. A warning names each skipped opt-in provider: “Compatible provider ‘mineral_occurrences’ was not consulted because it is disabled by default. Retry with include=[“mineral_occurrences”].”
  • Fifty records each. Each provider returns 50 records by default. The server sorts earthquakes newest first, but faults and mineral occurrences by name, with unnamed records first. So a truncated fault list keeps the first 50 in that order. Check truncated before you count.
  • Earthquakes just outside the box. The local earthquake search pads the box by 0.05° on each side (margin_degrees in the provenance), so a few events can lie just beyond the box you sent.
  • No box across 180°. Send two boxes, one on each side of the antimeridian. The Python SDK’s query_extent splits a wrapping extent for you, but the Earth Engine providers cannot take split extents.
  • Live calls disclose the box. Live sources, such as mineral occurrences, live earthquake mode and Earth Engine, send the bounds to third parties. Local earthquake and fault data keep the box on your machine.
  • Large live searches. A live USGS search that matches too many events fails with “USGS live query returned more than 20000 events; narrow time, magnitude, or bounds filters.”

Adding your own regions or countries

The mineral occurrence lookup ships with Ontario and Quebec as example sources, and the fault lookup ships DISS for Italy as its regional example. You can add your own region or country, but it is a code change, not a setting:

  1. Write a source adapter with a query_bbox(bounds) method, an endpoint and a normalizer_version, plus a function that turns its response into records with a name, longitude and latitude. knowledge/sources/ogs_minerals.py does this for Ontario.
  2. Register the source in default_source_registry() in knowledge/sources/registry.py, with family="mineral_occurrences" and coverage_bounds set to your region’s rectangle.
  3. Bind it in KnowledgeService._mineral_occurrence_provider_factory in knowledge/service.py, next to the Ontario and Quebec branches.
  4. List its id in GEOMAP_MINERAL_OCCURRENCE_SOURCE_IDS. Regional fault sources follow the same pattern through GEOMAP_ACTIVE_FAULT_SOURCE_IDS.

The coverage rectangle then does double duty. It routes each query, and it triggers the out-of-coverage warning that tells you a box missed your region.

FAQs

Can geology AI query earthquakes and faults without a map?

Yes. Send four EPSG:4326 coordinates as bounds to geomap_query_knowledge, and the default earthquake and active-fault providers search that box. The query needs no scan, detector or georeference. It does need the local earthquake and fault data, which the agent can install through geomap_prepare_knowledge once the user agrees.

Why did my bounding box query come back empty?

Either nothing in the searched data falls inside the box, or the box is not where you meant. By default, earthquakes come from one USGS file named for magnitude 4.5 and above since 1970. Swapped coordinates between 90°W and 90°E, or minutes typed as decimals, still pass the check. Look for place names and warnings before trusting an empty list.

What coordinates does a geology AI bounding box need?

Decimal degrees in EPSG:4326, as the named fields min_lon, min_lat, max_lon and max_lat. OGC:CRS84 works as an alias, and the server treats a box with no label as EPSG:4326. It refuses any other label rather than reprojecting the box, so convert UTM or NAD27 coordinates first. It also refuses a box across 180°.

Can I add my own region or country?

Yes, though it is a code change rather than a setting. Write a source adapter for your survey’s service, register it with a coverage rectangle, bind it in the knowledge service and list its id in GEOMAP_MINERAL_OCCURRENCE_SOURCE_IDS. Ontario and Quebec are the shipped examples, and your rectangle also triggers the out-of-coverage warning for your region.

Try It With Geocluster

Stratigraphic Amenity is one of the Geocluster tools, MCP servers that let AI agents work with geology data and maps.

When a scanned sheet does turn up, the full map pipeline adds georeferencing and an overlay to the same query, and with them the witnesses this route leaves out.