@yodolabs/caveat-mcp
v0.1.2
Published
A physical-world context layer for agents that cites its sources and admits what it doesn't know. covered=false => value=null.
Downloads
866
Maintainers
Readme
Geo MCP servers are a dime a dozen — there are 100+, and a 177★ one already serves the same Japanese flood/tsunami/landslide data. So caveat-mcp does not compete on data. It competes on two disciplines that the top geo MCP servers all lack: provenance (every answer is citable) and honesty (un-surveyed ⇒
unknown, never a fake "safe").
agent> Before I plan this inspection route — what's at 35.6585, 139.7010?
caveat> A 1983 bridge, max weight 3 t (jartic_kisei), river-flood depth 1.2 m
(ksj_A31_2024). Landslide risk: UNKNOWN — not surveyed here.
agent> So is it safe from landslides?
caveat> Unknown. That hazard was never surveyed at this location, so I will not
call it safe. (hazard_at → landslide_risk: covered=false, value=null)The one rule
Every answer obeys the ecosystem-wide honesty invariant:
| | meaning | record |
| -------------- | ----------------------------------- | ------------------------------------------------------------- |
| ✅ known | actually surveyed | covered=true, a real value, a confidence tier, a source |
| ⬜ unknown | not surveyed = we won't pretend | covered=false, value=null, confidence=null |
A coordinate nobody has assessed is never defaulted to "safe" / "clear" /
"no restriction". That honesty contract — plus a citation for every value — is the
moat, not the data (the data comes from
plateau-bridge and public sources).
Quickstart
npx -y @yodolabs/caveat-mcp demo # the honesty walkthrough, no network, no setup
npx -y @yodolabs/caveat-mcp # start the MCP server over stdioWire it into a client (full configs in examples/):
// Claude Desktop: claude_desktop_config.json · Cursor: .cursor/mcp.json
{
"mcpServers": {
"caveat-mcp": { "command": "npx", "args": ["-y", "@yodolabs/caveat-mcp"] },
},
}By default it serves a small bundled honest fixture (zero setup). Point it at a
real backend by setting CAVEAT_PARQUET to a
plateau-bridge GeoParquet export to
enable the DuckDB backend.
Tools
| tool | answers | honesty behaviour |
| -------------------- | -------------------------------------------------------------- | -------------------------------------------- |
| whats_here | assets + known facts near a point, with coverage | empty area ⇒ unknown, not clear |
| asset_context | full per-asset dossier (identity / condition / rules / hazard) | missing field ⇒ explicit unknown |
| hazard_at | the 5 hazard classes at a point | un-surveyed ⇒ unknown, never safe |
| rules_at | zoning / weight / height / access / FAR / BCR | undetermined ⇒ unknown, not "no limit" |
| knowledge_boundary | what we know / don't know here | the differentiating tool |
| route_advisory | hazards + unknown gaps along a path | unsurveyed segment ⇒ flagged, not free space |
| cite | the provenance chain for any answer_id | unknown id ⇒ found:false, never invented |
Full reference: docs/tools.md.
Architecture
plateau-bridge (record layer: semantics + 5 hazards + coverage/provenance)
│ bridge-C query + honesty core
▼
┌──────────────────────────────────────────────────────────┐
│ caveat-mcp (TypeScript / Node + official MCP SDK) │
│ │
│ tools/ ──► query/RecordStore ──► backend │
│ (MCP adapters) (= bridge-C, honesty (fixture | duckdb) │
│ │ enforced on every read) │
│ └──────────► caveat/ ◄───────────────────────────┤
│ record · honesty invariant · provenance │
└───────────────────────────┬──────────────────────────────┘
┌───────────────────────┼────────────────────────┐
▼ ▼ ▼
Claude Desktop / terra-incognita robot planner
Cursor / any client agent (context_api) (with ros-mcp)Dependencies point inward, toward the honesty core. Absence is converted to an
explicit, citable unknown in exactly one place (RecordStore), so the guarantee
holds no matter which backend is mounted. See DESIGN.md.
Honesty, enforced by tests
The invariant is guarded at six independent layers, so drift is a test failure,
not a silent regression — see docs/honesty-spec.md:
construction, JSON-schema (the frozen shared record.schema.json), the semantic
boundary, the read path, coverage math, and each tool. test/honesty.test.ts
asserts that a covered=false record can never carry a value, a 0, a false, or
a confidence.
npm test # 53 tests, incl. the honesty suite + an end-to-end MCP run
npm run build && npm run demoCompanion to ros-mcp, not a competitor
caveat-mcp does not drive robots — ros-mcp-server
already owns that. ros-mcp answers "what my sensors see now"; caveat-mcp answers
"what is officially known here, and where the blanks are". A planner uses both, and
treats caveat-mcp's unknowns as cost, not free space.
See docs/ros-mcp-companion.md.
Contract
caveat-mcp serves the frozen, ecosystem-wide
record.schema.json — the universal honest
record where state, rules and hazard are the same shape (only attribute
differs), with the non-negotiable covered=false ⇒ value=null invariant. The query
surface mirrors plateau-bridge's bridge-C core. Part of the Physical AI Record
Layer ecosystem alongside
plateau-bridge,
plateau-id-resolve,
plateau-triage and
robo-permit.
Limitations & scope (v0.1)
Honesty holds regardless of the below; these are scope boundaries, not gaps in the invariant (full rationale in DESIGN.md §10.1):
- HTTP transport is unauthenticated. The default, recommended path is local
stdio.
--httpis stateless with no auth/quota — put auth/rate-limiting in front of it before any remote/production deployment. knowledge_boundaryis a checklist-based approximation, not a true coverage polygon set-difference (that belongs in plateau-bridge's coverage logic).coverage_ratiois "fraction of records-on-file that are surveyed", not "fraction of safety questions answered" — useknowledge_boundaryfor the latter.- DuckDB is optional. Without
CAVEAT_PARQUET(or the native@duckdb/node-apibinding) the server runs on the bundled honest fixture — great for trying it, not a source of truth. - Rule data is served, not fused here. Fusing sources like OSM
maxweightisrobo-permit's job; caveat-mcp serves the resulting records.
License
MIT (LICENSE) — consistent with the @yodolabs npm packages. caveat-mcp
ships no authoritative data of its own; served records carry each upstream source's
attribution in their source field, which downstream consumers must preserve
(NOTICE).
A grounding layer that admits its blind spots — not a substitute for the real-time perception or human judgement a safety-critical decision requires.
