Note (2026-04-24): After this document was written,
legal_entitywas renamed totenantand the oldtenantwas renamed toorganization. Read references to these terms with the pre-rename meaning.
Two MCP tools for persisting and retrieving Data Maps produced by the Data
Discovery Protocol (DDP). Plus a scope refactor to move from flat mcp:*
scopes to domain-scoped ones.
Replace mcp:read/mcp:write with domain-scoped permissions:
| Scope | Tools |
|---|---|
docs:read |
orcha-docs-list, orcha-docs-get, orcha-docs-search, orcha-docs-line-items |
docs:write |
(future: upload, annotations) |
fpna:read |
orcha-fpna-context |
fpna:write |
orcha-fpna-save-dm |
master-data:read |
(future: orcha-data-master-data) |
Scopes are independent — fpna:write does not imply fpna:read.
Changes:
discovery.clj: update supported scopes listmcp:read → docs:read/mcp route: update or remove transport-level scope gate (per-tool
checking already happens in call-tool)fpna_data_mapAppend-only history. Every save inserts a new row. Context tool queries the
latest by legal_entity_id.
CREATE TABLE fpna_data_map (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
legal_entity_id UUID NOT NULL REFERENCES legal_entity(id),
protocol_version TEXT NOT NULL,
status TEXT NOT NULL CHECK (status IN ('draft', 'ready')),
content TEXT NOT NULL,
last_reviewed TIMESTAMPTZ,
reviewed_by TEXT,
created_by UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_fpna_data_map_latest
ON fpna_data_map (legal_entity_id, created_at DESC);
orcha-fpna-contextCalled at session start to determine the state of data discovery for a legal entity.
fpna:readlegal_entity_id (optional UUID)legal_entity_id omitted: resolve from identity. Single LE → use it.
Multiple LEs → error listing available entities.legal_entity_id ∈ identity's allowed set.fpna_data_map row for that entity.| Status | Returns |
|---|---|
boot (no row) |
DDP protocol doc only |
draft |
DDP protocol doc + partial Data Map content |
ready |
Completed Data Map content only |
{status, legal_entity_id, protocol_version?, content}
draft, content is an object with protocol and data_map keys.orcha-fpna-save-dmPersists the Data Map. Inserts a new row (append-only history).
fpna:writelegal_entity_id (optional, same auto-resolution as context tool)content (required, markdown string)protocol_version (required)status (required: draft | ready)last_reviewed (optional)reviewed_by (optional){id, legal_entity_id, status, created_at}| Condition | Tool | Response |
|---|---|---|
legal_entity_id omitted, multiple LEs |
both | Error instructing the agent to use orcha-master-data-legal-entities to ask the user which entity they mean |
legal_entity_id not in identity's set |
both | Error: not accessible |
| Invalid UUID format | both | Error: invalid format |
status not draft/ready |
save-dm | JSON Schema enum validation |
content empty/missing |
save-dm | JSON Schema required validation |
last_reviewed/reviewed_by with draft |
save-dm | Silently ignored |
Stored as classpath resource at resources/com/getorcha/controlling/data-discovery-protocol.md.
Read via clojure.java.io/resource at runtime.
| File | Purpose |
|---|---|
resources/com/getorcha/controlling/data-discovery-protocol.md |
DDP as classpath resource |
resources/migrations/YYYYMMDD-add-fpna-data-map.up.sql |
Migration |
resources/migrations/YYYYMMDD-add-fpna-data-map.down.sql |
Rollback |
src/com/getorcha/link/mcp/tools/fpna_context.clj |
Context tool |
src/com/getorcha/link/mcp/tools/fpna_save_dm.clj |
Save tool |
test/com/getorcha/link/mcp/tools/fpna_test.clj |
Tests for both |
Modified files:
src/com/getorcha/link/oauth/discovery.clj — scopessrc/com/getorcha/link/mcp/tools.clj — require new namespacessrc/com/getorcha/link/mcp/tools/*.clj — mcp:read → docs:read/mcp route — transport-level scope gateKey scenarios: