MCP tools

Griot has a generated MCP tool catalog for agent clients. Tool discovery and execution still depend on the actor's credentials and grants.

How to use this reference

Inspect the server's tool list with your authorized MCP client. The available tools can be narrower than the public API because some destructive or privileged operations are intentionally excluded. Discovery does not replace authorization at call time.

The catalog shown below is a checked snapshot copied from the combined integration source, not live discovery. Its source commit and hash appear beside the tool list. A stdio bridge forwards to K01's governed HTTP MCP endpoint instead of maintaining an independent registry. It provides only two legacy argument mappings when their target tools are advertised: run_query(sql)query_dataset(sql) and sample_dataset(slug)get_dataset_sample(slug). Read Connect an MCP client for credential and endpoint setup. Do not assume this snapshot matches a different server revision.

For API calls outside an agent client, use the public API operations.

Checkout MCP snapshot: 0d83c096558ec10915a3baca2065f0e9c85e3b7ca0b2419231092af707fc4a9b · source 52d51edb6458bf345089fd6e08880060078b46c5. Live discovery may differ.

Generated tool catalog

Discovery and execution depend on your grants.

271 of 271 tools

accept_clean_room_invitation

Accept a clean-room invitation: attach this tenant's own contract contribution(s) and join. The room activates when every party has accepted and contributed.

Capability: clean_room.create

Arguments: room_id (required), contributions (required)

add_draft_threads_turn

Add one turn to a drafting thread (one column's ask, or one step)

Capability: contract.create

Arguments: thread_id (required)

add_session_table

Bring one MORE dataset into an already-open workbook session (ADR-0043) — forks a private branch for the given `dpi` on top of the existing session. Use when a query/op needs a dataset you didn't open the session with. Returns the updated manifest.

Capability: dataset.read

Arguments: session_id (required), dpi (required)

amend_quarantine_row

Amend a quarantined row's column values and release it by its `row_id`. Pass `amendments` (column→value map) and a `reason`.

Capability: dataset.update

Arguments: row_id (required), amendments (required), reason (required)

approve_clean_room_operation

Record this tenant's decision (approved/rejected) on an operation version. The version activates only when EVERY accepted party has approved it.

Capability: clean_room.create

Arguments: room_id (required), operation_id (required), version (required), decision (required), reason

approve_contract_version

Cast YOUR vote on an open approval workflow (e.g. a contract-version activation opened by publish_contract). `approve` is REQUIRED and must be stated: an empty vote is refused (422 K01_APPROVAL_NO_DECISION) rather than taken as a yes, because this records a person's authorisation and an approval nobody can be shown to have intended is worth nothing. When your vote drives the workflow to APPROVED, the governed contract version is ACTIVATED immediately (its active_version flips in T03) and the response is `{state:'approved', active:{...}}`. A NO vote (approve=false) rejects the workflow. While more votes are still needed the response is `{state:'pending', approvals, threshold, voters}`. This is the step that actually makes a pending_approval contract go live — without it an amended draft stays pending forever. IF YOU ARE AN AGENT you cannot use this on a `contract_activation` workflow (the kind request_contract_activation opens): it is refused with K01_APPROVAL_AGENT_CANNOT_APPROVE, because that record exists to capture a HUMAN's decision and an agent voting on it would be the agent authorising itself. Show the person the draft and let them approve in their own session. PERSONAL DATA: when the contract governs personal data, approving is NOT enough — you must also pass lawful_basis_affirmed=true and lawful_basis='<the basis the contract declares>'. Approving the activation and affirming the lawful basis are two different statements and the second is recorded separately against you; omitting it returns 422 K01_LAWFUL_BASIS_AFFIRMATION_REQUIRED with the exact sentence you would be affirming.

Capability: contract.publish

Arguments: workflow_id (required), approve, lawful_basis_affirmed, lawful_basis

approve_marketplace_request

Approve a marketplace access request by its `request_id` — grants the requester governed access to the listing.

Capability: marketplace_listing.publish

Arguments: request_id (required)

ask_griot

Ask the hosted Griot agent a natural-language question. This is the same NL entry point the Ask-Griot UI uses: the agent plans, calls governed tools (search_contracts → describe_contract → query_dataset → render_*), and answers. STREAMING: the underlying route is Server-Sent-Events; over MCP the dispatcher waits for the full stream and returns the assembled answer (higher latency than a simple read). Pass `prompt` (required) and optional `thread_id` to continue an existing conversation. Prefer the granular governed tools directly when you already know the query; use this for open-ended questions.

Capability: public

Arguments: prompt (required), thread_id

audit_lakehouse_orphans

Run an Iceberg ORPHAN-FILE audit — find data files no longer referenced by any snapshot (reclaim candidates). Admin.

Capability: dataset.admin

Arguments: namespace, table

cancel_job_run

Cancel an in-flight run by `run_id`. Only a PENDING or RUNNING run can be cancelled; a run that already reached a terminal status answers with a conflict rather than pretending — read the error, it tells you the status it is actually in. Cancelling marks the run CANCELLED and stops scheduling further tasks; tasks already SUCCEEDED stay succeeded, which is what makes a later retry_job_run resume rather than redo.

Capability: pipeline.update

Arguments: run_id (required)

clone_role

Clone a role by its `role_key` into a new role (seed its permissions). Pass the new role `name`.

Capability: member.admin

Arguments: role_key (required), name

compliance_posture

Get the tenant's compliance posture (control status).

Capability: report.read

create_catalog

ADMIN: create or update a catalog (a tenant-defined namespace/folder in your bucket, e.g. 'raw'/'prod'). Upsert by name. Set is_published=true to designate it as THE published catalog analysts' datasets resolve to — this atomically demotes the previously published catalog (exactly one is ever published). Catalogs are an engineer/steward concern; analysts cannot create them.

Capability: dataset.admin

Arguments: catalog (required), description, is_published

create_catalog_bucket

Create an empty catalog bucket

Capability: dataset.admin

Arguments: catalog (required), domain (required), bucket (required), classification, governing_contract_id

create_clean_room

Create a Compare clean room (docs/design/clean-rooms.md): the agreement header (name, purpose, floor, term, proposal-expiry window), the parties to invite by tenant handle, and the convener's own contract contribution(s). The room activates only when every invited party accepts and contributes.

Capability: clean_room.create

Arguments: name (required), purpose (required), parties (required), contributions (required), room_type, not_intended_for, floor_min, proposal_expiry_days, term_months, message

create_compute_resource

Create a compute definition at version 1 — a named, reusable pod-spec fragment (size + image + idle/lifetime timeouts) that a notebook session, a job task or a pipeline can attach to by `name` afterwards. ALWAYS call validate_compute_resource with the same payload FIRST — it is free, and it is the only way to learn BEFORE creating that the cluster can actually schedule this size. `name` is the stable handle every later call uses. `cpu`, `memory` and `image` are required; `max_lifetime_s` has no 'unlimited' and defaults to 8 hours if omitted.

Capability: compute.create

Arguments: name (required), display_name, description, cpu (required), memory (required), ephemeral_storage, image (required), env_extras, max_idle_s, max_lifetime_s, allowed_consumers

create_contract

Create a GDCP data contract (draft) via T03. A contract is keyed by (domain, dataset). Call get_contract_template FIRST to get a ready-to-fill skeleton with every required section. REQUIRED for a structured base contract: `purpose` (§1 semantic_purpose) needs primary_insight (string, min 10 chars) + questions (array, >=1 item, each >=5 chars) + business_context (string, min 20 chars); `schema` (§5 value_semantics) needs fields[] where each field.name is snake_case (^[a-z_][a-z0-9_]*$) plus type/nullable/description; AND `quality` IS REQUIRED — it needs completeness (required_fields_non_null_pct: {field: 0..1}), validity, and freshness (max_staleness_hours >=1). `temporal` (ingestion_cadence + freshness_sla_hours + retention) is also required unless inherited from a domain/policy. The draft is created 'draft' — activation is a separate step (publish_contract).

Capability: contract.create

Arguments: domain (required), dataset (required), purpose, schema, quality, privacy, temporal, governance

create_domain

Create a governance DOMAIN — the place a dataset lands and the unit that governs it (ADR-0018). Call this when an ingest is refused because no suitable domain exists. You need only `slug` (lowercase/digits/hyphens, e.g. 'sales') and `name` (e.g. 'Sales'); `owner_actor_id` is OPTIONAL — omit it and YOU (the authenticated caller) become the domain's owner, which is what you want when you do not know your own actor id. Then retry the ingest with domain=<slug>.

Capability: domain.create

Arguments: slug (required), name (required), owner_actor_id, parent_slug, description, catalog

create_evidence_pack

Generate a regulator-facing compliance EVIDENCE PACK for a `framework` (K07). Returns {evidence_pack_id, status:'generating'} — the pack assembles audit trails, control status, and certificates.

Capability: report.create

Arguments: framework (required)

create_job

Create a JOB — a named, versioned DAG of tasks that K02 runs. Use this for procedural work: 'run these steps, in this order, on this schedule'. `name` is a slug, unique in the tenant, and it is the STABLE HANDLE for everything after: get_job, update_job, run_job and list_job_runs all address the job by that name, so you can compose the next call from what you read last turn without holding a UUID in context. Each task in `tasks` is {key, type: 'griotql'|'notebook', depends_on: [keys], config, retries}. ALWAYS call validate_job with the same payload FIRST — it is free, it checks the DAG for cycles, that every referenced object exists, each declared_purpose against its contract, run_as capability, and returns a credit estimate. Guessing is fine; guessing expensively at 06:00 tomorrow is not. `run_as` names the actor the run executes as and is REQUIRED for any job that reads governed data (a scheduled run has no interactive caller, so the four-gate needs an actor and Semantic Law needs a purpose); the job is REFUSED at author time without it rather than failing on its first fire. `schedule` is an optional cron. To change a job later use update_job's deltas — never re-create it.

Capability: pipeline.create

Arguments: name (required), tasks (required), description, run_as, schedule, tags

create_notebook

Create (persist) a notebook — the general compute instrument (ADR-0024). A notebook is an ordered list of typed cells (python | sql | griotql | markdown) run in ONE shared kernel context top-to-bottom; state flows between cells. Read the bound governed dataset in a sql cell via `SELECT * FROM raw_input` (or `griot.dataset('griot://{domain}/{dataset}')`), reshape in python, and emit the notebook's declared output with `griot.output(df)`. Bind the notebook to the governed dataset it reads with `contract_id` ('{domain}/{dataset}'). Returns `notebook_id` + `version` — pass BOTH to `create_pipeline` (which materializes the notebook's output to a governed tier through the contract + promotion gate). Declare third-party libraries the cells need in `packages` (PEP-508 specs); they are installed in the kernel when the notebook RUNS (`run_notebook` or a pipeline run). FLOW: create_notebook → (optional) run_notebook → create_pipeline → run_transform. Tip: call `run_notebook` first to preview before saving.

Capability: pipeline.read

Arguments: name (required), cells (required), contract_id, params, packages

create_partner

Register a new sharing partner organisation.

Capability: partner.create

Arguments: org_name (required), contacts, partner_type, description, purpose

create_pipeline

Create a notebook-backed transform pipeline via K02 (ADR-0024). A pipeline REFERENCES a notebook+version and materializes the notebook's declared output to a governed tier through the contract + promotion gate — it no longer carries inline transform SQL/Python. FLOW: author the notebook with `create_notebook` (optionally preview with `run_notebook`) to get `notebook_id` + `version`, then call this. Required: `name` (the pipeline id), `notebook_id` (the stored notebook the pipeline runs — from `create_notebook` or `list_notebooks`), `notebook_version` (the pinned version, an integer >= 1, so the pipeline is reproducible), and `contract_id` ('{domain}/{dataset}' — the contract the materialized output is bound to). `target_tier` names the CATALOG the output is materialized to — a tenant-defined bucket folder (e.g. 'prod'/'raw'/'default'), NOT a fixed platform tier; raw/stg/prod are just example catalog names (ADR-0029). Defaults to 'prod'. Pass an optional cron/@daily `schedule` to run it on a cadence.

Capability: pipeline.create

Arguments: name (required), notebook_id (required), notebook_version (required), contract_id (required), target_tier, schedule

create_report

PUBLISH a Griot report — a versioned ANALYSIS document under an overarching `theme`, composed from an EXPLORATION (an Ask Griot thread and/or a workbook session), NOT a chat transcript. Provide EITHER a full `document` (report.json: meta + sections[] + sources[]) OR a `thread_id` and/or a `session_id` to compose from: the thread's answers and the workbook session's recorded ops are aggregated into a conclusive analysis (overview answer, headline metrics, headed argumentative sections, method appendix). `theme` is the report title (a question is a special case of a theme); it is required with a `document` and defaults to the thread title when composing from a thread. `answer` optionally steers the overview.

Capability: report.create

Arguments: theme, answer, thread_id, session_id, document, domain, slug

create_role

Create a custom role (admin).

Capability: member.admin

Arguments: role_key (required), name (required), description, permissions, clone_from

create_source

Connect a new data source (warehouse, file, stream, API, website). Raw/bronze landing is CONTRACTLESS — you do NOT need a contract first; omit `contract_id` and the platform auto-provisions a permissive raw contract on the landed dataset. The full GDCP contract is authored later and enforced at PROMOTION (raw→stg→prod). `connector_type` accepts exactly TWO values: 'website' (fetch + land a web CSV/JSON/HTML page) and 'api' (an ADR-0041 runtime connection that lands nothing). 'file', 'postgres', 's3' and 'stream' are NOT supported and are refused with K01_CONNECTOR_NOT_SUPPORTED — Griot has no scheduled warehouse or stream ingestion, and a file is uploaded through the UI file-uploader, not this tool. ADR-0041: connector_type='api' creates a RUNTIME CONNECTION (e.g. Earth Engine), NOT an ingestion source — supply `connector_key` (a K04B connector-registry key like 'earth_engine') + optional non-secret `params` (e.g. {'project': 'griot-pos'}), plus an optional `contract_id` binding the governing connector contract (e.g. 'sources/earth_engine'). It lands NOTHING (no scheduler/profiler) and is used by notebook runs; check connectivity with `test_source` (a quota-free auth probe). Never put credentials in `params`. FOR AN INGESTION SOURCE (anything that lands data, e.g. connector_type='website'): `domain` is REQUIRED and must name an EXISTING governance domain — list_domains / create_domain(slug, name). After the data lands it is NOT queryable yet: a contract is drafted for it automatically, so poll get_dataset_status(dpi='griot://{domain}/{dataset}') until state='active'. The response's `lifecycle` block spells this out.

Capability: source.create

Arguments: label (required), connector_type (required), contract_id, host, credentials, url, domain, dataset, format, selector, connector_key, params, mode

dataset_lineage

ADMIN: get the column-level lineage graph rooted on a dataset — where its data came from and what derives from it. Use this only when the question is about PROVENANCE or impact (upstream sources / downstream consumers); for analysis of the data itself, use describe_contract + query_dataset. Pass the dataset slug to root the graph on. (Requires dataset.admin. Analysts use describe_contract to read the contract + schema instead.)

Capability: dataset.admin

Arguments: dataset (required)

delete_agent

DELETE an agent by its `agent_id` — the real delete (TASK-209), not a disable. Removes the K03 agent definition (or, for an identity-only agent, tombstones its T01 identity) and cascades: T01 identity DELETE, gak_ key revoke, extras + identity-link cleanup. The response's `cascade` block reports each step truthfully: {id, deleted:true, cascade:{...}}. Personal agents refuse with 409 K03_PERSONAL_AGENT_UNDELETABLE. To temporarily deactivate an agent instead, use `disable_agent`.

Capability: agent.delete

Arguments: agent_id (required)

delete_partner

Delete a sharing partner by `partner_id` (#165 deletions). Refuses with 409 listing the active shares unless `cascade` is true, which revokes them all first, then deletes.

Capability: partner.grant

Arguments: partner_id (required), cascade

delete_role

Delete a custom role by its `role_key`.

Capability: member.admin

Arguments: role_key (required)

deliveries_enumerate_webhook_source

List Webhook Deliveries

Capability: source.read

Arguments: source_id (required)

deny_marketplace_request

Deny a marketplace access request by its `request_id`, with an optional `reason`.

Capability: marketplace_listing.publish

Arguments: request_id (required), reason

deploy_agent

Deploy a SPECIALIST agent to do a task, for a DECLARED PURPOSE. Griot picks the specialist by reading the candidates' contracts: it ranks them by how well the purpose matches each contract's declared questions/use-cases, and EXCLUDES any agent whose contract lists this purpose under `purpose.not_intended_for`. Declare the purpose HONESTLY — a prohibited purpose is REFUSED (422 A2A_PURPOSE_REFUSED) and the refusal names the contract and the prohibition. Returns an A2A Task {id, contextId, status:{state,message,timestamp}, artifacts, metadata}; `state` is SUBMITTED (queued), WORKING, COMPLETED, FAILED, or REJECTED (depth limit, budget exhausted, or purpose refused). Poll it with get_deployment using the Task id. The child runs BOUNDED: depth ≤ 2, budget clamped to ≤ half your remaining budget, a tool allowlist, and a chain-of-causation entry linking it to you. Optionally pin a specific specialist with `agent` (id, DPI or name) — pinning does NOT bypass the purpose check. Set `wait` to poll the child to completion inline.

Capability: agent.create

Arguments: purpose (required), task (required), budget_usd, agent, context_id, max_steps, wait, parent_task_id

deprecate_contract

Deprecate the active version of a contract lineage (T03). The contract's active_version is retired; downstream reads against it stop satisfying. Pass `type` to target a specific lineage (default 'internal').

Capability: contract.publish

Arguments: name (required), type

describe_contract

Read the data contract for a dataset — and the call to make BEFORE every query_dataset. In Griot a 'data contract' IS the governed dataset: the schema you query against and the guarantees it makes. Returns FOUR keys: (1) `dataset` — identity, status, modality, AND the PUBLISH VERSION you can pin in a query (FROM "domain/dataset/2"). (2) `purpose` — the questions it answers, business_context, `not_intended_for[]` — the uses it is NOT for — AND `data_class` when it is `representative` (illustrative/mock data: results from it are auto-tainted and rendered artifacts carry a warn banner; verbally note it in your answer). This is an ENFORCEMENT boundary, not a suggestion: query_dataset checks your declared_purpose against the permitted purpose set and rejects an out-of-bounds purpose (fails loud). (3) `schema` — every field's type, enum values, nullability and PK, plus per-field query-hints + free-text markers, the row GRAIN, and metric UNITS. (4) `declared_loss` — the EXCLUDED columns: physically dropped, never present, so a query naming one fails. A section may also carry `authored` — how its WORDS came to be: `measured` | `model` | `human` | `unavailable`. `unavailable` means NOBODY wrote them: no model or person was reachable, so the platform inserted a stand-in that deliberately asserts nothing about the data. Do NOT read such a section as a description of the dataset — treat it as undescribed, lean on the measured field shape + statistics, and say so if your answer leans on it. (No `authored` key = a contract drafted before this was recorded; the measured shape, quality and sensitivity are unaffected either way.) Lets you write a correct, in-bounds query first-try, no sample rows needed. Pass the `dataset` value search_contracts returned (the slug or full '{domain}/{dataset}' id). NOTE: an API-kind connector contract (a runtime connection, e.g. 'ksa/earth_engine') has no landed rows — its `business_context` carries the usage rules and its `schema` is the response shape the connection returns; read through it from a notebook (connections:[key]), do not query_dataset it.

Capability: dataset.read

Arguments: slug (required)

describe_whatsapp_callback_url

Describe this tenant's WhatsApp Business webhook connection state (connected/not, key prefix, created_at) -- read-only, no credential is minted or returned.

Capability: tenant_settings.read

disable_agent

Disable (deactivate) an agent by its `agent_id`.

Capability: agent.update

Arguments: agent_id (required)

discard_session

Discard a workbook session (ADR-0043) — drop every session branch and the scratch namespace. Production/main is provably UNTOUCHED. Use this to abandon exploratory work. Idempotent (an already-discarded session returns 'discarded').

Capability: dataset.read

Arguments: session_id (required)

dismiss_notification

Dismiss (hide) a single notification by its `notification_id`.

Capability: public

Arguments: notification_id (required)

download_model

Download Model

Capability: public

Arguments: domain (required), name (required), version

draft_clean_room_operation

AI-draft a Compare-room operation from a plain-English question. Read-only: returns candidate GriotQL plus the compiler's verdict (compiles, or the named refusal). Nothing is proposed or stored.

Capability: clean_room.read

Arguments: room_id (required), question (required)

drop_quarantine_row

Permanently drop a quarantined row by its `row_id` (steward action).

Capability: dataset.update

Arguments: row_id (required)

dry_run_refine_check

Dry-run a candidate standards payload against settled-type data, without applying it.

Capability: contract.create

Arguments: dpi (required), run_id (required)

enable_agent

Enable (activate) an agent by its `agent_id`.

Capability: agent.update

Arguments: agent_id (required)

enumerate_billing_credit_pack

List credit top-up packs

Capability: public

enumerate_catalog_bucket

List catalog buckets or a bucket's files

Capability: dataset.read

Arguments: catalog (required), domain, bucket

enumerate_compute_attachment

List what is currently attached to a compute definition

Capability: compute.read

Arguments: name (required)

enumerate_compute_resource

List the compute pools this workspace's jobs can run on ({compute_resources:[{name, jurisdiction, provider, tier, healthy, default, storage_pool}]}). Which one a job uses is derived from the workspace's storage residency, not chosen separately: a row whose `jurisdiction` matches get_storage_residency's is the pool that will run the work. A row with `healthy: false` cannot take work and every job for a workspace in that jurisdiction is refused by name; a row with `name: null` means data can rest in that jurisdiction and no compute pool exists there yet.

Capability: tenant_settings.read

enumerate_model_providers_model

List a model provider's available models, live (dropdown source)

Capability: tenant_settings.read

Arguments: provider (required)

enumerate_refine_run

List every refinement run for a dataset, newest first.

Capability: contract.create

Arguments: dpi (required)

enumerate_storage_resource

List the storage pools this workspace can keep its data in ({storage_resources:[{name, jurisdiction, provider, tier, healthy, default}]}). The `default` row is the managed pool a workspace gets unless it chooses otherwise; an unhealthy pool is listed and cannot be bound. Use get_storage_residency to see which one is in use.

Capability: tenant_settings.read

enumerate_tenant_model_key

List this tenant's stored model-provider keys (masked)

Capability: tenant_settings.read

enumerate_webhook_source

List Webhook Sources

Capability: source.read

execute_notebook_headless

Execute a notebook HEADLESS (server-side, no editor) and return the run result. Pass the notebook `cells` (and optional `packages`); runs top-to-bottom in one shared kernel like run_notebook.

Capability: pipeline.read

Arguments: cells (required), packages

explain_job_run_failure

Diagnose a failed run in ONE call. Returns, assembled server-side: which task failed first (and which were UPSTREAM_FAILED because of it), the real error, the statement/notebook it was running, the governing contract and the specific constraint that was violated, and any quarantined rows the run produced. This is the tool to reach for the moment a run reports FAILED — it replaces the run → task → logs → contract → quarantine click-path a human would otherwise walk, so do not stitch that together from get_job_run yourself. Works on a succeeded run too (it just has nothing to explain).

Capability: pipeline.read

Arguments: run_id (required)

explain_notebook_run_failure

Diagnose a failed NOTEBOOK run in one call: which cell failed, the real exception with its traceback, which downstream cells never ran because of it, and the run's terminal status. This is the notebook sibling of explain_job_run_failure — reach for it the moment a notebook run reports an error instead of re-running cells to see what happens.

Capability: pipeline.read

Arguments: run_id (required)

export_audit_log

Request a signed EXPORT of the tenant's audit log (returns {export_id, status}). Pass optional `from`/`to` ISO timestamps to bound the range.

Capability: audit_log.read

Arguments: from_ts, to_ts

get_a2a_agent_card

A2A v1.0 Agent Card (tenant-scoped, internal)

Capability: agent.read

Arguments: agent_id

get_activation_request

READ THE ACTIVATION APPROVAL for a dataset's draft contract — poll this after request_contract_activation. Returns the same self-describing payload (decision, personal_data, the draft's real sections, next_actions) plus the live `state`: 'pending' (nobody has decided yet — WAIT and poll; you cannot approve it and there is nothing to retry), 'approved' (a human authorised it — call publish_contract(name=dpi) NOW), 'rejected' (a human said no — do NOT retry and do NOT open another request; change what they objected to with update_contract first). A 404 K01_ACTIVATION_NOT_REQUESTED means nobody has been asked yet — polling will never change that; call request_contract_activation.

Capability: contract.read

Arguments: dpi (required), type, version

get_actor

Get one member/actor in the tenant by its `actor_id` (profile, roles, status).

Capability: member.read

Arguments: actor_id (required)

get_agent

Get one agent identity by its `agent_id` (caps, owner, config).

Capability: agent.read

Arguments: agent_id (required)

get_agent_decision_chain

Get the governed DECISION CHAIN for a specific agent run (`agent_id` + `run_id`) — the ordered tool calls, contract checks, and four-gate decisions that produced the run's outcome (the audit spine for 'no AI without provenance').

Capability: agent.read

Arguments: agent_id (required), run_id (required)

get_ai_usage

Get the caller tenant's AI usage (tokens, inferences, model spend) for the current period — the metered Ask-Griot / agent activity.

Capability: tenant_settings.read

Arguments: limit, offset

get_approval

Get one approval workflow's status: `state` (pending|approved|rejected), `approvals`, `threshold`, `voters`, the subject, and — for contract-promote — the contract name/type/version. Use to check whether a publish_contract workflow has reached quorum yet. For a `contract_activation` workflow it also returns `dpi`, `commits_to`, `governs_personal_data`, `human_approvers` (who actually authorised it) and any recorded `lawful_basis_affirmations`. To get that PLUS the draft contract the person is deciding about, use get_activation_request(dpi=...) instead — you need the draft to render the decision honestly.

Capability: contract.read

Arguments: workflow_id (required)

get_audit_event

Get one audit-log event's full detail by its `event_id`.

Capability: audit_log.read

Arguments: event_id (required)

get_auth_me

Get Me

Capability: public

get_billing_checkout

Poll a checkout session's status

Capability: billing.read

Arguments: reference (required)

get_capabilities

Get the caller tenant's enabled platform capabilities (feature flags / entitlements).

Capability: member.read

get_catalog_domain

Read one governance domain by its full catalog and domain slug. Use this when the same domain slug exists in multiple catalogs.

Capability: domain.read

Arguments: catalog (required), slug (required)

get_catalog_table

Read a table by its full catalog, domain, and table identity. Use this when a domain/table name is shared across catalogs.

Capability: dataset.read

Arguments: catalog (required), domain (required), table (required)

get_catalog_table_contract

Read a table contract by its complete catalog, domain, and table identity.

Capability: dataset.read

Arguments: catalog (required), domain (required), table (required)

get_cell_impact

Answer 'what breaks if I change this cell?' — returns the transitive downstream closure of one cell: every cell that would go stale, in execution order. Read this BEFORE editing a cell in a notebook you did not write; it is the blast radius, computed from the real graph rather than guessed.

Capability: pipeline.read

Arguments: nb (required), cid (required)

get_clean_room

One room's full detail by `room_id`: agreement (purpose, floor, term, proposal-expiry), parties, contributions, operations, recent runs, pending amendment.

Capability: clean_room.read

Arguments: room_id (required)

get_clean_room_ledger

The Room Ledger: every event that ever happened in the room - parties, contributions, agreement and operation versions with approvers, every run, every output, every refusal WITH its reason.

Capability: clean_room.read

Arguments: room_id (required), limit, offset

get_clean_room_operation

One operation's detail: every immutable version with its exact GriotQL, the columns it reads, the synthetic example output, every party's recorded decision, and today's run count against the approved cap.

Capability: clean_room.read

Arguments: room_id (required), operation_id (required)

get_clean_room_run

One run with THIS tenant's entitled outputs (columns pair the pooled group values with this tenant's own), the T05 certificate riding each output.

Capability: clean_room.read

Arguments: room_id (required), run_id (required)

get_compliance_framework

Get a compliance framework's control status by its `code` (e.g. 'gdpr', 'soc2', 'hipaa') — per-control posture + evidence coverage.

Capability: report.read

Arguments: code (required)

get_compute_resource

Get one compute definition by `name`: its size, image, timeouts, allowed consumers, current `version` and computed `credits_per_hour`. Pass `version` to read a HISTORICAL pinned snapshot exactly as a past attachment provisioned it — editing a definition bumps its version but never touches what is already running (§B.3). A 404 means no definition by that name in this tenant — call list_compute_resources rather than guessing another spelling. A soft-deleted definition still resolves (`deleted_at` set) rather than 404ing, so a past bill always explains itself.

Capability: compute.read

Arguments: name (required), version

get_connection

Read one live warehouse connection's PUBLIC view by `connection_id` (from list_connections): {id, name, source_type, config, has_credential, created_by, created_at}. NEVER the credential. 404 if no such connection exists for this tenant.

Capability: source.create

Arguments: connection_id (required)

get_connection_table_schema

Describe ONE remote table's typed columns over a live warehouse connection — the columns + types the warehouse reports, without copying data. Returns the connector's schema (typically {columns:[{name, type, nullable}]}). Pass `table` (required) and, for namespaced warehouses, `database` / `schema`. Read this before onboarding a table so you bind the right one.

Capability: source.create

Arguments: connection_id (required), table (required), database, schema

get_consent_records

Get the tenant's consent records (data-subject consent state) — the compliance ledger of who consented to what.

Capability: report.read

Arguments: limit, offset

get_contract

Get a contract's full detail (sections, version) by id.

Capability: contract.read

Arguments: contract_id (required)

get_contract_template

Get a ready-to-fill GDCP contract skeleton (every required section with the correct field shapes and example values) so you can author a valid contract for create_contract WITHOUT guessing. The skeleton is derived from T03's canonical section JSON Schemas — purpose (primary_insight + questions[] + business_context), schema (snake_case fields), quality (completeness/validity/freshness, REQUIRED), and temporal (cadence/sla/retention). Fill in the values, set domain + dataset, and pass it to create_contract.

Capability: contract.read

get_contract_validation_history

Get the validation history for a contract by its `name` — the record of quality/privacy/completeness check runs and outcomes.

Capability: contract.read

Arguments: name (required), limit, offset

get_contract_views

Get the derived VIEWS of a contract by its `contract_id` — the different projections (schema view, purpose view, privacy view) T03 materialises from the compiled contract.

Capability: contract.read

Arguments: contract_id (required)

get_contracts_schema

Get canonical contract section schemas

Capability: contract.read

get_dataset

Get dataset detail

Capability: dataset.admin

Arguments: slug (required), catalog, domain

get_dataset_activity

Get recent activity (reads/writes/promotions) for a dataset by its `contract_id` (domain/dataset). Audit-style timeline.

Capability: dataset.read

Arguments: contract_id (required), limit, offset

get_dataset_certificate

Get the CURRENT GDCP certificate for a dataset by its `contract_id` (domain/dataset) — the active provenance/trust certificate.

Capability: certificate.read

Arguments: contract_id (required)

get_dataset_columns

List a dataset's columns (name + type) as the governing contract exposes them — the cheap schema read for building a query without a full describe_contract. `slug` is the dataset DPI ('<domain>/<dataset>').

Capability: dataset.read

Arguments: slug (required)

get_dataset_contracts

List the contracts bound to a dataset by its `slug` — the governed contract(s) that activate/enforce the data.

Capability: dataset.read

Arguments: slug (required)

get_dataset_operations

List the operations (pipelines/transforms/queries) touching a dataset by its `contract_id` (domain/dataset).

Capability: dataset.read

Arguments: contract_id (required), limit, offset

get_dataset_sample

Get sample rows for dataset

Capability: dataset.read

Arguments: slug (required)

get_dataset_status

WHERE A DATASET IS IN ITS CONTRACT LIFECYCLE — poll this after ingesting anything, and whenever a query says a dataset is not queryable. Landing data does NOT make it queryable: Griot serves every dataset through a data contract, which is DRAFTED asynchronously after the bytes land and must then be ACTIVATED. Returns `state`, `queryable` (boolean), `meaning` (what the state means) and `next_action` (what to do next), plus the live `refinement_run` and, on failure, `reason` — the real upstream error, not a generic message. STATES: 'landed' (stored, no contract work started — poll again), 'drafting' (a contract is being written right now — WAIT and poll; this is normal progress, not an error), 'draft_ready' (a draft exists but is not active — still not queryable; activation is a governance step), 'active' (queryable NOW — call describe_contract then query_dataset), 'needs_human' (drafting is blocked and will NOT progress on its own — a person must decide the blocked stage), 'failed' (see `reason`). A 404 means no such dataset — a wrong name, not a wait: stop polling and call list_datasets. While the state is 'landed' or 'drafting', do NOT re-upload the file and do NOT start a second contract — one run is already in flight for this dataset.

Capability: dataset.read

Arguments: dpi (required)

get_dataset_trust

Get the trust posture for a dataset by its `contract_id` (domain/dataset) — the three GDCP trust scores (AI/audit/operational readiness) + certificate status.

Capability: dataset.read

Arguments: contract_id (required)

get_deployment

Get a deployment's current state as an A2A Task, by the `task_id` deploy_agent returned. Projects the live spawn record — `status.state` is SUBMITTED | WORKING | INPUT_REQUIRED | COMPLETED | FAILED | CANCELED | REJECTED, `status.message` names the reason, and `artifacts` carries the specialist's result once COMPLETED.

Capability: agent.read

Arguments: task_id (required)

get_doc

Read one Griot handbook page and return its raw markdown ({slug, title, markdown}). Pass a `slug` from list_docs — example slugs: 'contracts/authoring', 'pipelines/transform-and-promotion-model', 'tutorials/cisa-kev-walkthrough', 'index' (the welcome page). Read the page that matches your task BEFORE attempting an unfamiliar operation.

Capability: public

Arguments: slug (required)

get_document_content

Read the FULL extracted text of an unstructured (GMF) DOCUMENT — a PDF, DOCX, PPTX, HTML, text file or image landed in Griot. Use this to read, summarize, or answer questions about an uploaded document: its text was extracted at ingest (parsed for text formats, OCR'd for scanned PDFs and images). Returns {dpi, content, chars} where `content` is the whole document text. `content` is EMPTY for a structured (tabular) dataset — those are queried with query_dataset, not read. Find the document first via search_contracts / list_datasets (a document has data_modality='unstructured'). Accepts the slug or the full '{domain}/{dataset}' id.

Capability: dataset.read

Arguments: slug (required)

get_domain

Read one domain's record (its datasets, owner/steward, description). `slug` is the domain name (e.g. 'sales').

Capability: domain.read

Arguments: slug (required), catalog

get_draft_thread

Read a drafting thread back, turns included

Capability: contract.read

Arguments: thread_id (required)

get_erasure_records

Get the tenant's erasure records (right-to-be-forgotten fulfilment state) — the compliance ledger of erasure requests + outcomes.

Capability: report.read

Arguments: limit, offset

get_finops_attribution

Get cost ATTRIBUTION — spend broken down by domain/dataset/pipeline/team (who is driving cost).

Capability: report.read

Arguments: limit, offset

get_finops_chargeback

Get CHARGEBACK allocations — cost split across cost-centres/teams.

Capability: report.read

Arguments: limit, offset

get_finops_exports

List FinOps data EXPORTS (billing/cost export artifacts).

Capability: report.read

Arguments: limit, offset

get_finops_idle

Get IDLE-resource findings — provisioned capacity/datasets not being used (reclaim candidates).

Capability: report.read

Arguments: limit, offset

get_finops_posture

Get the tenant's FinOps posture — spend vs budget, cost drivers, and optimisation signals.

Capability: report.read

get_finops_predictions

Get forward cost PREDICTIONS (projected spend for the period).

Capability: report.read

get_gdcp_certificate

Get a GDCP certificate's detail by id (T05).

Capability: certificate.read

Arguments: cert_id (required)

get_glossary

Get the tenant's business glossary — the governed terms/definitions used across contracts and datasets.

Capability: dataset.read

Arguments: limit, offset

get_governance_settings

Read the tenant's contract-approval governance settings: `contract_approval_threshold` (distinct approvers required to ACTIVATE a non-first contract version — 1 means the publisher alone satisfies it) and `contract_approval_separation_of_duties` (when true, the proposer cannot count as one of the approvers). Use this to understand why publish_contract returned pending_approval and how many votes a revision needs.

Capability: contract.read

get_incident

Get one incident (full timeline + impact) by its `incident_id`.

Capability: report.read

Arguments: incident_id (required)

get_ingestion_status

Get the run status of an ingestion PIPELINE by pipeline name. NOTE: this is about a scheduled pipeline's runs — to find out whether an uploaded dataset is QUERYABLE yet, use get_dataset_status(dpi='griot://{domain}/{dataset}') instead.

Capability: pipeline.read

Arguments: name (required)

get_insight

Get a single insight's detail.

Capability: report.read

Arguments: insight_id (required)

get_job

Get one job's full definition by `name`: its tasks (keys, types, depends_on, config), current `version`, `run_as`, `schedule` and tags. Read this BEFORE update_job so your delta names task keys that actually exist. A 404 means no job by that name in this tenant — call list_jobs rather than guessing another spelling.

Capability: pipeline.read

Arguments: name (required)

get_job_run

Get one run by `run_id`: its status, the job + job VERSION it pinned, timings, and every task run beneath it with its own status. Statuses are the same vocabulary at both levels — PENDING / RUNNING / SUCCEEDED / FAILED / UPSTREAM_FAILED (a dependency failed, so this task never ran) / CANCELLED / SKIPPED. This is the poll companion to run_job. When something FAILED, call explain_job_run_failure instead of piecing the story together from here.

Capability: pipeline.read

Arguments: run_id (required)

get_lakehouse_table

Get an Iceberg table's metadata (schema, snapshots, partitions) by `namespace` + `table`.

Capability: dataset.read

Arguments: namespace (required), table (required)

get_listing

Get a marketplace listing's detail by slug.

Capability: marketplace_listing.read

Arguments: slug (required)

get_listing_sample

Get masked SAMPLE rows for a marketplace listing (ADR-0032) — a preview of the data product before subscribing. `slug` is the listing slug (from list_marketplace).

Capability: marketplace_listing.read

Arguments: slug (required)

get_listing_schema

Get the SCHEMA (column names + types) a marketplace listing exposes (ADR-0032) — inspect a data product's shape before subscribing. `slug` is the listing slug (from list_marketplace).

Capability: marketplace_listing.read

Arguments: slug (required)

get_marketplace_download

Download the FULL dataset behind a marketplace listing (subscribers only)

Capability: marketplace_listing.read

Arguments: listing_ref (required), format

get_model_info

Read one GMF model version's metadata (ADR-0047): the vN.gmf.json — declared input/output signature, statistics (metrics), packaging, lineage (snapshot-pinned training inputs), and artifacts.root_digest (the content fingerprint). Pass `domain` + `name` (from list_models) and optionally `version` to pin a specific one; omit `version` for the latest. Metadata ONLY — the model bytes are not returned (agent download is the P1 governed handout).

Capability: public

Arguments: domain (required), name (required), version

get_model_rate

Per-model credit rate menu (K03 passthrough)

Capability: public

get_notebook

Get one notebook (its cells + metadata) by its `notebook_id`.

Capability: pipeline.read

Arguments: notebook_id (required)

get_notebook_graph

Read a notebook's dependency graph — cells, the names each defines and references, the edges between them, execution order and which cells are currently STALE — with no session attached and nothing to pay for. This is how you reason about a notebook before touching it: what feeds what, what a re-run would execute, what is already consistent.

Capability: pipeline.read

Arguments: nb (required)

get_partner

Get one federation partner by its `partner_id` (status, config).

Capability: partner.read

Arguments: partner_id (required)

get_permissions

Get the full RBAC permission matrix (roles × capabilities) for the tenant — the source for who-can-do-what.

Capability: member.read

get_pipeline

Get one pipeline's definition + status by its `name`.

Capability: pipeline.read

Arguments: name (required)

get_quarantine

Get a single quarantine row's detail.

Capability: dataset.read

Arguments: row_id (required)

get_raw_dataset_profile

ADMIN. Read a RAW dataset's STORED authoring artifacts by its `dataset` id ('{domain}/{dataset}') — the sample rows, inferred schema snapshot and full-table profile statistics captured at landing (null rates, cardinality, min/max, top values). The cheap first look: read this BEFORE spending inspect_raw_dataset queries. 404 means nothing was captured yet — an honest empty state, not an error in your call.

Capability: dataset.admin

Arguments: contract_id (required)

get_refine_editable

Read the editable-state projection of a refinement run's decisions (two-step wizard).

Capability: contract.create

Arguments: dpi (required), run_id (required)

get_report

Get a Griot report's full document + version log by id (pass `version` to pin a specific version; omit for latest).

Capability: report.read

Arguments: report_id (required), version

get_role

Get one role definition by its `role_key` (name, permissions).

Capability: member.admin

Arguments: role_key (required)

get_source_schema

Get the inferred/declared SCHEMA of a connected source by its `source_id` — the columns + types the connector sees.

Capability: source.read

Arguments: source_id (required)

get_steward

Get one data steward's detail by its `steward_id`.

Capability: member.read

Arguments: steward_id (required)

get_storage_residency

Get where this workspace's data is stored: {tenant_id, pool, jurisdiction, status, since, migrated_from}. `status` is 'bound' or 'unbound' — 'unbound' means a sovereignty-declaring workspace has not chosen a pool yet and its uploads are refused until it does. Changing the binding is an administrative migration, not a tool call.

Capability: tenant_settings.read

get_storage_usage

Get the caller tenant's storage usage by tier/catalog (bytes, object counts) for the current period.

Capability: tenant_settings.read

Arguments: limit, offset

get_subscription

Get the caller tenant's current subscription (plan_key, seats, status, current_period, limits). Use change_subscription to modify.

Capability: tenant_settings.read

get_tenant

Get the caller tenant's profile (name, slug, tier, status, plan) — the tenant self-view.

Capability: member.read

get_thread

Read one Ask-Griot thread and its full message history by `thread_id` (from list_threads). Returns the persisted user + assistant messages (markdown + any rendered artifacts).

Capability: public

Arguments: thread_id (required)

get_transform_status

Poll one pipeline run's live status (the async companion to run_transform). K02's stored run state is authoritative (the run records its terminal state at completion), so the status is current. Returns `status` (queued|running|succeeded|failed), `completed_at`, row counts (rows_in/rows_out/rows_quarantined), `prod_prefix`, `cert_id` (the gold certificate, present once succeeded — pass it to get_gdcp_certificate), `stages`, and `error` (when failed). Poll this every few seconds after run_transform instead of blocking.

Capability: pipeline.read

Arguments: name (required), run_id (required)

get_usage

Get the caller tenant's aggregate usage vs plan limits (rows, queries, storage, compute) for the current period.

Capability: tenant_settings.read

Arguments: limit, offset

get_webhook_source

Get Webhook Source

Capability: source.read

Arguments: source_id (required)

get_workbench_session

Read a workbook session's current MANIFEST (ADR-0043): its `tables`, `ops` log (with undo/redo depth), `scratch` tables, and `table_refs` (the branch-head read map). Use it to inspect where a session stands before recording another op or publishing. An unknown/foreign `session_id` fails loud (404).

Capability: dataset.read

Arguments: session_id (required)

get_workspaces_readiness

Workspace Readiness

Capability: workspace.read

govern_raw_dataset

Govern a document: author an unstructured contract, then promote it.

Capability: dataset.admin

Arguments: contract_id (required)

grant_actor_role

Grant a role to a member/actor (`actor_id`). Pass the `role_key` to assign.

Capability: member.grant

Arguments: actor_id (required), role_key (required)

ingest_data

Ingest data into Griot (warehouse, stream, API, website). Use connector_type='website' with `url` to pull a file or page from the web (CSV/JSON/HTML table). `domain` is REQUIRED and you must choose it EXPLICITLY — it is WHERE the data lands and who governs it; the platform will never pick one for you. Call list_domains first; if none fits, create_domain(slug, name). Naming a domain that does not exist is refused up front (the error lists the domains you DO have). WHAT HAPPENS NEXT — read this before you plan your next step: the data LANDS, and it is NOT queryable yet. Griot serves every dataset through a data contract, and one is DRAFTED for it automatically after landing; the dataset becomes queryable only once that contract is ACTIVE. The response carries a `lifecycle` block naming the dataset id and what to poll. Then: call get_dataset_status(dpi='griot://{domain}/{dataset}') until `state` is 'active' — do NOT re-ingest the same file because a query failed, and do NOT author a contract yourself; a run is already in flight. `contract_id` is optional (raw landing is contractless). For file uploads use the UI file-uploader (multipart upload is not an MCP tool).

Capability: source.create

Arguments: label (required), connector_type (required), contract_id, host, credentials, url, domain, dataset, format, selector, mode

inspect_raw_dataset

ADMIN. Run read-only DuckDB SQL over a dataset's REAL landed bytes and get the rows back. Give it `dataset` ('{domain}/{dataset}') and `sql`; the dataset's raw data is registered as the relation `raw_input`, so you SELECT FROM raw_input. NO CONTRACT IS REQUIRED — this is the tool to use while AUTHORING a contract, when query_dataset (GriotQL) cannot serve you because the contract it would enforce does not exist yet. Explore before you draft: `SELECT DISTINCT status FROM raw_input` for real enum values, `SELECT min(qty), max(qty) FROM raw_input` for ranges, `SUMMARIZE raw_input` for a whole-table overview, `SELECT count(*) FILTER (WHERE x IS NULL) FROM raw_input` for null patterns. Nothing is written — no run record, no output dataset, no certificate. A SQL error comes back with DuckDB's real message and your offending SQL, so read it and fix the query. `limit` caps the returned rows (1..200, default 50); it does NOT cap what your aggregate scans.

Capability: dataset.admin

Arguments: contract_id (required), sql (required), limit

invite_user

Invite a new member to the tenant (admin).

Capability: member.grant

Arguments: email (required), role (required)

list_actor_roles

List the roles assigned to a member/actor by its `actor_id`.

Capability: member.read

Arguments: actor_id (required)

list_agent_runs

List an agent's execution runs by its `agent_id` ({items:[{run_id, status, started_at, …}]}). Use get_agent_decision_chain to inspect a run's governed decisions.

Capability: agent.read

Arguments: agent_id (required), limit, offset

list_agents

List the tenant's agent identities (ADR-0021). Each record carries its config plus the optional harness/model/quality_rules/resources when set (merged from the agent-extras store).

Capability: agent.read

list_audit_log

List the tenant's audit log events ({items:[{event_id, actor, action, resource, at}]}). Every governed action (reads, writes, agent tool calls) lands here — this is the compliance/provenance spine.

Capability: audit_log.read

Arguments: limit, offset

list_catalogs

List this tenant's catalogs. A catalog is a tenant-defined namespace/folder in your bucket (e.g. 'raw'/'prod'/'default'); the PUBLISHED catalog is the one analysts' datasets resolve to. Returns each catalog's name, description, whether it is published, and when it was created. Read-only — use create_catalog (admin) to add or publish one.

Capability: dataset.read

list_certificates

List GDCP certificates (T05).

Capability: certificate.read

Arguments: limit, offset

list_clean_room_invitations

This tenant's clean-room invitation inbox - each row carries the whole proposal (agreement header, type promise, parties, the convener's already-attached contribution).

Capability: clean_room.read

list_clean_room_operations

List a room's operations with state (proposed/active/suspended/rejected/expired) and schedule.

Capability: clean_room.read

Arguments: room_id (required)

list_clean_room_results

This tenant's entitled results across runs, newest first - results accumulate into series per operation. Optionally filter by operation_id.

Capability: clean_room.read

Arguments: room_id (required), operation_id, limit

list_clean_room_runs

List a room's runs, newest first, each with terminal state (succeeded/refused/failed) and the refusal reason where one applies.

Capability: clean_room.read

Arguments: room_id (required), limit

list_clean_rooms

List the clean rooms this tenant is a party of, with state (awaiting_parties/active/suspended/dissolved), role and activity summary.

Capability: clean_room.read

list_compute_resources

List the tenant's compute definitions ({items:[{name, display_name, cpu, memory, image, max_idle_s, max_lifetime_s, allowed_consumers, version, is_platform, credits_per_hour, ...}]}). The platform definition 'serverless' is ALWAYS present and always first. `consumer` filters to definitions a given consumer kind may attach to — pass 'notebook' before offering a notebook compute picker, for instance. An empty (beyond 'serverless') list means this tenant has authored no definitions yet, not that the lookup failed.

Capability: compute.read

Arguments: consumer

list_connection_tables

List the REMOTE tables a live warehouse connection exposes — Griot asks the warehouse for its table list without copying any data. Returns the connector's table listing (typically {tables:[{schema, name, approx_rows}]}). Optional `database` / `schema` narrow the listing for warehouses that need a namespace context (e.g. Snowflake database.schema). Use this to find a table to inspect with get_connection_table_schema and then onboard with onboard_connection_table.

Capability: source.create

Arguments: connection_id (required), database, schema

list_connections

List the tenant's LIVE WAREHOUSE CONNECTIONS (ADR-0049 federation) — governed links to external warehouses (postgres / redshift / mysql / snowflake / databricks / oracle) Griot queries IN PLACE, under contract, without copying the data. Returns {connections:[{id, name, source_type, config, has_credential, created_by, created_at}]}. SECRETS ARE NEVER RETURNED — `config` is non-secret settings only and `has_credential` is a bool. Honest empty ({connections:[]}) when the tenant has none. A human provisions the connection (with its credential) in the UI; you operate the ones that already exist.

Capability: source.create

list_contract_versions

List a contract's version history with per-version lifecycle state. Each version returns `version`, `semver`, `status` (draft|active|deprecated), `is_active` (the live version), and — for a draft with an OPEN approval workflow — `workflow_id` + `approvals` + `threshold` + `voters` so you can see vote progress and cast a vote via approve_contract_version. Use this to decide whether to publish, vote, or deprecate.

Capability: contract.read

Arguments: name (required)

list_contracts

List GDCP data contracts visible to this agent (T03). Defaults to ACTIVE contracts only; set include_deprecated:true to also list DEPRECATED contracts (each flagged status:'deprecated' with a resolved `successor` DPI when one exists).

Capability: contract.read

Arguments: limit, offset

list_dataset_certificate_versions

List all GDCP certificate VERSIONS issued for a dataset by its `contract_id` (domain/dataset) — the certificate history.

Capability: certificate.read

Arguments: contract_id (required)

list_datasets

List datasets for current tenant

Capability: dataset.admin

Arguments: limit, offset, catalog, domain, tier, kind, include_quarantine

list_docs

List the Griot handbook table of contents — the platform's documentation. The handbook explains how to ingest data, author GDCP contracts, build notebooks, run pipelines (raw→stg→prod), and drive the whole platform via these MCP tools, plus end-to-end tutorials. Returns {items:[{slug, title, section}]}. Call get_doc(slug) to read a page. STRONGLY RECOMMENDED: read the relevant handbook page BEFORE attempting an unfamiliar operation (e.g. read 'contracts/authoring' before create_contract) so you use the right shapes and flow.

Capability: public

list_domains

List this workspace's governance DOMAINS (T03). A domain is where a dataset lands and who governs it — every ingest must name one that already exists, so call this BEFORE ingesting anything. If none fits, create one with create_domain(slug, name). (Not to be confused with a storage catalog: a domain is the governance grouping; the catalog is where its bytes sit.)

Capability: domain.read

Arguments: limit, offset, catalog

list_dpia

List DPIA assessments.

Capability: report.read

Arguments: limit, offset

list_dsr

List Data Subject Requests (DSR).

Capability: report.read

Arguments: limit, offset

list_incidents

List operational/data incidents ({items:[{incident_id, severity, status, opened_at, …}]}).

Capability: report.read

Arguments: limit, offset

list_insights

List AI-generated insights for the tenant.

Capability: report.read

Arguments: limit, offset

list_job_runs

List runs from the tenant's SINGLE run ledger ({items:[{run_id, job, status, started_at, ...}]}). Filter with `job` (a job name), `status` (PENDING|RUNNING|SUCCEEDED|FAILED|UPSTREAM_FAILED|CANCELLED|SKIPPED) and `limit`. Everything that executes in this tenant is here — a pipeline run IS a job run, so there is no second history to check. Use this to answer 'what ran, what failed, when' and to find the run_id for get_job_run / explain_job_run_failure.

Capability: pipeline.read

Arguments: job, status, limit

list_jobs

List the tenant's jobs ({items:[{name, description, version, schedule, run_as, tags, ...}]}). Start here when the user names a job you have not seen this session — job names are stable handles, so a name you find here stays valid for get_job / update_job / run_job. An empty list means this tenant has authored no jobs yet, not that the lookup failed.

Capability: pipeline.read

Arguments: limit, offset

list_lakehouse_namespaces

List the Iceberg lakehouse namespaces (the physical table namespaces behind the governed datasets). Engineer/admin view.

Capability: dataset.read

Arguments: limit, offset

list_marimo_reports

List captured marimo notebook report runs ({items:[{run_id, notebook_id, created_at, status}]}). Fetch one with get_marimo_report_html.

Capability: pipeline.read

Arguments: limit, offset

list_marketplace

List published marketplace listings.

Capability: marketplace_listing.read

Arguments: limit, offset

list_marketplace_requests

List access requests on the caller tenant's marketplace listings ({items:[{request_id, listing_slug, requester, status}]}). Approve/deny with approve_marketplace_request / deny_marketplace_request.

Capability: marketplace_listing.read

Arguments: limit, offset

list_marketplace_subscriptions

List the marketplace listings the caller tenant is SUBSCRIBED to (consumer view).

Capability: marketplace_listing.read

Arguments: limit, offset

list_models

List the tenant's published GMF models (ADR-0047). Returns {models:[{domain, name, latest_version, created_at, statistics, packaging}]} — one row per model with its latest version and metrics. Honest empty ({models:[]}) when none are published. Optional `domain` filters to one domain. Call get_model_info(domain,name) for a version's full signature + statistics + content digest. NOTE: downloading the model bytes to an agent is a P1 (governed-handout) capability, not available over MCP yet.

Capability: public

Arguments: domain

list_my_listings

List the marketplace listings the CALLER tenant publishes (producer view) — {items:[{slug, title, status, subscribers}]}.

Capability: marketplace_listing.read

Arguments: limit, offset

list_notebooks

List the tenant's saved notebooks. A notebook is the general compute instrument (ordered language cells run in one kernel context); pipelines, reports and validations are bindings that reference a notebook+version. Use this to find a `notebook_id` (+ its `version`) to pass to `create_pipeline`. FLOW: author with `create_notebook` (optionally preview with `run_notebook`) → `create_pipeline` (notebook_id, notebook_version, target_tier, contract_id) → `run_transform`.

Capability: pipeline.read

list_notifications

List the caller's notifications (tenant drawer). Returns {items:[{id, kind, title, body, read, created_at, …}], unread_count}. Use mark_notification_read / mark_all_notifications_read / dismiss_notification to manage them.

Capability: public

Arguments: limit, offset

list_partner_datasets

List the datasets a partner exposes to the caller tenant by the partner `slug` (cross-tenant federation catalog).

Capability: partner.read

Arguments: slug (required), limit, offset

list_partner_federated_queries

List the federated (cross-tenant) queries run against a partner by its `slug` — the query history + SLA outcomes.

Capability: partner.read

Arguments: slug (required), limit, offset

list_partner_shares

List the dataset shares granted to a partner by its `partner_id` ({items:[{share_id, dataset, contract, status}]}).

Capability: partner.read

Arguments: partner_id (required), limit, offset

list_partners

List the tenant's sharing partners.

Capability: partner.read

Arguments: limit, offset

list_pending_approvals

List the tenant's OPEN approval workflows — the queue a reviewer must act on. Each item returns `workflow_id`, `workflow_type`, `subject_resource`, `state`, `approvals` (yes-vote count), `threshold` (quorum needed), `voters`, and — for contract-promote workflows — `contract_name`/`contract_type`/`contract_version`. Cast a vote with approve_contract_version(workflow_id). Pass include_resolved=true to also see approved/rejected ones. `workflow_type:'contract_activation'` rows are the ones an agent raised asking a HUMAN to authorise activating a dataset's contract; they additionally carry `dpi`, `requested_by`, `commits_to` (what activation commits to), `governs_personal_data`, `lawful_basis` and `lawful_basis_affirmation_required`. Only a human may vote on those.

Capability: contract.read

Arguments: include_resolved

list_pipeline_runs

List a pipeline's runs by its `name` ({items:[{run_id, status, started_at, …}]}).

Capability: pipeline.read

Arguments: name (required), limit, offset

list_pipelines

List the tenant's transform pipelines.

Capability: pipeline.read

Arguments: limit, offset

list_plans

List the platform's subscription plans + their limits/features (ADR-0020). Returns {plans:[{plan_key, name, price, limits, features}]}. Use change_subscription to switch the tenant's plan.

Capability: public

list_quarantine

List quarantined rows (contract / quality rejections).

Capability: dataset.read

Arguments: limit, offset

list_raw_datasets

ADMIN. List the tenant's RAW (pre-contract, quarantined) datasets — the ones landed but not yet governed by a contract. This is the ONLY surface that shows them; they are deliberately invisible to normal discovery (list_datasets / search_contracts show governed data only). Use this to find the `dataset` id ('{domain}/{dataset}') to pass to get_raw_dataset_profile and inspect_raw_dataset.

Capability: dataset.admin

list_reports

List the tenant's Griot reports (versioned, data-bound documents) — each with its latest headline question + answer.

Capability: report.read

list_roles

List default + custom roles for the tenant (admin).

Capability: member.admin

list_sources

List the tenant's connected data sources. Includes classic ingestion sources (file/website/warehouse — landed datasets) AND ADR-0041 API sources (type: 'api' runtime connections, e.g. Earth Engine). An API source carries `connector_key` + non-secret `params`, an optional `contract_id` naming its governing connector contract (e.g. 'sources/earth_engine'), and a live `health` field (its cheap, quota-free auth probe, cached ~60s so the list stays cheap); it lands no data and is used by notebook runs, not ingested.

Capability: source.read

Arguments: limit, offset

list_stewards

List the tenant's data stewards ({items:[{steward_id, name, domains_owned, on_call}]}).

Capability: member.read

Arguments: limit, offset

list_threads

List the caller's Ask-Griot conversation threads ({items:[{thread_id, title, updated_at, message_count}]}). Use get_thread to read one, or ask_griot to start / continue a thread.

Capability: public

Arguments: limit, offset

list_transforms

List the CATALOG-materialization options a notebook-backed pipeline can target (the real K04B/K02 surface). A pipeline runs a NOTEBOOK (not a mode/sql) and materializes its declared output to a tenant-defined catalog — a bucket folder, e.g. 'prod'/'raw'/'default', NOT a fixed platform tier; raw/stg/prod are example catalog names (ADR-0029). This enumerates those catalogs + their aliases. Use it before create_pipeline to choose a `target_tier`.

Capability: pipeline.read

list_users

List the tenant's members / actors (admin).

Capability: member.read

Arguments: limit, offset

mark_all_notifications_read

Mark ALL of the caller's notifications read.

Capability: public

mark_notification_read

Mark a single notification read by its `notification_id`.

Capability: public

Arguments: notification_id (required)

mask_dataset

Mask or unmask one column of an existing dataset.

Capability: dataset.admin

Arguments: ref (required), column (required), action

materialize_session_notebook

Materialize a workbook session's operation log as a REAL marimo NOTEBOOK (ADR-0044 — 'the notebook is the third face of the session') and register it in the tenant notebook registry so it appears in list_notebooks / 'Open as notebook'. Turns the recorded sql/edit ops into reproducible ordered cells. Optional `title` names it. Returns {notebook_id, registered, op_count, materialized_count, unmaterializable[], …}. The session itself is unchanged.

Capability: pipeline.read

Arguments: session_id (required), title, workbook_id

onboard_connection_table

Onboard a REMOTE warehouse table as a governed Griot dataset (DPI) — the federation 'add to catalog' step. Binds the remote table (`database`/`schema`/`table`) to the DPI `domain/dataset_name`: writes the T02 FEDERATED POINTER (so the DPI resolves to the live remote table, not an Iceberg copy), registers catalog citizenship, and opens a DRAFT contract if none exists. The data is NOT copied — queries run in place. Returns each leg honestly {pointer, catalog, contract, ok}. AFTER onboarding, the table is an ORDINARY DPI: author + activate its contract (mask PII), then query it with the SAME `query_dataset` tool over GriotQL — masking + row-filters apply exactly as for any landed dataset. This does NOT need the credential (it stays vaulted; K04D fetches it per-query server-side).

Capability: source.create

Arguments: connection_id (required), database, schema, table (required), domain (required), dataset_name (required)

open_draft_thread

Open a contract-drafting thread (one per wizard session)

Capability: contract.create

open_workbench_session

Open a WORKBOOK SESSION over one or more datasets (ADR-0043) — the analyst's live, undoable workspace. Forks a private Iceberg BRANCH per resource; nothing you do touches production/main until you publish_session. Pass `resources` (a list of dataset DPIs, '<domain>/<dataset>'), and optionally `workbook_id` to bind the session to an existing workbook. Returns the session MANIFEST incl. `session_id` (use it for every later session call), `tables`, `ops`, and `table_refs`. Next: record_session_op to do work, session_query to see the delta, then publish_session or discard_session.

Capability: dataset.read

Arguments: resources (required), workbook_id

pause_partner

Pause a federation partner by its `slug` (suspends all shares).

Capability: partner.grant

Arguments: slug (required)

pause_webhook_source

Pause Webhook Source

Capability: source.update

Arguments: source_id (required)

preview_contract

Dry-run PREVIEW a contract via T03 WITHOUT persisting anything — resolves inherited defaults + compiled checks so you can inspect the final shape before create_contract. Pass the same contract `spec` object you would create. (Read contracts/authoring in the handbook first for the shape.)

Capability: contract.read

Arguments: spec (required)

preview_transform

Dry-run PREVIEW a SQL transform WITHOUT persisting — returns the shape/sample of the transform output so you can validate it before create_pipeline. Pass the transform `sql` + input `dataset`; the dataset's raw frame is registered as the relation `raw_input`, so the SQL selects FROM raw_input.

Capability: pipeline.read

Arguments: sql (required), dataset (required), limit

preview_transform_python

Dry-run PREVIEW a PYTHON transform WITHOUT persisting — runs the transform `code` against the input `dataset` in the sandbox and returns the output shape/sample. The code receives the raw frame as the DataFrame `raw` and must produce the DataFrame `stg`. Validate before create_pipeline.

Capability: pipeline.read

Arguments: code (required), dataset (required), limit

promote_raw_dataset

Promote a quarantined dataset by activating its contract.

Capability: dataset.admin

Arguments: contract_id (required)

propose_clean_room_operation

Propose an operation (or a new version of one): the GriotQL is COMPILED against the room's slots (named refusals for raw columns, joins, sub-floor groupings, purpose mismatches), dry-run on synthetic rows, and put to every party for approval.

Capability: clean_room.create

Arguments: room_id (required), griotql (required), name, question, floor_min, max_runs_per_day, schedule_interval_minutes, operation_id, authored_via

publish_contract

Activate (publish) a contract draft (T03) — the step that makes a dataset queryable. IF YOU ARE AN AGENT, A HUMAN MUST HAVE AUTHORISED IT FIRST. This call is REFUSED unless a recorded human approval exists for exactly this contract, type and version: call request_contract_activation(dpi=...), show the person the draft it returns, and call this again once get_activation_request(dpi=...) reports state 'approved'. The refusal names which of those is true — K01_ACTIVATION_NOT_REQUESTED (nobody has been asked), K01_ACTIVATION_AWAITING_HUMAN_APPROVAL (asked, not yet decided — WAIT), K01_ACTIVATION_REJECTED (a person said no — do not retry), K01_LAWFUL_BASIS_AFFIRMATION_MISSING (personal data, and the approver has not affirmed the lawful basis). There is no argument you can add to this call to satisfy the check: the approval is a record written by the human, verified server-side. HONEST about the outcome: a FORK or the FIRST version of a base contract self-activates and the response is `{state:'active', ...}`. If the contract declares approvers and this is a REVISION of an already-active version, this OPENS a steward approval workflow and returns `{state:'pending_approval', workflow_id, approvals, threshold}` (HTTP 202) — the version is NOT yet live. Drive it to APPROVED by casting votes with `approve_contract_version(workflow_id)`; the version activates only once the threshold is met. Use `list_pending_approvals` to find open workflows and `list_contract_versions` to see per-version state + any open workflow.

Capability: contract.publish

Arguments: name (required)

publish_listing

Publish a dataset/contract view as a marketplace listing. The bound contract's semantic_purpose must include 'marketplace_consumption'.

Capability: marketplace_listing.publish

Arguments: contract_id (required), dataset_id, product_name, description, visibility, pricing_tier

publish_session

Publish a workbook session (ADR-0043) — merge its session branches to production/main in dependency order (write-audit-publish). THIS is the only step that touches main. FAIL LOUD: on a partial failure the call returns a 409 HALT carrying the structured `halt` (which table diverged/failed, what merged so far) VERBATIM so you can show exactly what needs attention; the session stays HELD (safe) and nothing is half-applied. On success, returns the publish result. Only call this when the session's ops are correct — otherwise discard_session.

Capability: dataset.update

Arguments: session_id (required)

query_dataset

Run a read-only, contract-mediated SQL query AFTER you have read the contract with describe_contract — use its exact field names/enums, never query a declared_loss-excluded column, and set `declared_purpose` to one of the contract's purpose.questions[] (NOT anything in not_intended_for[]). Name the dataset in the FROM clause as a double-quoted contract id, e.g. SELECT … FROM "cyberguard/cisa-kev". You MAY pin a specific published version by appending /<version>, e.g. FROM "cyberguard/cisa-kev/2"; omitting the version resolves the latest published version. Supports SELECT/WITH with WHERE/GROUP BY/COUNT/ORDER BY. BOUNDED READS ARE MANDATORY: every query you send MUST carry a LIMIT of at most 200 or use an aggregate (COUNT/SUM/AVG/MIN/MAX). A statement with neither is REFUSED with HTTP 422 `K01_QUERY_UNBOUNDED` and reads nothing — add a LIMIT or an aggregate and retry. Even a bounded query is capped server-side at 200 rows; when that cap bites, the result carries `truncated:true`, `row_cap` and a `truncation_note`. NEVER count a truncated result's rows and report that as a total — use COUNT in SQL — and never describe a truncated result as the complete set. ERROR CONTRACT: on a contract violation (purpose out of bounds / excluded column / tier) the call returns HTTP 422 with {code, message, request_id} naming the failed constraint — parse it, adjust the query or declared_purpose, and re-query a satisfiable form. NOT-READY-YET IS A DIFFERENT ERROR, AND NOT YOUR FAULT: HTTP 409 `K01_DATASET_NOT_QUERYABLE_YET` means the dataset has no ACTIVE contract yet (usually one is still being drafted). It carries `dataset_state` and a full `lifecycle` block. Do NOT rewrite the SQL and do NOT re-ingest the data — poll get_dataset_status(dpi=...) until state='active', then re-run this exact query. HTTP 404 `K01_DATASET_NOT_FOUND` means no such dataset: fix the name (list_datasets), never poll. SUCCESS: the engine transparently masks PII and applies row-filtering, so check `result.masked_columns` and each `result.columns[].masked`, and note `row_count` reflects the filtering. Returns columns + rows + a stable `result_id` — to visualize, pass that result_id to render_table/render_visual/render_map (never retype the numbers). DATA CLASS: some datasets are `representative` (illustrative/mock, not observed measurements) — the platform taints such results and any artifact you render from them carries a top-level `dataClass:"representative"` and a warn banner AUTOMATICALLY. You do not set this and cannot suppress it; when a result is representative, also say so in your prose (e.g. 'on representative data') so the reader knows.

Capability: dataset.read

Arguments: sql (required), dataset, declared_purpose

record_session_op

Record + execute ONE operation on a workbook session (ADR-0043), appending it to the session's op log and running it on the session branch (main is untouched until publish). `kind` is one of 'sql' (a transform SQL, in `write`), 'edit' (a cell/scratch edit), 'ai' (a UI-driven AI op), or 'filter' (a grid filter). `summary` is a short human label; `write` carries the op payload (e.g. the SQL for kind='sql'). An `kind='ai'` op runs the SAME plan-limits AI-run gate the rest of the front door uses (FAIL-LOUD 402 at your monthly ceiling) and is stamped metered; sql/edit/filter are not metered. After recording, call session_query to see the resulting delta. Undo with undo_session_op.

Capability: dataset.read

Arguments: session_id (required), kind (required), summary, write, prompt_metadata

redo_session_op

Redo the top of a workbook session's redo stack (ADR-0043) — re-applies the most recently undone op. Returns the updated manifest.

Capability: dataset.read

Arguments: session_id (required)

refine_next

Get the NEXT open decision for a refinement run (ADR-0051), plus the context needed to decide it (e.g. the profiled sample for the 'type' stage). Call before `refine_submit_decision` to know which stage is open and what to reason over.

Capability: contract.create

Arguments: dpi (required), run_id (required)

refine_start

Start the Contract Refinement Process (ADR-0051) for a landed dataset identified by `dpi` ('{domain}/{dataset}' or a bare slug). CHECK FIRST: a run is normally started AUTOMATICALLY when data lands, so call get_dataset_status(dpi=...) before this — if the state is 'drafting' a run already exists and starting another just duplicates work. Use this when the state is stuck at 'landed', or after a 'failed' run whose cause you have fixed. Returns `{run_id, stages, state}`. Drive the SAME run stage-by-stage with `refine_next` (what to decide next) and `refine_submit_decision` (submit the decision) — one pipeline; a human wizard uses the identical routes. Stages: read -> type -> classify -> explain -> standards, then the platform assembles, validates, and certifies the contract.

Capability: contract.create

Arguments: dpi (required)

refine_status

Get the current state of a refinement run (ADR-0051) — its stage-by-stage progress and every decision recorded so far. `state` is one of 'open' (a decision stage is still open), 'needs_human' (a stage hit its retry cap), 'completing' (every decision is accepted; the platform is still assembling/validating/certifying the contract in the background — call this again shortly), 'completed' (draft contract + evidence ready; check `certificate`), or 'failed' (see `last_error`). Requires a `run_id`: if you do not have one (e.g. the run was started automatically when the data landed), call get_dataset_status(dpi=...) instead — it finds the run for you and answers the question you actually have ('can I query this yet?'). NOTE 'completed' here means a DRAFT contract exists — the dataset is still not queryable until that contract is ACTIVE.

Capability: contract.create

Arguments: dpi (required), run_id (required)

refine_submit_decision

Submit a refinement DECISION for one stage of a run (ADR-0051) — THE ONE WRITE in the process; the K09 human wizard submits through this identical route. `stage` is one of 'read'|'type'|'classify'|'explain'|'standards'; supply ONLY that stage's fields: read -> `column_notes` ({column: notes, ...}); type -> `types` ([{column, type, from?}]) and optionally `derived` ([{name, expr, type}]); classify -> `classify` ([{column, sensitivity: 'none'|'pii'|'sensitive'}]) — a LABEL ONLY, never set a mask/noise field here, it is rejected; explain -> `explain` ({description, primary_insight, questions?, not_intended_for?, consumers?}); standards -> `standards` ({required_non_null?, unique?, ranges?, enums?, freshness_hours?, custom_checks?}). Any raw SQL you supply (types[].from, derived[].expr, standards.custom_checks[].expr) is validated server-side before it is accepted — a rejected expression returns the reason so you can revise. IMPORTANT for stage='standards' (the LAST stage): this call returns PROMPTLY with `state: 'completing'`, NOT 'completed' — the platform finishes assembling, validating, and certifying the contract in the background (it can take a while on a real dataset). 'completing' is a normal, successful outcome, never an error — call `refine_status` afterward (poll until `state` is 'completed' or 'failed') to see the finished draft contract and certificate.

Capability: contract.create

Arguments: dpi (required), run_id (required), stage (required), column_notes, types, derived, classify, explain, standards

refresh_refine_section

Targeted, section-scoped contract refresh for a refinement run.

Capability: contract.create

Arguments: dpi (required), run_id (required)

release_quarantine_row

Release a quarantined row back into the dataset by its `row_id` (steward action — the row passed re-review).

Capability: dataset.update

Arguments: row_id (required)

remove_actor_role

Remove a role from a member/actor (`actor_id`). Pass the `role_key` to revoke.

Capability: member.grant

Arguments: actor_id (required), role_key (required)

renew_partner

Renew a federation partner agreement by its `slug`.

Capability: partner.grant

Arguments: slug (required)

request_contract_activation

ASK A HUMAN TO AUTHORISE ACTIVATING A DATASET'S DRAFT CONTRACT — the step between 'draft_ready' and a queryable dataset. Call this when get_dataset_status reports state 'draft_ready'. WHY IT EXISTS: activation makes the contract's terms binding on every future read of the dataset, so it requires an authenticated human decision recorded against that person. You may EXECUTE the activation once that record exists; you may never BE it. Reporting that the user agreed in conversation is not an approval and publish_contract will refuse it. RETURNS everything needed to put the decision in front of a person, self-describing so you can render it in your own UI: `approval_id`, `decision.question`, `decision.commits_to` (what saying yes commits the workspace to), `personal_data` (whether it governs PII, the lawful basis, whether a separate affirmation is required and the exact statement), `draft.sections` (the contract's REAL resolved sections — show these, do not summarise them) with `draft.section_legend` mapping identity/purpose/shape/quality/privacy/lifecycle onto the section keys, and `next_actions` naming the exact call for the human and for you. IDEMPOTENT: calling it again for the same draft returns the SAME request with already_requested=true — never open a second one. THEN: poll get_activation_request(dpi=...) until `state` is 'approved', then call publish_contract(name=...).

Capability: contract.read

Arguments: dpi (required), type, version

resume_webhook_source

Resume Webhook Source

Capability: source.update

Arguments: source_id (required)

retry_job_run

Retry a FAILED (or cancelled) run by `run_id`. The TASK is the retry unit, so the retry resumes the DAG from the failed task — tasks that already SUCCEEDED are not re-executed and their outputs are not rewritten. Fix the cause first: run explain_job_run_failure, then repair whatever it named (the statement via update_job, the contract, the quarantined rows), then retry. Retrying an unchanged run that failed for a deterministic reason will fail the same way and cost the same credits.

Capability: pipeline.create

Arguments: run_id (required)

retry_pipeline_run

Retry a failed pipeline run by its pipeline `name` + `run_id`. Re-enqueues the run from the failed step.

Capability: pipeline.create

Arguments: name (required), run_id (required)

revoke_partner_share

Revoke ONE dataset share (pending invite or accepted) by its `share_id`. Idempotent — a repeat revoke returns the terminal state, and the invite link then refuses with an honest 410. (TASK-206: this tool previously revoked the ENTIRE partner; it now targets the single share, which is what the name promises. To revoke the whole partner relationship, use `sunset_partner` or `delete_partner`.)

Capability: partner.grant

Arguments: share_id (required)

run_compliance_report

Run a compliance report NOW (create a compliance-report run) by its `report_id`. This is the K07 regulator-report run action — distinct from `create_report`, which PUBLISHES a Griot analytics report.

Capability: report.create

Arguments: report_id (required)

run_job

Trigger a run of the job `name` NOW. Returns IMMEDIATELY with the run (its `run_id` + PENDING/RUNNING status) — it does NOT wait for the DAG to finish, so do not re-call this to check progress. Poll get_job_run(run_id) until the status is terminal (SUCCEEDED / FAILED / UPSTREAM_FAILED / CANCELLED). The run PINS the job's current version, so a later edit never changes what this run meant. Optional `params` are passed to the run.

Capability: pipeline.create

Arguments: name (required), params

run_marimo_notebook

Run a marimo `.py` notebook HEADLESSLY and capture its report. REQUIRED: pass EXACTLY ONE of `source` (the inline marimo `.py` text you write) OR `notebook_id` (a stored notebook) — a call with NEITHER is rejected, so if you want to run code you just wrote, put it in `source`. This is a run-only tool: to CREATE a persisted notebook the user can open + edit in the workbench, use `create_notebook` (a python|sql|griotql|markdown cell notebook) instead — do NOT use this tool to "make a notebook". Optionally pass `connections` (e.g. ["earth_engine"]) to inject a registered connector's client into the kernel. Returns per-cell status, a `run_id` (fetch rendered HTML via get_marimo_report_html), AND `results[]` — every dataframe a cell registered via griot_result(df, name=...), each carrying a `result_id` you bind with render_visual / render_table / render_map. A missing connector env fails loud (424); an unknown connector fails loud (400).

Capability: pipeline.read

Arguments: source, notebook_id, connections

run_notebook

Run a notebook INTERACTIVELY to PREVIEW it before saving / before wiring a pipeline (ADR-0024). Runs the ordered cells in ONE shared kernel context against the bound governed dataset and returns, per cell, a BOUNDED sample of its output plus the notebook's declared output. This is the agent's way to verify the reshape is correct before `create_notebook` + `create_pipeline`. FAIL LOUD: a failing cell's status + traceback / SQL error is returned inline (the run stops at that cell with prior results intact) — never swallowed. Provide `cells` inline (you do NOT need to save the notebook first); set `contract_id` to the governed dataset the notebook reads. Declare any third-party libraries the cells import in `packages` (PEP-508 specs) — they are pip-installed in the kernel before the cells run; a bad spec fails loud (422) and no cell runs.

Capability: pipeline.read

Arguments: cells (required), contract_id, params, packages, limit

run_transform

Trigger a pipeline run now via K02. Returns IMMEDIATELY with a `run_id` — it does NOT wait for the job to finish. The run executes asynchronously. Do NOT hold the call open or re-call this to check progress; instead poll `get_transform_status(name, run_id)` until status is `succeeded`/`failed`, then read the gold certificate via `get_gdcp_certificate(cert_id)` using the cert_id it returns.

Capability: pipeline.create

Arguments: name (required), declared_purpose

sample_connection_table

Preview up to 10 RAW rows from a remote table over a live warehouse connection (hard-capped at 10 — never a full scan). Pass `table` (required) and, for namespaced warehouses, `database` / `schema`; `limit` is clamped to <=10. IMPORTANT — this browse preview is UNGOVERNED / RAW: it is the warehouse's own rows, NOT masked. Contract masking + row-filtering apply on the GOVERNED query path only — after you onboard the table (onboard_connection_table) and query it with `query_dataset`, which runs through GriotQL under its contract. Use this only to eyeball shape before onboarding; never treat these rows as governed output.

Capability: source.create

Arguments: connection_id (required), table (required), database, schema, limit

save_refine_editable

Save the editable-state Step 1 (Schema & Structure) decisions for a refinement run.

Capability: contract.create

Arguments: dpi (required), run_id (required)

search

Semantic search across everything in your workspace — documents, contracts, datasets, notebooks, reports, agents — one query finds it all. Unlike search_contracts (keyword-ranked contracts only), this is a VECTOR search over every embedded resource and returns MIXED kinds. Each result carries `asset_id` (the resource DPI), `kind` (dataset|contract|notebook|report|agent|model|…), `title`, `description`, `href` (its tenant-UI path), and `score` (higher = closer). Use it to find anything by meaning ('the churn analysis I ran last week', 'documents about flood risk') when you don't know the exact name. An honest empty `results:[]` means no matches; an error (e.g. the embedding model is not configured) is returned as a clear error, never a fake empty.

Capability: dataset.read

Arguments: q (required), k, scope

search_contracts

The PRIMARY discovery tool — your FIRST call for any analysis. In Griot a 'data contract' IS a governed dataset: its purpose, schema, and the guarantees you query against — and the ONLY way to reach data. This searches those contracts by keyword and returns only the few best matches: `dataset` (the contract id to pass next), `domain`, `purpose`, `columns`, `catalog` (the bucket folder the data lives in, ADR-0029). Pick ONE, then call describe_contract(its `dataset`) to read it before you query. NOTE: some matches are API-kind connector contracts (e.g. 'ksa/earth_engine') — a runtime connection to a live system, not a landed table; you read through it from a notebook rather than query_dataset it (its business_context carries the usage rules).

Capability: dataset.read

Arguments: query (required), limit

search_mentions

Search @-mentionable platform entities (datasets, contracts, domains, agents, reports, members, …) for a query. Returns grouped matches with griot:// URIs. Use this to resolve a human name to a canonical entity reference before acting on it (ADR-0037).

Capability: public

Arguments: q (required), kinds, limit, resolve

search_tenants

Search the Griot tenant directory for another organisation by name or slug, to invite it to a clean room or add it as a sharing partner. Returns at most 10 matches as {items:[{tenant_id, slug, display_name, exact, is_partner, partner_status}], total} — a deliberately minimal directory record and nothing that describes the organisation's data. `is_partner`/`partner_status` ('active' | 'pending' | null) say whether the caller already shares with that organisation, so an invitation that could not be accepted is not offered.

Capability: partner.read

Arguments: q (required), limit

search_tools

Find which MCP tool(s) do what you need, by describing the capability in a few words (e.g. 'make a chart' -> render_visual, 'who answered / provenance' -> the certificate tools, 'delete an agent' -> delete_agent). Use this INSTEAD of guessing a tool name or holding every tool's schema in context — call it whenever you're not sure which tool applies. Returns the ranked matches: {name, description, input_schema}. An exact tool-name match always wins. Honest empty {tools:[]} means nothing matched — try broader words.

Capability: public

Arguments: q (required), limit

send_certificate

Send/deliver a GDCP certificate by its `cert_id` to a recipient (e.g. email a signed provenance certificate to an auditor).

Capability: certificate.read

Arguments: cert_id (required), recipient

session_query

Run a read-only, contract-mediated SQL query SCOPED TO A WORKBOOK SESSION (ADR-0043) — it reads the session's BRANCH heads (your uncommitted work) for tables in the session and production/main for everything else, so you SEE THE DELTA your ops produced before publishing. Name the contract in the FROM clause exactly like query_dataset; the same contract enforcement, PII masking, and row-filtering apply. Returns {columns, rows, row_count, …} — the engine is hidden (there is no DuckDB path; it runs on GriotQL). Requires `session_id`; without one, use query_dataset for a plain production read. BOUNDED READS ARE MANDATORY, exactly as for query_dataset: carry a LIMIT of at most 200 or an aggregate, or the call is refused 422 `K01_QUERY_UNBOUNDED`; a result that hits the 200-row cap carries `truncated:true` + a `truncation_note` and is a SLICE, never the complete set.

Capability: dataset.read

Arguments: sql (required), session_id (required)

set_display_name

Set the CALLER's own display name. Pass `display_name`.

Capability: public

Arguments: display_name (required)

share_dataset

Share a dataset view (contract + view) with a partner (grant).

Capability: partner.grant

Arguments: partner_id (required), contract_id (required), view_type (required)

shared_a2a_agent_card

A2A Agent Card as a PARTNER would receive it (narrowed, §5.4)

Capability: agent.read

Arguments: agent_id (required)

submit_approval_vote

Cast a single vote on a contract-approval workflow by its `workflow_id`. `decision` is 'approve' or 'reject'; `reason` is optional context. (approve_contract_version is the same act in the `approve: true/false` spelling and returns the richer, state-aware body — prefer it.) The same rules apply as on approve_contract_version: an AGENT may not vote on a `contract_activation` workflow, and approving one whose contract governs personal data ALSO requires lawful_basis_affirmed=true plus the lawful_basis being affirmed.

Capability: contract.publish

Arguments: workflow_id (required), decision (required), reason, lawful_basis_affirmed, lawful_basis

submit_framework_evidence

Submit evidence for a compliance framework control by its `framework_code`. Pass an `evidence` object describing the control + artifact reference.

Capability: report.create

Arguments: framework_code (required), evidence

subscribe_to_listing

Subscribe the caller tenant to a marketplace listing by its `slug` (or `listing_slug`). Grants governed access to the shared data product per its contract.

Capability: marketplace_listing.read

Arguments: listing_slug (required)

sunset_partner

Sunset (permanently wind down) a federation partner by its `slug`, with an optional `reason`.

Capability: partner.grant

Arguments: slug (required), reason

test_connection

Test a live connection (K04A)

Capability: source.create

Arguments: connection_id (required)

test_source

Test connectivity/credentials for a connected source by its `source_id` — returns {ok, detail} without ingesting. ADR-0041: for an API source (id 'apisrc_…', a type: 'api' runtime connection) this runs the connector's CHEAP, QUOTA-FREE auth probe (for earth_engine: the WIF token exchange only — zero Earth Engine quota, never an EE data call) and returns {ok, status, connector_key, detail}. A connector with no registered probe returns an honest status:'unknown' (never a fake 'healthy').

Capability: source.create

Arguments: source_id (required)

transform_schedule_lakehouse_maintenance

Run the clean transform for stale (or one) dataset (K02)

Capability: dataset.admin

undo_session_op

Undo the last op on a workbook session (ADR-0043) — rolls that op's branch back one step and moves it onto the redo stack. Main is never involved. Returns the updated manifest (with the new op/undo depth).

Capability: dataset.read

Arguments: session_id (required)

update_compute_resource

Edit an existing compute definition by `name`. Unlike jobs, a compute definition has no DAG to corrupt, so this is a plain PARTIAL PATCH — send only the fields that change; anything you omit stays as it was. Bumps `version`. A RUNNING attachment is IMMUNE to this edit (§B.3): it stays pinned to whatever version it was provisioned under and keeps billing at that version's rate — only the NEXT attach gets the new version. The platform definition 'serverless' cannot be edited (403).

Capability: compute.update

Arguments: name (required), display_name, description, cpu, memory, ephemeral_storage, image, env_extras, max_idle_s, max_lifetime_s, allowed_consumers

update_contract

Edit a contract draft (PATCH the draft sections).

Capability: contract.update

Arguments: name (required), sections, type, description

update_contract_section

Edit ONE section of a contract (purpose, quality, or privacy) via T03 — publishes a NEW version carrying every OTHER section forward unchanged, then activates it, so improving a contract is incremental rather than a whole re-author. `schema`/`domain`/`dataset`/`data_modality` are REFUSED (400) -- those describe what the data IS; editing them would describe a different dataset, not an edit of this one. A `privacy` edit that LOWERS a previously-declared PII field (removes it from pii_fields, or turns pii_detection off) is REFUSED (409) unless `reason` is set -- lowering sensitivity is an unmasking action and is recorded + audited when done.

Capability: contract.update

Arguments: name (required), section (required), value (required), reason, type

update_domain

Update a data domain by its `slug` (ADR-0018). Only provided fields change; omitted fields are left as-is.

Capability: domain.update

Arguments: slug (required), name, owner_actor_id, parent_slug, description

update_governance_settings

Update the tenant's contract-approval governance settings (admin). Set `contract_approval_threshold` (>= 1) to control how many distinct approvers must vote before a non-first contract version activates — 1 lets a single publisher activate immediately; raise it to require multi-party sign-off. Set `contract_approval_separation_of_duties` true to exclude the proposer from counting toward quorum (requires threshold >= 2 to have effect). Both fields are optional; an omitted field is left unchanged. Requires the tenant-admin / owner capability; a threshold < 1 is rejected.

Capability: tenant_settings.update

Arguments: contract_approval_threshold, contract_approval_separation_of_duties

update_job

Change an existing job with ORDERED DELTA OPS — the right way to edit a job. Pass `ops`: [{op:'add_task', task:{...}}, {op:'update_task', key:'clean', ...}, {op:'remove_task', key:'old'}, {op:'set_fields', schedule:'0 6 * * *'}]. Send ONLY what changes: there is deliberately no whole-object PUT here, because re-sending a 200-line job to add one task is how the other 199 get corrupted by a summarised context window. Each op is applied in order and the whole PATCH is atomic — a rejected op leaves the job untouched. Editing a job does NOT rewrite history: past runs pinned the version they ran, so 'what changed since the last successful run' stays answerable.

Capability: pipeline.update

Arguments: name (required), ops (required)

update_notebook

Update a notebook by its `notebook_id` — replace its `cells` (ordered typed cells) and/or `name`/`packages`.

Capability: pipeline.read

Arguments: notebook_id (required), name, cells, packages

update_role

Update a role by its `role_key` — change `name`/`description` and/or its `permissions` list. Only provided fields change.

Capability: member.admin

Arguments: role_key (required), name, description, permissions

validate_compute_resource

DRY-RUN a compute definition — creates NOTHING. Send exactly what you would send to create_compute_resource (or the post-edit shape you are about to update_compute_resource) and get back, before anything exists: whether cpu/memory/name are legal, whether `image` is an allowlisted key, whether `env_extras` trips the credential denylist, and — the single most important check — whether the cluster could EVER schedule this (a definition bigger than the worker pool's largest node is refused here with the numbers named, never silently accepted and left Pending forever). Also returns the computed `credits_per_hour`. Call this BEFORE create_compute_resource every time.

Capability: compute.create

Arguments: name, display_name, description, cpu, memory, ephemeral_storage, image, env_extras, max_idle_s, max_lifetime_s, allowed_consumers

validate_job

DRY-RUN a job definition — creates NOTHING. Send exactly what you would send to create_job (or the post-edit shape you are about to PATCH) and get back, before anything exists: whether the DAG is acyclic, whether every referenced notebook/dataset/contract exists, whether each task's declared_purpose is one of its target contract's purpose.questions[] (and not in not_intended_for[]), whether `run_as` actually holds the capabilities the tasks need, and a credit estimate. Call this BEFORE create_job every time — it is cheap on purpose, and a wrong guess found here is loud and free instead of silent and expensive.

Capability: pipeline.create

Arguments: name (required), tasks (required), description, run_as, schedule, tags

validate_notebook

DRY-RUN a notebook — parses every cell, rebuilds the dependency graph and reports cycles, multiply-defined names, undefined references and per-cell errors, WITHOUT executing anything or attaching compute. Call this after editing cells and before starting a session: a graph error found here is free and named; the same error at run time costs a kernel and a wait. `name` is the notebook's stable name.

Capability: pipeline.read

Arguments: nb (required)

view_by_token_report

View a report by share token (signed-in — enforces scope)

Capability: report.read

Arguments: token (required)