Skip to content
SkyKeephelp

Agent tools (MCP)

Any MCP-compatible client reaches the vault through the tools below at POST /mcp, presenting a delegation token — the shape the three flows below mint, and the only agent credential this transport accepts. Every call travels the same verified, compartment-bounded, audited path as a human query — this page is generated from the same registry tools/list publishes. An agent running on ANOTHER machine gets that token by client-credentials exchange rather than by signing in as a person — see connecting a remote agent for the administrator's provisioning steps.

Which token this transport takes

One shape: a delegation token from /api/agent/self, /api/agent/exchange or /api/agent/device/poll. The ordinary opaque session that POST /api/agent/login mints is not accepted here — a tool call presenting one is refused with denied and a message saying so, and the refusal is audited. That session is still how an agent uses the PORTAL's own routes; nothing about it is deprecated and nothing about this narrows what an agent may reach.

The reason is what each shape can say. A delegation token carries a signed chain naming who acted and for whom, so the audit row for the request answers that question and the rate meter charges the person the work was done for. An opaque agent session names only the agent, which would make the wider-reaching credential the one the record says least about. An agent acting purely as itself loses nothing by the change: /api/agent/self returns a chain one link long that reaches exactly the compartments that agent was granted.

How an agent gets a token

Three ways, and all three end the same way: the token goes to POST /mcp in an Authorization: Bearer header, the same header an ordinary session travels in. Every credential travels in the POST body, never in a URL, and every refusal is the same 403 with no detail in it — a refusal that named the wrong part would tell a caller which of its guesses had the right shape.

Every one of these tokens lives at most FIVE MINUTES, and a token acting for a person never outlives that person's own authority: the chain is re-checked against the vault on every single call, so a revoked agent client, a disabled account in the chain, or a compartment taken back stops the token inside those five minutes rather than after them. There is no refresh call — an agent that needs longer asks again. Every grant, every refusal and every use is audited, and the audit row for a served call carries the whole chain of who acted for whom. The operator's side of all of this — registering the client, granting its compartments, revoking it — is on connecting a remote agent.

What an agent cannot do

These tools are the vault's DOCUMENT surface, and that is the whole of it. An agent reads, searches, thinks over, uploads, edits, lists and compares documents, sees the ones the vault could not read, withdraws its own held uploads, works the review queue, and reads its own figures — always inside the compartments its token reaches, and never outside them.

It does not administer anything. Creating accounts, making or granting compartments, registering agents, changing vault settings, purging documents, and letting a held document into the vault are the administrator's console and have no tool here. Neither does changing anybody's password, e-mail, second factor or profile, nor reading the audit trail. There is no tool name for any of them: an agent that asks for one is told the tool is unknown, and the listing never offers one.

An administrator's own account reaches none of these tools either, and is told so plainly rather than handed an empty result — an administrator holds no compartment, so an empty answer would read to an agent as an empty vault.

Hybrid search over the caller's admitted compartments. Fewer than k results after over-fetch is reported (under_return), never silently truncated. date_from/date_to narrow the results to the DOCUMENT'S own date (what the document claims about itself, not when the vault received it). compartment_ids narrows to named compartments and concept_type to one kind of document. A filter only ever narrows what the caller may already reach: naming a compartment you do not belong to returns no hits and no error, exactly as a compartment holding nothing relevant does.

ParameterTypeDescription
query requiredstring
kinteger
include_all_versionsboolean
date_fromstringinclusive lower bound on the document's own date, YYYY-MM-DD
date_tostringinclusive upper bound on the document's own date, YYYY-MM-DD
compartment_idsarraynarrow to these compartments. Only ever a narrowing of what you may already reach: an id you do not belong to simply matches nothing. An empty array names no compartment and so matches nothing at all; omit the argument for no filter.
concept_typestringnarrow to one kind of document, as the vault classified it at ingest. A label the vault does not publish is refused (invalid-params) naming the labels that are, never guessed at and never answered with an empty result.
representationstringWhich representation to render. Overrides the Accept header. One of: application/json, text/markdown; profile="okf-bundle". Anything else is refused with HTTP 406 before the tool runs.

Error codes: denied, invalid-params, model-unavailable, rate-limited

read

The full canonical markdown of one visible document version (superseded versions included — history is readable).

ParameterTypeDescription
version_id requiredstring
representationstringWhich representation to render. Overrides the Accept header. One of: application/json, text/markdown; profile="okf-concept". Anything else is refused with HTTP 406 before the tool runs.

Error codes: denied, invalid-params, rate-limited

synthesize

Think mode: a cited answer synthesized ONLY from DAL-admitted passages (ADR-0009). covered=false with a verbatim not-covered statement when the corpus holds no match — no model call is made in that case.

ParameterTypeDescription
question requiredstring
kinteger

Error codes: denied, invalid-params, model-unavailable, rate-limited

ingest

Ingest one document through the full gated pipeline (malware gate, parse, content screen, classification bounded by the caller's write reach). Gate-held content answers 'quarantined' — honest, not stored.

ParameterTypeDescription
filename requiredstringFilename, recorded as an unverified hint from the caller. It does NOT choose the parser: the type is decided from the file's own bytes, so a Word document named report.txt is read as a Word document. An unclaimed format quarantines, never silently stores.
content_textstringDocument content as UTF-8 text (markdown family).
content_base64stringDocument content base64-encoded (binary formats).
compartment_idsarrayExplicit classification request; must sit inside the caller's own write reach or the call is denied.
folderstringWhere to FILE the document: a relative path of folder names, '/' separated, never the document's own filename. Filing only — a folder confers no access and hides nothing; the compartments decide who can reach it. Omit it, or send an empty string, and the document is unfiled, which is the absence of a folder and not a root folder. An absolute path, a '..' segment, a backslash, a control character or more than the deployment's segment limit is refused as invalid-params and nothing is stored.

Error codes: denied, invalid-params, quarantined, rate-limited, duplicate, storage-full

checkout

The document's current visible version as an edit base: content plus base_version_id to present at commit.

ParameterTypeDescription
document_id requiredstring
representationstringWhich representation to render. Overrides the Accept header. One of: application/json, text/markdown; profile="okf-concept". Anything else is refused with HTTP 406 before the tool runs.

Error codes: denied, invalid-params, rate-limited

commit

Commit an edit as a NEW version superseding the checkout base (versions are never destroyed). A base that is no longer current answers 'stale-base': checkout again and rebase.

ParameterTypeDescription
document_id requiredstring
base_version_id requiredstring
filename requiredstringFilename, recorded as an unverified hint from the caller. It does NOT choose the parser: the type is decided from the file's own bytes, so a Word document named report.txt is read as a Word document. An unclaimed format quarantines, never silently stores.
content_textstringDocument content as UTF-8 text (markdown family).
content_base64stringDocument content base64-encoded (binary formats).
compartment_idsarrayExplicit classification request; must sit inside the caller's own write reach or the call is denied.
folderstringWhere to FILE the document: a relative path of folder names, '/' separated, never the document's own filename. Filing only — a folder confers no access and hides nothing; the compartments decide who can reach it. Omit it, or send an empty string, and the document is unfiled, which is the absence of a folder and not a root folder. An absolute path, a '..' segment, a backslash, a control character or more than the deployment's segment limit is refused as invalid-params and nothing is stored.

Error codes: denied, invalid-params, quarantined, stale-base, rate-limited, duplicate

documents

The document versions the caller may read, newest first. Superseded versions are excluded unless asked for -- history is readable, not implied. The answer states which ORDER actually ran, which is not always the one asked for: an unrecognised order falls back to the vault's own received date rather than refusing.

ParameterTypeDescription
include_all_versionsboolean
orderstringWhich date to order by. Anything the vault does not recognise falls back to the received date, and the answer says which order ran.

Error codes: denied, invalid-params

actionable

The documents this vault could not fully read and would like help with, bounded by the caller's own reach. A document whose later version converted cleanly is not listed. The answer names the rule that actually ran and the rules that exist.

ParameterTypeDescription
rulestringWhich actionable rule to apply. Empty means the deployment's configured rule; an unrecognised value falls back to it rather than refusing, and the answer says which rule ran.

Error codes: denied, invalid-params

diff

What changed between two versions of ONE document. Both reads happen under the caller's own predicates in a single transaction. Two versions whose combined text is over the cap answer 'too-large' rather than a truncated comparison -- a diff missing its last hunk claims two versions agree in a place nothing looked.

ParameterTypeDescription
version_a requiredstring
version_b requiredstring

Error codes: denied, invalid-params, too-large

original

The bytes of one version exactly as they were uploaded, base64-encoded. This is the only way to reach a version the vault stored without ever reading it, whose canonical markdown is empty by construction. A version that retained no original answers 'not-retained', which is not a refusal of authority.

ParameterTypeDescription
version_id requiredstring

Error codes: denied, invalid-params, not-retained, rate-limited

quarantine

The caller's OWN uploads that the ingest gates held for review, with the vault's reason for each. No argument names whose queue to read, on any layer. Letting a held document into the vault is a reviewer's act and is not a tool.

ParameterTypeDescription

Error codes: denied, invalid-params

quarantine_withdraw

Withdraw one of the caller's own held uploads. An item that is not the caller's and an item that does not exist are one answer, and the trail carries which.

ParameterTypeDescription
item_id requiredstring

Error codes: denied, invalid-params

workflow

The processing queue for the caller's own compartments: what each document is waiting for and how long it has waited. Finished items are excluded unless asked for.

ParameterTypeDescription
orderstringQueue ordering. An unrecognised value falls back to the vault's own default.
include_finishedboolean

Error codes: denied, invalid-params

workflow_item

One queue item in full, including the summary the vault made of it. A version outside the caller's compartments, an unknown version and one the vault no longer holds are ONE answer.

ParameterTypeDescription
version_id requiredstring

Error codes: denied, invalid-params

workflow_advance

Approve the next processing stage for each named version the caller may write. Answers per id what was done AND what was refused -- a bulk action reporting only its successes would let a selection quietly shrink. An id that is not a uuid refuses the whole call rather than being dropped.

ParameterTypeDescription
version_ids requiredarrayThe versions to approve.

Error codes: denied, invalid-params

workflow_abandon

Stop processing the named versions deliberately, with a short reason. This does NOT remove a document from the vault: there is no such transition from an admitted version, so one already serving readers refuses. Answers per id what was done and what was refused.

ParameterTypeDescription
version_ids requiredarrayThe versions to stop.
reasonstringWhy, in a sentence. It is recorded in the audit trail; empty is allowed and means no reason was given.

Error codes: denied, invalid-params

workflow_mode

Choose who advances the named versions through processing: 'manual' means a person approves each stage, 'automatic' means the vault decides. Required, with no default -- a call that named no mode would otherwise decide silently which way a control went. A mode outside the vocabulary is refused and the refusal is recorded.

ParameterTypeDescription
version_ids requiredarrayThe versions to switch.
mode requiredstring'manual' or 'automatic'. The vault holds the vocabulary and refuses anything else.

Error codes: denied, invalid-params

workflow_reconvert

Read one stored document again, optionally as another type and with other conversion settings. ONE version, never a list: re-conversion re-reads and re-parses a whole document, and a bulk form would let one call start an unbounded amount of work.

ParameterTypeDescription
version_id requiredstring
media_typestringRead it as this type instead. Empty keeps the type the vault decided. The vocabulary is the format registry's, one layer down.
settingsobjectConversion settings as scalar values. A nested object or array is refused rather than coerced.

Error codes: denied, invalid-params

workflow_requeue

Send one admitted document back through processing. It builds the NEXT version from the retained original; the version already in the vault keeps answering every reader the whole time, so nothing has to be removed.

ParameterTypeDescription
version_id requiredstring

Error codes: denied, invalid-params

workflow_review

Submit a person's own reading of a document the vault read poorly. It becomes a NEW version through the ordinary pipeline, with the reviewer and the time on it; the version it corrects is untouched. Needs write reach, not read reach.

ParameterTypeDescription
version_id requiredstring
text requiredstringWhat the document actually says.

Error codes: denied, invalid-params

stats_documents

Per-document figures for the documents the caller may read. ADR-0067: every count is the CALLER'S, never the vault's.

ParameterTypeDescription

Error codes: denied, invalid-params

stats_compartments

Per-compartment figures, bounded to the caller's own reach.

ParameterTypeDescription

Error codes: denied, invalid-params

stats_compartment_documents

The documents in ONE compartment the caller may read. A compartment outside the caller's reach and a compartment that does not exist are the same answer, so an identifier cannot become an existence oracle.

ParameterTypeDescription
compartment_id requiredinteger

Error codes: denied, invalid-params

stats_compartment_documents_over_time

How one compartment's document count moved, day by day, bounded to the caller's reach exactly as the listing above is. The vault-WIDE series has no compartment dimension to bound a caller to and is not a tool.

ParameterTypeDescription
compartment_id requiredinteger

Error codes: denied, invalid-params

models

Which models this deployment will answer with, and which one answers when the caller names none.

ParameterTypeDescription

Error codes: denied, invalid-params

limits

The caps in force on every text field, so a request can be composed within them rather than refused by them. These are the numbers IN FORCE on this deployment, not shipped defaults.

ParameterTypeDescription

Error codes: denied, invalid-params

status

Whether the vault's database and its model runtime are answering. Three states each, and 'unknown' is a first-class one: it means the check could not run, which is neither of the other two.

ParameterTypeDescription

Error codes: denied, invalid-params

duplicates

The documents in the caller's reach that closely resemble one another, with the distance and the kind (near or whitespace_only) and the decision if one has been made. Listing only: it never removes anything.

ParameterTypeDescription
include_decidedboolean

Error codes: denied, invalid-params

decide_duplicate

Record what one detected near-duplicate pair is: dated_version, numbered_version, whitespace_only, or discard. A decision is made once and is audited. 'discard' destroys nothing by itself: it requires discard_version_id naming which of the pair's two versions to throw out, records the verdict, and asks an administrator to destroy that copy. They destroy it or decline with a reason, and the pair reports which. Every other verb refuses discard_version_id.

ParameterTypeDescription
candidate_id requiredstring
decision requiredstring
discard_version_idstring

Error codes: denied, invalid-params

cancel

Stop a synthesis this caller submitted, by the job reference the vault handed back. Cancelling twice, or cancelling one that has already finished, is not an error: cancelled=false means this call did not end it, and status says what it actually is. A reference the caller did not submit is refused exactly as an unknown one is.

ParameterTypeDescription
job requiredstring

Error codes: denied, invalid-params