← Back to Library

MCP Reference (tools + resources)

api ·  agent/app builders
mcpapitoolsresourcesagent-integration

MCP Reference (tools + resources)

What it is. The wip_mcp package (installed as wip-mcp, console script wip-mcp = wip_mcp.server:main) is WIP's Model-Context-Protocol server. It exposes the platform's five stores — registry, def-store, template-store, document-store, reporting-sync — as MCP tools (actions) and resources (wip://… readables), so an AI coding agent can discover, create, and query WIP entities without constructing raw HTTP calls (components/mcp-server/src/wip_mcp/server.py:1-10). It owns no data itself: server.py is a mcp.server.fastmcp.FastMCP tool/resource layer over client.py's WipClient, a thin httpx-based HTTP client to the five stores.

Reaching it. Three transports, selected by CLI flag to wip-mcp / python -m wip_mcp.server:

For --http/--sse, the server binds MCP_HOST (default 0.0.0.0) / MCP_PORT (default FastMCP's 8000), registers an unauthenticated GET /health liveness probe (for compose/k8s orchestration, checked before the auth middleware so it can be exempted), and — only if API_KEY or WIP_AUTH_LEGACY_API_KEY is set — installs ApiKeyMiddleware, which requires X-API-Key (header) or api_key (query param) on every other path. If neither env var is set, the server starts anyway with only a stderr warning and serves unauthenticated — see gotchas. MCP_ALLOWED_HOST additionally appends to the transport's allowed_hosts/allowed_origins for DNS-rebinding protection.

Underneath, every tool call is itself an authenticated HTTP call from the MCP server to one of the five WIP services: registry (:8001), def-store (:8002), template-store (:8003), document-store (:8004), reporting-sync (:8005) — direct defaults, each overridable by its own *_URL env var, or all five collapsed onto one base via WIP_API_URL (e.g. a router/Caddy front door). Every outbound request carries X-API-Key: <resolved key>, resolved in priority order WIP_API_KEY env → MASTER_API_KEY env → API_KEY env → WIP_API_KEY_FILE (file contents, for rotation without editing client config) → a hardcoded dev default (components/mcp-server/src/wip_mcp/client.py:47-82). See also: Auth & Access; Routing & Ingress.

Conventions that apply.

See also: API Conventions; PoNIFs.

Resources

Five static/dynamic Markdown resources registered under wip://… URIs. An MCP client reads these as context, not as callable actions.

wip://conventions

Static text (server.py:70-324). The canonical write-up of: Bulk-First 200 OK; update_document PATCH semantics and its full error-code list; the Idempotent Bootstrap endpoints (PUT /api/registry/namespaces/{prefix} upsert + its deletion_mode safety guards; POST /templates?on_conflict=validate's three-tier compatibility check; the equivalent on_conflict=validate for terminologies/terms); querying tools (query_by_template, run_report_query, get_table_view, export_table_csv); Soft Delete (retain vs full deletion_mode, and the independent exceptions — binary files and mutable-terminology terms are always hard-deletable); Identity & Versioning (template multi-version coexistence, document identity-field dedup rules); Namespaces & Authorization (permission model, open/strict isolation, relationship-document cross-namespace rejection, single- vs multi-namespace API-key namespace derivation); Ontology Relations; Reporting & Aggregation; the Template Cache and Namespace-Config Cache TTLs (5 s each); Pagination (page_size default 50 / max 100, pages field). This is the same source text the API Conventions library doc is generated from — see that doc for the full canonical write-up; this reference only names the sections.

wip://data-model

Static text (server.py:327-464). Covers Terminologies, Terms, Templates (inheritance, versioning, usage: entity|reference|relationship, versioned: true|false, header_fields), Field Types, Semantic Types, Reference Field Types (document/term/terminology/template), File Field config, Array Field config, other field properties (mandatory not required, full_text_indexed), cross-field Validation Rules (CONDITIONAL_REQUIRED, CONDITIONAL_VALUE, MUTUAL_EXCLUSION, DEPENDENCY), Template Draft Mode, Reporting Configuration, Documents, Files, Registry & Synonyms, and Ontology Relations. Same source text the Data Model Reference library doc is generated from.

wip://development-guide

Static text (server.py:467-560). "Building Applications on WIP" — the 4-phase workflow: Phase 1 Exploratory (inventory existing templates/terminologies with get_wip_status, list_namespaces, list_terminologies, list_templates, query_by_template, get_template_fields — reuse, don't recreate); Phase 2 Data Model Design (map the domain to terminologies/templates, plan ontology relations for hierarchical vocabularies, choose identity_fields carefully, apply semantic_types, use the correct field-naming conventions); Phase 3 Implementation (create terminologies → terms → templates via draft mode + activate_template for circular deps → test documents, pinning template_version explicitly); Phase 4 Application Layer (build the frontend with @wip/client/@wip/react; MCP tools remain useful for debugging/queries). Points to the /explore, /design-model, /implement, /build-app slash commands for step-by-step detail. No dedicated Library doc covers this resource, so it is described here in full.

wip://ponifs

Static text (server.py:563-761). WIP's eight PoNIFs (Powerful, Non-Intuitive Features — the reading list's canonical expansion, sourced from this same file):

  1. Nothing Ever Dies — soft delete is the default; only a namespace explicitly flipped to deletion_mode: full allows hard_delete=true.
  2. Template Versioning — update creates a new version, old stays active; existing docs are pinned via template_id (canonical across versions).
  3. Document Identity — the identity-field hash decides create vs. version; zero identity fields = append-only, no PATCH path (error_code=append_only).
  4. Bulk-First — 200 OK always; check results[i].status.
  5. Registry Synonyms — multiple IDs per entity is normal; merge_entries reconciles (one-way, no reactivation endpoint yet).
  6. Template Cache — 5 s TTL on "latest" resolution; explicit-version lookups cache permanently.
  7. Edge Types Are Stored as Templates — usage: relationship templates get extra validation, /relationships + /traverse, and dedicated reporting columns; usage is immutable; endpoints are append-only-widenable via add_edge_type_endpoints.
  8. versioned: false — an edge-type-only exception to PoNIF #2: updates overwrite in place, no history; requires non-empty identity_fields; immutable after creation.

This is the same source text the PoNIFs library doc is generated from — read that doc for the full write-up (traps, rules, and the "Compactheimer's Warning" section for AI agents recovering from context compaction); this reference only summarizes.

wip://query-assistant-prompt

Dynamic (async, server.py:764-833) — at read time it calls the same data-model-summarizing logic describe_data_model uses (_build_data_model_markdown) and embeds the live template/terminology catalog into the returned text. Falls back to a placeholder message if that call fails. Intended for direct use as the system prompt for a read-only, natural-language WIP query assistant: it states the assistant's capabilities (search, list/filter, terminology lookup, run_report_query SQL, describe_data_model), a query strategy (use search for free text, query_by_template for filtered listing, get_document to resolve reference fields, run_report_query for cross-template JOINs/aggregation, namespace-qualified Postgres table names), and explicit "don't guess / don't invent / don't modify" guardrails. No dedicated Library doc covers this resource, so it is described here in full.

Tools

97 tools total (grep -c '^@mcp\.tool()' server.py = 97), registered in the file order below, which this reference preserves as its stable order.

How tool responses/errors work — stated once, not repeated per tool below. Every tool takes its parameters as named MCP-tool arguments (not a REST path + body) and returns a JSON string (json.dumps(data, indent=2, default=str)) of whatever the wrapped WIP-service call returned, unless noted in the Notes column. Concretely, three response shapes recur:

Where the source docstring gave a literal example call, it is reproduced under Notes; tools without one are invoked by name with the parameters listed — no example response is invented for them (per the reading list's "never invent a response" rule).

Discovery

ToolParamsPurposeNotes
get_wip_status()Health of all five services.Hits each service's /api/<service>/health (not the container-root /health used by orchestrator liveness probes) — see gotchas.
describe_data_model(namespace=None)namespaceMarkdown summary of all active templates (fields, identity fields) + terminologies + query conventions, for system-prompt injection.Paginates internally over list_templates/list_terminologies until exhausted.
list_namespaces(include_archived=False)include_archivedList namespaces.
create_namespace(prefix, description="", isolation_mode="open", deletion_mode="retain")prefix, description, isolation_mode, deletion_modeCreate a namespace.
upsert_namespace(prefix, description=None, isolation_mode=None, deletion_mode=None, allowed_external_refs=None, confirm_enable_deletion=False)as listedIdempotent PUT-style upsert — creates on missing, patches supplied fields on existing.Guards: the wip namespace can never go full; retain→full on an existing namespace needs confirm_enable_deletion=true (else 400); a new namespace may be created deletion_mode=full directly.
get_namespace_stats(prefix)prefixEntity counts by type for a namespace.
delete_namespace(prefix, dry_run=True, force=False)prefix, dry_run, forceDelete a namespace and all its data.Destructive; requires deletion_mode=full; dry_run=True by default returns an impact report only.

Namespace Grants

ToolParamsPurposeNotes
list_grants(namespace)namespaceList permission grants on a namespace.Requires admin on the namespace.
create_grant(namespace, subject, subject_type, permission, expires_at=None)`subject_type: userapi_keygroup, permission: read
revoke_grant(namespace, subject, subject_type)as listedRevoke a grant.

API Key Management

ToolParamsPurposeNotes
create_api_key(name, owner="system", groups=None, namespaces=None, description=None, expires_at=None, grant_permission=None)as listedCreate a runtime API key.Returns the plaintext key once, never stored. namespaces=None = unrestricted. Without grant_permission, a namespace-scoped key can read but not write its namespaces; grant_permission='write' also provisions the matching grant.
list_api_keys()List config-file + runtime keys.No hashes/plaintext exposed.
revoke_api_key(name)nameHard-delete a runtime key.Config-file keys cannot be revoked this way.

Registry Entries & Synonyms

ToolParamsPurposeNotes
get_entry(entry_id)entry_idFull Registry entry: synonyms, composite keys, metadata.
lookup_entry(entry_id=None, namespace=None, entity_type=None, composite_key=None)one of entry_id OR namespace+entity_type+composite_keyLook up an entry by ID or by composite key (also searches synonyms).Errors with a usage message if neither form is supplied.
add_synonym(target_id, synonym_namespace, synonym_entity_type, synonym_composite_key)as listedAdd an alternative composite key that resolves to an existing entry.For cross-namespace linking / external ID mapping.
remove_synonym(target_id, synonym_namespace, synonym_entity_type, synonym_composite_key)as listedRemove a synonym.
merge_entries(preferred_id, deprecated_id)preferred_id, deprecated_idMerge two entries; the deprecated one goes inactive and its ID becomes a synonym of the preferred one.One-way — no reactivation endpoint for the deprecated entry yet.

Terminologies

ToolParamsPurposeNotes
list_terminologies(namespace=None, page=1, page_size=50)as listedList terminologies.
get_terminology(terminology_id)terminology_idGet by ID or value.
get_terminology_by_value(value, namespace=None)value, namespaceGet by value code, case-sensitive.
create_terminology(value, label, namespace=None, description=None, mutable=False, on_conflict="error")as listedCreate a terminology.value convention UPPER_SNAKE_CASE. mutable=true implies extensible=true and terms become hard-deletable. on_conflict='validate': identical re-create → status=unchanged; drifted config → error_code=incompatible_config.
create_terminologies_bulk(items, namespace=None, on_conflict="error")as listedCreate many at once.*_bulk shape — see response note above.
update_terminology(terminology_id, label=None, description=None, mutable=None, namespace=None)as listedUpdate label/description/mutability.mutable only changeable when term_count == 0. Errors if no field supplied.
delete_terminology(terminology_id, force=False, hard_delete=False, namespace=None)as listedDelete a terminology.Mutable terminologies are always hard-deleted regardless of the flag; immutable ones soft-delete unless hard_delete=true (needs deletion_mode=full). Blocked if terms exist unless force=true.
restore_terminology(terminology_id, restore_terms=True, namespace=None)as listedReactivate a deactivated terminology.restore_terms=True also reactivates its inactive terms.

Terms

ToolParamsPurposeNotes
list_terms(terminology_id, search=None, page=1, page_size=50)as listedList/search terms in a terminology.
get_term(term_id, namespace=None)term_id, namespaceGet by ID, value, or synonym.
create_terms(terminology_id, terms, on_conflict="error")terms: [{value, label, description?, aliases?}]Create terms.Single-term calls: on_conflict='validate'unchanged/incompatible_config. Multi-term calls always skip duplicates (status=skipped) regardless of on_conflict. Example in source: create_terms("T-xxx", [{"value":"GB","label":"United Kingdom","aliases":["UK","Britain"]}, {"value":"US","label":"United States","aliases":["USA"]}]).
validate_term_value(terminology, value)terminology, valueTest whether a value resolves in a terminology.
update_term(term_id, label=None, aliases=None, description=None, sort_order=None, namespace=None)as listedUpdate a term.aliases replaces the existing list wholesale, not merges. Errors if no field supplied.
delete_term(term_id, hard_delete=False, namespace=None)as listedDelete (soft by default).Terms in mutable terminologies are always hard-deleted. hard_delete=true on an immutable terminology needs deletion_mode=full.
deprecate_term(term_id, reason, replaced_by_term_id=None, namespace=None)as listedDeprecate with a reason + optional replacement pointer; term stays queryable, flagged superseded.Use instead of delete for historically-valid terms.

Ontology (Relations)

ToolParamsPurposeNotes
get_term_hierarchy(term_id, direction="children", relation_type=None, max_depth=10, namespace=None)`direction: childrenparentsancestors
create_term_relations(term_relations, namespace=None)term_relations: [{source_term_id, target_term_id, relation_type}]Create ontology relations.relation_type ∈ {is_a, part_of, has_part, regulates, positively_regulates, negatively_regulates} (plus custom types via the _ONTOLOGY_RELATIONSHIP_TYPES terminology, per wip://conventions). Example: create_term_relations([{"source_term_id":"ALZHEIMERS_DISEASE","relation_type":"is_a","target_term_id":"NEUROLOGY"}]).
list_term_relations(term_id, direction="outgoing", relation_type=None, namespace=None, page=1, page_size=50)`direction: outgoingincomingboth`
delete_term_relations(term_relations, namespace=None, hard_delete=False)same shape as createDelete relations.

Templates

ToolParamsPurposeNotes
list_templates(namespace=None, status=None, latest_only=True, page=1, page_size=50)`status: activeinactivedraft`
get_template(template_id, version=None, namespace=None)as listedGet a template with inherited fields resolved.version=None = latest.
get_template_by_value(value, namespace=None)value, namespaceGet by value code.
get_template_raw(template_id, namespace=None)as listedGet without inheritance resolution — only fields defined directly on this template.
create_template(template: dict, namespace=None)template: {value, label, fields, description?, extends?, extends_version?, identity_fields?, header_fields?, status?}Create a template.Field naming: mandatory (not required), terminology_ref/template_ref (not *_id). status='draft' skips reference validation (for circular deps). Updating an existing value creates a new version — see update_template. On an "already exists" error, the tool appends a hint to use update_template instead of retrying create_template.
create_templates_bulk(templates, namespace=None)as listedCreate many templates at once.Pairs with draft mode + activate_template for circular dependencies.
create_edge_type(value, label, source_templates, target_templates, fields, namespace=None, description=None, versioned=True, identity_fields=None, rules=None)as listedCreate an edge type — a template with usage: relationship — the documented happy path over hand-rolling create_template with usage set manually.Performs its own pre-flight validation in Python before calling template-store: source_templates/target_templates non-empty; fields must include source_ref and target_ref, each type=reference, reference_type=document, with target_templates matching the corresponding template-level list. On failure, returns the plain string "Edge-type contract validation failed:\n - ..."not the usual _error()/error_code shape. identity_fields defaults to [source_ref, target_ref] when omitted (pass [] explicitly to opt into true append-only). usage, source_templates/target_templates (widen-only via add_edge_type_endpoints), and versioned are immutable after creation.
update_template(template_id, updates: dict, namespace=None)updates keys: label, description, fields (full replace), identity_fields, header_fields, extends, rules, metadata, reportingUpdate by creating a new version; template_id stable, only the version increments.Returns template_id, value, version (new), is_new_version, previous_version. Existing documents keep validating against the version they were created with.
activate_template(template_id, namespace=None, dry_run=False)as listedActivate a draft template — validates all references, cascades to referenced drafts.All-or-nothing: any failure in the chain activates none.
deactivate_template(template_id, version=None, force=False, hard_delete=False, namespace=None)as listedDelete a version (soft by default).Blocked if other templates extends it. force=true overrides the "documents exist" block. hard_delete=true needs deletion_mode=full.
reactivate_template(template_id, version, namespace=None)version requiredRestore an inactive version to active — inverse of deactivate_template.Idempotent on an already-active version; rejects a draft version.
add_edge_type_endpoints(template_id, add_source_templates=None, add_target_templates=None, namespace=None)as listedAdditively widen an edge type's allowed source/target templates.Append-only (never removes); applied in place with no new version; preserves every existing edge; idempotent; each new endpoint must be a real template.
get_template_dependencies(template_id, namespace=None)template_id, namespaceWhat depends on a template: child templates + documents.
get_template_versions(template_value=None, template_id=None, namespace=None)one of template_value or template_idList all versions, newest first.
validate_template(template_id, namespace=None)template_id, namespaceCheck terminology_ref/extends references resolve to active entities.Useful pre-activate_template.

Documents

ToolParamsPurposeNotes
list_documents(template_value=None, namespace=None, template_id=None, status=None, latest_only=True, page=1, page_size=20)as listedList documents, optionally filtered by template.
get_document(document_id, version=None)as listedGet a document.version=None = latest.
validate_document(template_id, data: dict, namespace=None)as listedValidate data against a template without saving.Returns valid, errors, warnings, identity_hash (if valid), template_version. Useful for computing an identity hash pre-submission.
validate_documents(template_id, items: list[dict], namespace=None, template_version=None)as listedBulk, side-effect-free validation of many items against one template.Returns {"results": [...]} in input order, each shaped like validate_document's result. An unresolvable template_id fails the whole call (404) since the batch is single-template; a single invalid item is reported via that item's valid=false, not a call failure.
create_document(document: dict, namespace=None)document: {template_id, template_version (recommended), data}Create (or, on identity match, version) a document.Term fields: submit the human-readable value; WIP resolves to term_id (clear error on resolution failure). Without template_version, resolves "latest active" — may not be the version you expect if multiple are active. Example in source: create_document({"template_id":"TPL-xxx","template_version":1,"namespace":"wip","data":{"name":"Jane Doe","email":"jane@example.com","gender":"Female"}}).
create_documents_bulk(documents: list[dict], namespace=None)as listedCreate many documents.*_bulk shape.
query_documents(filters: dict)filters: {template_id, namespace?, status?, page?, page_size?, filters: [{field, operator, value}]}Low-level document query.filters[].field needs the data. prefix (e.g. data.country). Operators: eq, ne, gt, gte, lt, lte, in, nin, exists, regex. Prefer query_by_template for the auto-prefixed convenience version.
get_document_relationships(document_id, direction="both", template=None, namespace=None, active_only=True, page=1, page_size=50)`direction: incomingoutgoingboth`
traverse_documents(document_id, depth=1, types=None, direction="outgoing", namespace=None)depth: 1..10N-hop BFS graph traversal via relationship documents.Returns a flat node list with depth, path, via_relationship. Visited nodes are skipped (cycles terminate). Capped at depth=10 and 1000 nodes; sets truncated=true if a cap fires. Edges are implicit — call get_document_relationships on individual nodes for edge data.
get_document_versions(document_id)document_idList all versions of a document, with latest version number + total count.
archive_document(document_id)document_idSoft-delete (status → inactive).
update_document(document_id, patch: dict, if_match=None)as listedApply an RFC 7396 JSON Merge Patch to data, creating version N+1 (previous becomes inactive; publishes NATS DOCUMENT_UPDATED, which reporting-sync consumes to refresh the reporting layer).Objects deep-merge; arrays are replaced wholesale, not merged element-wise; null deletes a key. Error codes: identity_field_change (cannot PATCH identity fields — create a new document instead), append_only (template has no identity_fields), archived (unarchive first), not_found (deleted/nonexistent), concurrency_conflict (if_match mismatch). The merged document must still validate against the template version the document was originally created with — PATCH does not migrate to a newer template version.
migrate_documents(template_id, from_version, to_version, dry_run=True, namespace=None)as listedRe-pin a cohort of documents from one template version to another.dry_run=True by default — reports per-document readiness without writing (validation_failed details name e.g. unknown_field for a removed field or required for a newly-mandatory one). Identity-preserving only: both versions must declare the same identity_fields, else the whole call is rejected (identity_fields_changed — a fork needs new documents, not a migrate). On apply, creates a new version (or overwrites in place for versioned: false templates) keeping the same document_id/identity_hash. Source version may be inactive (frozen); target must be active. See gotcha below — this tool is a write despite living in a read-adjacent-sounding name.
delete_document(document_id, hard_delete=False, version=None)as listedDelete (soft by default).hard_delete=true needs deletion_mode=full. version (hard-delete only) defaults to all versions.
delete_documents_bulk(document_ids, hard_delete=False, namespace=None)as listedDelete many documents.*_bulk shape; hard_delete applies uniformly to every ID.

Import/Export (Terminology)

ToolParamsPurposeNotes
export_terminology(terminology_id, format="json", include_relations=True, namespace=None)`format: jsoncsv`Export a terminology with its terms (and optionally ontology relations).
`import_terminology(data: dictlist, format="json", skip_duplicates=True, update_existing=False, namespace=None)`as listedImport a terminology + terms from JSON data.

Table View (Denormalized Export)

ToolParamsPurposeNotes
get_table_view(template_value, status=None, page=1, page_size=100, namespace=None)as listedFlattened, spreadsheet-like document view for a template.Arrays are cross-product expanded into rows, capped at 1000 rows.
export_table_csv(template_value, status=None, include_metadata=True, namespace=None)as listedExport a template's documents as CSV.Returns raw CSV, but this MCP tool truncates the response to the first ~100 data rows (102 lines incl. header) if the export is larger, appending "... truncated (N total lines)".

Search & Reporting

ToolParamsPurposeNotes
search(query, types=None, namespace=None, page=1, page_size=20, template=None, mode="auto", include_inactive=False, snippet_format="html")as listedUnified search across all WIP entity types, via reporting-sync.mode: auto (default, FTS where a field declared full_text_indexed: true, ILIKE substring fallback elsewhere) / fts (force FTS, skips unindexed tables) / substring (legacy ILIKE, no ranking, works everywhere). types filters entity type (terminology, term, template, document, file); template further restricts document hits to one template value. Response groups hits per entity type, each with its own items/total/page/page_size/pages envelope. include_inactive=False by default (PoNIF #1 — retired ≠ deleted). FTS hits carry score (ts_rank) + snippet (ts_headline, HTML or plain per snippet_format); substring/non-document hits have neither.
search_registry(query, namespace=None, entity_type=None)`entity_type: terminologiestermstemplates

Files

ToolParamsPurposeNotes
list_files(namespace=None, page=1, page_size=20)as listedList files (MinIO-backed binary storage).
get_file_metadata(file_id)file_idMetadata only, not content.
upload_file(file_path, namespace=None, description=None, tags=None, category=None)as listedUpload a local file.file_path must be an absolute local path; content-type is guessed via mimetypes; tags is a comma-separated string split into a list. Returns file_id (UUID7) + metadata.
delete_file(file_id, force=False)as listedSoft-delete (status → inactive).Blocked if documents reference the file unless force=true.
hard_delete_file(file_id)file_idPermanently remove from MinIO, reclaiming storage.File must already be soft-deleted; irreversible.
get_file_documents(file_id)file_idWhich documents reference a file, and at which field path.

Template-Aware Query

ToolParamsPurposeNotes
get_template_fields(template_value, namespace=None)template_value, namespaceClean field summary (name/type/mandatory/references) + template_id, for use before querying/creating documents.
query_by_template(template_value, field_filters=None, status=None, page=1, page_size=20, namespace=None)field_filters: [{field, operator, value}]Query documents by template value with easy field filtering.Resolves template_value → template_id automatically. Field names auto-prefixed with data. unless already prefixed or one of the reserved top-level names (document_id, template_id, namespace, status, version, created_at, updated_at). Same operator set as query_documents.

Reporting & SQL Query

ToolParamsPurposeNotes
list_report_tables(table_name=None)table_nameDiscover reporting tables.Omit table_name for a compact summary (name, row_count, column_count) of all tables; pass it for full column detail (name, type, nullable) on one table.
run_report_query(sql, params=None, max_rows=1000, namespace=None)as listedExecute a read-only SQL SELECT against the PostgreSQL reporting database, for cross-template JOINs/aggregation/analytics the document API can't do.Each namespace is its own Postgres schema: a table is "<namespace>"."doc_<value>". Term fields expose two columns: {field} (value) + {field}_term_id. namespace= sets search_path so unqualified names resolve there; omit and schema-qualify for cross-namespace queries. Example: run_report_query("SELECT name, country FROM doc_patient WHERE country = $1", ["CH"], namespace="clinic-a").
export_report_csv(table=None, sql=None, params=None)exactly one of table/sqlExport reporting data as CSV — a whole table, or a filtered/joined query result.table mode is restricted to doc_* and metadata tables. Same first-~100-rows truncation as export_table_csv.

Import (CSV/XLSX)

ToolParamsPurposeNotes
import_documents_csv(file_path, template_value, column_mapping=None, namespace=None, skip_errors=True)as listedImport documents from a local CSV/XLSX file into a template, bulk-creating documents.Without column_mapping, auto-maps CSV headers to field names by case-insensitive match (spaces → underscores); errors listing both header and field-name sets if nothing auto-maps. skip_errors=True skips rows that fail validation rather than aborting.

Event Replay

ToolParamsPurposeNotes
start_replay(template_value=None, template_id=None, namespace=None, throttle_ms=10, batch_size=100)as listedRepublish stored documents as NATS events (a dedicated stream, metadata.replay=true) — for onboarding new consumers or backfilling.throttle_ms 0-5000; batch_size 10-1000; omitting both template filters replays the whole (active) namespace.
get_replay_status(session_id)session_idPublished count, total, status of a replay session.
cancel_replay(session_id)session_idCancel a session and delete its NATS stream.
pause_replay(session_id) / resume_replay(session_id)session_idPause/resume a running session.
start_backup(namespace=None, include_files=False, include_inactive=False, skip_documents=False, skip_closure=False, skip_synonyms=False, latest_only=False, template_prefixes=None, dry_run=False)as listedStart a namespace backup; returns the initial BackupJobSnapshot. Runs in the background — poll get_backup_job until complete/failed, then download_backup_archive.In-source WARNING: include_files=true is a v1.0-documented-unsafe path — the archive writer buffers all blob bytes in RAM and can OOM the document-store container; leave it false until a streaming archive path ships.
start_restore(namespace, archive_path, mode="restore", target_namespace=None, register_synonyms=False, skip_documents=False, skip_files=False, batch_size=50, continue_on_error=False, dry_run=False)as listedRestore a namespace from a local .zip archive (uploaded multipart); returns the initial BackupJobSnapshot.In-source GOTCHA: mode='restore' writes back to the source namespace embedded in the archive and ignores target_namespace — use only to restore into the same namespace the archive came from. mode='fresh' generates new IDs and honors target_namespace — use for a round-trip into a new namespace. register_synonyms (original IDs as synonyms of new IDs) only makes sense with mode='fresh'.
get_backup_job(job_id)job_idPoll a backup/restore job's state: status, phase, percent, message, archive_size (when complete).
list_backup_jobs(namespace=None, status=None, limit=50)`status: pendingrunningcomplete
download_backup_archive(job_id, dest_path)job_id, dest_pathStream a completed backup's .zip to a local path.Job must be a backup job in complete status. Parent directories of dest_path are auto-created.
delete_backup_job(job_id)job_idDelete a backup/restore job and its archive file.Cannot delete a running job.
get_sync_status()Reporting-sync service status: NATS connection, PostgreSQL connection, events processed/failed, tables managed.Useful for diagnosing sync lag/failures.

Store-specific gotchas

See also

API Conventions; PoNIFs; Auth & Access; Routing & Ingress; Document-Store API; Registry API; Template-Store API; Def-Store API; Reporting & Analytics (REST + SQL layer).

Generated from real source code, not hand-written — see the WIP Technical Library.