DocsSign inInstall Kastel
Reference

MCP tools: the full contract.

Every tool, every parameter, every result shape and every error behaviour. This page is not written: it is generated from the schema the engine's conformance suite checks.

A generated page

The blocks on this page come out of the open interface schema, published as they stand. These are the very strings your AI receives when it plugs in: translating them would make them diverge from the product.

01

What you plug into

Any MCP-capable AI plugs into your Kastel and reads your company's context, under the rights of whoever is asking. Kastel runs no model: it holds the knowledge, and it exposes it.

The contract is published in the open kastel-interface package, under Apache-2.0, and the engine's conformance suite checks that the running server matches it exactly. That schema is what is rendered below. You can build on it without asking us.

02

Two transports

Locally, your AI launches kastel mcp and talks over standard input and output on the same machine, with no access to present. Over a network, kastel mcp --transport http serves the same surface at /mcp: every request carries its access in the Authorization header, never in the URL.

The server listens on the loopback address by default. Exposing it on an externally reachable address requires TLS, either through a proxy in front or natively.

HTTP endpoint/mcp
AuthorizationAuthorization: Bearer <token>
Session headerMcp-Session-Id
Local transportstdio
Protocol revisions2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25, 2026-07-28
OAuth metadata/.well-known/oauth-protected-resource
Tasks extensionio.modelcontextprotocol/tasks (ask_company_context, propose_lesson, propose_page)
03

The rule to remember

On every responsibility-gated path, a refusal and an absence return the same result, byte for byte. Nobody can infer that a page exists from being denied it. This rule is not a promise made by this page: it is written tool by tool in the schema, on the Errors line.

Most read tools accept on_behalf_of: the effective scope is the intersection of the presented access's scope and that person's. A declaration can only narrow, never widen; an unknown identifier resolves to the empty scope.

04

The tools

The base tools answer questions about the organisation: departments, responsibilities, entities, glossary. The retrieval tools cover reading, search, context recipes, expertise routing and governed writes.

Base tools

4

get_departmentread-onlyidempotentnon destructiveclosed world

A department's index: its roles, the key documents the AI needs, processes.

ParameterTypeDescription
namestringrequiredThe department name (org-map name).
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.

ResultMarkdown: the department index rendered from the live org map (roles, key documents, processes).

ErrorsAn unknown department and a denied department render the SAME shape (no oracle). An unbuilt Brain returns a friendly not-built note.

get_person_aorread-onlyidempotentnon destructiveclosed world

A person's area of responsibility: role, departments, what they decide/validate.

ParameterTypeDescription
namestringrequiredThe person's slug or display name.
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.

ResultJSON: the person's AOR entry (role, departments, decides, validates), departments filtered to the caller's visibility.

ErrorsUnknown person, denied person, and zero-visible-departments return the SAME message, carrying NO list of known people for scoped consumers.

get_glossary_termread-onlyidempotentnon destructiveclosed world

Look up a house term (canonical name or alias): definition + synonyms.

ParameterTypeDescription
termstringrequiredCanonical term or alias.
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.

ResultJSON: term, definition, aliases, lifecycle_status, source_trust, rel_path. answer_guidance is never served (v1.1).

ErrorsUnknown term and out-of-scope term return the same not-found line.

list_company_entitiesread-onlyidempotentnon destructiveclosed world

List the company's typed entity pages. The type set is per-deployment: read the type shown on each returned line, never assume a fixed list. Optional type filter.

ParameterTypeDescription
typestringoptionalOptional entity type filter. Pass a type exactly as it appears in the type of a returned line; empty lists every type. An unknown type yields an empty list, never an error.
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.

ResultMarkdown list: one line per visible entity with its type, name, one-line summary, and source_trust.

ErrorsAn empty scope yields '_No entities visible._' (no oracle).

Retrieval tools

18

search_company_contextread-onlyidempotentnon destructiveclosed world

Search the company Brain (hybrid semantic + lexical, ranked).

ParameterTypeDescription
querystringrequiredThe natural-language query.
kintegeroptional · default 8How many chunks to return (clamped server-side).
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.
include_indexesbooleanoptional · default falseInclude compiled index pages (type: index) in the results (debug only; they are excluded by default).
include_neighborsbooleanoptional · default falseAdd a 'neighbors' list to each result: the visible adjacent sections of the same page (context material, bounded by the deployment's neighbor token budget; empty when that budget is 0). The payload is byte-identical when false.
explainbooleanoptional · default falseAdd the deterministic retrieval readout: a response-level 'explain' object (pipeline parameters, candidate counts, destination_filtered) and one per result (per-leg ranks, RRF decomposition, recency/graph multipliers). Numbers the pipeline already computed - it never changes the ranking. The payload is byte-identical when false.
budgetintegeroptional · default 0Approximate-token cap on the response's text volume. Deterministic OUTPUT pruning only: the served results are a truncated prefix of the SAME ranking (never reordered, never rescored), announced via a top-level 'budget_truncated': true. 0 (default) = no budget, byte-identical response. The opt-in explain readout is never counted.
formatstring (compact | full | toon)optional · default "compact"Response verbosity. 'compact' (the default) serves each result's text, coordinates, and safety markers (source_trust, quotable, lifecycle_status) without the ranking diagnostics or the sources chain, minified; 'full' serves the complete payload (scores, per-leg contributions, sources, department, doc_type); 'toon' serves the SAME compact projection as TOON text (tabular, fewest tokens - prefer it) and is refused with explain=true (diagnostics stay JSON).
show_expiredbooleanoptional · default falseAlso serve pages whose declared validity date (frontmatter 'expires:') is past. By default expired pages are excluded from recall - archived in effect, at the declared date, without any lifecycle_status change. The payload is byte-identical when false.
doc_typesarray[string]optionalRestrict results to pages of the listed frontmatter types (e.g. ["decision"]). Compiled into the candidate SQL next to the AOR predicate (never a post-filter); unknown types simply match nothing. Null/empty (default) = byte-identical payload.
as_ofstringoptionalHISTORICAL mode: an ISO date (YYYY-MM-DD). The results are the facts as known at that date - later edits excluded, a then-current page that has since been superseded comes back, expiry evaluated at the pinned date. The response then carries a top-level 'as_of' key: always surface it, the payload reflects THAT date, not today. Empty (default) = current mode, byte-identical payload.

ResultJSON: {query, results: [...]} - compact results carry [rank, rel_path, heading_path, lifecycle_status, source_trust, quotable, updated, text]; format='full' results carry [rank, score, vector_score, fts_score, rel_path, heading_path, lifecycle_status, source_trust, quotable, sources, updated, department, doc_type, text]; a full result whose page carries a provenance origin also carries 'origin': {connector, url?} - the link back to the source document (absent when the page has none, never null). Plus a top-level 'confidence': 'low' marker when the evidence is weak (advisory only, nothing suppressed). With include_neighbors, each result also carries 'neighbors': [chunk_index, heading_path, text, truncated]. With explain, the response carries 'explain': {pipeline, counts, destination_filtered} and each result 'explain': {vector, fts, entity, relational, rrf_score, title_boost, verified_boost, recency_multiplier, graph_boost, lifecycle_tier, final_rank} (keys present ONLY when explain=true).

ErrorsAn empty or unavailable index returns a human-readable note (never a crash); out-of-scope content is simply absent from the results. An empty, over-long, or control-character query returns {error: invalid_query, message} before any retrieval work.

grep_company_contextread-onlyidempotentnon destructiveclosed world

Exact literal search over the Brain (grep semantics, no regex).

ParameterTypeDescription
patternstringrequiredThe literal substring to find (2-256 characters; never a regex - LIKE metacharacters are neutralized).
prefixstringoptionalOptional rel_path prefix narrowing (e.g. memory/commerce/).
case_sensitivebooleanoptional · default falseMatch case-sensitively (default false).
kintegeroptional · default 20Total match cap (clamped server-side to 1..100).
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.
formatstring (json | toon)optional · default "json"Response serialization. 'json' (the default) is byte-identical to the historical payload; 'toon' serves the SAME payload as TOON text (tabular, fewest tokens - prefer it).

ResultJSON: {pattern, matches: [{rel_path, line, text}], truncated?} - exact line numbers and short excerpts from the live pages, at most 5 lines per page. Compiled index pages are excluded like the search_company_context default.

ErrorsAOR-filtered like every read path: an out-of-scope page is simply absent (no oracle), and a page over the destination_policy.mcp ceiling appears in NO result and NO count. An empty, over-long, or control-character pattern returns {error: invalid_pattern, message} before any search work. An empty or unavailable index returns a human-readable note (never a crash).

read_pageread-onlyidempotentnon destructiveclosed world

Read ONE Brain page whole (frontmatter + markdown body).

ParameterTypeDescription
rel_pathstringrequiredThe page path relative to the deployment root (memory/...).
sectionintegeroptional · default 00 = the whole page (or its section listing when over the size cap); N = the Nth section of the listing.
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.

ResultThe raw markdown page (frontmatter + body); over the size cap, the page's frontmatter followed by an H2 section listing, then one section per call via section=N (the frontmatter - provenance origin included - is never lost to pagination).

ErrorsDenied, absent, and structurally-refused (personal/, outside memory/) paths return the SAME not-available line (no oracle). A configured destination_policy.mcp ceiling withholds over-sensitive content with a neutral pointer.

list_pagesread-onlyidempotentnon destructiveclosed world

Map the Brain without reading it: the visible pages under a prefix.

ParameterTypeDescription
prefixstringoptionalOptional rel_path prefix (e.g. memory/commerce/); empty = all.
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.
formatstring (json | toon)optional · default "json"Response serialization. 'json' (the default) is byte-identical to the historical payload; 'toon' serves the SAME payload as TOON text (tabular, fewest tokens - prefer it).

ResultJSON: {prefix, pages: [rel_path, title, description, updated, lifecycle_status], truncated?} - AOR-filtered, capped server-side.

ErrorsOut-of-scope pages are simply absent (no oracle).

get_linksread-onlyidempotentnon destructiveclosed world

The link neighborhood of one page: outgoing wikilinks + backlinks.

ParameterTypeDescription
rel_pathstringrequiredThe page path relative to the deployment root (memory/...).
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.
formatstring (json | toon)optional · default "json"Response serialization. 'json' (the default) is byte-identical to the historical payload; 'toon' serves the SAME payload as TOON text (tabular, fewest tokens - prefer it).

ResultJSON: {rel_path, outgoing: [relation, target, rel_path, title, unresolved], backlinks: [rel_path, title]}. Unresolved outgoing targets are marked (Brain-health signal).

ErrorsAOR-filtered on BOTH ends: an edge whose other end is out of scope is invisible in both directions. A denied anchor is byte-identical to an absent one (no oracle).

get_indexread-onlyidempotentnon destructiveclosed world

The compiled index of a Brain scope: the catalogue to read first.

ParameterTypeDescription
scopestringoptional · default "root"root | general | a department folder slug | entities/<type>.
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.

ResultThe compiled index.md of the scope: structure + catalogue of pages with descriptions, linked entities, recent decisions, journal tail. The root index carries department/entity-type names and counts only.

ErrorsNon-root scopes are AOR-gated: a denied scope and an unknown scope return the SAME not-available line (no oracle). The root index is served unscoped by design (names + counts, never page titles).

who_knowsread-onlyidempotentnon destructiveclosed world

Who decides, who knows, on one topic - two registers, never merged.

ParameterTypeDescription
topicstringrequiredThe topic, free text.
kintegeroptional · default 12How many search hits anchor the topic (clamped to 1..24).
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.
formatstring (json | toon)optional · default "json"Response serialization. 'json' (the default) is byte-identical to the historical payload; 'toon' serves the SAME payload as TOON text (tabular, fewest tokens - prefer it).

ResultJSON: {topic, matched_pages, decides: [{person, name, role_aor, department}], knows: [{person, name, evidence: {n_pages, n_digest_answers, n_lessons}, recent, pages}]} - declared authority (the AOR matrix) vs demonstrated expertise (page authorship, digest answers, promoted lessons), factual counts only. May carry destination_filtered, the advisory confidence: low marker, and authorship_evidence: unavailable when the git history could not be read (the knows register then rests on digest answers alone).

ErrorsEvery register derives from pages the CALLER's scope can read (consumer x on_behalf_of intersection): out-of-scope evidence and its people are absent, not redacted (no oracle). An empty, over-long, or control-character topic returns {error: invalid_topic, message}. An empty or unavailable index returns a human-readable note (never a crash).

find_precedentsread-onlyidempotentnon destructiveclosed world

Has this been decided before? Past decisions matching a situation, with decider, status, date, and causal chain.

ParameterTypeDescription
situationstringrequiredThe situation to find precedents for, free text (validated like the who_knows topic: empty, over-long, and control-character inputs are refused).
kintegeroptional · default 5Distinct decisions returned (clamped to 1..12).
chain_depthintegeroptional · default 1Causal context per result (clamped to 0..3): each decision carries its ascendants (what it follows from or supersedes) and descendants (what it led to or was replaced by) up to this many hops. 0 = no causal block.
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.

ResultJSON: {situation, results: [rel_path, title, decided_by, validated_by, status, date, updated, department, lifecycle_status, source_trust, snippet, causal]} - one entry per DECISION page (doc_type 'decision'), rank order, accountability fields from the page frontmatter (null when absent, never invented), 'snippet' = the best-matching excerpt. 'causal' (present when chain_depth > 0) = {ascendants, descendants}, each a list of edges [relation, src, dst, src_title, dst_title, depth]. Plus the advisory top-level 'confidence': 'low' marker when the evidence is weak.

ErrorsAn empty, over-long, or control-character situation returns {error: invalid_situation, message} before any retrieval work. Decisions outside your scope are absent from results AND from causal chains (no oracle); a page over the destination_policy.mcp ceiling is withheld and never named by a causal edge. An empty or unavailable index returns a human-readable note (never a crash).

get_context_packread-onlyidempotentnon destructiveclosed world

Resolve a context pack: the vetted, governed context recipe for one recurring task type, assembled fresh at call time.

ParameterTypeDescription
packstringrequiredThe pack slug (its page is memory/packs/<slug>.md).
task_hintstringoptionalOptional task context (e.g. the client message); substituted into the pack's {task_hint} query placeholders and used to resolve entity lookups.
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.

ResultJSON, sections per PACK_RESULT_KEYS: {pack: {slug, title, description, owner_aor, instructions}, context: [page and chunk items with provenance and a quotable marker; an item whose page carries a provenance origin also carries 'origin': {connector, url?}, the link back to the source document], unavailable: [{rel_path, status}], never: [the pack's exclusion globs, echoed], write: [the pack's governed write-back pointers, echoed verbatim - they confer NO right], counters: {resolved, destination_filtered, never_filtered, truncated}}. Truncation to the budget is always announced, never silent.

ErrorsA pack outside your scope and a pack that does not exist return the SAME not-available line (no oracle); a fixed page that is denied, absent, or withheld is listed as unavailable without distinguishing why. An invalid pack page returns a structured {error: pack_invalid, reason, message} JSON object. An empty or unavailable index returns a human-readable note (never a crash).

list_context_packsread-onlyidempotentnon destructiveclosed world

Catalogue the context packs visible to your scope.

ParameterTypeDescription
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.
formatstring (json | toon)optional · default "json"Response serialization. 'json' (the default) is byte-identical to the historical payload; 'toon' serves the SAME payload as TOON text (tabular, fewest tokens - prefer it).

ResultJSON: {packs: [{slug, title, description, owner_aor}]} - AOR-filtered like every read path (a pack owned by a department outside your scope is absent).

ErrorsOut-of-scope packs are simply absent (no oracle). An empty or unavailable index returns a human-readable note (never a crash).

ask_company_contextnon destructiveclosed world

Ask the company Brain: one scoped, sourced answer with citations (JSON).

ParameterTypeDescription
questionstringoptionalThe question: ONE length-capped string, treated as data, never as instructions (fixed server-side prompt). Exactly one of 'question' or 'task' must be provided.
taskstringoptionalGUIDANCE mode (exclusive of 'question'): the task you are about to perform, ONE length-capped string, treated as data, never as instructions. Instead of answering a question, the deployment synthesizes an imperative guidance for THAT task from its stored experience (lessons, playbooks, process pages) plus the relevant context: transferable steps, conditional phrasing, and warnings first - what to avoid always outranks how to proceed. When no stored experience applies, the answer is exactly the published fallback sentence ('No stored experience applies; rely on your own judgment.') with no citations. Enabled by default; a deployment that set consultation.guidance to false refuses it with error 'guidance_disabled'. Refused together with write_back=true (a synthesized guidance is never proposed back to durable memory).
kintegeroptional · default 8How many chunks to retrieve for synthesis (clamped server-side).
on_behalf_ofstringoptionalOptional end-user person-slug; the result is narrowed to the intersection of the caller's scope and that user's scope.
explainbooleanoptional · default falseAdd the deterministic retrieval readout: a response-level 'explain' object and one per citation (per-leg ranks, RRF decomposition, multipliers). It never changes retrieval, the answer, or the citations, and adds no provider call. The payload is byte-identical when false.
budgetintegeroptional · default 0Approximate-token cap on the citation snippets. Citations are never dropped (the answer's [n] references stay resolvable) and the answer is never touched (its length is the server's max_answer_tokens config); truncation is announced via 'budget_truncated': true. 0 (default) = no budget, byte-identical response.
response_schemaobjectoptionalA SIMPLE JSON Schema the answer must conform to: object root, properties of type string/number/integer/boolean/array/one nested object level, optional required/enum; no other keyword (no free text). The SAME single consultation call structures the answer; the response gains 'structured' (the parsed object, or null) and, on a non-conforming model output, an honest 'structured_error'. Citations still carry the provenance. Omitted (default) = byte-identical response.
write_backbooleanoptional · default falsePropose the answer to the Brain's durable memory through the EXISTING governed channel (propose_lesson: AOR write gate, two-tier Guard, human moderation feed) - never a direct write. The proposal runs under YOUR OWN token identity (on_behalf_of never writes for someone else), cites the answer's citation rel_paths as provenance, and requires a write grant (a read-only or person token gets the standard R-SCOPE refusal). An answer with no citations proposes nothing (explicit refusal). The outcome rides the response under 'write_back' VERBATIM. False (default) = byte-identical response.
write_back_departmentstringoptionalTarget department of the write-back proposal (a memory folder slug); null (default) = the general Brain. Your AOR write permissions gate it (deny wins). Ignored without write_back: true.
as_ofstringoptionalHISTORICAL mode: an ISO date (YYYY-MM-DD). The answer is synthesized from the facts as known at that date; the response then carries a top-level 'as_of' key - always surface it, the answer reflects THAT date, not today. Retrieval only: quota, history, and spend accounting are unchanged. Refused together with write_back=true (a historical answer is never proposed to durable memory as current truth). Empty (default) = current mode, byte-identical payload.

ResultJSON: {answer, confidence: 'normal'|'low', citations: [n, rel_path, title, heading_path, snippet, source_trust, trust_label, updated, department], retrieved, answered_at, answer_id}. Citations are VERIFIED: they list the extracts the answer text actually cites with its [n] markers, one entry per cited page (several extracts of one page share a marker), renumbered dense; a marker that resolves to nothing is dropped from the answer text. 'retrieved' lists what was served but NOT cited (same object shape minus 'n'; always present, empty = everything served was cited; a response_schema answer carries everything served here - a JSON body cites nothing). A citation whose page carries a provenance origin also carries 'origin': {connector, url?} - the link back to the source document (absent when the page has none, never null). A citation whose index row carries a line span also carries 'start_line'/'end_line' - the 1-based lines of the cited passage in its source file (absent on an index built before line spans, never null). The same shape the deployment's POST /api/ask returns, minus its usage counters. 'answer_id' is the stable identifier of THIS answer (always present): pass it to rate_answer to report whether the answer was any good. 'confidence' is the published answerability marker (B4b): 'low' when the retrieval evidence is weak, 'normal' otherwise - a closed vocabulary, never a numeric score. An unknown topic and an empty scope return the same honest 'the Brain does not know this' answer (no oracle). With response_schema, the response carries 'structured' (the parsed conforming object, or null) and possibly 'structured_error' (honest non-conformance, never patched). With explain, the response carries 'explain': {pipeline, counts, destination_filtered} and each citation 'explain': {vector, fts, entity, relational, rrf_score, title_boost, verified_boost, recency_multiplier, graph_boost, lifecycle_tier, final_rank} (keys present ONLY when explain=true). With write_back, the response carries 'write_back': {outcome, written, rel_path, moderation_item_id, refusal_messages, superseded} - the propose_lesson outcome verbatim (key present ONLY when write_back=true; the answer and citations are served either way). On a deployment whose ask runs a bounded multi-round read loop, the response also carries 'rounds_used' - the provider calls the answer took (key present ONLY then; same citations shape in both modes). With task (guidance mode), the same shape: the answer is the synthesized guidance, or exactly the published fallback sentence with an empty citations list when no stored experience applies.

ErrorsRefusals are JSON error objects with a plain-language message: invalid_question (empty or oversize; also when 'question' and 'task' are both present or both absent), guidance_disabled (a 'task' call on a deployment that set consultation.guidance to false - guidance is enabled by default -, refused BEFORE any quota or spend), invalid_schema (a response_schema outside the strict whitelist, refused BEFORE any quota or spend), quota_exceeded (per-person daily question quota), budget_reached (monthly AI budget cap), limit_reached (hard consultation spend caps). An empty or unavailable index returns a human-readable note (never a crash).

rate_answernon destructiveclosed world

Rate one ask_company_context answer you were served (up/down); the signal goes to a human.

ParameterTypeDescription
answer_idstringrequiredThe identifier the ask_company_context answer carried under 'answer_id'. It must be an answer served to YOU.
ratingstring (up | down)requireddown when the answer was wrong or useless, up when it helped.
commentstringoptionalOptional free text for the human who curates the Brain (what was wrong, what was missing). Length-capped by the deployment; an oversize comment is refused, never silently truncated.

ResultJSON: {recorded: true, answer_id, rating, rel_path} - the rating is appended as one immutable record under the caller's own feedback namespace. It is a SIGNAL raised to a human: it never edits the Brain, never applies a correction, and never changes ranking. A down rating may raise a signal card in the decision inbox of the human who owns the cited pages; that human decides what to fix.

ErrorsJSON error objects: unknown_answer (an id that was never issued to YOU, or whose rating window has expired - the same reply either way, no oracle), already_rated (one rating per answer), invalid_rating, comment_too_long, not_permitted (the anonymous demo identity).

log_tracenon destructiveclosed world

Record an execution trace (flight recorder; provenance, not truth).

ParameterTypeDescription
taskstringrequiredWhat the agent was doing.
statusstring (success | failure | partial)requiredHow the task ended.
summarystringrequiredShort outcome summary.
detailstringoptionalOptional longer detail.
duration_secondsnumberoptionalOptional task duration.
refsarray[string]optionalOptional memory/ rel_paths this trace refers to (Brain pages or traces). Coordinates only: an element that is not a memory/ rel_path is refused - free text does not belong here.
on_behalf_ofstringoptionalOptional end-user person-slug: when the agent works for an identified person, the trace records that attribution so the deployment's right-to-erasure lever can reach it. An unknown slug is refused (never silently misattributed).

ResultThe written trace rel_path (under the caller's own namespace, server-derived from the identity). Traces are immutable, size-capped (task + body), audited, never indexed for recall, and classified before writing (private/mixed content is refused, fail-closed).

ErrorsA person token is refused (agent identities only); content (task + body) that does not classify as business is refused (R-PRIVACY, fail-closed also when the classifier is unavailable); a refs element that is not a memory/ rel_path is refused; a refusal returns 'refused: <rule>' naming the violated rule.

propose_lessonnon destructiveclosed world

Propose a durable lesson to the Brain (governed; never a direct write).

ParameterTypeDescription
titlestringrequiredShort lesson title.
lessonstringrequiredThe lesson body.
kindstring (lesson | rule)requiredA lesson (observation) or a rule (behavioral).
departmentstringrequiredTarget department (null = general).
refsarray[string]requiredMUST cite at least one of the caller's traces or a Brain page.

ResultJSON outcome of the governed proposal (Guard verdict, moderation routing, refusal messages verbatim). A proposal the Guard does not refuse is staged for the human moderation feed; only a human approval lands it.

ErrorsThe proposal runs the FULL two-tier Guard; AOR write permissions gate the target department (deny wins). Never a direct write - nothing lands without a human decision.

propose_pagenon destructiveclosed world

Propose a NEW Brain page (governed; never a direct write).

ParameterTypeDescription
titlestringrequiredShort page title (it derives the page path).
contentstringrequiredThe page markdown. May open with a frontmatter block for free keys (description, a specific type); protected and server-derived keys are refused.
departmentstringrequiredTarget department (null = general).
refsarray[string]optionalOptional provenance rel_paths (traces or Brain pages), recorded as sources.

ResultJSON outcome of the governed proposal (Guard verdict, moderation routing, refusal messages verbatim). A proposal the Guard does not refuse is staged for the human moderation feed; only a human approval lands it.

ErrorsCreation only: an existing target page is refused. The proposal runs the FULL two-tier Guard; AOR write permissions gate the target department (deny wins). Never a direct write - nothing lands without a human decision.

governance_modelread-onlyidempotentnon destructiveclosed world

The current governance model (people AOR + agent access), plain language.

No parameter.

ResultJSON: the owner, the mandatory-validation list, each person's AOR (departments, reports_to, decides, validates), and each agent's department + area access.

ErrorsOwner-only: a non-owner identity returns an unauthorized JSON object.

governance_previewread-onlyidempotentnon destructiveclosed world

Preview an AOR/permissions operation (BEFORE/AFTER, FR+EN), without applying it.

ParameterTypeDescription
opstringrequiredOne operation of the fixed vocabulary (spec 2.2).
slugstringoptionalA person slug (aor ops).
deptstringoptionalA department slug.
targetstringoptionalset_reports_to target slug, or none/null/- to clear.
categorystringoptionalA decision category (decides/validates/require_validation ops).
agentstringoptionalAn agent name (permissions ops).
areastringoptionalA curated area: clients|suppliers|employees|decisions|timeline (never a raw glob).
modestringoptionalread or write (grant ops).

ResultJSON: {op, file, before{fr,en}, after{fr,en}, warning?} - plain language, never raw YAML.

ErrorsOwner-only. A refused operation returns {error:aor_refused, reason, message}; the vocabulary is fixed (no raw glob or raw YAML).

governance_applyclosed world

Apply an AOR/permissions operation (validated, owner-attributed, audited, reversible).

ParameterTypeDescription
opstringrequiredOne operation of the fixed vocabulary (spec 2.2).
slugstringoptionalA person slug (aor ops).
deptstringoptionalA department slug.
targetstringoptionalset_reports_to target slug, or none/null/- to clear.
categorystringoptionalA decision category (decides/validates/require_validation ops).
agentstringoptionalAn agent name (permissions ops).
areastringoptionalA curated area: clients|suppliers|employees|decisions|timeline (never a raw glob).
modestringoptionalread or write (grant ops).

ResultJSON: {status: applied, op, file, commit, scope_propagation} on a direct write, or {status: submitted_for_approval, item_id} when meta-approval is on.

ErrorsOwner-only (byte-identical refusal for every other identity). Fail-closed validation (schema/referential/cycle/orphan/widening/consistency) returns a typed refusal; nothing is written. on_behalf_of is never honored (no parameter).

05

The resources

Resources are the documents a runtime can read directly, without going through a tool. Most are filtered by the reader's responsibilities.

Resources

11
URIDescriptionScope
kastel://brain/overviewBrain page: overview (markdown; AOR-gated).AOR-gated
kastel://brain/org-chartBrain page: org-chart (markdown; AOR-gated).AOR-gated
kastel://brain/aor-matrixBrain page: aor-matrix (markdown; AOR-gated).AOR-gated
kastel://brain/process-indexBrain page: process-index (markdown; AOR-gated).AOR-gated
kastel://brain/data-sourcesBrain page: data-sources (markdown; AOR-gated).AOR-gated
kastel://brain/glossaryBrain page: glossary (markdown; AOR-gated).AOR-gated
kastel://brain/gapsBrain page: gaps (markdown; AOR-gated).AOR-gated
kastel://brain/agentsBrain page: agents (markdown; AOR-gated).AOR-gated
kastel://brain/indexThe compiled root index of the Brain: departments, entity types, counts. The first document a runtime should read.not AOR-scoped
kastel://org-mapThe company org map: services, roles, the filing guide.not AOR-scoped
kastel://healthHealth report: memory health, governance health, context-depth metrics (JSON).not AOR-scoped
06

The skill pack

The skill pack is part of the open interface: a set of skills in Agent Skills format that kastel connect --write-skills writes for you, teaching the plugged-in runtime the right way to read.

Skill pack

7
FileSKILL.md
Version0.7.2
Skillskastel, kastel-recap, kastel-decisions, kastel-actionables, kastel-blockers, kastel-prep, kastel-wrap-up

Generated from the interface schema, version 0.18.0, refreshed on 2026-08-23 (engine d1e57f93ef0e).

A question about integrating?

Write to us: a question asked by email gets an answer the same day. Our network of partner integrators can also help.

Contact usSee the integrator programme