mazarbul
Indexes live Google Drive content the agent is connected to over MCP via a pointer, short summary, and freshness anchor rather than the document body, allowing recall to span local memory and Drive sources without duplication.
Indexes live Linear content exposed to the agent over MCP by storing a pointer, short summary, and freshness anchor instead of the full body, so hybrid recall can surface relevant Linear data alongside local memories.
Indexes Notion content that the agent is already connected to over MCP: Mazarbul stores a pointer, a short summary, and a freshness anchor rather than the body, letting recall span the agent's own memory and live Notion sources without duplicating data.
Local model provider set up by the installer for embedding generation required by semantic recall, and optionally as a server-side chat model for agent-less ingestion and maz ask.
Mazarbul
The system of records for the era of agents.
Local-first, git-native memory and structured data for your AI agents. One Go binary. Talks MCP. Your data never leaves your machine.

What is Mazarbul
Your agents have anterograde amnesia. They forget everything between sessions, so you re-explain your codebase, your preferences, and your decisions every single time. The usual fixes do not hold: a CLAUDE.md caps out and goes stale, a markdown vault is not a database, and cloud memory is an opaque blob you cannot query, audit, or own.
Mazarbul is the place your agents remember. A single local binary, maz, that any MCP-aware agent (Claude Code, Cursor, your own) talks to. Under the hood it is an append-only, cryptographically signed event log, projected into a graph, a vector index, and full-text search, and synced over plain git. Every fact carries its source. Nothing phones home.
It is both a memory for free-text episodes and a real database for typed entities, relations, and facts you can query. Think of it as a personal knowledge graph, a CRM, a decision log, and an agent memory, in one file you own.
And it runs headless. One lean binary gives you a CLI and an MCP server, with no separate database server to stand up and no UI required. So anything that needs to persist structured or unstructured data can lean on it: an agent over MCP, a script or cron job that shells out to maz, or you at the command line. Mazarbul is a local data layer you can drop into virtually anything.
What makes it different:
Event-sourced and signed. Every memory is an immutable, ed25519-signed event. The log is the source of truth; the indexes are rebuildable derivatives. Nothing is silently overwritten.
Four-layer hybrid recall. Vector similarity, full-text BM25, graph traversal, and name-embedding, fused into one ranked result with the score breakdown visible.
Git-native, conflict-free. Plaintext JSONL syncs over any git remote. Two devices converge by construction (CRDT), so concurrent writes never overwrite each other.
Provenance and audit on every fact.
maz blameshows who changed what and when, likegit blamefor your agent's memory. No other memory layer treats this as first-class.Structured and unstructured. Free-text
remember, plus typed entities, relations, and facts you define and query. A database, not a pile of notes.Reference your live tools, don't copy them. Your agent is already connected over MCP to Notion, Linear, Drive, and more. Mazarbul indexes them with a pointer, a short summary, and a freshness anchor, never the body, so recall spans your own memory and your live sources at once with nothing duplicated.
Related MCP server: agent-memory-os
Your agent is the brain, Mazarbul is the memory
The agent that calls Mazarbul over MCP (Claude Code, Cursor, your own) is already a strong model, so let it do the reasoning. It decides what is worth remembering, writes entities, relations, and facts with the structured tools (createEntity, relate, fact), resolves duplicates, and answers your questions from what recall and getContext return. Mazarbul stores, indexes, recalls, and proves where every record came from. That is why maz init configures no server-side chat model by default: you need only a small local embedding model for semantic recall, not a second LLM. A server-side model (Anthropic or a local Ollama model) is an optional extra that helps only when no agent is in the loop: passive file watching, connector ingestion, maz ask from a plain terminal, and background consolidation.
Install
curl -fsSL https://raw.githubusercontent.com/mo-cmyk/mazarbul/main/scripts/install.sh | shOr with Homebrew (macOS and Linux):
brew install mo-cmyk/mazarbul/mazThe installer verifies the download checksum, places maz plus its bundled engine library and man pages, and sets up a local model provider (it installs Ollama and pulls the embedding model semantic recall needs, unless you opt out with --no-ollama). It pulls no chat model: your agent does the reasoning. Then run maz init. If you want Mazarbul to reason on its own as well (agent-less ingestion, maz ask), add --with-chat-model to the installer for a local model, or run maz init --provider anthropic --api-key ... for a remote one.
# Prerequisites: mise (https://mise.jdx.dev), git.
git clone https://github.com/mo-cmyk/mazarbul.git
cd mazarbul
mise install # provisions Go, golangci-lint, lefthook, vhs, ...
mise run setup # go mod download + engine lib + hooks
mise run build # builds ./bin/maz (with sqlite_fts5)
./bin/maz --helpmaz dynamically links a small native graph engine (LadybugDB), resolved via an rpath into your Go module cache, so a source build runs on the machine that built it. For a self-contained, relocatable binary that bundles the engine, use the installer above.
Quickstart: zero to agent memory
# 1. Initialize your Book: pick a data dir; keep the default "no server-side
# chat model" (your agent reasons) or opt into one. Turn on encryption and
# init shows a recovery Watchword to save (your only key).
maz init
# 2. Wire it into Claude Code over MCP. --capture records each session passively;
# --warm-start injects a context brief when a new session begins.
maz connect claude-code --capture --warm-start
# 3. Remember something. Over MCP your agent also writes the entities and
# relations it sees; with a server-side chat model, maz extracts them too.
maz remember "Frodo Baggins works at Bag End in the Shire as a ring-bearer."
# 4. Recall it. Hybrid search (vector + full-text + graph + name-embedding), scored.
maz recall "where does Frodo work"That is it. Claude Code now has a recall and remember tool pointed at your Book, and every session it works in gets remembered and fed back. Any other MCP agent connects the same way via maz mcp serve.
How it works
The event log is the source of truth. Everything else is a rebuildable projection of it.
flowchart TD
A["maz remember / relate / fact<br/>(CLI, MCP, ambient hooks)"] --> B
subgraph SOT["Source of truth"]
B["Signed, append-only JSONL event log<br/>(ed25519 author on every event)"]
end
B --> D{{"Dispatcher<br/>(the only writer to the projections)"}}
subgraph PROJ["Rebuildable projections (maz rebuild)"]
direction LR
E["SQLite<br/>relations + facts"]
F["LadybugDB<br/>graph traversal"]
G["sqlite-vec<br/>semantic recall"]
H["FTS5<br/>keyword / BM25"]
end
D --> E & F & G & H
E & F & G & H --> I["Hybrid recall<br/>(4 lanes, fused + scored)"]
I --> J["Surfaces<br/>MCP (agents) | CLI / TUI (humans)"]
B -. "seal + push (plaintext JSONL<br/>+ rendered markdown tree)" .-> K[("Any git remote<br/>conflict-free / CRDT")]
K -. "pull (no LLM re-extraction)" .-> BBecause the log is append-only and every event is immutable and signed, two devices that sync the same log converge to byte-identical state. There is no last-write-wins overwrite. If any index is ever corrupted, maz rebuild reconstructs all four from the log.
A database for your agents, not a pile of notes
This is the core of it. Mazarbul stores free text and structured data, and lets you query both.
# Define a typed entity kind and a custom relation, on the fly. An agent can do
# this over MCP too; the ontology is data, so it syncs and versions like the rest.
maz schema kinds add artifact --display-name "Artifact" --description "An object of power"
maz schema predicates add bears --description "carries an object of power"
# Preview what defineEntityKind would do before committing (mint / collapse / supersede):
maz schema preview kind artifact --description "An object of power"
# Mint structured entities with typed properties, then wire the graph by name.
# relate takes names or ULIDs and requires both endpoints to already exist.
maz entity create person "Frodo Baggins"
maz entity create artifact "The One Ring" --attributes '{"forged_in":"Mount Doom","power":"invisibility"}'
maz relate "Frodo Baggins" bears "The One Ring"
# Read it back: typed kind, typed properties, provenance, and the new relation.
maz get "The One Ring"
maz neighbors "Frodo Baggins"
# Assert a scalar fact with history. Later writes supersede the value but keep the
# old one, so you can still ask where the Ring-bearer was earlier in the journey.
maz fact set "Frodo Baggins" location "Rivendell"
maz fact get "Frodo Baggins"
# Close a fact that stopped being true (keeps history), or hard-delete one outright.
maz fact retract "Frodo Baggins" location # slot reads empty after; history preserved
maz forget facts/01ARZ3NDEKTSV4RRFFQ69G5FAV # remove a fact row entirely
# Query the lot with one hybrid recall over structured data and free text, and
# pin the view to a point in time (valid-time).
maz recall "who carries the ring"
maz recall "who carries the ring" --at 2026-01-01T00:00:00Z # facts as they were valid on Jan 1
Pure markdown cannot query, join, or track change. Pure vector search cannot connect facts across documents. Mazarbul gives you typed entities and relations with a queryable graph, and the free-text episodes, fused in one recall.
What you can do
Mazarbul is a universal, headless data layer and system of record. The same primitives become many tools:
Agent memory. The default.
rememberfacts,recallthem across sessions. Stop re-explaining your project to every agent.Notes and knowledge vault.
maz doc import ~/notespulls your markdown in; wikilinks resolve to entities;maz doc logandmaz doc diffgive every note a history.Personal CRM. People, organizations, and the relations between them (
works_at,reports_to,introduced_by). Capture how and why you met someone, not just a name.Decision log / ADRs. Append-only by design, with supersede links. The reasoning behind a decision survives, and stays queryable, long after you would have forgotten it.
Knowledge graph. Define domain kinds and predicates, install schema packs, and traverse the result.
Team brain. A shared, end-to-end-encrypted scope so a whole team's agents draw on the same memory.
Draft staging: stage before you commit
Sometimes you want to capture something without immediately making it part of your permanent memory. Write with --scope draft and it lands in a private staging area, invisible to recall, get, and every other read verb until you decide what to do with it:
# Stage privately. Nothing in recall or getContext sees this yet.
maz remember "rough notes from the Prancing Pony meeting" --scope draft
# Review what is staged.
maz scope draft list # episodes, entities, and relations in staging
maz scope draft diff # compare draft against your personal set side by side
# Promote into personal memory (now recall-able and sync-able).
maz scope draft promote episodes/01ARZ3NDEKTSV4RRFFQ69G5FAV
# Or throw it away. The audit event is appended; the projection is cleaned up.
maz scope draft discard episodes/01ARZ3NDEKTSV4RRFFQ69G5FAVPromotion always targets personal (or project). Promoting directly into a shared team scope is refused by design — unreviewed draft data should never land in a shared scope without an explicit team write. Discard removes the episode and all draft entities it created; the event log itself is append-only, so the audit trail is preserved.
Named recall shortcuts
Save a query once, replay it whenever you need it:
maz saved add standup --query "daily standup Berlin team" --limit 5
maz saved list # all saved queries
maz saved show standup # stored parameters
maz saved recall standup # run it through the live recall pipeline
maz saved remove standupSaved queries live in your Book's config.toml under [saved_recalls]. Replaying always hits the live index, so results evolve as new episodes arrive.
Build your own skills and ontology
A preset is a skill for your agent: a schema pack (entity kinds and predicates) plus an instructions.md that teaches the agent when and how to use them. Install one, author your own, or publish it for others.
maz install schema-org-core # built-in pack: common schema.org types
maz install business-de # built-in pack: German business + legal types
maz preset install agent-memory # teaches an agent when to reach for memory
maz preset install second-brain # life-graph: people, projects, notes, topics
maz preset install decision-trace # decision provenance: decisions, insights, principles
maz preset install github.com/you/your-preset # install a preset from any git repo
maz preset package ./my-preset # validate + print a checksum to publishOnce second-brain is installed, it seeds brain:Person, brain:Project, brain:Note, and brain:Topic kinds with relations like collaborates_on, tagged_with, and inspired_by. Try a recall after adding a few notes to see how the graph organizes them. decision-trace seeds decision, insight, and principle kinds and wires them together with first-class traceability edges.
Define types ad hoc with maz schema kinds add / maz schema predicates add, or let an agent define them over MCP with defineEntityKind / definePredicate. Use maz schema preview kind <name> to see the plan (mint / collapse-into / supersede) before writing. The ontology is data, not code, so it syncs and versions like everything else.
Bring your existing tools
Mazarbul meets your data where it already lives.
# Import an existing markdown / Obsidian vault. Wikilinks become entities;
# bodies become recall-able. Idempotent, so re-running skips unchanged files.
maz doc import ~/ObsidianVault
# Or point Mazarbul's vault straight at your Obsidian folder (it only ever writes
# documents it owns) and edit notes in Obsidian as usual.
maz config set vault.path ~/ObsidianVault
# Render an entity neighborhood as an Obsidian-openable canvas.
maz doc canvas "Frodo Baggins"
# Pull in your other sources. Connectors ingest untrusted external content, so
# the target scope needs encryption enabled first (maz doctor sets it up).
maz source connect local-git --repo . # your repo's commit history
maz source import claude-chats ~/Downloads/export.zip # your Claude.ai exports
This is "Karpathy-style" external memory (an agent that compiles a persistent, interlinked base instead of re-deriving everything per query) with the parts the markdown-wiki approach lacks: a typed query layer, an automatic entity graph, provenance, and a sync that does not corrupt.
Reference live sources instead of copying them
Importing copies data in. The other half is the opposite. Your agent is already connected, over MCP, to the tools your work actually lives in: Notion, Linear, Granola, Google Drive, GitHub. Mazarbul holds no tokens for any of them and never fetches them itself. It indexes them.
After your agent reads an item from one of those tools, a single captureExternal call records a pointer to it, the agent's own short summary, and a freshness anchor (a content hash plus the fetch time). The body never lands in Mazarbul. That summary is then searchable in recall alongside everything else you remember, and every hit grounded in a live source carries an inline freshness verdict and an external-lineage marker:
recall "the Q3 launch plan"
Q3 launch: connector wave ships first, then the public install path.
source: notion freshness: fresh (fetched 2h ago) trust: proposedWhen a hit goes stale (past that connector's freshness budget) the agent re-fetches the live item and re-captures, so the index never drifts from the source of truth. And because the lineage is external rather than authored, these land proposed, untrusted: searchable and rankable, but clearly summarized-from-elsewhere, not something you asserted. See agent-docs/external-references.md.
The result is one place to search across your own memory and your live tools at once, with no second store to keep in sync.
It's just git
Your memory is plaintext JSONL plus a rendered markdown tree in a normal git repo. Inspect it with semantic, entity-aware commands, or with the git you already know.
# Seal local memory into signed chunks and push to your git remote.
maz sync push
# Browse it semantically, from anywhere:
maz diff HEAD~5..HEAD # what changed: entities added, relations superseded
maz diff --kind person --operation changed --format json # changed person entities as JSON
maz blame "Frodo Baggins" # who changed this entity, and when
maz changelog # per-push summaries, newest first
# Or clone the synced repo and use plain git. It is JSONL plus a rendered markdown
# tree, so log, diff, and blame all just work on it:
git clone <your-remote> memory && cd memory
git log --stat
git blame rendered/by-uid/<...>.md # line-level provenance, in plain gitmaz diff also takes --predicate and --operation post-filters. JSON output (--format json) surfaces a filtered count and an active_filters map alongside the entries, so scripts can assert what changed without parsing prose.
Bulk import and re-embedding
Moving machines, restoring from a backup, or switching embedding models? Two commands cover it:
# Bulk-load a JSONL snapshot exported with "maz export".
maz load backup.ndjson # append every event (default)
maz load backup.ndjson --mode merge # skip events whose UID already exists (idempotent)
maz load backup.ndjson --dry-run # parse + validate, report counts, write nothing
# After switching embedding models, re-embed every episode.
maz reindex --reembed # drop episodes_vec and rebuild it
maz reindex --reembed --dry-run # count what would be re-embedded firstmaz load emits {mode, source, total, appended, skipped, invalid, dryRun}. Warning MAZ-LOAD-001 fires when merge mode skips duplicate UIDs; MAZ-LOAD-002 when a line is malformed. The batch is atomic: either all valid events land or none do. maz reindex --reembed requires an embedder configured (maz init --embed=ollama); the other three derived stores (SQLite, graph, FTS5) are untouched.
Both maz rebuild and maz reindex --reembed run with the daemon up. No maz daemon stop is required. When the daemon is running, the CLI routes these operations to the admin HTTP interface (POST /admin/v1/rebuild, POST /admin/v1/reindex), which is exposed only on the Unix socket, not TCP. The daemon builds a shadow projection in a temporary directory, quiesces for a brief swap window (seconds), renames the new indexes into place, and resumes serving on the same socket. The reconnecting maz mcp serve proxy masks the window for read traffic; in-flight writes fail clean and can be retried. maz reindex --dry-run is unavailable while the daemon runs (it requires in-process store access). The same socket-only /admin/ surface is how maz preset install, maz preset uninstall, maz load, and maz schema alias operations route privileged writes through the live daemon.

Markdown vaults synced over git overwrite each other on concurrent writes. Mazarbul's log is conflict-free by construction, so two machines pushing at once converge instead of clobbering. For an untrusted host, turn on per-scope encryption (XChaCha20-Poly1305) and the repo holds only sealed ciphertext.
Why Mazarbul
You are probably already doing this with one of these. Here is what Mazarbul gives you instead.
Obsidian + Claude Code + git. You get markdown silos, manual linking, no query or join, git sync that corrupts on concurrent writes, and provenance only if you hand-enforce it. Mazarbul keeps the git-native plaintext and adds a typed query layer, an automatic entity graph, conflict-free merge, and provenance on every fact.
Agent-memory libraries (mem0, Letta, agentmemory). A vector store, a cloud API, or a framework you are locked into; memories are opaque, LLM-rewritten blobs with no provenance or audit. Mazarbul is local, four-layer, event-sourced, and every fact cites its source and is auditable.
Key-value or vector stores, ChatGPT / Claude built-in memory. Opaque, cloud-locked, no schema or relations or query or audit, siloed per product. Mazarbul is a system of record you own, query, time-travel, and move.
Mazarbul | Vector memory (mem0, ...) | Obsidian + git + agent | Built-in cloud memory | |
Runs fully local, no account | yes | partial | yes | no |
You own the source of truth | signed event log | cloud / vector blobs | markdown files | vendor cloud |
Provenance + audit per fact | yes | no | manual | no |
Typed query + graph | graph + vector + FTS | vector (+opt. graph) | no | no |
Conflict-free multi-device git | yes | n/a | overwrites | n/a |
Time-travel (valid-time) | yes | no | no | no |
MCP-native for any agent | yes | SDK / REST | via plugins | vendor-only |
Shared encrypted team scope | yes | cloud tier | manual | no |
The wedge, in one line: agents need both free text and structure, and the systems that combine them (GraphRAG, Zep) all live in the cloud. Mazarbul brings that combination to a single file you own, with provenance and git-native sync no one else offers.
Use with Claude Code and any MCP agent
maz connect claude-code # register over MCP (also: claude-desktop, ...)
maz connect claude-code --capture --warm-start # passive capture + session warm-start
maz connect # show the live detection table for every clientOnce connected, Claude Code works from your Book, traversing the graph to connect facts rather than just retrieving text. The same memory answers a headless claude -p one-shot and a live interactive session, with no tool list and no prompts:

For Cursor, a custom agent, or any other MCP client, run the server directly:
maz mcp serve # stdio (default)
maz mcp serve --http # streamable HTTP at 127.0.0.1:7842
maz mcp serve --unix # Unix socketConnected agents get a clean tool surface: remember, recall, forget, relate, get, neighbors, relations, entities, query, createEntity, defineEntityKind, getContext, getEntityContext (a token-budgeted dossier for one entity), agentFeedback, and more. The humans on your team use the exact same data through maz on the command line or its TUI.
For humans: TUI, live watch, and the Agent Mirror
The same memory has rich interactive surfaces — no agent required:
maz self # the Agent Mirror: what Mazarbul knows about you
maz recall "the ring" --tui # interactive master-detail recall browser (recall → get → neighbors)
maz doc browse # two-pane TUI over your markdown vault
maz watch # live dashboard: events, jobs, embedding, and syncmaz learns how it's used
This is the centerpiece of the Omnigraph-parity wave. Every time an agent hits a confusing result, a wrong answer, or a hard-won rule worth keeping, it can record that friction. Recurring friction auto-promotes a distilled one-liner into a ## Known gotchas & lessons section that is appended last to every new MCP session's instructions — so every connected agent starts with the evolved guidance, without any human curation step.
# Record a durable lesson from the CLI (agents use the agentFeedback MCP tool).
maz feedback record --category lesson --severity medium \
--surface recall \
--summary "recall missed an exact name" \
--rule "prefer get when you already hold the exact name"
# See what is currently promoted into every session's instructions.
maz feedback gotchas
# Inspect the raw triage queue.
maz feedback list --category confusing
# Pin a cluster (always included, even if the cap fills up).
maz feedback pin "lesson|recall|prefer get exact name"
# Suppress a cluster from promotion.
maz feedback veto "lesson|recall|prefer get exact name"
# Edit the distilled rule text.
maz feedback edit "lesson|recall|prefer get exact name" --rule "use get for exact-name lookups"
# Export an allowlist-redacted diagnostic (safe to share; no user memory ever leaves).
maz feedback export --format md -o feedback.mdPromotion thresholds: a cluster promotes after 3 recurrences, or 2 when its highest observed severity is high. Pinned clusters are exempt from the 8-entry cap; vetoed clusters never appear. Every review appends an audited event — nothing is ever deleted. The export strips all user memory, principal IDs, cluster keys, and team scope: only {id, ts, category, severity, surface, summary, detail, keywords, version, activePreset} leaves. See agent-docs/feedback-loop.md for the full design.
Output formats and scripting
Every read verb honors --output (or the MAZ_OUTPUT env var):
maz recall "Frodo" --output json # single JSON document
maz entities --kind person --output ndjson # one JSON object per line (stream-friendly)
maz entities --kind person --output csv # CSV with a header row (cut/awk/spreadsheet)
maz entities --kind person --output kv # key: value lines, blank between records (grep-friendly)Aliases: table = text, jsonl = ndjson. Set a persistent default in your Book config:
maz config set output.default_format jsonThe config knob sits between MAZ_OUTPUT and the TTY heuristic in the precedence chain, so scripts get JSON automatically while interactive sessions still get a table.
Documentation
Architecture and design:
agent-docs/synthesis.md,agent-docs/designs/Sync, scopes, and teams:
agent-docs/sync.md,agent-docs/privacy.mdConnectors and presets:
agent-docs/connect.md,agent-docs/plugins.mdDraft staging workflow:
agent-docs/draft-scope.mdDynamic feedback loop:
agent-docs/feedback-loop.mdWarning codes:
agent-docs/warnings.mdBuilt-in help:
maz help-topics concepts,maz introspect,man maz
A hosted documentation site is on the way.
Contributing
Humans: start with DEVELOPMENT.md and CONTRIBUTING.md.
Agents: read AGENTS.md for the operating contract and subagent roster.
Security: see SECURITY.md for private disclosure (do not open public issues for vulnerabilities).
License
Mazarbul is licensed under the Apache License 2.0. See LICENSE for the full terms and NOTICE for attribution.
Available Tools
64 toolsaddIdentifierA
Attach an identifier (an alias by default) to an EXISTING entity, appending an entityIdentifierAdded event so the resolver and vault wikilinks match the entity by that surface form. Use this after renaming an entity's displayName via updateEntity to retain the prior name: addIdentifier{entityUid, identifier:"Old Name", kind:"alias"}. createEntity only seeds identifiers at mint time; this adds them later. kind defaults to "alias"; pass email/username/phone/id or a snake_case domain type for other identifiers. Returns E_NOT_FOUND when the uid does not resolve and E_VALIDATION on an empty identifier or malformed kind.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Identifier kind in snake_case. Canonical: alias, email, username, phone, id; domain types (hrb, lei, tax_id, …) keep their own lookup lane. Defaults to "alias" when omitted — the kind to use for retaining an old display name after a rename. | |
| entityUid | Yes | ULID of the existing entity to attach the identifier to. Required. | |
| identifier | Yes | The surface form / external identifier to attach, e.g. a prior display name "Erebor Global", an email, a username, or a domain id. Required. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the entity the identifier was attached to. |
| status | Yes | Always "added" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and mostly succeeds: it discloses the event emission, resolver/wikilink matching consequence, the kind default, and the two error codes (E_NOT_FOUND, E_VALIDATION) with their triggers. It does not address idempotency or what happens if the identifier is already attached, nor any permission requirements, which is the remaining gap for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the sibling distinction before the example and error behavior, and every sentence carries information. The inline call example partially restates the schema but is justified as usage illustration; it could be trimmed slightly without loss.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter mutation with an output schema present, the description covers the mutation's meaning, its downstream effect on resolution, the default and allowed kinds, and failure modes. Nothing beyond return-value shape is missing, and return values are handled by the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3; the description adds real value on top by stating kind defaults to "alias", listing accepted canonical kinds (email/username/phone/id) and domain snake_case types, and showing a worked call with the old-name alias case. Slight overlap with the schema's own kind description keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (attach) on a specific resource (identifier) with the critical scope constraint that the entity must already exist, plus the side effect of appending an entityIdentifierAdded event. It explicitly distinguishes itself from the two nearest siblings, createEntity and updateEntity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete when-to-use scenario (retain the prior name after renaming displayName via updateEntity) and names the alternative it is not (createEntity only seeds identifiers at mint time). The condition that selects this tool over its siblings is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agentFeedbackA
Record durable feedback about using Mazarbul: a friction point (confusing|missing|wrong_result|slow|tool_error|suggestion) or a lesson you learned (a one-line rule). Give a category, severity, and one-line summary; optionally the surface (tool/CLI), detail, and a distilled rule. Recurring feedback auto-promotes into your per-session guidance (the user can pin/edit/veto). File DURABLE friction or rules, not one-off disagreements.
| Name | Required | Description | Default |
|---|---|---|---|
| rule | No | For a lesson: the distilled one-line durable rule, phrased as guidance. This is what gets promoted into the session guidance. Optional. | |
| scope | No | Scope to record into. Defaults to personal (device-local diagnostic). | |
| detail | No | Optional longer context: reproduction or expected-vs-actual. | |
| summary | Yes | One-line description of the friction or rule. Required. | |
| surface | No | Tool / CLI / instruction the feedback is about, e.g. recall, "maz load". Optional but encouraged (part of the recurrence cluster). | |
| category | Yes | Kind of feedback. confusing|missing|wrong_result|slow|tool_error|suggestion are friction; lesson is a durable rule you learned. Required. | |
| keywords | No | Optional tags aiding clustering + search. | |
| severity | No | Impact. high promotes into guidance at a lower recurrence threshold. Required. | |
| activePreset | No | Active steering preset, if any. Optional; auto-context. |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | Always "recorded" on success. |
| clusterKey | Yes | Recurrence cluster this feedback was filed under. Reportable via maz feedback. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full behavioral burden and does so well: it discloses that recurring feedback auto-promotes into per-session guidance, that the user can pin/edit/veto that guidance, that 'rule' is the field that actually gets promoted, and that high severity lowers the recurrence threshold. It also discloses the default recording scope as device-local diagnostic, which an agent could not infer from the schema alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense paragraph that front-loads purpose, then field expectations, then the promotion consequence. Every clause does work, though the parenthetical enumerations make it feel packed; a couple of sentences could be tightened without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter mutation tool with no annotations, the description covers what an agent must know before calling: required fields, optional-but-encouraged fields, scope default, and the downstream effect on session guidance including user override. Since an output schema exists, the absence of return-value prose is not a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning on top: it identifies category/severity/summary as the required trio, clarifies 'surface' as part of the recurrence cluster and thus encouraged, and explains that severity's high value triggers promotion at a lower threshold — a consequence the enum alone doesn't convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource — 'Record durable feedback about using Mazarbul' — and enumerates the friction categories and the 'lesson' alternative, so the agent knows exactly what belongs here. It falls short of a 5 because it never names the sibling tools it could be confused with (remember, fact, contextPin) to draw the line between logging a rule as feedback versus storing it as knowledge.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a clear usage condition ('File DURABLE friction or rules') and an explicit exclusion ('not one-off disagreements'), which is exactly the kind of judgment call an agent needs. What's missing is a pointer to the alternative path for non-durable cases or for facts, so the routing is only half-resolved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancelJobC
Cancel a tracked background job by its AIP resource name ("jobs/{uid}").
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Resource name of the job to cancel: "jobs/{uid}". |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | |
| state | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are empty, so the description carries the full burden for a destructive mutation. It does not say whether cancellation is reversible, whether it is idempotent, what happens if the job already completed or failed, or whether any permission is required. An output schema exists, so return values need not be covered, but the core mutation semantics are missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero waste; the identifier format follows the operation rather than burying it. It may be slightly too terse given what is left unsaid about the mutation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with full schema coverage and an output schema, the description covers the minimum needed to invoke it correctly. It falls short on lifecycle semantics — job state at cancellation, post-cancel behavior — which matter for a cancel operation with no annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter already documents the 'jobs/{uid}' format and the pattern. The description only echoes the same format, adding no meaning beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Cancel a tracked background job' — plus the identifier format, so the agent knows exactly what operation is performed. It does not differentiate from the related listJobs sibling, which would be the natural way to discover a job name, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this versus alternatives, no prerequisite that the job must exist and be in a cancellable state, and no pointer to listJobs for obtaining a valid name. The only implied context is the word 'tracked'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
captureExternalA
Index an external item you fetched from a live connector (Notion, Linear, Granola, Drive, GitHub) WITHOUT copying its body into maz. One call stores a pointer + YOUR summary + a freshness anchor; maz never fetches or holds the content. recall later returns the summary with an inline freshness verdict so you reuse it when fresh and re-fetch live when stale. The capture is UNTRUSTED (lineage connector:): facts land proposed, never superseding your own. Idempotent by contentHash within the connector's TTL. Pass status=deleted|access-revoked to tombstone an item you can no longer reach. Refuses project scope and ephemeral connectors (gmail/gcal/slack; read those live). recall FIRST before capturing, to avoid duplicates.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | Yes | Absolute URI of the external item (must carry a scheme), e.g. a Notion page URL, a Linear issue URL, a Drive doc link. The canonical identity of the external_ref pointer. | |
| label | No | Human-readable display name for the external_ref. Defaults to the externalId or connector, NEVER the raw URI (which would leak into a shared render). | |
| scope | No | Scope to capture into. Defaults to personal. Project is refused: captured external content is sensitive and project renders to shared git. | |
| status | No | active (default) records a live snapshot. deleted (a 404 on re-fetch) or access-revoked (a 403) tombstones the prior capture so recall flags it access-unverified instead of dropping it. | |
| stream | No | Sub-channel within the connector, e.g. a Notion database id or a Linear team key. Optional. | |
| summary | No | Your faithful summary of the fetched content. Put the stable external id and key facts in the prose so recall can find it. Required unless you pass summaries[] or a tombstone status. | |
| dedupKey | No | Idempotency key. Defaults to <connector>:<externalId>:<scope>. Recapturing the same item must reuse the same dedupKey (omit it and pass a stable externalId, or pass it explicitly). | |
| connector | Yes | The connector the item came from: notion, linear, granola, drive, github. Drives the freshness budget and the untrusted-lineage trust tag. Ephemeral connectors (gmail, gcal, slack) are refused: read those live. | |
| fetchTime | No | When you fetched the item (RFC 3339 UTC). Defaults to now. | |
| summaries | No | Chunked summary: one episode per element, all sharing one external_ref. Use for long items; otherwise pass summary. | |
| externalId | No | The source-system stable id (Notion page id, Linear issue key). Used to mint the dedupKey when you omit it; hashed in any plaintext render. | |
| sourceType | Yes | Open-taxonomy kind of the item, e.g. notion_page, linear_issue, meeting_notes, drive_doc. | |
| contentHash | No | SHA-256 hex of the item's canonical content subset (the freshness ETag). Recapturing with the same hash within the connector's TTL is a no-op. OMIT it if you cannot compute a real SHA-256 over the fetched content; do NOT fabricate one (any non-64-hex value is rejected). Defaults to the hash of your summary text when omitted. | |
| externalUrl | No | Dereferenceable location to re-fetch when stale. Defaults to uri. |
Output Schema
| Name | Required | Description |
|---|---|---|
| action | Yes | captured = first snapshot; skipped = unchanged within TTL (no write); revision = content changed (new episode, prior superseded); expired = unchanged but past TTL (fetch-time refreshed); tombstoned = item reported gone. |
| freshness | Yes | The resulting freshness verdict for this item, the same value recall will report. |
| episodeNames | Yes | Resource names of the summary episode(s) this capture is grounded in (one per chunk). |
| sourceRefNames | Yes | Resource names of the SourceRef provenance rows. |
| externalRefName | Yes | AIP resource name of the external_ref pointer entity. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are empty, so the description carries the full burden — and it does cover a lot: untrusted lineage (connector:<name>), facts landing as proposed rather than superseding, TTL-scoped idempotency by contentHash, and tombstoning via status. It does not state auth/permission requirements or what the response contains on a duplicate no-op beyond the idempotency claim.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core distinction (pointer, not body) and each subsequent sentence adds a distinct constraint (freshness verdict, trust tag, idempotency, tombstones, refusals, dedup workflow). Dense but nearly every clause earns its place; minor tightening possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the description covers the trust model, idempotency, refusal rules, and dedup ordering that the schema alone cannot convey. Sufficient for a 14-parameter mutation tool with no annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 14 parameters; the description largely restates what the schema says (contentHash idempotency within TTL, status=deleted|access-revoked tombstoning, summary requirement). It adds framing about why project scope is refused but no syntax or format detail beyond the schema — baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb and resource: 'Index an external item you fetched from a live connector ... WITHOUT copying its body', naming the pointer+summary+freshness-anchor model. It explicitly distinguishes itself from ingest/remember siblings by stating maz never fetches or holds the content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives both directions: 'recall FIRST before capturing, to avoid duplicates' and hard exclusions ('Refuses project scope and ephemeral connectors (gmail/gcal/slack; read those live)'). The alternative for ephemeral sources is named explicitly, and the tombstone path is described.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connectSourceA
Connect a source and run a bounded first backfill into the graph. Give a connector (local-git, claude-chats, or granola) and, for the file-based ones, repoPath (granola uses a stored API key instead); optionally scope (personal|team, default personal), dryRun (preview + count without writing), maxItems, and maxExtractionCalls. Ingested content is UNTRUSTED: facts land proposed and capped, never superseding your own. Returns a run report with itemsApplied/Skipped and a jobUid. Refuses project scope.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Scope to ingest into. Defaults to personal. Project scope is refused: ingested external content is sensitive and project is plaintext. | |
| dryRun | No | Preview only: validate the source and count would-be items WITHOUT writing anything (the consent gate). | |
| maxItems | No | Cap on items considered this run (backfill bound). Defaults to 500. | |
| repoPath | No | Source locator for file-based connectors: a local git repository path (local-git), or an export file path (claude-chats: a .zip bundle or a conversations.json). Omit for granola, which authenticates with a keychain API key (set it via 'maz source add granola'). | |
| connector | Yes | Source connector name. Supported: local-git, claude-chats, granola. | |
| maxExtractionCalls | No | Cap on episodes appended this run, each one downstream extraction. Defaults to 500. |
Output Schema
| Name | Required | Description |
|---|---|---|
| dryRun | No | |
| jobUid | No | Job UID; pass to listJobs / cancelJob to track or cancel a long backfill. |
| streams | No | |
| connector | Yes | |
| itemsApplied | Yes | Items turned into episodes (or, in a dry run, that WOULD be). |
| itemsSkipped | Yes | Items skipped because their content hash was unchanged (idempotent re-ingest). |
| episodesAppended | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the trust model (ingested content is UNTRUSTED; facts land proposed and capped, never superseding your own) and the return shape (itemsApplied/Skipped plus a jobUid). It omits auth/permission requirements beyond the granola key hint and says nothing about idempotency or repeat-run behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Opens with the action and outcome in one clause, then packs connector selection, optional knobs, trust model, and return value into three dense sentences with zero filler. Parenthetical asides are used efficiently rather than sprawling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter mutating ingestion tool, the description covers the safety model, refusals, per-connector prerequisites, and the return report, and an output schema exists to carry return detail. A gap remains around the jobUid's lifecycle (polling via `listJobs`/`waitForIdle`) and how this differs from `ingestSource`.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: it groups which parameters apply to which connector, restates defaults (personal), and characterizes maxItems/maxExtractionCalls as run bounds and dryRun as a count-only preview. The enum for scope is reinforced with the project-refusal rationale.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Connect') and resource ('a source') plus the key scope ('bounded first backfill into the graph'), which is far more informative than a bare name. It implicitly separates itself from the ongoing-ingest sibling (`ingestSource`) via 'first backfill', but never names that sibling outright, so an agent must infer the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives per-connector guidance (repoPath for file-based, stored API key for granola, `maz source add granola` to set it) and explains dryRun as the preview/consent gate. It also states a hard exclusion ('Refuses project scope'). It stops short of saying when to prefer this over `ingestSource` or `listSources`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
contextCorrectA
Correct a wrong item the cold-start brief surfaced. Pass the item's id (a pin's contextPins/{uid}, or an entities/{uid} the brief showed) and the corrected text; the brief renders your text in its place. The correction is a NEW event, not an in-place edit — history is preserved and the latest correction wins. Returns the overlay's contextPins/{uid}.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The corrected text to show in place of the surfaced item. Required, non-empty. | |
| scope | No | Scope to write into; match the scope the corrected pin lives in. Defaults to personal ("project" = this repo; "team" requires admitted membership, else E_PERMISSION). | |
| targetId | Yes | Id of the item to correct: a contextPins/{uid} (or bare ULID) of a pin shown in the brief, or an entities/{uid} surfaced in it. The brief renders this corrected text in the item's place. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the correction overlay; retire it with contextUnpin. |
| status | Yes | Always "corrected" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does meaningful work: it discloses append-only semantics ('history is preserved'), conflict resolution ('the latest correction wins'), and the exact return shape (the overlay's contextPins/{uid}). It leaves out idempotency and permission failure behaviour beyond what the schema's scope caveat already covers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the action and the input contract, followed by the event-sourcing semantics and the return value. No sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and parameter coverage is complete, so the description only needs to explain the non-obvious mutation model — which it does. It could still say what happens when the targetId isn't in the current brief or how the overlay interacts with the original pin, which is the only gap for a write tool with zero annotation coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so targetId, text and scope are already fully documented, including the ULID/entities/{uid} forms and the team membership caveat. The description restates the id forms and adds only that the text is rendered 'in its place' — a marginal delta over the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
A specific verb-plus-target — correct a wrong item surfaced by the cold-start brief — plus a stated effect (the brief renders the corrected text in place). It distinguishes itself from updateEntity/editDocument by declaring the correction is a new event rather than an in-place edit, so an agent can pick it apart from the neighbouring mutation tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly scopes usage to items the cold-start brief surfaced, and the 'NEW event, not in-place edit' note tells the agent when this is the right mechanism versus a normal edit. It never names an explicit alternative sibling or states a when-not condition, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
contextPinA
Pin a free-text steering note to the top of the user's cold-start context brief. Use it when the user states a durable preference or constraint they want surfaced first every session (e.g. "I'm mid-migration off Postgres — don't suggest new Postgres features"). The note wins a budget slot before auto-surfaced documents and entities. Returns the pin's contextPins/{uid}; retire it with contextUnpin or override it with contextCorrect.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The steering note to surface at the top of the cold-start brief, e.g. "Mid-migration off Postgres — don't suggest new Postgres features". Required, non-empty. | |
| scope | No | Scope to write into — a pin steers whoever reads that scope. Defaults to personal (steers only the user). Use "project" to steer anyone working in this repo. Use "team" to steer the whole team (requires admitted membership, else E_PERMISSION). | |
| targetRef | No | Optional resource the note is about, e.g. an entities/{uid}. Omit for a free-floating steering note. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the new pin; pass to contextUnpin or contextCorrect. |
| status | Yes | Always "pinned" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the full burden and mostly succeeds: it discloses the ordering effect (the note wins a budget slot before auto-surfaced documents and entities) and the return shape (contextPins/{uid}). It does not discuss limits on how many pins are allowed or failure modes beyond what the schema states, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the action and trigger, then the behavioral effect and lifecycle pointers. Every sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter tool with an output schema and no annotations, the description supplies the trigger, the ordering behavior, the return reference, and the sibling lifecycle tools. An agent has everything needed to decide to call it and what to do afterward.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the scope/targetRef semantics, including the E_PERMISSION condition, are already documented in the schema. The description adds the concept of what a pin steers but no parameter-level detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: pin a free-text steering note to the top of the cold-start context brief. It clearly distinguishes the tool from contextUnpin (retire) and contextCorrect (override) named in the same description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('when the user states a durable preference or constraint they want surfaced first every session') with a concrete example. It also names both alternatives and the conditions that select them: contextUnpin to retire, contextCorrect to override.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
contextUnpinA
Retire a steering pin or correction so it stops surfacing in the cold-start brief. Pass its contextPins/{uid} (or bare ULID). The row is tombstoned, not deleted — history is preserved and the retire converges across devices. Use when a pinned note or correction is no longer relevant.
| Name | Required | Description | Default |
|---|---|---|---|
| pin | Yes | The pin or correction to retire: contextPins/{uid} or a bare ULID, as returned by contextPin/contextCorrect or shown in the brief. | |
| scope | No | Scope the tombstone is written into; match the pin's scope. Defaults to personal. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the retired pin or correction. |
| status | Yes | Always "unpinned" on success: the row is retired (a convergent tombstone), not deleted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are empty, so the description carries the full burden and does well: it discloses that the row is tombstoned rather than deleted, that history is preserved, and that the retire converges across devices. It omits permission/scope requirements and any error behavior for unknown or already-retired pins.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the outcome, then the input format, then the tombstone semantics, then the usage cue — a sensible ordering. The closing 'use when' sentence partly repeats the first sentence's framing, so there is minor redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be explained, and the mutation's semantics (soft delete, cross-device convergence) are covered. The scope parameter's meaning is only in the schema, which is acceptable but leaves the description slightly incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented, and the description's restatement of the contextPins/{uid} or bare ULID format adds little. The scope parameter and its 'match the pin's scope' guidance are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (retire/unpin) and resource (steering pin or correction) and states the observable effect: it stops surfacing in the cold-start brief. It also names the sibling tools that produce pin identifiers (contextPin/contextCorrect), so an agent can distinguish this teardown operation from the creation path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit trigger: 'Use when a pinned note or correction is no longer relevant,' and implicitly pairs with contextPin/contextCorrect as the inverse. It does not discuss any when-not conditions or what happens if the pin is already retired or the UID is wrong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
countA
Count entities matching an AIP-160 filter — the deterministic answer to "how many …". With groupBy, returns a per-value breakdown (e.g. people per status) instead of a single total. Same filter grammar as the entities tool. Scope: defaults to project+personal; pass scopes:["team"] to include team entities.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Convenience prefilter to one entity kind, AND-combined with filter. | |
| limit | No | Max groups to return when groupBy is set, most-populous first. Defaults to 50. Ignored without groupBy. | |
| filter | No | AIP-160 filter expression selecting which entities to count. Same grammar as the entities tool: reference entity columns (kind, displayName, confidence, resolutionStatus, createTime), fact slots by state_key (e.g. status = "pending"), and related("predicate", "target"). Operators = != < > <= >= : with AND / OR / NOT. | |
| scopes | No | Scope filter: which data partitions to count. Allowed values: project, personal, team. Defaults to [project, personal] when omitted — team entities are hidden unless you pass scopes:["team"]. | |
| groupBy | No | When set, return a per-value breakdown counted by this field instead of a single total. The field is an entity column (kind, resolutionStatus, …) or a fact slot state_key (status, …); entities with no open fact for that slot bucket under the empty value. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | Total matching entities. Present when groupBy is not set. |
| groups | No | Per-value breakdown, most-populous first. Present when groupBy is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the behavioral burden and does well: it discloses that team entities are hidden unless scopes:["team"] is passed, that groupBy switches to a per-value breakdown, and that entities without an open fact bucket under the empty value. Minor gaps on return shape are offset by the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then scope and groupBy behavior in tight sentences. No filler; each sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 0 required params, full schema coverage, and an output schema present, the description covers the behavioral essentials an agent needs: scope defaults, groupBy semantics, and filter grammar reference. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds meaning beyond the schema — the team-hidden scope default and the groupBy bucketing behavior — which helps an agent reason about parameter outcomes rather than just syntax.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Count entities') and frames it as 'the deterministic answer to how many', which distinguishes it from a list/query tool. The groupBy breakdown and scope language further narrow what the tool returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the scope default (project+personal) and the condition to include team entities, and points to 'the entities tool' for the filter grammar. It doesn't explicitly say when to prefer this over the 'entities' or 'query' siblings, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createEntityA
Mint a structured entity of a registered kind directly, bypassing LLM extraction — the write-side complement to relate. Use it when you already hold an entity as (kind, displayName) and need its entities/{uid} to assert a relation, without a remember() round-trip. Inputs: kind (a core kind or a registered extension kind — register first with defineEntityKind, check with introspect), displayName, optional confidence (default 1.0), identifiers (anchor the entity so the resolver attaches future mentions instead of duplicating), alternateNames, and properties (typed attributes validated against the kind's propertySchema). Deduplicates before minting: a matching identifier returns the existing entity (status reused); an existing same-name or near-duplicate of the same kind is NOT created (status duplicate_candidates) — inspect candidates, then reuse a uid, merge with mergeEntities, or retry with force=true to record a genuinely distinct entity that happens to share a name. On a plain create (status created) any advisory near-matches are still listed in candidates. Returns E_VALIDATION on a malformed kind, empty displayName, out-of-range confidence, or non-object properties.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Entity kind. A core kind (person, organization, place, project, event, document) or a registered extension kind (e.g. user:vehicle). Register a new kind with defineEntityKind first; introspect lists what exists. | |
| force | No | Skip the duplicate check and mint a new entity even when one with the same name already exists. Use to record a genuinely distinct entity that shares a name with an existing one (e.g. a second real person named the same). Defaults to false. | |
| scope | No | Scope to write into — pick by who should see it. Defaults to personal (private to the user, syncs to their devices). Use "project" for records tied to the current repo/codebase (shared with anyone who has repo access). Use "team" for the shared team brain (requires admitted membership, else E_PERMISSION). | |
| confidence | No | Writer confidence in the entity's identity. Defaults to 1.0 (user-confirmed). | |
| properties | No | Typed attribute values matching the kind's propertySchema (P3), e.g. {"vin":"…","make":"…"}. Validated on write when strict_attributes is enabled. Optional. | |
| displayName | Yes | Human-readable label, e.g. "Mithril Corp" or "Eowyn". | |
| identifiers | No | Strong/weak external identifiers to anchor the entity so the resolver attaches future mentions instead of minting a duplicate. Optional. | |
| alternateNames | No | Other surface forms for this entity. Optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| uid | No | Bare ULID of the entity (set on status created/reused). |
| kind | No | The entity's kind (set on status created/reused). |
| name | No | AIP resource name of the entity (set on status created/reused). Pass to relate or get(entities/{uid}). |
| status | Yes | created = a new entity was minted; reused = an existing entity matched by identifier and is returned in uid/name; duplicate_candidates = NOT created because same-name or near-duplicate entities exist (see candidates) — reuse one, merge with mergeEntities, or retry with force=true. |
| candidates | No | Existing entities that match by name or embedding. On duplicate_candidates the create was refused; on created these are advisory near-matches you may want to merge. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does: it discloses deduplication semantics per status (reused, duplicate_candidates, created), that same-name or near-duplicates are NOT minted silently, that advisory candidates are still listed on a plain create, and that E_VALIDATION fires on malformed kind, empty displayName, out-of-range confidence or non-object properties. That is unusually rich behavior disclosure for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and usage are front-loaded in the first two sentences, followed by dedup behavior and error surface, which is the right ordering. It loses a mark for the middle "Inputs:" enumeration, which duplicates what the schema already says and bloats an otherwise tight paragraph.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter mutation tool with nested identifier objects, no annotations, but a full output schema, the description covers what it must: prerequisites, dedup/override workflow, per-status outcomes and validation errors. Return shape is correctly left to the output schema, so nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents kind, force, confidence, identifiers, alternateNames and properties in detail; the description's "Inputs:" clause mostly restates it. It adds modest relational meaning — that identifiers anchor the resolver into a distinct lookup lane and that force overrides the duplicate gate — but not enough to exceed the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: "Mint a structured entity of a registered kind directly, bypassing LLM extraction." It immediately positions itself against siblings — the write-side complement to relate, explicitly not a remember() round-trip — so an agent can distinguish createEntity from remember, relate, updateEntity and defineEntityKind without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit use condition ("when you already hold an entity as (kind, displayName) and need its entities/{uid} to assert a relation") and then names the alternatives in the duplicate case: reuse a uid, merge with mergeEntities, or retry with force=true. The defineEntityKind/introspect prerequisite for extension kinds is stated outright, so there is nothing left to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
defineEntityKindA
Register a new entity kind in the dynamic-ontology registry — but first check whether an existing kind already covers the concept (introspect → entityKinds, or describeType). The built-in dedup check runs automatically: a near-identical kind returns status="reused" with the existing name so you avoid minting a synonym; a medium-similarity near-duplicate mints but records a SKOS closeMatch alias (response field closeMatch + similarity, internal URN maz:kind: added to sameAs). Because that dedup runs a semantic embedding pass over existing kinds, this call routinely takes a few seconds to return — that latency is expected, not a hang; do not abort or retry on a short timeout. Inputs: name (bare snake_case, no namespace), displayName, description (required for dedup), optional extends (parent kind — must be a core kind or an already-registered active kind; bare names resolve to their canonical registered form), sameAs (external vocabulary IRIs), propertySchema (JSON Schema for typed attributes). Appends an entityKindRegistered event; the dispatcher materialises it into entity_kinds and the render pipeline writes it to the git-synced ontology/ tree. Re-registering an existing user kind with force=true overwrites it. Attempting to modify a core kind, or extending an unknown/ambiguous parent, returns E_VALIDATION.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Bare snake_case kind identifier, e.g. vehicle. No namespace prefix — user: is added automatically. Must not start with core:. | |
| force | No | Bypass the reuse-before-mint dedup check and register unconditionally. Default false. | |
| sameAs | No | Alias/sameAs IRIs to canonical external vocabularies, e.g. ["schema.org/Vehicle", "wikidata:Q42889"]. Optional. | |
| extends | No | Parent kind name for single-inheritance subtype hierarchy (RDFS subClassOf). Must be a core kind or an already-registered active kind; a bare name (vehicle) resolves to its canonical registered form (user:vehicle) when unambiguous. E_VALIDATION when unknown or ambiguous. Optional. | |
| preview | No | When true, compute and return a plan of what this call would do (collapse, supersede, or mint) WITHOUT appending any event. The event log is unchanged. Use this to inspect impact before committing. Default false. | |
| description | Yes | One-sentence explanation of the kind. Used by the dedup check and agents. | |
| displayName | Yes | Human-readable label, e.g. Vehicle. | |
| propertySchema | No | Optional JSON Schema (Draft 2020-12) for typed attributes. Compiled before registration; E_VALIDATION on compile failure. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | The registered kind name, e.g. user:vehicle. |
| plan | No | Present only when preview=true. Describes what the call would do without writing any event. |
| status | Yes | registered = kind written as active; reused = existing near-identical kind returned instead of minting; proposed = kind queued for review in governed mode; preview = plan computed without writing any event (preview=true was set). |
| warnings | No | Non-fatal advisory warnings. MAZ-KIND-001 = close match found; MAZ-KIND-002 = semantic dedup skipped; MAZ-SCHEMA-001 = supersede; MAZ-SCHEMA-002 = orphaned fields; MAZ-SCHEMA-003 = collapse. |
| closeMatch | No | The name of a closely related existing kind (skos:closeMatch semantics). Present when a medium-similarity near-duplicate was found during minting. |
| reusedKind | No | The existing kind name when status=reused. Absent otherwise. |
| similarity | No | Dedup similarity score (0..1). Present when status=reused or when closeMatch is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it discloses the automatic dedup pass (reused / closeMatch alias / maz:kind URN in sameAs), the expected multi-second latency with an explicit 'do not abort or retry' warning, the event-append plus dispatcher/materialisation and git-sync side effects, and the E_VALIDATION failure modes for core-kind edits and unknown parents.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is long, but front-loaded with the purpose followed by dedup, latency, inputs, side effects, and errors in a deliberate order. Nearly every sentence carries operational information; a couple of clauses (event appending plus materialisation plus render pipeline) could be tightened without loss.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given eight parameters, nested propertySchema, an output schema, and a mutation with real side effects, the description covers prerequisites, latency, dedup outcomes, error codes, and reversibility (force overwrite) — nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further by explaining name must be bare snake_case with no namespace, that description is required specifically for dedup, that extends must resolve to a core or active registered kind, and that sameAs is for external vocabulary IRIs. It adds real semantic framing beyond the property descriptions rather than repeating them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause states a specific verb and resource — 'Register a new entity kind in the dynamic-ontology registry' — and immediately names the siblings (introspect→entityKinds, describeType) that serve the alternative purpose. An agent can distinguish this from definePredicate/defineSchema/describeType without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs the agent to check for an existing covering kind first and names the two concrete alternatives (introspect → entityKinds, describeType). It also flags the preview parameter as the way to inspect impact before committing and force=true for overwriting, giving both when-to-use and when-not-to-mint guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
definePredicateA
Register a new predicate in the shared predicates vocabulary — but first call introspect to check existing predicates (works_at, member_of, etc.) so you don't mint a synonym. Inputs: predicate (snake_case), kind (functional for at-most-one-live-value, non-functional for multiple concurrent values), description, and optional typing: subjectKinds/objectKinds (domain/range — the entity kinds allowed on each end), sameAs (external-vocabulary IRIs), and propertySchema (a JSON Schema for the relation's attributes). Domain/range and attribute constraints are advisory by default and enforced only when [ontology] strict_domain_range is enabled. The predicate is immediately queryable via introspect and usable in relate calls. Re-registering an existing predicate updates its kind, description, domain/range, sameAs, and propertySchema and returns status=updated. Returns E_VALIDATION if the predicate name or propertySchema is malformed.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | functional = at most one live value per subject (e.g. works_at). non-functional = multiple concurrent values allowed (e.g. member_of). | |
| sameAs | No | Optional alias IRIs mapping this predicate to external vocabularies, e.g. ["https://schema.org/worksFor", "wikidata:P108"]. | |
| predicate | Yes | Snake_case predicate identifier, e.g. works_at or member_of. Must be unique in the predicates vocabulary. | |
| description | Yes | One-sentence human-readable explanation of what the predicate means. | |
| objectKinds | No | Optional range constraint: entity kinds allowed as the object of this relation, e.g. ["organization"] for works_at. Omit to accept any kind. | |
| subjectKinds | No | Optional domain constraint: entity kinds allowed as the subject of this relation, e.g. ["person"] for works_at. Omit to accept any kind (open-world default). | |
| propertySchema | No | Optional JSON Schema (Draft 2020-12) constraining the relation's attributes map, e.g. require a string role. Validated against relation instances only when [ontology] strict_domain_range is enabled. |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | registered = new predicate written to the vocabulary; updated = existing predicate's kind, description, domain/range, sameAs, and propertySchema overwritten. |
| predicate | Yes | The registered predicate identifier. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does most of it: it discloses that re-registering mutates kind/description/domain-range/sameAs/propertySchema and returns status=updated, that domain/range constraints are advisory unless [ontology] strict_domain_range is enabled, and that malformed input returns E_VALIDATION. The gap is scope/authorization — a 'shared' vocabulary mutation with no statement about who may register or whether it affects other teams.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the introspect prerequisite, then a compact parameter enumeration, then consequences and error behavior. Dense but nearly every clause is load-bearing; the parenthetical domain/range glosses are mildly redundant with the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter mutation with nested propertySchema, the description covers semantics, config-gated enforcement, upsert behavior, error conditions, and cross-tool workflow. An output schema exists, and it still flags the status=updated shape, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the 3 baseline is met by structured fields alone; the description adds a domain/range framing for subjectKinds/objectKinds and connects propertySchema to the relation's attributes map, plus notes the advisory-vs-enforced behavior of those constraints. It doesn't add format detail beyond the schema's examples, so it stops short of a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Register a new predicate in the shared predicates vocabulary') and immediately positions it against siblings: introspect for checking, relate for consuming. An agent can distinguish this from defineEntityKind or defineSchema without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States an explicit prerequisite workflow ('first call introspect to check existing predicates ... so you don't mint a synonym'), explains re-registration as an update path, and names where the result is used (queryable via introspect, usable in relate calls). No alternative tool is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
defineSchemaA
Register a JSON Schema document in the dynamic-ontology schema registry. Use this to attach validation schemas for custom entity-kind properties (schemaKind=entityKind:vehicle) or to define schemas for new event types. Inputs: schemaKind (bare camelCase or colon-namespaced, e.g. entityKind:deal), version (semver vX.Y.Z), definition (JSON Schema object). Core schema kinds (entity, episode, etc.) are protected and return E_VALIDATION. The schema is immediately usable for property validation via ValidateEntityProperties. Returns E_VALIDATION if the definition is not a JSON object or if schemaKind is a protected core kind.
| Name | Required | Description | Default |
|---|---|---|---|
| preview | No | When true, compute and return a plan (supersede or register) WITHOUT appending any event. Use this to inspect impact before committing. Default false. | |
| version | Yes | Semver version, e.g. v0.1.0. Higher versions replace lower ones; same version with a different definition is a conflict. | |
| definition | Yes | JSON Schema document (Draft 2020-12) to register. Must be a JSON object. | |
| schemaKind | Yes | Lookup key for the schema, e.g. entityKind:vehicle or myCustomEvent. Bare camelCase or colon-namespaced. No spaces. Core kinds (entityKindRegistered, schemaRegistered, predicateRegistered, entity, episode, etc.) cannot be overwritten. |
Output Schema
| Name | Required | Description |
|---|---|---|
| plan | No | Present only when preview=true. Describes what the call would do. |
| status | Yes | registered = schema written to the event log; preview = plan computed without writing any event (preview=true was set). |
| version | Yes | The registered schema version. |
| warnings | No | Non-fatal advisory warnings. MAZ-SCHEMA-001 = supersede; MAZ-SCHEMA-002 = orphaned fields. |
| schemaKind | Yes | The registered schema kind identifier. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does reasonably well: it discloses that core schema kinds are protected, that E_VALIDATION is returned for non-object definitions or protected kinds, and that schemas become immediately usable via ValidateEntityProperties. It omits auth/permission requirements and doesn't describe the preview/dry-run behavior, which is only in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the core action and use cases in a compact four-sentence block. The repeated E_VALIDATION mentions are slightly redundant, but nothing is wasted at a structural level.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with an output schema present, the description covers purpose, use cases, protection rules, and error conditions. The preview parameter and version-conflict behavior are left entirely to the schema, which is acceptable given 100% schema coverage, but mentioning preview would strengthen it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all four parameters, including preview and version-conflict semantics. The description mentions the same shapes (bare camelCase or colon-namespaced, semver) but adds little beyond the schema, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Register a JSON Schema document in the dynamic-ontology schema registry.' It distinguishes the tool from siblings like defineEntityKind and definePredicate by naming the schema-kinds it applies to (entityKind:vehicle, new event types).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear contexts for use: attaching validation schemas for custom entity-kind properties, or defining schemas for new event types. It also states the 'when not' case for protected core kinds. It does not explicitly name a sibling alternative (e.g., defineEntityKind), so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteEntityA
Hard-delete an entity by ULID: removes the entity and all its derived data (relations, facts, mentions, identifiers, citations) and detaches its graph node, appending an entityDeleted tombstone to the audit log. This is for unwanted or junk entities — to consolidate DUPLICATES without losing data use mergeEntities instead. Safe default: refuses with E_VALIDATION when the entity still has active relations (so a connected entity is never dropped by accident); pass cascade=true to tombstone those relations first and proceed. Returns E_NOT_FOUND when the uid is unknown.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional free-text reason for the deletion. Surfaced in audit/log views and stamped on the cascaded relationForgotten tombstones. | |
| cascade | No | Delete the entity even when it still has active relations. When true, each active relation is first tombstoned (relationForgotten) for the audit trail, then the entity and all its remaining derived data (facts, mentions, identifiers, citations) are removed. When false (default) the delete is REFUSED if any active relation exists, so a well-connected entity is never dropped by accident — merge it with mergeEntities instead, or pass cascade to confirm. Defaults to false. | |
| entityUid | Yes | ULID of the entity to delete. Required. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the deleted entity. |
| status | Yes | Always "deleted" on success. |
| forgottenRelations | No | Number of active relations tombstoned by the cascade before the entity was removed (0 unless cascade was needed). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and does so: it discloses irreversible hard-delete scope, the safety refusal (E_VALIDATION), the E_NOT_FOUND case, tombstone/audit side effects, and that cascade tombstones relations first. That is exactly the pre-call risk context an agent needs for a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the destructive action and scope, followed by the alternative, the default safety behavior, and the error case in that priority order. Dense but every clause adds distinct decision-relevant information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers everything an agent needs before a destructive call: what is destroyed, what happens to connected data, the safe default, how to override it, which sibling to prefer, and failure modes. An output schema exists, so the description is not obliged to explain return payloads, and it doesn't waste space doing so.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description nonetheless adds semantic consequence beyond the schema by framing cascade as a confirmation gate ('pass cascade=true to tombstone those relations first and proceed') rather than just a boolean. It adds less for entityUid and reason, which the schema already documents thoroughly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+identifier type: 'Hard-delete an entity by ULID', then enumerates exactly what is removed (relations, facts, mentions, identifiers, citations, graph node, audit tombstone). It explicitly distinguishes itself from mergeEntities, so an agent can tell which destructive tool applies without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the intended case ('unwanted or junk entities') and the alternative with its condition ('to consolidate DUPLICATES without losing data use mergeEntities instead'). Also gives the operational branch: default refusal on active relations vs. cascade=true to proceed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describeTypeA
Describe a single entity kind in full: displayName, description, parent (extends), child kinds, external-vocabulary aliases (sameAs), provenance lane, and how many entities currently carry it. The deep counterpart to introspect's cheap kind index — call it to confirm a kind's shape and reuse before minting a near-duplicate with defineEntityKind, or before createEntity. Accepts a canonical name (person, user:vehicle) or a bare local name (vehicle) that resolves to the user: kind when unambiguous. Returns E_NOT_FOUND with near-name suggestions when the kind is not registered.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Entity kind to describe, e.g. person or user:vehicle. A bare local name (vehicle) also resolves to the user: kind when unambiguous. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Canonical kind name, e.g. user:vehicle. |
| parent | No | Parent kind in the subtype hierarchy (extends). Absent for root kinds. |
| sameAs | No | Alias IRIs to external vocabularies (schema.org, Wikidata, FOAF, …). |
| addedBy | Yes | Who registered the kind: seed, llm, user, or extension. |
| children | No | Registered kinds that extend this one. |
| provenance | Yes | Namespace lane: core, user, or extension:<name>. |
| usageCount | Yes | Number of entities currently carrying this kind. |
| description | Yes | One-sentence explanation of the kind. |
| displayName | Yes | Human-readable label. |
| propertySchema | No | JSON Schema for the kind's typed properties (attr_schema). Present only when the kind declares typed properties; use this to validate or populate the properties field in createEntity. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden, and it does disclose real behavior: name resolution semantics, the E_NOT_FOUND failure mode with near-name suggestions, and the depth of the returned record. It stops short of stating permission/auth requirements, which for a read tool is a minor gap rather than a serious one.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what the tool returns, then usage routing, then input resolution and error behavior — a sensible order with no filler sentences. The field enumeration overlaps with the output schema, which is slight redundancy but still aids scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read tool with an output schema and no annotations, this covers everything an agent needs: what it returns, when to prefer it over siblings, how names resolve, and what happens on failure. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description's note about a bare local name resolving to the user: kind when unambiguous largely restates the schema's own parameter description, adding little beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (describe) and resource (a single entity kind) and enumerates exactly what is returned: displayName, description, parent, child kinds, sameAs aliases, provenance lane, entity count. It explicitly differentiates itself from introspect's 'cheap kind index', so an agent can distinguish it from the sibling without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete when-to-use triggers: confirm a kind's shape and reuse before minting a near-duplicate with defineEntityKind, or before createEntity. It also names the cheaper alternative (introspect) and the condition that selects it, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dismissInsightA
Dismiss a synthesized insight the user judges wrong or unhelpful. Appends a durable insightDismissed event (the source of truth) that flips the insight to a terminal 'dismissed' state - it drops out of hot recall and is never re-promoted by access. This is NOT a decay/demotion (which the system does on its own); it records an explicit user decision and survives a rebuild. Identify the insight by insights/{uid} or a bare uid. Returns the dismissed insight's resource name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The insight to dismiss: an insights/{uid} resource name (paste a listInsights / recall hit's name) or a bare uid. | |
| reason | No | Optional free-text justification for the dismissal, retained on the event for audit. | |
| scopes | No | Scopes to resolve the insight in: project, personal, team. Defaults to project+personal. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Resource name insights/{uid} of the dismissed insight. |
| status | Yes | Always "dismissed" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and does substantial work: it discloses the durable event append, the terminal 'dismissed' state, removal from hot recall, no re-promotion by access, and survival across rebuilds. What is missing is idempotency behavior (dismissing an already-dismissed insight) and any permission/scope authorization requirements for the mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the action and followed by the state effects and the contrasting non-use case. Every sentence carries information, though the identification-format sentence partially duplicates the schema and could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with empty annotations, the description covers lifecycle effects, durability, and visibility consequences, and an output schema exists so return values need not be re-explained. The remaining hole is operational detail: error behavior for unknown or already-dismissed uids, and what 'scopes' resolution means for lookup failures.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented in the schema, including the name formats. The description repeats the 'insights/{uid} or a bare uid' identification guidance and says nothing about 'reason' or 'scopes', so it adds essentially no meaning beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb (dismiss) and resource (synthesized insight) and immediately fences off the closest conceptual neighbor: 'This is NOT a decay/demotion (which the system does on its own)'. An agent can distinguish this from system-driven insight lifecycle handling without consulting any other tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a clear trigger condition ('the user judges wrong or unhelpful') and explicitly excludes the system-managed decay case, which is the main ambiguity risk. It also tells the agent where to obtain the identifier (a listInsights / recall hit's name). It does not name a preferred alternative tool for other cases, so it falls short of a full when/when-not/alternatives treatment.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
editDocumentA
Edit a document by exact string replacement (Claude-Code Edit semantics): oldString must match the current body exactly and be unique unless replaceAll. The result is ingested as a new revision (history kept; wikilink edges re-resolved; removed links forgotten) and the vault file refreshes. Use writeDocument to replace a whole body. Result counts (edges, unresolved) are whole-document snapshots after the edit.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Vault-relative path of the document to edit. | |
| scope | No | Disambiguates when the same path exists in more than one scope. Omit when the path is unambiguous. An edit never changes a document's scope; it is preserved. | |
| newString | Yes | Replacement text. Must differ from oldString. | |
| oldString | Yes | Exact text to replace. Must match the current body exactly (including whitespace) and, unless replaceAll, be unique in it. | |
| replaceAll | No | Replace every occurrence instead of requiring oldString to be unique. |
Output Schema
| Name | Required | Description |
|---|---|---|
| file | No | Absolute path of the materialized vault file. |
| name | Yes | entities/{uid} resource name of the document-as-entity. |
| path | Yes | |
| edges | No | Total resolved wikilink and frontmatter edges the whole document holds after this write (snapshot, not a delta — counts all [[links]] in the current body that resolved, regardless of how many were already in the graph). |
| changed | Yes | False when the content matched the latest revision (no-op). |
| warnings | No | Non-fatal advisory messages — e.g. a title-collision warning when the document's display name shadows a non-document entity. Does not affect the written content; the document body is stored byte-for-byte as supplied. Omitted when empty. |
| reconciled | No | Count of wikilinks in OTHER vault documents that this write newly made resolvable (cross-document reconcile pass; separate from the document's own edge snapshot above). |
| unresolved | No | Count of [[wikilinks]] left dangling in the whole document after this write (snapshot, not a delta). |
| documentUid | Yes | |
| pendingEdit | No | True when the vault file holds an un-ingested manual edit and was left untouched. |
| revisionUid | No | |
| unresolvedTargets | No | The dangling wikilink targets by name (text inside [[…]] that matched nothing) — fix a typo or create the target. Omitted when none dangle. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does so well: it discloses that edits create a new revision, history is kept, wikilink edges are re-resolved, removed links are forgotten, and the vault file refreshes. It also explains that edges and unresolved counts are whole-document snapshots after the edit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core operation and then layers behavioral consequences and the sibling alternative in only three sentences. Every sentence adds distinct information without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although annotations are absent, the description explains the side effects an agent most needs to know for a mutation: revision history, link re-resolution, and refresh behavior. Because an output schema exists, it need not fully describe return values, and its note about result counts is sufficient context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters already carry their own documentation in the input schema. The description repeats the key oldString uniqueness rule and replaceAll behavior but does not add syntax or format detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: editing a document by exact string replacement. It immediately distinguishes this from whole-body replacement by naming writeDocument in the next sentence, so an agent can select it without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly contrasts the tool with writeDocument, giving the alternative and the condition that selects it: use writeDocument to replace a whole body. The uniqueness and replaceAll rules further clarify when the edit will be accepted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
entitiesA
List and filter entities by kind, name substring, and confidence, with pagination. LLM-free discovery surface: find an anchor here, then pivot into neighbors/relations. sortBy=recallCount returns the most-recalled entities (replaces listTopEntities). Spot a duplicate of the same real-world thing? Consolidate the pair with mergeEntities (lossless); remove a junk entity with deleteEntity.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Filter to one entity kind, e.g. person, place, organization. See introspect for the kinds present. | |
| limit | No | Maximum entities to return. Defaults to 50. | |
| filter | No | AIP-160 filter expression, AND-combined with the other params. Reference entity columns (kind, displayName, confidence, resolutionStatus, createTime), the short alias status for resolutionStatus (values: resolved, confirmed, tentative, split_candidate, deleted), an entity's fact slots by state_key, and related("predicate", "target"). Operators: = != < > <= >= : (substring) with AND / OR / NOT and parentheses. OR binds tighter than AND. Example: kind = "person" AND status = "resolved" AND related("works_at", "Mithril"). Applies to the default sortBy=recent. | |
| offset | No | Pagination offset (recent sort only). Defaults to 0. | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. | |
| sortBy | No | Ordering. "recent" (default) = newest first. "recallCount" = most-recalled first (requires usage stats). | |
| window | No | Aggregation window for sortBy=recallCount. Defaults to last7Days. | |
| nameLike | No | Case-insensitive substring match on display name. | |
| nameExact | No | Case-insensitive exact match on display name (unbounded; takes precedence over nameLike). Use this to resolve a known name to its entity. | |
| minConfidence | No | Drop entities below this resolution confidence. |
Output Schema
| Name | Required | Description |
|---|---|---|
| entities | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose key traits: it is an LLM-free read/discovery surface, recallCount ordering depends on usage stats, and merge/delete are noted as separate lossless/destructive operations rather than being conflated with this tool. It stops short of stating permission or scope implications for reading across project/personal/team, which leaves a small gap for a 10-param tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the core list/filter capability, then routing and lifecycle escapes. Every sentence either defines scope or redirects to a sibling; nothing is redundant with the schema text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, and all 10 parameters are documented in-schema, making this largely sufficient for correct invocation. The remaining gap is behavioral: with an empty annotations object, the description could state read-only safety and any scope/permission caveats for cross-scope reads.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents every parameter and baseline is 3. The description adds value beyond it by explaining the intent of sortBy=recallCount (most-recalled first, and that it replaces listTopEntities) and framing the name/confidence filters as discovery levers, though it doesn't elaborate on filter syntax since the schema already does.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List and filter entities by kind, name substring, and confidence, with pagination') and immediately frames its role against siblings: an anchor-discovery surface that feeds neighbors/relations, plus explicit replacement of listTopEntities. An agent can distinguish it from query, neighbors, or relations without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing: start here to find an anchor, then pivot into neighbors/relations; use the duplicate detection path with mergeEntities and junk cleanup with deleteEntity. It also names the deprecated alternative it supersedes (listTopEntities), which is exactly the kind of when-to-use signal that prevents wrong-tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
factA
Record a scalar fact — an attribute, state, or preference — about an entity as a (subject, stateKey, value) slot, bypassing LLM extraction. The fact-shaped counterpart to relate: relate records edges between entities, fact records a single entity's slots (e.g. state.task.status=pending). A later write to the same stateKey supersedes the prior value (kept as history). Read them back via get(entities/{uid}) for the current slots, or get(facts/{uid}) for one.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Scope to write into — pick by who should see it. Defaults to personal (private to the user, syncs to their devices). Use "project" for facts tied to the current repo/codebase (shared with anyone who has repo access). Use "team" for the shared team brain (requires admitted membership, else E_PERMISSION). | |
| value | Yes | The scalar value the slot holds, e.g. "pending", "Steven". | |
| source | No | Provenance label for the appended event, e.g. "cli:fact". Optional; defaults to "mcp:fact". | |
| subject | Yes | Subject entity the fact is about: entities/{uid}, a bare ULID, the literal "self", or a human display name (resolved case-insensitively, like maz get). | |
| stateKey | Yes | Hierarchical slot address: lowercase, dot-separated, e.g. state.task.status, preference.coffee.milk. The first segment is the category (event|state|relationship|preference|plan|absence|timeless). | |
| eventStart | No | When the fact became true in the world (RFC 3339 UTC). Optional; defaults to now. | |
| sourcePriority | No | Recall-lane priority, 0..1. Optional; defaults to 1.0. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the asserted Fact; pass to get(facts/{uid}). |
| status | Yes | Always "asserted" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are empty, so the description carries the full burden, and it delivers the key non-obvious behavior: a later write to the same stateKey supersedes the prior value, which is retained as history. It also discloses that this bypasses LLM extraction. It does not cover failure modes or permission behavior beyond what the scope parameter already documents.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and slot shape, then sibling differentiation, a concrete example, supersede semantics, and read paths in that order. Every sentence carries information; nothing is restated from the schema verbatim.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter mutation tool with an output schema (so return values need not be explained), it covers the slot model, supersede/history behavior, and how to read back. Gaps are the absence of guidance on removal (retractFact) and on error/permission outcomes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces stateKey as a hierarchical slot and combines it with a sample value, but adds no format or default detail beyond what the schema already documents for scope, source, eventStart, and sourcePriority.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Record a scalar fact ... as a (subject, stateKey, value) slot') and explicitly contrasts itself with the sibling `relate`: edges between entities vs. a single entity's slots. The parenthetical example (state.task.status=pending) makes the shape unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit selection rule against `relate` and names the read path (get(entities/{uid}) for current slots, get(facts/{uid}) for a single fact). It does not mention `remember` (extraction-based writing) or `retractFact` for removal, so the when-not / deletion story is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forgetA
Forget an Episode, single Relation, or single Fact by ULID: appends a tombstone that removes derived state across the storage layers while preserving the JSONL audit trail. factUid hard-deletes a fact (state/preference) slot value — use retractFact to close a fact while keeping its history.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional free-text reason for the forget; surfaced in audit/log views. | |
| factUid | No | ULID of a single Fact (a state/preference slot value) to hard-delete. Mutually exclusive with episodeUid/relationUid. To close a fact while keeping its history, use retractFact instead. | |
| episodeUid | No | ULID of the Episode to forget. Mutually exclusive with relationUid/factUid. | |
| relationUid | No | ULID of a single Relation to forget. Mutually exclusive with episodeUid/factUid. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the forgotten Episode, Relation, or Fact. |
| status | Yes | Always "forgotten" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description does useful behavioral work: it discloses tombstoning, derived-state removal across storage layers, audit-trail preservation, and hard deletion for factUid. It does not discuss permissions, confirmation, or broader irreversibility beyond the fact case.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences front-load the core action and then add the important factUid exception. There is no filler, and the alternative is placed where it matters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich schema and existing output schema, the description is nearly complete: it covers the operation's storage effect and the key retractFact alternative. Minor gaps around permissions or confirmation are acceptable because the schema and annotations carry most structural details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters, including mutual exclusivity and the factUid/retractFact distinction. The description reinforces the ULID-based selection model but adds little parameter meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource scope: forget an Episode, Relation, or Fact by ULID. It also distinguishes the factUid hard-delete path from retractFact, so an agent can differentiate this tool from a key sibling without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context for fact deletion by explicitly naming retractFact as the alternative when history should be kept. It does not fully address when to use forget versus relation-specific siblings such as unrelate, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getA
Fetch one record by AIP resource name — entities/{uid}, episodes/{uid}, relations/{uid}, facts/{uid}, insights/{uid}, or consolidatedMemories/{uid} — plus its provenance lineage. For an entity you may also pass a bare uid or a human display name (resolved case-insensitively, the same forms relations/neighbors accept). When a name is shared across kinds, a non-document entity deterministically wins over a same-named document — the passed-over document(s) are surfaced in shadowedDocuments as entities/{uid} you can fetch directly; pass kind to target a specific kind, or a vault path / entities/{uid} to address a document. A name that is ambiguous among non-document entities (or unknown) returns a pointed error naming the candidates. The structured, LLM-free way to follow any recall hit's name field. Returns a discriminated union tagged by type. An entity record returns the canonical node (uid, kind, displayName, confidence, resolutionStatus) AND its typed properties, external identifiers, and currently-open scalar facts. A relation record carries hydrated endpoints + validity. An episode carries its source text. An insight (type=insight) returns the synthesized statement, insightType, currentConfidence, state, synthesizedAt, and its sourceUids as entities/{uid} citations. A consolidated memory (type=consolidatedMemory) returns the compressed summary, memoryType, confidence, consolidatedAt, and its sourceUids as episodes/{uid} citations. Demoted insights (state='demoted') are still fetchable — get is not the hot-recall index.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | Valid-time anchor (RFC 3339 UTC) for an entity record's fact rows: return each slot's value live at this instant. Defaults to now. Does not move the entity identity row; ignored for non-entity records. | |
| asOf | No | Transaction-time anchor (RFC 3339 UTC) for an entity record's fact rows: hide facts recorded after this instant. Ignored for non-entity records. | |
| kind | No | Optional entity kind hint (e.g. 'document', 'person', 'product'). When supplied alongside a display name, narrows the resolution to entities of that kind only. Useful when a name is shared between a document and a domain entity and you want the document specifically. Ignored for resource-name lookups (entities/{uid}) and bare uid lookups. | |
| name | Yes | What to fetch: an AIP resource name whose collection prefix routes the lookup (entities/{uid}, episodes/{uid}, relations/{uid}, facts/{uid}, insights/{uid}, or consolidatedMemories/{uid}) — feed one straight from a recall hit's name field — OR, for an entity, a bare uid or a human display name (resolved case-insensitively, like relations/neighbors). A non-entity record must use its collection prefix. | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. | |
| includeInactive | No | Include superseded / expired facts (the full slot history) on an entity record. Off by default. Ignored for non-entity records. |
Output Schema
| Name | Required | Description |
|---|---|---|
| fact | No | Present when type=fact. A scalar state slot: subjectUid, stateKey, value, validity window. |
| type | Yes | Which record kind this response carries. |
| facts | No | Present when type=entity: the entity's currently-open scalar facts (its attributes), newest slot value per state_key. Empty when the entity has none. |
| entity | No | Present when type=entity. The canonical node: uid, kind, displayName, confidence, resolutionStatus, and (when createEntity stored them) a 'properties' object of typed attributes validated against the kind's propertySchema. Its scalar facts (status, first name, preferences) arrive in the sibling 'facts' array; its external identifiers (hrb, email, …) in the sibling 'identifiers' array; its edges (who it connects to) live on relations — call relations or neighbors for those. |
| episode | No | Present when type=episode. |
| insight | No | Present when type=insight. A synthesized reflection: statement, insightType, currentConfidence, state (hot|demoted), synthesizedAt, and sourceUids typed as entities/{uid} citations. |
| relation | No | Present when type=relation. Carries subject/object resource names for onward traversal, plus a 'status' trust posture: 'asserted' (authoritative) or 'proposed' (extracted from an untrusted connector source — excluded from supersession until promoted via 'maz promote' / the promoteRelation tool). |
| provenance | No | Source/confidence/decided-at lineage walked back to the record's origin episode(s): direct for an episode, via source_event_uid for a relation, aggregated across citing episodes for an entity. Empty when none recorded. |
| identifiers | No | Present when type=entity and the entity has external identifiers: the strong/weak identifiers (type + value, e.g. {type:"hrb",value:"HRB 12345 B"}) that anchor it for the resolver. Omitted when none. |
| shadowedDocuments | No | Present when the name argument was resolved by display name AND one or more document entities share that name but were passed over in favour of a higher-priority non-document entity. Each entry gives the document's entities/{uid} resource name (ready to pass to get) and its bare uid. Omitted when the lookup was by resource name or uid, or when no document shares the winner's display name. |
| consolidatedMemory | No | Present when type=consolidatedMemory. A compressed episode summary: summary, memoryType, confidence, consolidatedAt, and sourceUids typed as episodes/{uid} citations. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden, and it does substantial work: it discloses the resolution precedence (non-document entity beats same-named document), that passed-over documents appear in `shadowedDocuments`, that ambiguous non-document names return a pointed error naming candidates, and that demoted insights remain fetchable. It never states permission/scope requirements around the `scopes` default or side-effect freedom beyond what 'get' implies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded correctly, leading with the fetch action and the accepted name forms, but the back half is a long per-type enumeration of returned fields (insight statement/insightType/state, consolidated memory summary/memoryType, etc.) that duplicates what the output schema already declares. That block is padding against a tool that has an output schema and dilutes the high-value resolution rules.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given six parameters, no annotations, and an existing output schema, the description covers everything an agent needs to call it correctly: accepted name forms, resolution precedence, the ambiguity error path, scope semantics, and temporal anchors by reference to the schema. Nothing required for a correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns above that by adding resolution semantics the schema does not state — case-insensitive display-name resolution, the entity-over-document precedence rule, and the fact that `kind` is ignored for resource-name and bare-uid lookups. It leaves `at`, `asOf`, `scopes`, and `includeInactive` entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb+resource ('Fetch one record by AIP resource name') and enumerates the exact collection prefixes the lookup accepts. It also positions itself against the sibling recall tool ('the structured, LLM-free way to follow any recall hit's name field' ... 'get is not the hot-recall index'), so an agent can pick between them without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is clear: use this to resolve a name coming out of a recall hit, and use `kind` / a vault path when a document and a domain entity share a name. It stops short of an explicit exclusion sentence (e.g. 'to search by content or filter by user, use recall/query instead') and gives no guidance on when to prefer the sibling `entities`, `relations`, or `fact` readers over this one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getBacklinksA
List a document's wikilink edges without its body: backlinks (notes/entities that reference it) and links (what it references). The fast way to map a note's place in the graph. Identify the document by path or documentUid.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Vault-relative path of the document. Provide this OR documentUid (exactly one). | |
| documentUid | No | Stable document UID. Provide this OR path (exactly one). |
Output Schema
| Name | Required | Description |
|---|---|---|
| links | Yes | Outgoing edges — what this document references. Always present; [] when none. |
| backlinks | Yes | Incoming edges — documents/entities that reference this one. Always present; [] when none. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose a key behavioral trait: the document body is deliberately excluded, so only edges are returned. It also explains the semantics of each returned field, though it says nothing about permissions, dangling/unresolved links, or ordering.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: what it returns, why it's useful, and how to identify the target. The scope qualifier and payoff are front-loaded, and no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, fully documented read tool with an output schema, the description covers purpose, return shape, and identification well. Remaining gaps (link resolution behavior, whether backlinks include entity references, permissions) are minor but not trivial for graph tooling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema itself already states the exactly-one constraint between path and documentUid. The description's final sentence repeats that same rule without adding format or resolution guidance, so it merely matches structured data rather than exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List a document's wikilink edges') and enumerates the two edge categories returned (backlinks, links). The clause 'without its body' distinguishes it from readDocument/get, and 'the graph' framing separates it from the entity-oriented relations/neighbors tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'The fast way to map a note's place in the graph' gives clear context for when to reach for it versus the heavier document readers. It does not name an explicit alternative or state exclusions, so it falls short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCapacityA
Return per-storage-layer on-disk byte totals: event log, sqlite+fts, graph, vector index, embedding cache, plus free disk.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| onDisk | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. The verb "Return" strongly implies a read-only operation and there are no parameters that could mutate state, but the description does not explicitly confirm read-only behavior, side effects, authorization needs, or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence that states the return scope immediately. The enumerated storage layers earn their place by making the output scope concrete, with no wasted wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with an output schema, the description is largely complete: it explains what gets returned and the output schema can define the exact response shape. The only gap is the lack of explicit read-only or safety framing, which is more noticeable because annotations are empty.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter semantics for the description to explain. The schema coverage is 100%, and the baseline for no-parameter tools is a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: it returns on-disk byte totals by storage layer. It enumerates the exact layers covered plus free disk, which makes the tool's scope unambiguous and distinguishable from the sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states what the tool returns but gives no explicit guidance on when to use it, when not to use it, or what alternative to prefer. Usage is only indirectly implied by the tool name and the capacity-related return fields.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getContextA
Assemble a token-budgeted markdown brief of the user's working set — pinned documents, recently-updated documents, key entities, and (when you pass a query) the most relevant hits — for loading at the start of a session. Deterministic and fast (no LLM). The brief never exceeds budgetTokens; lower-priority content is dropped behind a visible marker. Prefer this over many small reads when you need to warm up context about the user.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Optional focus. When set, the brief adds a section of the most query-relevant hits (documents + episodes), co-ranked by the same recall used by recall/ask. | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. | |
| budgetTokens | No | Token budget for the brief (default 4000). The brief never exceeds it; the lowest-priority tail is dropped behind a marker. |
Output Schema
| Name | Required | Description |
|---|---|---|
| budget | Yes | The token budget that was applied. |
| tokens | Yes | Estimated token count of the brief (always <= budget). |
| dropped | No | How many lower-priority items were omitted to fit the budget. |
| markdown | Yes | The assembled context brief as markdown: pinned documents, recently-updated documents, key entities, and (when a query is given) relevant hits. Load this verbatim at session start. |
| sections | No | Per-section counts of what made it into the brief. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose key traits: deterministic, no LLM call, hard budget cap, and visible truncation markers. It doesn't explicitly state that it is a read-only operation with no side effects, which is the main remaining safety question for an agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight sentences; the purpose is front-loaded, then behavior, then the routing hint. Every sentence carries distinct information with no restatement of the name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and the return format (markdown brief) is already characterized, so the description needn't explain return values. For a zero-required-parameter tool with full schema coverage, the description covers purpose, budget behavior, and session-start usage — nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description reinforces the effect of `query` (adds a co-ranked relevance section) and `budgetTokens` (never exceeded, tail dropped behind a marker), but adds little beyond what the schema descriptions already say, and `scopes` semantics are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Assemble a token-budgeted markdown brief of the user's working set') and enumerates exactly what goes into the brief: pinned docs, recently-updated docs, key entities, and query-relevant hits. An agent can distinguish this from recall/readDocument/listDocuments siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a clear usage context ('for loading at the start of a session') and an explicit preference rule ('Prefer this over many small reads when you need to warm up context about the user'). It doesn't name specific sibling tools (recall, readDocument, query) or state when not to use it, which keeps it short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getEntityContextA
Assemble a single token-budgeted markdown dossier for ONE entity, collapsing what otherwise takes five calls (get + relations + neighbors + recall + facts) into one card. The dossier carries a header (name, kind, entities/{uid}, resolution status), Connections (the entity's typed relations as direction-aware predicate fragments), What I know (its scalar facts), Mentioned in (recall hits naming it), and a counts footer. Pass entity as an entities/{uid} resource name, a bare uid, a display name (resolved case-insensitively), or self. Use at (RFC 3339) to time-slice the relations + facts to a past instant; the header is unchanged. The card never exceeds tokenBudget; lower-priority bullets are dropped behind a marker. An unknown entity returns E_NOT_FOUND; an ambiguous display name returns E_VALIDATION naming the candidates. Prefer this over many small reads when you need the full picture of one entity.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | Valid-time anchor (RFC 3339 UTC): return the Connections and What-I-know rows as they were live at this instant. Defaults to now. Per ADR-0001 the anchor binds the relation + fact sub-queries only; the entity header (identity) is unchanged. | |
| entity | Yes | Which entity to profile: an entities/{uid} resource name (feed one straight from a recall hit's entities[] / name), a bare uid, a human display name (resolved case-insensitively), or 'self'. An ambiguous name returns E_VALIDATION naming the candidates; an unknown one returns E_NOT_FOUND. | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. | |
| include | No | Optional section filter. Omit for all three sections; pass a subset (e.g. ["facts"]) to narrow the card. The entity header and footer always render. | |
| tokenBudget | No | Token budget for the dossier (default 4000). The card never exceeds it; the lowest-priority bullets are dropped behind a marker, then a counts footer is appended. |
Output Schema
| Name | Required | Description |
|---|---|---|
| budget | Yes | The token budget that was applied. |
| tokens | Yes | Estimated token count of the dossier (always <= budget). |
| dropped | No | How many lower-priority bullets were omitted to fit the budget. |
| markdown | Yes | The entity dossier as markdown: a header (name · kind · entities/{uid} · resolution), Connections (typed relations as direction-aware predicate fragments), What I know (the entity's scalar facts), Mentioned in (recall hits naming it), and a counts footer '_N relations, M facts · budget X · used Y_'. Load this verbatim instead of issuing get + relations + neighbors + recall + facts separately. |
| sections | No | Per-section counts of what made it into the dossier. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the behavioral burden. It discloses truncation behavior ('lower-priority bullets are dropped behind a marker'), time-slice semantics ('header is unchanged'), and error contracts ('E_NOT_FOUND' for unknown, 'E_VALIDATION' naming candidates for ambiguous names). It also defines the dossier's structure (header, Connections, What I know, Mentioned in, counts footer).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and every sentence contributes useful information. The description is dense but appropriately sized for a composite tool with five parameters, though it could be slightly tighter by avoiding restatement of schema details such as entity formats and budget truncation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers the critical dimensions: what the dossier contains, how time-slicing behaves, how truncation works, and what errors to expect. An output schema exists, so return-value formatting need not be explained further. The definition is complete enough to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter in detail, including accepted `entity` formats, `at` time semantics, `scopes` defaults, `include` filtering, and `tokenBudget` truncation. The description largely restates that information rather than adding new parameter-level meaning, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Assemble a single token-budgeted markdown dossier for ONE entity.' It immediately distinguishes itself from siblings by naming the five calls it collapses (get + relations + neighbors + recall + facts) and explicitly says to prefer it over 'many small reads' for a full picture. An agent can tell exactly what this tool does and that it is a composite read.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is explicit: use it when you need the full picture of one entity instead of many small reads. It also names the alternative pattern ('many small reads') and explains the section-filtering option via `include`, plus the time-slicing use case via `at`. No major inference is required to choose this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getSourceRefA
Fetch one external-source provenance record (SourceRef) by AIP resource name sourceRefs/{uid}. A SourceRef records what a memory was derived from — the connector, stream, external id/url, content hash, and fetch time (W3C PROV wasDerivedFrom). Its provenance is SELF-ASSERTED and UNVERIFIED (trustState is always "unverified"): there is no cryptographic attestation of the external claim yet. Use recordSourceRef to create one.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | AIP resource name to fetch: sourceRefs/{uid}. The uid is the SourceRef ULID returned by recordSourceRef. | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. |
Output Schema
| Name | Required | Description |
|---|---|---|
| uid | Yes | SourceRef ULID identity. |
| name | Yes | AIP resource name of this SourceRef. |
| scope | No | Scope this SourceRef lives in: personal, project, or team. |
| stream | No | Sub-channel within the connector. Omitted when absent. |
| dedupKey | Yes | Idempotency key for the source_refs projection. |
| connector | No | Connector that produced the reference, e.g. gmail, slack. Omitted when absent. |
| fetchTime | Yes | When the source content was fetched (RFC 3339 UTC). |
| createTime | No | When the SourceRef event was recorded (RFC 3339 UTC). |
| externalId | No | Source-system opaque identifier for the item. Omitted when absent. |
| sourceType | Yes | Kind of external source (open taxonomy), e.g. email, slack_message, web_page. |
| subjectUid | Yes | ULID of the record this source was derived from (PROV wasDerivedFrom). |
| trustState | Yes | Provenance is self-asserted by the appending device and is NOT cryptographically verified. No principal/signature trust exists for a SourceRef yet (#207). |
| contentHash | No | Appender-supplied SHA-256 hex of the fetched content. Omitted when absent. |
| externalUrl | No | Dereferenceable location of the source item. Omitted when absent. |
| sourceEventUid | Yes | UID of the sourceRefRecorded event that carried this record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does real work: it discloses that provenance is SELF-ASSERTED and UNVERIFIED, that trustState is always 'unverified', and that no cryptographic attestation exists. That is exactly the kind of trust caveat an agent would otherwise mishandle. It stops short of stating read-only semantics explicitly or what happens when the name does not resolve.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the verb and resource path, then the domain explanation, then the sibling pointer. No filler and no repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the schema fully covers both parameters including scope defaults. What remains unaddressed is failure behavior for an unknown or unreachable sourceRefs name, which matters slightly for a name-pattern-constrained lookup.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both `name` (with its ULID pattern) and `scopes` are already fully documented in the schema. The description restates the sourceRefs/{uid} shape but adds no new meaning about scopes or identifier provenance, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Fetch') and a precisely bounded resource ('one external-source provenance record (SourceRef) by AIP resource name sourceRefs/{uid}'). It then explains what a SourceRef actually is (connector, stream, external id/url, content hash, fetch time), which distinguishes it cleanly from siblings like get, recall, or listSources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only routing guidance is the closing sentence 'Use recordSourceRef to create one,' which correctly points at the sibling for the write direction. There is no guidance on when to call this versus other read tools (get, getContext, recall, getBacklinks) that might also surface provenance, nor any when-not condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getUsageSnapshotA
Return the current usage snapshot: events written, recalls performed, embed-cache hit rate, recall latency percentiles.
| Name | Required | Description | Default |
|---|---|---|---|
| window | No | Aggregation window. Defaults to "today" when omitted. |
Output Schema
| Name | Required | Description |
|---|---|---|
| events | Yes | |
| window | Yes | |
| recalls | Yes | |
| bytesIngested | No | |
| embedCacheHits | No | |
| embedCacheMisses | No | |
| embedCacheHitRate | No | |
| recallLatencyP50Ms | No | |
| recallLatencyP95Ms | No | |
| recallLatencyP99Ms | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. 'Return' weakly implies a read-only operation, and enumerating the metrics tells the agent what kind of data comes back, but it says nothing about snapshot freshness, cost, permissions, or whether 'current' means pre-aggregated versus computed live — the main behavioral unknown for a telemetry tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the verb and resource, followed by a compact enumeration of the returned metrics. Nothing is redundant or padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return shapes need not be spelled out, and the description still names the key metrics. What's missing is only the relationship to similarly-scoped siblings (getCapacity) and any note on snapshot recency, which is a modest gap for a read-only telemetry tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single 'window' parameter is fully documented with its enum and default ('today'), so the baseline is 3. The description adds no meaning about how window affects aggregation or which window the metrics default to, so it neither compensates nor detracts.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Return') and resource ('current usage snapshot') and enumerates the exact metrics returned (events written, recalls, embed-cache hit rate, recall latency percentiles). It does not, however, distinguish itself from the closely related sibling getCapacity, which an agent could easily confuse with a usage/telemetry call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the enumerated metrics suggest 'call this to read telemetry', but there is no explicit when-to-use statement, no exclusion, and no pointer to alternatives such as getCapacity or idleStatus. The agent must infer the choice from the metric list alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
idleStatusA
Return current background-work counters: extraction queue depth, in-flight enrichment, in-flight embeddings. Use to poll whether the kernel has caught up after a burst of remember() calls, before calling recall() for a clean retrieval measurement.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| isIdle | Yes | True when every background lane reports 0 in-flight work. |
| vecInflight | Yes | Background embedding+vec0-upsert goroutines currently running. When 0 the vector side is quiescent. |
| enrichmentInflight | Yes | Total background enrichment work in flight (queued + running). When 0 the extraction/resolution side is quiescent. |
| enrichmentQueueDepth | Yes | Jobs sitting in the bounded extraction worker pool, not yet picked up by a worker. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does so adequately: 'Return' plus 'current ... counters' plus 'poll' makes clear this is a non-blocking read-only snapshot rather than a mutation or a blocking wait. What remains implicit is that it does not wait for idle and returns immediately even when work is pending, which is the one behavioral trait that would most change how an agent sequences the call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler. The return contents come first and the usage scenario second, so the agent gets the 'what' before the 'when'. Every clause carries information: each of the three counters is named, and the remember()/recall() context is specific rather than generic.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description is not obligated to explain the return shape, and with no parameters and no annotations this is a low-complexity tool that the text covers well. The only material omission is the relationship to waitForIdle — whether to poll this or block on that — which is exactly the decision an agent faces when background work is in flight.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate and no risk of undocumented inputs. Baseline for a no-param tool is 4, and the description does nothing to lower it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return current background-work counters') and enumerates exactly which counters: extraction queue depth, in-flight enrichment, in-flight embeddings. That is far more precise than the bare name idleStatus. It stops short of a 5 because it never names its obvious sibling waitForIdle, so the agent must infer the polling-vs-blocking split from the surrounding tool list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete usage scenario: poll after a burst of remember() calls, before recall(), for a clean retrieval measurement. That is real when-to-use guidance tied to named siblings. It offers no when-not or exclusion, and does not say why an agent would poll here rather than call waitForIdle, which is the main alternative an agent would weigh.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ingestSourceA
Ingest the delta from a previously connected source, resuming from its saved watermark (cheap incremental pull). Give a connector (local-git, claude-chats, or granola) and, for the file-based ones, repoPath (granola uses a stored API key instead); optionally scope (personal|team), dryRun, maxItems, and maxExtractionCalls. Idempotent: unchanged items are skipped by content hash. Returns a run report with a jobUid. Refuses project scope.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Scope to ingest into. Defaults to personal. Project scope is refused: ingested external content is sensitive and project is plaintext. | |
| dryRun | No | Preview only: validate the source and count would-be items WITHOUT writing anything (the consent gate). | |
| maxItems | No | Cap on items considered this run (backfill bound). Defaults to 500. | |
| repoPath | No | Source locator for file-based connectors: a local git repository path (local-git), or an export file path (claude-chats: a .zip bundle or a conversations.json). Omit for granola, which authenticates with a keychain API key (set it via 'maz source add granola'). | |
| connector | Yes | Source connector name. Supported: local-git, claude-chats, granola. | |
| maxExtractionCalls | No | Cap on episodes appended this run, each one downstream extraction. Defaults to 500. |
Output Schema
| Name | Required | Description |
|---|---|---|
| dryRun | No | |
| jobUid | No | Job UID; pass to listJobs / cancelJob to track or cancel a long backfill. |
| streams | No | |
| connector | Yes | |
| itemsApplied | Yes | Items turned into episodes (or, in a dry run, that WOULD be). |
| itemsSkipped | Yes | Items skipped because their content hash was unchanged (idempotent re-ingest). |
| episodesAppended | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does most of it well: it discloses that the tool writes data, that it is idempotent via content-hash comparison, that project scope is refused and why (plaintext vs. sensitive external content), the default caps, and that dryRun acts as a consent gate. The gap is job lifecycle — it returns a jobUid but doesn't say whether the run is synchronous or must be polled via listJobs/waitForIdle, nor what failure mid-ingest leaves behind.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and its incremental nature, then moves to inputs, then to guarantees and return value — a sensible order. Dense but nearly every clause carries information; the stacked parentheticals in the parameter sentence make it slightly harder to scan than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter mutation with an output schema, this covers prerequisite state, connector-specific setup, scope safety, defaults, and idempotency — enough to invoke correctly. What's missing is how the returned jobUid is meant to be used (job tracking via the sibling job tools), which matters given the ingest is potentially long-running and bounded by maxItems/maxExtractionCalls.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description adds real meaning by grouping parameters by connector type (repoPath applies to file-based connectors, omitted for granola) and by characterizing dryRun as a consent gate and maxItems as a backfill bound. It also flags the one hard constraint that matters most — scope only accepts personal/team and project is refused — before the agent reads the enum. Minor redundancy with the schema's own descriptions keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Ingest the delta from a previously connected source, resuming from its saved watermark") and immediately frames the operation as incremental rather than full-sync. The phrase "previously connected source" distinguishes it from connectSource, and the connector list makes the operating domain concrete without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear selection context: use this for a cheap incremental pull against an existing connection, with an explicit exclusion ("Refuses project scope") and per-connector setup guidance (granola needs a keychain key set via 'maz source add granola', file-based ones need repoPath). It never names what to call when no source is connected yet (presumably connectSource) or how to follow up on the returned jobUid, so the alternative-routing guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
introspectA
Return the ontology you navigate by: the registered relation predicates (edge vocabulary, with functional/non-functional semantics), the entity kinds present (node vocabulary with live counts, plus taxonomy metadata — displayName, description, provenance namespace, extends/parent hierarchy, sameAs external URIs — for kinds in the registry), a namespaces summary (core/user/extension: buckets), and the event types recorded. Custom kinds added at runtime appear under the user or extension: provenance namespace. Call once to learn the vocabulary before filtering neighbors/relations/entities. NOTE: this lists what has been registered or extracted, so it can include rarely- or never-populated predicates — e.g. a role/title is usually an attributes.role string on a works_at/founded edge rather than a populated has_role edge — so confirm a predicate is actually in use (via relations) before relying on it. LLM-free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| views | Yes | Curated read-only views for the query tool — the stable SQL schema. Query these names, not the physical tables. |
| eventTypes | Yes | Registered event-schema kinds the store records. Empty when no ontology registry is wired. |
| namespaces | Yes | Provenance namespaces aggregated from the registered entity kinds: core (built-in), user (manually added), extension:<name> (plugin-contributed). Predicate provenance joins in a later phase. |
| predicates | Yes | Registered relation predicates — the edge vocabulary for neighbors/relations filtering. |
| entityKinds | Yes | Entity kinds present in the store or registered in the taxonomy, with live counts and optional taxonomy metadata. Includes registered-but-zero-count kinds (e.g. core kinds not yet ingested). Custom kinds added at runtime appear in user or extension namespaces. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the behavioral burden and does well: it explains provenance namespace behavior, live counts, taxonomy metadata, and the caveat that registered predicates may be unused. It does not explicitly state permissions or side effects, though 'Return' and 'LLM-free' strongly imply a safe read-only operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and every clause contributes useful information. The first sentence is long and dense with nested parentheticals, which slightly reduces readability, but it remains efficient for a complex ontology introspection tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not fully explain return values. Given that, it provides complete context: what is returned, how custom kinds appear, when to call it, and a caution about unused predicates.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and full schema coverage, so parameter semantics are not a concern. The baseline for a parameterless tool is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb, 'Return', and a concrete resource, 'the ontology you navigate by', then enumerates relation predicates, entity kinds, namespaces, and event types. It also distinguishes the tool's role by saying to call it before filtering neighbors/relations/entities, making it clearly identifiable among siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly advises calling once to learn the vocabulary before filtering neighbors/relations/entities, and it points to relations as the way to confirm a predicate is actually in use. It lacks an explicit when-not statement, so it falls short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lintDocumentsA
Run a read-only health check over the markdown vault: orphans (no graph edges), deadLinks (unresolved [[wikilinks]]), contradictions (contradicts edges), danglingEdges (live link to a deleted doc), nearDuplicates (pairs of docs whose chunk embeddings exceed cosine 0.92, non-blocking lint signal only), and nameCollisions (documents whose title shadows a non-document entity of the same display name — wikilink resolution silently favours the entity). Takes no arguments; scans the whole vault.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| orphans | Yes | Documents with no inbound or outbound graph edges (isolated notes). |
| deadLinks | Yes | Documents that still carry an unresolved [[wikilink]]; each entry's 'unresolved' array names the exact target strings that resolve to nothing. |
| danglingEdges | Yes | Active links from a live document to a DELETED document (a backlink left behind when deleteDocument tombstoned its target). Each entry carries the live 'subjectPath' and the deleted 'targetPath'/'targetTitle' it still points at, so the fix is 're-point or remove the link in subjectPath'. |
| contradictions | Yes | Document pairs joined by an active contradicts edge. |
| nameCollisions | Yes | Documents whose title (display name) shadows a non-document entity with the exact same name. Wikilink resolution silently favours the non-document entity in this case; use the vault path or a kind qualifier to disambiguate. |
| nearDuplicates | Yes | Pairs of live documents whose chunk embeddings are suspiciously similar (cosine >= 0.92). Non-blocking lint signal only — does NOT prevent writes or imports. Each pair is reported once. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the disclosure burden and does well: it declares the operation read-only, notes that it scans the entire vault (a cost signal), and flags `nearDuplicates` as "non-blocking lint signal only" so the agent won't treat it as an error. It does not quantify scan cost or note whether results stream or are returned in one payload, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence that front-loads the action, then lists categories with backticked names and tight parenthetical definitions. The final independent clause carries the scope/arity constraint. No sentence is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the read-only, whole-vault, no-argument contract is fully stated. The only material gap is the absence of any indication of runtime cost or result-volume expectations for a full-vault scan, which matters for an agent deciding when to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no schema semantics to add; the description correctly confirms "takes no arguments" and explains that scope is implicitly the whole vault. Baseline 4 applies for a 0-param tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("run a read-only health check over the markdown vault") and then enumerates all six check categories with a definition of each, including the precise thresholds (`cosine 0.92`). An agent knows exactly what this tool inspects and can distinguish it from `listInsights` or `listDupCandidates` at a glance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the tool's nature (a health check) and the scope note "takes no arguments; scans the whole vault" clarifies it is an all-in-one sweep. However, it never states when to prefer this over related siblings like `listDupCandidates` (overlapping with `nearDuplicates`) or `listInsights`, and offers no when-not guidance for large vaults.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listDocumentsA
List vault documents, most-recently-updated first, filtered by pathPrefix, tag, and/or pinned. Bodies are omitted to stay lightweight; call readDocument for one document's full body and edges.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Restrict to documents whose frontmatter tags include this value. | |
| limit | No | Max documents to return (default 50). | |
| pinned | No | When true, only pinned documents. | |
| pathPrefix | No | Restrict to documents whose path starts with this prefix, e.g. notes/. |
Output Schema
| Name | Required | Description |
|---|---|---|
| documents | Yes | Matching documents, most-recently-updated first. Bodies are omitted; call readDocument for the full body. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description still discloses two meaningful traits: results are sorted by recency, and bodies are omitted to keep responses lightweight. It does not discuss pagination behavior or what happens when limit is exceeded, but with an output schema present that burden is partly absorbed elsewhere.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both load-bearing: the first defines scope and ordering, the second defines what is returned and where to go for more. No filler and the key scoping constraint is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-param optional-filter list tool with a 100%-covered schema and an output schema, this covers scope, ordering, and payload shape. The only gap is pagination/limit interaction, which the schema's defaults and maximum largely cover.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter's meaning is already documented. The description adds only that filters are optional and combinable ('and/or'), which is marginal value on top of an already complete schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (list vault documents) plus the ordering guarantee (most-recently-updated first) and the filter set. It also names the sibling readDocument, so an agent can tell listing apart from fetching a single document without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: use this to enumerate, call readDocument when a full body and edges are needed. That is a clear when-to-use plus named alternative, though it gives no guidance on when this tool is the wrong choice versus query/recall-style siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listDupCandidatesA
List entity pairs the post-consume dedup sweep flagged as likely cross-device duplicates. Auto-merged strong-identifier pairs (same email / username) are not included — only advisory candidates that need human review. Call mergeEntities on a pair to consolidate; use maz review dups for the interactive CLI view.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | Total candidate count (may exceed the 200-row page). |
| candidates | Yes | Entity pairs flagged by the post-consume dedup sweep after cross-device sync. Auto-merged strong-identifier pairs (email, username) do not appear here — they are already consolidated. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose key traits: results are advisory-only ('need human review'), auto-merged pairs are filtered out, and the source is a post-consume sweep. It leaves unstated that the operation is read-only, whether the list is paginated or how fresh it is, which keeps it out of the top band.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the primary scope and followed by the exclusions and next action. Every clause earns its place; nothing is repeated from the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A simple 0-param read whose return values are covered by the output schema, so the description only needs scope and follow-up — both present. Minor gap: no statement of read-only safety or whether an empty list is a normal outcome, which matters given the absent annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate beyond what the empty schema already shows. Baseline for a 0-param tool applies; no param text is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb + resource with full scope: 'List entity pairs the post-consume dedup sweep flagged as likely cross-device duplicates.' It even carves out what is excluded (auto-merged strong-identifier pairs), so an agent can distinguish this from mergeEntities or listInsights without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent forward: 'Call mergeEntities on a pair to consolidate' and names an alternative surface ('maz review dups for the interactive CLI view'). It does not state a when-not-to-use condition (e.g., after a full merge pass), but the follow-up path is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listInsightsA
List synthesized insights by lifecycle state - the Insight Inbox read surface. Defaults to the hot (live, recall-visible) insights, most-confident first, each carrying its statement, confidence, lifecycle state, and the entity source records it cites (as entities/{uid} citations plus a count). Pass state=demoted, state=dismissed, or state=all to review the rest. Pair with get(insights/{uid}) to inspect one, dismissInsight to dismiss one, and triggerReflection to synthesize more.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum insights to return. Defaults to 50. | |
| state | No | Which insights to list. "hot" (default) = live, recall-visible insights. "demoted" = decayed out of hot recall. "dismissed" = explicitly dismissed by the user (terminal). "all" = every state. | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. |
Output Schema
| Name | Required | Description |
|---|---|---|
| insights | Yes | Insights in the requested state, most-confident first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses the read-only nature, the default filter, the sort order (most-confident first), and what each row contains. It stops short of stating permission requirements or pagination behavior beyond the limit parameter, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and default, then alternatives, then sibling pairings — a logical order. The parenthetical about citation format is slightly dense but still earns its place by clarifying output shape.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with a full output schema and 100% schema coverage, the description supplies everything an agent needs: default behavior, state alternatives, ordering, and the sibling workflow. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the state enum is fully documented in the schema, so the description's restatement of state values adds little. It does reinforce the default and the ordering, but limit and scopes semantics come entirely from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) plus resource (synthesized insights) and scope (by lifecycle state), and explicitly frames itself as 'the Insight Inbox read surface', distinguishing it from get, dismissInsight, and triggerReflection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the default behavior (hot insights), gives the exact escape hatches for other states (state=demoted/dismissed/all), and routes to the correct siblings for inspecting, dismissing, and generating insights. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listJobsA
Return the currently-tracked background jobs (running and recent history), optionally filtered by state.
| Name | Required | Description | Default |
|---|---|---|---|
| stateFilter | No | Optional filter; absent returns every job. |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses that only running jobs plus a bounded 'recent history' are returned, which is real behavioral context, but it omits retention window, ordering, and pagination/result limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the resource and scope, with the optional filter clause last. Nothing wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, and the single optional parameter is fully specified. The only gap is the unquantified 'recent history' window and lack of result-volume guidance for a list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single enum parameter is fully documented in the schema, including the absent-means-all behavior. The description's 'optionally filtered by state' merely restates the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ('Return') plus resource ('currently-tracked background jobs') and scope ('running and recent history'). It is clearly distinct from the mutation sibling cancelJob, though it never names that relationship explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is the read-side counterpart to cancelJob, but the description never states when to call it versus alternatives or that it should be paired with cancelJob to find a job ID.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listPresetsA
List the presets currently active (steering this agent's operating instructions). Returns name, version, and description for each — read-only. Presets are installed via the maz preset install CLI, not by agents.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| presets | Yes | Active presets, ordered by name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does so for the key traits: it declares the operation read-only and enumerates returned fields (name, version, description). It doesn't discuss errors or empty states, but for a zero-parameter read tool the risk surface is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short clauses: what it lists, what it returns, and how presets get created. Every sentence earns its place and the core purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-argument read tool with an output schema, the description supplies everything an agent needs: the meaning of the resource, the field set, read-only status, and the fact that this tool cannot create presets.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so the baseline is 4. The description correctly says nothing about filtering inputs, matching the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List the presets currently active') and even defines what a preset is in this system ('steering this agent's operating instructions'), which no sibling tool name conveys. An agent knows exactly what it gets back.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The final sentence explicitly rules out the obvious wrong assumption by saying presets are installed via the `maz preset install` CLI, not by agents — a clear exclusions signal. There are no true alternatives among the siblings, so the absence of a 'use X instead' pointer is not a gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listSourcesA
List the external source connectors available to ingest from (e.g. local-git) and the resume watermark of each source connected so far (connector, stream, items ingested, last advance time). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| connectors | Yes | Registered connector names available to connectSource/ingestSource. |
| watermarks | Yes | Per-(connector, stream) resume state for sources connected so far, with a derived freshness status. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the burden; it does disclose 'Read-only', which is the key safety signal. It also enumerates the data returned (connector, stream, items ingested, last advance time). It stops short of pagination, volume, or auth expectations, so it's adequate rather than rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with what is listed and the parenthetical field list that removes ambiguity, then 'Read-only.' as a terminal safety note. Dense but every clause adds information; the first sentence is long but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Zero parameters, an output schema that covers return shape, and a stated read-only guarantee mean little more is required. The only residual gap is operational context — how large the result can be or whether unconnected-but-available connectors are distinguished from connected ones.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing to disambiguate and the baseline of 4 applies. The description correctly implies an unfiltered global listing with no arguments needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource pair: lists available external ingest connectors (with an example, local-git) plus the per-source resume watermark. The example connector and enumerated returned fields make the scope concrete. It doesn't explicitly name siblings like connectSource or ingestSource, so differentiation is inferable rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied — check what connectors exist before connecting, and check progress of existing ingests — but the description never says when to call this versus connectSource, ingestSource, or recordSourceRef. No exclusions or prerequisites are given, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mergeEntitiesA
Merge source entity into target: repoints all relations, facts, and mentions from source to target, then removes the source entity row. Append-only: an entityMerged event is written to the audit log. Returns E_VALIDATION when source and target are the same uid, E_NOT_FOUND when either uid is unknown.
| Name | Required | Description | Default |
|---|---|---|---|
| sourceEntityUid | Yes | ULID of the entity to absorb (will be deleted). Required. | |
| targetEntityUid | Yes | ULID of the surviving entity. Must differ from sourceEntityUid. Required. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the surviving (target) entity. |
| status | Yes | Always "merged" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well: it discloses destructive effects (source row removed), side effects (relations, facts, and mentions repointed), audit logging, and specific error conditions. It stops short of mentioning permissions, authorization requirements, or explicit irreversibility.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and uses three tight sentences with zero waste: operation mechanics, audit behavior, and error returns all earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema and fully described input schema, the description is nearly complete for invocation: it explains behavior, side effects, and error modes. It misses only usage guidance and permission/auth context for this destructive operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the parameter descriptions already provide detailed ULID semantics and constraints. The tool description reinforces source/target roles but adds no syntax or format details beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: merging a source entity into a target entity. It explains the operation's mechanics—repointing relations, facts, and mentions, then deleting the source row—which clearly distinguishes it from sibling tools like deleteEntity or updateEntity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not say when to use this tool versus alternatives such as deleteEntity, updateEntity, or listDupCandidates. It provides no explicit context, prerequisites, or exclusions to guide tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
neighborsA
Expand an entity's neighborhood up to 6 hops and return the hydrated neighbor entities plus the relations connecting them, each hop tagged direction=outgoing|incoming relative to the seed. LLM-free graph walk: pass a recall anchor as the seed and traverse the structure yourself. The DEFAULT view is point-in-time NOW: only edges valid now and not superseded; pass includeInactive=true for full history, or time-travel with at/asOf. Filter edges by predicate. The limit (default 50) caps total neighbors across all hops, so deep walks stay bounded.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | Valid-time anchor (RFC 3339 UTC). Walk edges live at this instant. Defaults to now. | |
| asOf | No | Transaction-time anchor (RFC 3339 UTC). Ignore edges recorded after this instant. | |
| seed | Yes | Entity to expand from: an entities/{uid} ref (as returned in a recall hit's entities[]), a bare uid, or a display name (resolved case-insensitively; an unknown or ambiguous name returns an error naming the candidate uids so you can retry). | |
| depth | No | Hops to expand. 1 = direct neighbors, 2 = neighbors-of-neighbors, up to 6. Defaults to 1. | |
| limit | No | Maximum neighbors to return across all hops. Defaults to 50. | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. | |
| predicates | No | Only follow edges with these predicates. Omit to follow any. | |
| includeInactive | No | Follow superseded / expired edges too. Off by default. |
Output Schema
| Name | Required | Description |
|---|---|---|
| neighbors | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load, and it does disclose the key behavioral trait: the default view is point-in-time NOW with only currently-valid, non-superseded edges, plus the fact that limit caps neighbors across all hops. It says nothing about permissions, scope enforcement behavior, cost of deep walks, or what happens when the walk is truncated by limit — meaningful gaps for a traversal tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action and return shape, then layers defaults, time modes and the limit cap. Dense but nearly every clause carries information; the 'LLM-free graph walk' framing is the only clause that is more rhetorical than operational.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the essentials for an 8-parameter traversal tool: seed forms, depth, the three time modes, predicate filtering, scope defaults and the cross-hop limit cap. Since an output schema exists, it need not describe the return payload, and its remaining omission (pagination/truncation behavior and permission requirements) is minor but real.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter is thoroughly documented in the schema (seed ref formats, depth 1–6, limit, scopes, at/asOf semantics). The description restates depth, limit default, includeInactive, predicate filtering and time anchors, adding emphasis but little meaning beyond what the schema already provides, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Expand an entity's neighborhood up to 6 hops' — and names exactly what comes back (hydrated neighbors plus connecting relations, hop-tagged direction). It is clearly not a generic query, but it never contrasts itself with plausible siblings like relations, getEntityContext, or recall, leaving disambiguation to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete usage pattern ('pass a recall anchor as the seed and traverse the structure yourself') and explicit mode selection guidance: default NOW view, includeInactive=true for full history, or at/asOf for time travel. No statement of when NOT to use it versus sibling graph tools, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
promoteRelationA
Promote a proposed relation to asserted: verify an untrusted connector-ingested fact and lift its trust quarantine. A fact extracted from an external source (Granola transcript, Claude-chats export) lands status=proposed — it surfaces in recall but is excluded from supersession until confirmed. Promoting it asserts it, so it then behaves like any user-authored edge. Idempotent: promoting an already-asserted edge is a no-op.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Resource name of the Relation to promote: relations/{uid}, as returned by recall/get/relations/neighbors. | |
| scope | No | Scope the promotion event is written into. Defaults to personal. Use the scope the relation lives in; promoting a team-scope edge requires admitted team membership, else E_PERMISSION. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Resource name of the promoted Relation. |
| status | Yes | Always "asserted" on success — the relation now carries the authoritative trust posture. |
| promoted | Yes | true when this call flipped a proposed edge to asserted; false when the edge was already asserted (idempotent no-op, no event appended). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are empty, so the description carries the full burden and does well: it discloses idempotency (already-asserted promotion is a no-op), the trust-quarantine model, and the supersession exclusion semantics. It omits reversibility (whether retractFact can undo a promotion) and any notes on what the call returns, leaving a small but real gap for a mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action, then the rationale, then the behavioral guarantee. No sentence repeats the name or the schema, and the idempotency note is placed where an agent would look for safety information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the trust-model context is thorough for a two-parameter mutation. The remaining gap is the absence of guidance on undoing a promotion or on what happens to dependent edges, which matters for an operation whose whole purpose is changing assertion state.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — both `name` and `scope` are documented in the schema, including the E_PERMISSION case for team scope. The description adds no parameter-level detail beyond that, so the baseline 3 applies; the schema does the work here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource+state transition: 'Promote a proposed relation to asserted'. It further distinguishes the operation by explaining the source of the input (connector-ingested fact) and the resulting behavior change (behaves like a user-authored edge), so an agent knows exactly what class of operation this is versus siblings like relate or relateBatch.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context on when this applies — facts from external sources land status=proposed, surface in recall, and are excluded from supersession until confirmed. That tells the agent when promotion is needed. It does not name an alternative tool or state when-not to use it (e.g., how to create a fresh edge instead via relate), so it stops short of explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
queryA
Run a read-only SQL SELECT over the curated views (v_entities, v_relations, v_facts) — the analytical escape hatch for questions the structured entities/count filters can't express. Single statement, SELECT/WITH only; writes are rejected and impossible. Run introspect for the view columns. Scope: results default to project+personal; pass scopes:["team"] to include team rows. The views are pre-filtered to the requested scopes before your SQL runs — no WHERE scope = … clause needed.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | A single read-only SELECT (or WITH … SELECT) statement. Query the curated views: v_entities, v_relations, v_facts (run introspect for their columns). Writes, multiple statements, PRAGMA/ATTACH and DDL are rejected; the connection is read-only regardless. | |
| limit | No | Maximum rows to return. Defaults to 200, hard-capped at 1000. Rows beyond the cap set truncated=true. | |
| scopes | No | Scope filter: which data partitions to include. Allowed values: project, personal, team. Defaults to [project, personal] when omitted — team rows are hidden unless you pass scopes:["team"]. The curated views are pre-filtered to the requested scopes before your SQL runs, so no WHERE scope = … clause is needed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | Result rows as column→value objects. |
| columns | Yes | Result column names in order. |
| rowCount | Yes | Number of rows returned (after the limit cap). |
| truncated | Yes | True when more rows matched than the limit returned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: single SELECT/WITH statement only, writes rejected, read-only connection, scopes pre-filtered, and no WHERE scope clause needed. These are exactly the safety and execution traits an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core purpose and safety constraints, then adds scope behavior efficiently. Every sentence contributes operational context without redundant restatement of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema and fully described parameters, the description is complete enough to call the tool correctly. It covers the SQL surface, safety constraints, scope semantics, and the dependency on introspect for column knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds useful meaning beyond the schema by explaining that the views are pre-filtered to the requested scopes and by directing the agent to introspect for columns.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: run a read-only SQL SELECT over curated views. It explicitly positions the tool as an analytical escape hatch for questions the structured entities/count filters cannot express, which distinguishes it from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear use condition—questions that structured entity/count filters cannot express—and points to introspect for view columns. It also explains scope defaults and how to include team rows, leaving little ambiguity about when and how to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
readDocumentA
Read one vault document by path or documentUid: its title, verbatim body, frontmatter, tags, its wikilink edges — links (what it references: mentions of entities, links_to other docs) and backlinks (what references it) — and observations (the - [category] text lines parsed from the body). Each observation is projected to a durable fact ON THIS DOCUMENT ENTITY, so query them with get(entities/{documentUid}) or maz fact get <documentUid>. A document is also an entity, so the returned document.name (entities/{uid}) pivots straight into neighbors/relations to walk the unified graph.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Vault-relative path of the document, e.g. notes/project-alpha.md. Provide this OR documentUid (exactly one). | |
| documentUid | No | Stable document UID (= its entity UID). Provide this OR path (exactly one). |
Output Schema
| Name | Required | Description |
|---|---|---|
| links | Yes | Outgoing wikilink edges (what this note references): mentions → entities, links_to → other documents. Always present; [] when none. |
| document | Yes | The document: path, title, verbatim body, frontmatter, tags, pinned. The name field is the entities/{uid} resource name for pivoting to neighbors/relations. |
| backlinks | Yes | Incoming edges (what references this note). Always present; [] when none. |
| observations | Yes | Structured observations parsed from the body ('- [category] text #tag (context)' lines). EACH is projected to a durable fact on THIS document entity — query them with get(entities/{documentUid}) or 'maz fact get <documentUid>'. Always present; [] when none. |
| unresolvedLinks | Yes | Target names of [[wikilinks]] in the body that resolve to nothing in the graph (dead links). These have NO edge in 'links' precisely because they did not resolve; surface them to flag a broken reference. Always present; [] when none. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does explain the returned sections, observation projection, and graph pivot behavior. However, it omits operational behavior such as missing-document errors, permissions, and an explicit statement that reading has no side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main action and return contents are front-loaded in a single dense paragraph with no wasted preamble. It is somewhat complex due to the observation projection and graph-walking instructions, but those details are relevant to understanding the result.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not fully explain return values, but it still gives useful semantic context for the document, links, backlinks, and observations. It is nearly complete for a read operation, lacking only edge-case behavior such as missing documents.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents the path/documentUid alternative with examples and the exactly-one constraint. The description repeats the selectors but adds no new parameter semantics beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Read one vault document by path or documentUid', and lists exactly what is returned. This clearly distinguishes it from sibling tools such as listDocuments, writeDocument, and editDocument.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly frames usage as fetching a single document and notes that exactly one of path or documentUid should be provided. It also points to get for querying projected observations, but does not explicitly contrast with listDocuments, getBacklinks, or writeDocument.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallA
Search long-term memory for facts matching a query — about the user OR any person, place, organization, or event in the graph. CALL THIS before answering anything that depends on stored context (names, roles, projects, history, people, places, decisions); Mazarbul persists across sessions and clients, your conversation context does not. It is a SEED-FINDER: ground answers on each hit's text and entities[] — feed an entity name into get/neighbors/relations for the authoritative structured facts — not on the raw rank. fusedScore is a blended relevance score where rank ORDER is the signal, not absolute magnitude (normalized to [0,1] under the default weighted fusion, or a small reciprocal-rank value under rrf), so read each hit's text rather than blindly taking hit[0]. A miss is cheap; a confident hallucination is not. Recall ALWAYS returns its best-ranked candidates even when nothing strongly matches, so low, flat scores across unrelated hits usually mean the subject is NOT in memory — confirm a name with entities/get before treating a hit as fact, and use relations/neighbors (not recall) for the AUTHORITATIVE list of what mentions or links a known entity. Pass compact: true, maxTokens, or both to shrink the returned payload when you only need seeds to traverse. Returns ranked hits with citable ULIDs.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | RFC 3339 UTC instant to scope the query. Bi-temporal valid-time anchor. Optional. | |
| asOf | No | RFC 3339 UTC instant. Hides any event whose transaction time is later than this anchor, answering 'what did we know on X?'. Bi-temporal transaction-time anchor. Optional. | |
| near | No | Restrict results to episodes citing entities within a geographic radius of a named place. Both fields required when present. | |
| kinds | No | Restrict hits to these record kinds (set semantics). Omit for the default mix of episodes + vault documents. Pass ["documentRevision"] for document-only recall, ["episode"] to exclude documents. | |
| limit | No | Maximum number of hits to return. Defaults to 10. | |
| query | Yes | Natural-language question or keyword phrase to search the event log for. | |
| anchor | No | Entity ULID. When set, restricts candidates to episodes that cite entities within anchorDepth hops of this anchor (default depth 1, max 6). Useful when you already hold an entity anchor and want topically-adjacent recalls without widening to all memory. Requires navigate to be wired; gracefully degrades to full recall when it is not. | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. | |
| source | No | Constrain hits to these origin sources (set semantics, OR across values). Matches a hit's eventSource — the originating event's source tag, e.g. "remember", "extractor/v1", or a connector tag like "connector:granola". A bare connector name ("granola") matches its "connector:granola" / "connector/granola" forms too. Filtered AFTER ranking, so survivors keep their unfiltered rank order. An unknown source yields an empty hits array (not an error). | |
| compact | No | Return a reduced per-hit envelope — {name, kind, snippet, fusedScore, entities} plus source for document hits — dropping the full text, the per-lane score components, confidence, citations, and createTime. Use when you only need anchors to seed-then-traverse (feed an entity name into get/neighbors/relations); cuts token cost sharply. Off by default (verbose). | |
| explain | No | When true, attach per-lane candidate counts and total wall-clock time under the optional '_meta' key in the response. Off by default. | |
| noGraph | No | Skip the graph traversal lane when true (vector + FTS only). Off by default. | |
| maxTokens | No | Soft cap on the total estimated tokens across all returned hits (estimated at ~4 bytes/token). Hits are dropped lowest-fusedScore-first until the payload fits; the single top-ranked hit is always returned even when it alone exceeds the cap. Combine with compact for the smallest payload. Omit for no cap. | |
| anchorDepth | No | Hop radius around the anchor entity (1..6). Defaults to 1 (immediate neighbourhood). Ignored when anchor is absent. | |
| currentDate | No | Caller's "now" anchor (RFC 3339 UTC or YYYY-MM-DD) the rewriter uses to resolve relative phrases like "two months ago" into an absolute timestamp. Folded into 'at' only when 'at' is unset. Requires rewriteQuery=true to take effect. | |
| asOfEventUID | No | Event ULID. Resolves to that event's createTime and uses it as the asOf anchor. Mutually exclusive with 'asOf' and 'at'; supply at most one of the three. | |
| rewriteQuery | No | Expand the query via the query-rewrite-v1 LLM prompt before retrieval. Off by default. | |
| minConfidence | No | Filter out hits whose writer confidence is below this value. Defaults to 0. | |
| embedDeadlineMs | No | Per-call deadline in milliseconds for the query-embedding step. When the embedder does not respond within this window the call degrades to FTS-only and surfaces MAZ-RECALL-001. Absent means no per-call deadline (the session context deadline still applies). | |
| hasPrimarySource | No | Keep only hits grounded in a primary source: the hit (or one of its entity anchors) is the subject of a recorded source_ref or of an active has_primary_source edge (#207/#208). Filtered AFTER ranking. Off by default. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hits | Yes | Ranked hits. In compact mode (compact=true) each hit carries only {name, kind, snippet, fusedScore, entities} plus source for document hits; the verbose-only fields (hitType, text, confidence, components, citations, createTime) are omitted, so only that subset is guaranteed present. |
| lanes | Yes | The retrieval lanes that actually contributed to this result: ["vector","fts","graph","nameEmb"] for full hybrid, or a subset like ["fts"] when degraded. Always present. |
| degraded | Yes | True when recall ran BELOW full hybrid because the embedder was unavailable: FTS(+graph)-only, no dense-vector lane. Semantic matching did not run, so treat low, flat scores cautiously and lean on the entities/get tools to confirm. Restart the embedder (e.g. Ollama) to restore full hybrid. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it discloses that recall ALWAYS returns best-ranked candidates even on weak matches, that flat low scores indicate absence, that fusedScore magnitude is meaningless versus rank order, and that embedding can degrade to FTS-only. These are non-obvious retrieval behaviors an agent could easily misread.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the trigger and the seed-finder framing before any caveats, and nearly every sentence carries a distinct instruction. It is dense and long, but the length is buying genuine behavioral guidance rather than restating the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 20-parameter retrieval tool with no annotations, the description covers the critical interpretive risks (rank semantics, empty-ish results, traversal alternatives) and an output schema covers return values. It is silent on the bi-temporal (at/asOf), scope, and geographic filtering capabilities, which are significant but fully documented in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema does the heavy lifting and baseline is 3. The description adds decision-level meaning beyond the schema by recommending compact/maxTokens together for the smallest payload and by framing compact output as the seed-traversal mode, which turns a mechanical flag into a workflow choice.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search long-term memory for facts matching a query') and immediately widens scope ('about the user OR any person, place, organization, or event in the graph'). It also distinguishes itself from siblings by naming get/neighbors/relations as the tools for authoritative structured facts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('CALL THIS before answering anything that depends on stored context') and an explicit exclusion ('use relations/neighbors (not recall) for the AUTHORITATIVE list of what mentions or links a known entity'). The seed-then-traverse workflow tells the agent exactly how this tool chains into others.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recordSourceRefA
Record where a memory came from: append an external-source provenance reference (SourceRef, W3C PROV wasDerivedFrom) for a subject record. Give the subject's uid, a sourceType (open taxonomy), and a dedupKey for idempotency; optionally a connector, stream, externalId, externalUrl, and contentHash. Returns the new SourceRef's resource name. Provenance is self-asserted and UNVERIFIED. Does not fetch the source.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Scope to record into. Defaults to personal. | |
| stream | No | Sub-channel within the connector, e.g. a mailbox label or channel id. Optional. | |
| dedupKey | Yes | Idempotency key. Recording the same external item twice (same dedupKey) collapses to one SourceRef. Required. | |
| connector | No | Connector that produced the reference, e.g. gmail, slack. Optional. | |
| fetchTime | No | When the source content was fetched (RFC 3339 UTC). Defaults to now. | |
| externalId | No | Source-system opaque identifier for the item, e.g. a message id. Optional. | |
| sourceType | Yes | Kind of external source, drawn from an open taxonomy: email, slack_message, notion_page, web_page, etc. Required. | |
| subjectUid | Yes | ULID of the record this source was derived from (PROV wasDerivedFrom): an entity, episode, or fact uid. Required. | |
| contentHash | No | SHA-256 hex of the fetched content. Optional; supplied by the caller (fetch is out of scope). | |
| externalUrl | No | Dereferenceable location of the source item. Optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the recorded SourceRef; pass to getSourceRef. |
| status | Yes | Always "recorded" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden well: it discloses the append-style mutation, idempotency via dedupKey, that provenance is self-asserted and UNVERIFIED, that fetching is out of scope, and that it returns the new SourceRef resource name. It does not mention permissions or error behavior, keeping it below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: it states the core action, required fields, return value, verification caveat, and non-fetching boundary in three dense sentences with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the existing output schema and 100% schema coverage, the description is complete enough on behavior and return semantics. The main gap is explicit sibling routing, which matters in a crowded tool list but is not fatal here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all ten parameters. The description reinforces required inputs and adds some framing around dedupKey idempotency and sourceType taxonomy, but much of that is already present in the schema and it omits scope and fetchTime entirely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: append an external-source provenance reference (SourceRef, W3C PROV wasDerivedFrom) for a subject record. It also distinguishes this from source-ingestion behavior by explicitly saying it does not fetch the source, which helps separate it from fetch/capture siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'Record where a memory came from' and the required inputs, and the exclusion 'Does not fetch the source' gives one boundary. However, it does not explicitly name when to use this instead of captureExternal, ingestSource, connectSource, or getSourceRef.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
referenceA
Mint-or-return an external_ref entity for a URI: a first-class local pointer to information held in another system (a GitHub issue, a Drive doc, a Granola transcript, a repo file). Returns the external_ref's resource name so you can relate(localEntity, has_primary_source, name) to record that a local record is grounded in it. Idempotent: the same URI in the same scope returns the same entity. Defaults to personal scope (local, not rendered to the shared project git tree); pass scope=project to share. Mazarbul does NOT fetch the URI — to make the referenced content searchable, fetch it with your own tools, remember() it, then reference() the URI and relate the two. Returns E_VALIDATION on a URI with no scheme or an unknown scope.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | Yes | Absolute URI of the external thing, e.g. https://github.com/org/repo/issues/42, mailto:a@b.com, or a connector URL. Must carry a scheme. | |
| label | No | Optional human-readable display name. Defaults to the URI. Keep third-party identity metadata out of project (git-rendered) scope. | |
| scope | No | Scope to write into. Defaults to personal (local, not rendered to the shared project git tree). Pass "project" to share. Dedup is WITHIN scope: the same URI in two scopes yields two entities. |
Output Schema
| Name | Required | Description |
|---|---|---|
| uid | Yes | Bare ULID of the external_ref, derived deterministically from (scope, uri). |
| uri | Yes | The canonical URI, echoed back. |
| name | Yes | AIP resource name of the external_ref; pass to relate(localEntity, has_primary_source, name) or get(name). |
| scope | Yes | The resolved scope the external_ref lives in. |
| created | Yes | true if a new external_ref was minted, false if an existing one was returned (mint-or-return). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full burden and does so: idempotency ('same URI in the same scope returns the same entity'), cross-scope dedup semantics, the side effect of writing into project git tree when scope=project, the explicit non-behavior (does not fetch), and the E_VALIDATION failure conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action and resource in the first clause, then layers semantics, defaults, and failure modes in a logical order. It is dense but nearly every sentence carries distinct information; the parenthetical example list of sources is the only mildly expendable element.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, idempotency, scope defaulting, the non-fetching boundary, the downstream relate() pattern, and the validation error case. An output schema exists, so return-shape detail is not required, and the description still names the returned resource name for follow-up use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all three parameters are already documented, including the scope dedup caveat and the label guidance. The description's scope commentary largely restates the schema's own dedup note, so it adds only marginal meaning beyond the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource: 'Mint-or-return an external_ref entity for a URI', then defines what that entity is (a local pointer to information held elsewhere). This is clearly distinct from siblings like captureExternal, getSourceRef, and remember, which the description implicitly partitions by explaining itself as the pointer-creation step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete workflow context: it does NOT fetch the URI, so the agent should fetch with its own tools, remember() the content, then reference() the URI and relate the two. It also explains the personal-vs-project scope choice. It stops short of naming an explicit alternative sibling for the cases this tool is wrong, so it is a strong 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
relateA
Assert a structured (subject, predicate, object) relation directly. You are the extractor: when you see a relationship, record it here rather than relying on server-side extraction (off unless a chat model is configured). Pass source for provenance. Returns the new relation's resource name.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Scope to write into — pick by who should see it. Defaults to personal (private to the user, syncs to their devices). Use "project" for edges tied to the current repo/codebase (shared with anyone who has repo access). Use "team" for the shared team brain (requires admitted membership, else E_PERMISSION). "draft" is private staging — invisible to recall until promoted via the CLI (maz scope draft promote); there is no listed MCP tool for draft promotion. | |
| object | Yes | Object entity: entities/{uid}, a bare ULID, the literal "self", or a human display name (resolved case-insensitively, like maz get). | |
| source | No | Provenance label for the appended event, e.g. "cli:relate". Optional; defaults to "mcp:relate". | |
| subject | Yes | Subject entity: entities/{uid}, a bare ULID, the literal "self", or a human display name (resolved case-insensitively, like maz get). | |
| predicate | Yes | Relationship type, e.g. works_at, reports_to, knows. See introspect for registered predicates. | |
| validFrom | No | Inclusive lower bound of the relation's valid-time (RFC 3339 UTC). Optional. | |
| attributes | No | Qualifying key/value pairs, e.g. {"role":"CEO"}. Optional. | |
| confidence | No | Writer confidence in the edge. Defaults to 1.0. | |
| provenance | No | Free-text rationale for the edge. Optional. | |
| validUntil | No | Exclusive upper bound of the relation's valid-time (RFC 3339 UTC). Optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the asserted Relation; pass to get(relations/{uid}). |
| status | Yes | Always "asserted" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are empty, so the description carries the full burden. It usefully discloses the return value ('the new relation's resource name') and the server-side extraction context, but says nothing about duplicate/conflicting edges, whether entities are auto-created from display names, or permission failures on write — details that matter for a mutation tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences that front-load the core action, then the usage rule, then the return value. No filler; the only slight redundancy is the 'Pass source for provenance' sentence, which duplicates the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 10 parameters, nested attributes, and an output schema, the description covers the action, the timing rule, provenance, and the return value, and the scope details live in the schema. Missing only notes on duplicate handling and relationship to unrelate/promoteRelation, which would round out a mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including a detailed scope enum and validFrom/validUntil semantics, so the baseline is 3. The description only adds 'Pass source for provenance', which is a marginal restatement of what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Assert a structured (subject, predicate, object) relation directly,' which is unambiguous about what the tool creates. It does not name siblings such as fact, relateBatch, or promoteRelation, so the agent must infer the boundary from context rather than from the description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('when you see a relationship, record it here') and an explicit alternative to avoid ('rather than relying on server-side extraction (off unless a chat model is configured)'). It lacks exclusions for the sibling write tools (relateBatch for bulk, promoteRelation for drafts), so the guidance is clear but not complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
relateBatchA
Assert multiple (subject, predicate, object) relations in ONE atomic event-log append. All edges are validated before any write: a single invalid endpoint aborts the entire batch. Use this to seed a graph in one call instead of N sequential relate() calls. Returns the new relation resource names in input order.
| Name | Required | Description | Default |
|---|---|---|---|
| source | No | Provenance label for all appended events, e.g. "mcp:relateBatch". Optional; defaults to "mcp:relateBatch". | |
| relations | Yes | Array of relation assertions to append atomically. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | Number of relations appended. |
| names | Yes | AIP resource names of the asserted Relations, in input order. |
| status | Yes | Always "asserted" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden — and it does disclose the key behavioral traits: atomicity, validate-before-write, all-or-nothing abort, and return ordering. It does not cover permission requirements for team scope (only the schema does, via E_PERMISSION), idempotency on retry, or batch size limits, so it falls short of fully complete for a write tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place: what it does, the atomicity guarantee, the alternative it replaces, and the return shape. The most decision-relevant fact (ONE atomic append) is front-loaded in capital letters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter batch-write tool with a full output schema and 100% schema coverage, the description supplies exactly the missing decision layer: atomicity and error behavior. Return values are already covered by the output schema, so no gap remains that would prevent a correct call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the nested relation fields are richly documented, so the baseline is 3. The description adds only the 'input order' return guarantee and the atomic grouping; it does not add syntax or format meaning beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Assert multiple (subject, predicate, object) relations in ONE atomic event-log append') and explicitly contrasts with the sibling relate() by batching. An agent can distinguish it from relate and from query/neighbors without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative ('instead of N sequential relate() calls') and the condition that selects this tool: seeding a graph in bulk. It also gives the exclusionary rule that a single invalid endpoint aborts the whole batch, which tells the agent when this tool is risky versus safe per-edge calls.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
relationsA
List an entity's typed relations (incoming + outgoing), each row tagged direction=outgoing|incoming relative to the queried entity so directional predicates (reports_to, manages) read unambiguously. Endpoint names are hydrated. LLM-free. The DEFAULT view is point-in-time NOW: only edges valid now and not superseded; pass includeInactive=true for expired/superseded history, or time-travel with at/asOf. Filter by predicate. Role/title is often carried as an attributes.role string on a works_at/founded edge rather than a separate has_role edge; each row's sourceEventUid links back to the originating episode. Pair with neighbors to walk further.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | Valid-time anchor (RFC 3339 UTC). Returns relations live at this instant. Defaults to now. | |
| asOf | No | Transaction-time anchor (RFC 3339 UTC). Hides relations recorded after this instant. | |
| limit | No | Maximum relations to return. Defaults to 50. | |
| entity | Yes | Entity whose relations to list: an entities/{uid} ref (as returned in a recall hit's entities[]), a bare uid, or a display name (resolved case-insensitively; an unknown or ambiguous name returns an error naming the candidate uids so you can retry). | |
| scopes | No | Scopes to read from: project, personal, team. Defaults to project+personal. Unknown values are rejected. | |
| predicates | No | Restrict to these predicates, e.g. ["works_at","reports_to"]. Omit to return all. | |
| includeInactive | No | Return superseded / expired relations too (full history). Off by default. |
Output Schema
| Name | Required | Description |
|---|---|---|
| relations | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: it discloses direction tagging, endpoint hydration, default point-in-time semantics, superseded-edge exclusion, history and time-travel options, predicate filtering, attributes.role conventions, and sourceEventUid provenance. These are meaningful behavioral details beyond what the schema alone conveys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and direction semantics, and most sentences add useful information. It is information-dense and somewhat run-on, but not padded with irrelevant material.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a seven-parameter temporal graph-query tool with no annotations but an output schema, the description is complete enough to call correctly. It explains the default temporal view, history and time-travel behavior, direction semantics, role/title modeling, and provenance links without needing to restate the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is a 3. The description adds useful semantics for includeInactive, at/asOf temporal anchoring, predicate filtering, and entity context, though it does not add meaning for limit or scopes beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: list an entity's typed relations, including both incoming and outgoing edges. It also explains the direction tagging so directional predicates are unambiguous, and it distinguishes the tool's role from walking further via neighbors.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear operational guidance for the default now view, includeInactive for historical/superseded edges, and at/asOf for time travel. It also points to neighbors for walking further, but it does not explicitly say when to prefer other relation-oriented siblings such as relate, unrelate, fact, or query.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberA
Persist a fact to the user's long-term memory. CALL THIS whenever the user tells you something about themselves, their work, their preferences, decisions, plans, or corrects a prior fact, even if you think you'll remember it within the current conversation. Mazarbul is the durable store; your own context is not. Pass the original sentence verbatim. remember stores and indexes the text for recall; entities and relations are extracted server-side only when a chat model is configured (usually not), so write the structure you see yourself with createEntity, relate, and fact.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Natural-language record to remember. Stored verbatim as the Episode text. | |
| actor | No | Who said it. "user" (the human), "assistant" (the AI agent), or "system". Defaults to "user" when omitted. Assistant-actor episodes are routed through a different extractor branch so AI-generated facts ("I've booked your flight for March 3rd") become first-class memories instead of being filtered as third-party narration. | |
| scope | No | Sync / encryption boundary for the Episode. "personal" (default) is local-only; "project" is in-repo; "team" is shared under the team key; "draft" is private staging — invisible to recall until promoted via the CLI (maz scope draft promote); there is no listed MCP tool for draft promotion. Omit for the personal default. | |
| source | No | Optional. Where the Episode originated (free-form, e.g. "cli:remember", "providers/anthropic"). Defaults to "mcp:remember" when omitted — just call remember({text}) for an ordinary fact. | |
| confidence | No | Writer's confidence in the Episode. Range 0..1 inclusive. Defaults to 1.0 when omitted. | |
| coordinates | No | Optional geographic coordinates (WGS84) associated with this Episode. When present, the resolver forwards them onto any matched or created place Entity. | |
| coordinatesProvenance | No | Origin of the coordinates, e.g. user_provided or geocoded:nominatim. Required when coordinates is set; rejected when coordinates is absent. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the created Episode: "episodes/{uid}". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are empty, so the description carries the full burden and does well: it discloses that storage is durable and verbatim, that indexing feeds recall, and — critically — that entity/relation extraction is conditional on a chat model being configured. Missing: nothing on deduplication/overwrite behavior or failure modes, which matters for a persistence tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded action statement followed by trigger, rationale, and the structural-write fallback — each sentence does work. The final clause is dense and runs long, but no sentence is expendable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-param write tool with an output schema, the description covers what the schema cannot: when to call, that writes are durable rather than conversational, and that automatic graph extraction usually will not happen so the agent must call the structural siblings itself. Nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all seven parameters including scope boundaries and the coordinates/coordinatesProvenance coupling. The description only reinforces the `text` argument ("Pass the original sentence verbatim"), which the schema already states, so it adds little beyond the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb plus resource ("Persist a fact to the user's long-term memory") with clear scope. It also implicitly distinguishes itself from retrieval siblings (recall, get) and from structural writers (createEntity, relate, fact) by naming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit, enumerated trigger list (user facts, preferences, decisions, plans, corrections) plus an anti-exclusion ("even if you think you'll remember it within the current conversation"). It also names the alternatives — createEntity, relate, fact — and the condition that selects them, namely that server-side extraction usually does not run.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retractFactA
Close the current value of a fact slot — the scalar counterpart to unrelate. Records that a fact STOPPED being true (a status that no longer holds, a preference that changed with no replacement) by retracting it: it drops out of current reads but its history is PRESERVED (unlike forget, which deletes the row). The slot then reads as EMPTY — retraction does NOT fall back to an earlier value. Identify the value by its facts/{uid} or by the (subject, stateKey) pair (which closes the slot's single open value). To set a different value instead, just write it with fact() — a later write supersedes the prior.
| Name | Required | Description | Default |
|---|---|---|---|
| fact | No | The fact to retract: facts/{uid} or a bare ULID (as returned by fact() or get). Use THIS or a (subject, stateKey) pair, not both. | |
| scopes | No | Scopes to search when identifying the slot by (subject, stateKey): project, personal, team. Defaults to project+personal. | |
| subject | No | Subject entity whose slot to close: entities/{uid}, a bare ULID, "self", or a display name. Provide with stateKey as an alternative to fact. | |
| stateKey | No | Slot address to close, e.g. state.task.status, preference.coffee.milk. Provide with subject. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Resource name of the retracted fact. |
| status | Yes | Always "retracted" on success: the value is closed but its history is preserved. |
| retractedAt | Yes | The instant the fact was retracted (RFC 3339 UTC). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does most of it well: history is PRESERVED (unlike forget, which deletes the row), the value drops out of current reads, and critically the slot reads as EMPTY with no fallback to an earlier value. It stops short of stating failure/idempotency behavior (e.g. what happens if the slot has no open value, or if the same retraction is issued twice).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and its counterpart, then consequences, then alternatives — a sensible order. It runs long for what it says and leans on capitalization for emphasis, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description covers side effects, data retention, and read-visibility well. The remaining gap is edge-case behavior — empty slots, repeated retractions, and failure modes — which matters for a mutation with zero annotation coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both invocation paths and the oneOf exclusivity are already documented in the schema. The description reinforces the either/or ('Use THIS or a (subject, stateKey) pair, not both') and adds the semantic that the pair closes the slot's single open value, but adds no format or scope guidance beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Close the current value of a fact slot') and immediately positions it against two siblings: the scalar counterpart to unrelate, and distinct from forget (which deletes). An agent can pick this tool over forget/fact/unrelate without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ('a status that no longer holds, a preference that changed with no replacement') and an explicit when-not/alternative: 'To set a different value instead, just write it with fact().' Both identification paths are named, so the agent also knows the two valid invocation modes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_createA
Create the team scope (genesis): mints a fresh per-team data-encryption key, admits this device's principal as the genesis owner, and switches the team scope to encrypted envelope mode. Fails if a team already exists.
| Name | Required | Description | Default |
|---|---|---|---|
| remote | No | Optional git remote URL to pin for the team scope (e.g. git@github.com:org/team-brain.git). |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | Always "created" on success. |
| dekEpoch | Yes | Epoch of the freshly-minted data-encryption key (always 0 at genesis). |
| genesisPrincipalUid | Yes | Principal UID admitted as the team's genesis owner (this device's bound principal). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With zero annotations, the description carries the full behavioral burden and does much of it: it discloses irreversible-sounding state changes (mints a new key, switches the scope to encrypted envelope mode) and a hard failure condition. Gaps remain around required permissions and whether the mode switch can be undone, which matters for a genesis operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the core action front-loaded and the failure condition last. Every clause (key minting, genesis owner, envelope mode, failure) carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter bootstrap tool with an output schema handling returns, this covers purpose, side effects, and failure mode well. Missing only the preconditions (does a device/account need to be set up first?) and the relationship to the team_join path.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the `remote` parameter is already documented, and the description adds nothing about it (e.g. what pinning does or how it interacts with the team scope). Baseline 3 is correct when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Create the team scope (genesis)" gives a specific verb and resource, and the following clauses spell out the concrete effects: DEK minting, genesis-owner admission, and switching to encrypted envelope mode. An agent can distinguish this from team_join or team_grant without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Fails if a team already exists" supplies an explicit exclusion condition, which implies when not to use it. However, it never names the alternative (team_join) as the path for existing teams, so the routing guidance stops one step short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_device_listA
List all devices enrolled under the local principal's identity, including revocation status. Each device entry shows its signing-key fingerprint (sigKeyId), optional label, create time, and whether it has been revoked.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| devices | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden alone. 'List' implies a safe read, and it usefully enumerates what each entry contains (sigKeyId, label, create time, revocation status), but it says nothing about authorization requirements, pagination, or result size.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the scope and then the shape of the returned entries. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained in detail, and no parameters exist to document. The description is essentially complete; only the lack of any read-scope or pagination note keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline 4 applies: the empty schema is self-explanatory and the description does not need to add parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (list) and resource (devices enrolled under the local principal's identity) with scope clearly bounded to the caller's own identity. This cleanly separates it from siblings like team_members or team_device_revoke.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'list all devices', but the description does not explicitly state when to use this versus team_members or team_device_revoke, nor any preconditions for enrollment visibility. The purpose is inferable but not routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_device_revokeA
Revoke an enrolled device by its ULID. Appends a deviceRevoked event to the team scope. After revocation, any event authored by this device with a UID greater than the revocation event's UID is dropped on all peers (convergent fold). The revoker must be the device's own principal, or a team admin/owner.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional free-form reason for the revocation (audit trail). | |
| deviceId | Yes | ULID of the device to revoke. Required. |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | Always "revoked" on success. |
| deviceId | Yes | ULID of the revoked device. |
| eventUid | Yes | UID of the appended deviceRevoked event. |
| principalUid | Yes | ULID of the device's owning principal. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and does so well: it discloses the side effect of appending a deviceRevoked event, the convergent-fold propagation behavior across peers, and the authorization requirement. It goes well beyond what the schema alone provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and is composed of four dense, purposeful sentences. Every sentence contributes operational meaning without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations and an available output schema, the description covers the essential invocation context: purpose, side effects, propagation semantics, and authorization. Minor details such as idempotency or re-enrollment behavior are not required to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents deviceId and reason. The description does not add meaning beyond the schema for either parameter, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: revoke an enrolled device by ULID. It is clear enough to distinguish from list-oriented siblings like team_device_list, but it does not explicitly contrast itself with team_revoke or similar team-level revocation tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context by specifying the authorization constraint: the revoker must be the device's own principal, or a team admin/owner. It does not explicitly say when not to use it or name alternatives such as using team_device_list to find the deviceId.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_grantA
Admit a principal to the team by wrapping the current team data-encryption key to their pasted x25519 public key. The grantee unwraps it on their next sync pull. Requires the caller to hold at least admin role. The optional role parameter sets the grantee's access level (default: member).
| Name | Required | Description | Default |
|---|---|---|---|
| role | No | Access role to assign the grantee. Defaults to "member" when absent. | |
| label | No | Optional human label for local logging; never serialized into the synced recipients.jsonl. | |
| joinKey | Yes | The grantee's join-key blob (the opaque token from team_key / 'maz team key'). It carries their principal UID, wrap public key, and signing identity — this is the trust input; obtain it out of band. |
Output Schema
| Name | Required | Description |
|---|---|---|
| role | Yes | Effective access role assigned to the grantee. |
| status | Yes | Always "granted" on success. |
| dekEpoch | Yes | Highest (current) DEK epoch wrapped to the grantee. |
| grantedEpochs | Yes | Every DEK epoch wrapped to the grantee (ascending). A full-history grant covers 0..dekEpoch; it is a subset only when this device lacks a prior epoch's DEK. |
| granteePrincipalUid | Yes | Principal UID that was admitted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does substantial work: it discloses the mutation mechanism, the authorization requirement, and the asynchronous consequence that "The grantee unwraps it on their next sync pull," plus the role default. It does not say what happens if the principal is already a member (idempotency/overwrite) or point at team_revoke for reversal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, zero filler, front-loaded with the action and its mechanism before the preconditions. Each sentence adds a distinct fact (mechanism, propagation timing, auth, role default).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, and the description covers inputs, auth, and timing adequately for correct invocation. The remaining gap is failure/duplicate handling and the revocation path, which matter for a security-sensitive grant operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so joinKey and label are already fully documented, including the note that label is never serialized. The description's only parameter claim, that role "sets the grantee's access level (default: member)," restates the schema enum description rather than adding new meaning; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Admit a principal to the team") plus the mechanism (wrapping the current team DEK to their x25519 public key), which is enough to distinguish it from a plain read like team_members. It never names a sibling such as team_join (the grantee side) or team_role_set (changing an existing member's role), so the discrimination is inferred rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is clear and a real prerequisite is stated: "Requires the caller to hold at least admin role," which prevents a whole class of failed calls. It lacks explicit when-not guidance (e.g. use team_role_set for existing members, team_join if you are the joining party), so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_joinA
Point this device at an existing team's encrypted remote so it can sync the shared brain, WITHOUT creating a new team. Use this (not team_create) to join a team someone else created. After joining, run team_key and send the blob to an admitted member to be granted, then sync pull to bootstrap the team key.
| Name | Required | Description | Default |
|---|---|---|---|
| remote | Yes | The team's shared git remote URL to sync through (e.g. git@github.com:org/team-brain.git). |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | Always "joined" on success. |
| nextSteps | No | What to do next to finish joining. |
| remoteUrl | Yes | The team remote this device is now configured to sync with. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full disclosure burden. It reveals that the remote is encrypted, that joining alone does not grant access (a separate grant via an admitted member is required), and that a sync pull is needed to bootstrap — genuinely useful context. However, it omits idempotency (what happens if the device already joined), failure behavior for an unreachable or non-team remote, and whether it writes persistent local state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences: the action, the sibling exclusion, then the post-join workflow — front-loaded and waste-free. Minor cost is jargon density ('blob', 'shared brain', 'admitted member') that may not be self-evident without prior context, but every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the single required parameter is fully documented. The description supplies the multi-step workflow around the call, which is the main non-obvious element. Slightly incomplete on what to do if the join fails or the caller lacks standing with the team.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single 'remote' parameter is documented in the schema with a concrete git URL example. The description reinforces the semantics ('the team's encrypted remote ... to sync through') but adds no format or validation detail beyond what the schema already provides, so baseline 3 is right.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — point this device at an existing team's encrypted remote to sync the shared brain — and explicitly names the scope boundary (WITHOUT creating a new team). An agent can distinguish it from team_create purely from the text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use this (not team_create) to join a team someone else created', naming the alternative and the condition that selects it. It then gives the mandatory follow-up sequence (team_key → send blob to an admitted member → sync pull), which is when-to-use guidance of a high order.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_keyA
Show this device's team join request: its bound principal UID and base64 x25519 wrap public key. Send both to an admitted team member so they can grant you (maz team grant --principal --wrap-pubkey ). Read-only; neither value is secret.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| joinKey | Yes | Opaque join-key blob to hand an admitted member (maz team grant --join-key <blob>). Carries the principal UID, wrap public key, and signing identity; nothing in it is secret. |
| principalUid | Yes | This device's bound principal UID. |
| wrapPublicKey | Yes | This device's base64 x25519 wrap public key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With empty annotations the description carries the full burden, and it does disclose the two things that matter most: the operation is read-only and the returned values are not secret, pre-empting an agent's hesitation about exposing a 'key'. It leaves unstated what happens when the device has no pending join request or whether the key rotates.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose, followed by the handoff action and a safety note in two tight sentences. The embedded CLI invocation ('maz team grant --principal ... --wrap-pubkey ...') is marginal for an MCP agent that will more likely call the team_grant tool, but it clarifies the argument handoff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read tool with an output schema and no annotations, the description covers purpose, output identity, safety profile, and next step. Missing only edge-case behavior — error when no request exists, and how a request is created or refreshed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero input parameters, so the 4 baseline applies. The description goes further by naming the two values it returns, which is useful framing even though an output schema already exists.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Show this device's team join request' — and names exactly what is returned: the bound principal UID and base64 x25519 wrap public key. It is clearly distinct from the mutation siblings like team_grant or team_join, though it never names team_grant explicitly, leaving the pairing to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a concrete use context: send both values to an admitted team member so they can grant you access. This implied handoff makes the relationship to the grant flow clear. It does not state when not to call it (e.g. already-joined device, or that team_members is the counterpart tool for the member side).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_membersA
List the admitted team members (the derived ACL): opaque principal UID, DEK epoch, wrap public key, and whether each is the genesis owner. Read-only and contains no display names or other PII.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| members | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the load. It explicitly discloses read-only behavior and the privacy-relevant fact that no display names or PII are returned, which is valuable context beyond the empty schema. It does not mention required permissions or auth scope, but the safety profile is substantially covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences with no filler. The core purpose is front-loaded, followed immediately by field and privacy details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters and an existing output schema, the description is nearly complete. It covers the purpose, read-only nature, privacy posture, and returned field semantics. A small gap remains around permissions or what 'admitted' excludes (e.g., pending members), but overall it is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so the baseline is 4. The description adds useful detail about return fields (opaque principal UID, DEK epoch, wrap public key, genesis owner), even though a full output schema already exists.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Uses a specific verb ('List') and a precise resource ('admitted team members (the derived ACL)'), then enumerates the returned fields. This clearly distinguishes it from team_device_list, team_grant, team_revoke, team_role_set, and other team_* siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose implies when to use it (to inspect the admitted ACL), but it never states when not to use it or names a specific alternative among the many sibling tools. An agent can infer usage, but must do the routing work itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_revokeA
Revoke a team member and forward re-key the team: appends the revocation, mints a fresh data-encryption key at the next epoch, and re-wraps it to every remaining member. Returns a checklist — you must separately remove the principal's git-host access, which Mazarbul cannot do.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional human-readable revocation reason recorded in the audit trail. | |
| principalUid | Yes | ULID of the principal to revoke. |
Output Schema
| Name | Required | Description |
|---|---|---|
| checklist | Yes | Post-revoke operator checklist: what Mazarbul did and what you must still do. |
| newDekEpoch | Yes | Epoch of the fresh DEK the remaining members were re-keyed to; the revoked principal has no grant here. |
| rewrappedTo | No | Principal UIDs the new DEK was re-wrapped to (the remaining members). |
| revokedPrincipalUid | Yes | Principal UID that was revoked. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the forward re-key, new DEK at next epoch, re-wrapping to remaining members, and the returned checklist. It stops short of stating permission requirements, idempotency, or whether revocation is reversible, which would be needed for a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both front-loaded: the action and its re-key semantics come first, the external-access caveat second. Every clause conveys distinct operational information with no padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so the checklist return value needs no elaboration, and with only two fully documented parameters the description is nearly sufficient. The remaining gap is the absence of any prerequisite or permission context for a destructive-key-rotation operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so principalUid (ULID) and the optional audit-trail reason are already documented. The description adds no parameter-level detail beyond the schema's own text, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Revoke a team member') and goes on to describe the concrete mechanism (append, mint DEK, re-wrap). The phrase 'team member' distinguishes it from the sibling team_device_revoke, which acts on devices rather than principals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies the use case (removing a person from the team) and gives an important post-condition ('you must separately remove the principal's git-host access'). However, it never contrasts with adjacent tools like team_role_set (demotion) or team_device_revoke, so the agent must infer which one applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
team_role_setA
Change an admitted team member's access role (owner | admin | member | reader) without re-wrapping key material. Requires the caller to hold at least admin role; assigning admin or owner requires owner. The change is recorded as a teamRoleChanged event and converges identically on every peer.
| Name | Required | Description | Default |
|---|---|---|---|
| role | Yes | New access role. Assigning admin or owner requires the caller to hold owner role. | |
| principalUid | Yes | ULID of the admitted team member whose role is being changed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| role | Yes | New effective role. |
| status | Yes | Always "role_set" on success. |
| eventUid | Yes | UID of the appended teamRoleChanged event. |
| subjectPrincipalUid | Yes | Principal whose role was changed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the authorization model, states no key material is re-wrapped, notes an audit side effect (teamRoleChanged event) and cross-peer convergence. It doesn't cover failure modes (e.g., demoting the last owner) or whether the change is reversible by re-invoking.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: action first, then authorization gate, then effect. No filler, no repetition, and the most decision-relevant constraint (auth requirement) is front-loaded after the action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter mutation with an output schema and no annotations, it covers action, permissions, side effects and consistency semantics. The main remaining gap is what happens on invalid transitions (e.g., removing the last owner), which matters for a role-change tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the enum is already declared, so the description's inline role list and ownership rule largely restate structured data. Baseline 3 applies — it adds no syntax or format detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — changing an admitted team member's access role — and enumerates the exact role values. The phrase 'without re-wrapping key material' distinguishes it from cryptographic operations like team_key or team_grant at a glance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit preconditions for use ('caller must hold at least admin; assigning admin or owner requires owner'), which is the main gating decision. It stops short of naming sibling alternatives such as team_grant or team_revoke, so the agent must infer which tool handles membership vs. role modification.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unrelateA
End a relation as of a date — the temporal counterpart to relate. Records that a relationship STOPPED being true (someone left a job, a project ended) by closing the edge with a valid_until: it drops out of current reads but its history is PRESERVED (unlike forget, which deletes the edge). Identify the edge by its relations/{uid} or by the (subject, predicate, object) triple (which closes the single open match). Pass endedAt for when it ended (defaults to now); pass supersededBy when a newer relation replaces it.
| Name | Required | Description | Default |
|---|---|---|---|
| object | No | Object of the relation to close: entities/{uid}, a bare ULID, "self", or a display name. | |
| scopes | No | Scopes to search when identifying the edge by triple: project, personal, team. Defaults to project+personal. | |
| endedAt | No | When the relationship ended (RFC 3339 UTC); becomes the edge's valid_until. Defaults to now. | |
| subject | No | Subject of the relation to close: entities/{uid}, a bare ULID, "self", or a display name. Provide with predicate+object as an alternative to relation. | |
| relation | No | The relation to close: relations/{uid} or a bare ULID (as returned by relations() or recall). Use THIS or a (subject, predicate, object) triple, not both. | |
| predicate | No | Predicate of the relation to close, e.g. works_at. | |
| supersededBy | No | Optional relations/{uid} of a newer relation that replaces this one (a correction). Omit for a pure close — the relationship simply ended. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Resource name of the closed relation. |
| status | Yes | Always "retracted" on success: the edge is closed (valid_until set) but its history is preserved. |
| validUntil | Yes | The valid_until the relation was closed at (RFC 3339 UTC). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that the edge drops out of current reads while history survives, that the triple form 'closes the single open match', and that endedAt defaults to now. It does not cover failure modes (no open match, multiple open matches, permission requirements), which is the only remaining gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and its key distinction, then parameter guidance. It is dense — three parenthetical explanations in four sentences — but every clause adds information an agent needs; nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the two identification modes, temporal defaults, the correction-vs-close distinction, and the read-visibility consequence; an output schema exists so return values need no explanation. The one thing an agent might still want — what happens when zero or multiple open edges match — is left implicit in 'the single open match'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds decision-level meaning beyond the schema: it explains the either/or between relations/{uid} and the triple form, states that endedAt defaults to now, and clarifies that supersededBy is for corrections while omission means a pure close.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (end a relation) with a specific temporal mechanism (closing the edge with valid_until), and immediately distinguishes itself from both `relate` (its inverse) and `forget` (which deletes rather than preserves). An agent can pick it out of a 60-tool sibling list without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames itself as 'the temporal counterpart to relate' and gives concrete when-to-use scenarios (someone left a job, a project ended). It also names the wrong-tool alternative and the consequence: 'unlike forget, which deletes the edge' — history is preserved here.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateEntityA
Relabel an entity's kind and/or displayName by appending an entityUpdated event. Supply at least one of kind or displayName; omitting both is E_VALIDATION. Returns E_NOT_FOUND when the uid does not resolve. Only the supplied fields change; confidence, properties, identifiers, and coordinates are untouched.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | New entity kind in snake_case. Omit to leave unchanged. | |
| entityUid | Yes | ULID of the entity to update. Required. | |
| displayName | No | New human-readable label. Omit to leave unchanged. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | AIP resource name of the updated entity. |
| status | Yes | Always "updated" on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full behavioral burden and does well: it discloses that the change is recorded as an appended event, that the update is partial ("only the supplied fields change; confidence, properties, identifiers, and coordinates are untouched"), and it names two concrete error codes. It omits permission/auth requirements and idempotency, which keeps it off a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, no filler, and the core action plus the 'at least one field' rule are front-loaded before error and partial-update details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter mutation tool with an output schema already documenting return values, the description covers action, constraint, error behavior, and untouched state. The only meaningful omission is who is allowed to perform the update.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so 3 is the baseline, but the description adds a constraint the schema cannot express: entityUid is the only required field yet at least one of kind/displayName must be present or the call fails with E_VALIDATION. That cross-parameter rule is genuine added meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb-plus-resource ("Relabel an entity's kind and/or displayName") and names the underlying mechanism ("appending an entityUpdated event"), which is enough to separate it from createEntity, deleteEntity, mergeEntities and relate without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a clear usage precondition — supply at least one of kind or displayName, otherwise E_VALIDATION — and gives the failure mode when uid doesn't resolve. It stops short of naming an alternative sibling (e.g. mergeEntities vs relabel) or an explicit "do not use this for X" exclusion, so it's a strong 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
waitForIdleA
Block until the kernel finishes all background extraction, resolution, and embedding work (or the timeout expires). Use between a burst of remember() calls and a benchmark recall() so the recall measures retrieval latency only, not the tail of ingestion. Cheap when the kernel is already idle.
| Name | Required | Description | Default |
|---|---|---|---|
| timeoutSeconds | No | Maximum seconds to wait. Defaults to 300. The tool returns timedOut:true rather than erroring when the budget expires. |
Output Schema
| Name | Required | Description |
|---|---|---|
| isIdle | Yes | True when both enrichment and vec drained within the budget; false if timedOut. |
| timedOut | Yes | True when the timeoutSeconds budget expired before the kernel went idle. |
| elapsedMs | Yes | Wall-clock spent waiting, in milliseconds. |
| vecInflight | Yes | Vec depth observed at return time (0 unless timedOut). |
| enrichmentInflight | Yes | Enrichment depth observed at return time (0 unless timedOut). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and discloses that the call blocks until background work completes or the timeout expires, and that it is cheap when already idle. It does not explicitly declare side-effect-free/read-only behavior, but the blocking and cost traits are well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences with the core blocking behavior front-loaded, followed by the intended usage pattern and a cost note. Every sentence adds useful information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter waiting tool with full schema coverage and an output schema, the description provides enough context to invoke it correctly and understand its purpose. Return-value details are covered by the output schema rather than needing repetition here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single timeoutSeconds parameter is already fully documented in the schema, including its default and timedOut return behavior. The description adds no parameter-specific meaning beyond what the schema provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific blocking verb and the resource it waits on: all background extraction, resolution, and embedding work. It is clear what the tool does, but it does not explicitly distinguish itself from the sibling idleStatus tool, which likely also reports kernel idleness.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear usage scenario: between a burst of remember() calls and a benchmark recall() so the recall measures retrieval latency only. It does not mention when not to use it or name idleStatus as a non-blocking alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
writeDocumentA
Create or replace a markdown document at path with body (stored verbatim, event-sourced — full history is kept). [[Wikilinks]] in the body resolve to canonical entities and other documents as graph edges; dangling links reconcile automatically when their target appears. Optional title/pinned/tags/frontmatter synthesize a YAML frontmatter block when the body has none. Frontmatter about: <name|entities/{uid}> records the document's primary subject as a high-confidence describes edge (distinct from body [[wikilinks]], which are mentions); resolve it by uid where you can, since a renamed subject keeps the link. Frontmatter canonical: true lets this document win name resolution over a same-named non-document entity, so a later-created entity cannot silently steal the name. The document materializes as an editable file in the vault. Idempotent: rewriting identical content is a no-op. scope picks who sees the document (personal by default; team requires membership, else E_PERMISSION) and is fixed at creation — the same path in a different scope is a separate document. Result counts (edges, unresolved, reconciled) are whole-document snapshots after the write, not deltas. A non-fatal warnings field appears when the title shadows a same-named non-document entity.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | The full markdown body, stored verbatim. May include its own YAML frontmatter block. | |
| path | Yes | Vault-relative path, e.g. notes/project-alpha.md (.md appended when no extension). | |
| tags | No | Tags, synthesized into frontmatter. | |
| scope | No | Storage scope, fixed at creation. personal (default) = only you; project = a shared project; team = every team member (requires membership, else E_PERMISSION); draft = private staging. The same path in a different scope is a SEPARATE document. | |
| title | No | Optional title, synthesized into frontmatter. Only when body has no frontmatter of its own. | |
| pinned | No | Pin the document (synthesized into frontmatter). Pinned documents surface first in context packs. | |
| frontmatter | No | Additional frontmatter keys (JSON object), synthesized into a YAML block. Only when body has no frontmatter of its own. |
Output Schema
| Name | Required | Description |
|---|---|---|
| file | No | Absolute path of the materialized vault file. |
| name | Yes | entities/{uid} resource name of the document-as-entity. |
| path | Yes | |
| edges | No | Total resolved wikilink and frontmatter edges the whole document holds after this write (snapshot, not a delta — counts all [[links]] in the current body that resolved, regardless of how many were already in the graph). |
| changed | Yes | False when the content matched the latest revision (no-op). |
| warnings | No | Non-fatal advisory messages — e.g. a title-collision warning when the document's display name shadows a non-document entity. Does not affect the written content; the document body is stored byte-for-byte as supplied. Omitted when empty. |
| reconciled | No | Count of wikilinks in OTHER vault documents that this write newly made resolvable (cross-document reconcile pass; separate from the document's own edge snapshot above). |
| unresolved | No | Count of [[wikilinks]] left dangling in the whole document after this write (snapshot, not a delta). |
| documentUid | Yes | |
| pendingEdit | No | True when the vault file holds an un-ingested manual edit and was left untouched. |
| revisionUid | No | |
| unresolvedTargets | No | The dangling wikilink targets by name (text inside [[…]] that matched nothing) — fix a typo or create the target. Omitted when none dangle. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are empty, so the description carries the full burden and does so thoroughly: event-sourced full history, idempotent no-op on identical content, scope fixed at creation with a same-path/different-scope being a distinct document, E_PERMISSION on team scope, non-fatal warnings, and result counts being whole-document snapshots rather than deltas. These are exactly the traits an agent cannot infer from schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single dense paragraph of roughly 150 words, but nearly every sentence carries non-obvious semantics and the core action is front-loaded. It would read better segmented into bullets (write behavior / links / frontmatter / scope / return values), which is the only thing keeping it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still notes that `edges`/`unresolved`/`reconciled` are post-write snapshots and that `warnings` is non-fatal — precisely the interpretation an agent needs. Combined with link reconciliation, idempotency, and scope rules, nothing material for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description earns above baseline by explaining semantics the schema cannot: frontmatter `about:` produces a high-confidence `describes` edge (distinct from `mentions` from wikilinks) and should be given by uid, while `canonical: true` makes the document win name resolution — behaviorally meaningful for a key passed inside the `frontmatter` object.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource pair ('Create or replace a markdown document at `path` with `body`') and immediately distinguishes itself from siblings like editDocument/readDocument by the replace-in-full semantics. The scope of the write (verbatim body, synthesized frontmatter, materialized vault file) is stated concretely.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'create or replace' and by the scope semantics (personal default; team requires membership else E_PERMISSION), which helps an agent choose a scope value. However, there is no explicit guidance on when to pick writeDocument over editDocument, which is the obvious sibling for modifying an existing document, so the routing decision is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
64 tool updates
v0.1.0- First observed
addIdentifier - First observed
agentFeedback - First observed
cancelJob - First observed
captureExternal - First observed
connectSource - First observed
contextCorrect - First observed
contextPin - First observed
contextUnpin - First observed
count - First observed
createEntity - First observed
defineEntityKind - First observed
definePredicate - First observed
defineSchema - First observed
deleteEntity - First observed
describeType - First observed
dismissInsight - First observed
editDocument - First observed
entities - First observed
fact - First observed
forget - First observed
get - First observed
getBacklinks - First observed
getCapacity - First observed
getContext - First observed
getEntityContext - First observed
getSourceRef - First observed
getUsageSnapshot - First observed
idleStatus - First observed
ingestSource - First observed
introspect - First observed
lintDocuments - First observed
listDocuments - First observed
listDupCandidates - First observed
listInsights - First observed
listJobs - First observed
listPresets - First observed
listSources - First observed
mergeEntities - First observed
neighbors - First observed
promoteRelation - First observed
query - First observed
readDocument - First observed
recall - First observed
recordSourceRef - First observed
reference - First observed
relate - First observed
relateBatch - First observed
relations - First observed
remember - First observed
retractFact - First observed
shareToTeam - First observed
team_create - First observed
team_device_list - First observed
team_device_revoke - First observed
team_grant - First observed
team_join - First observed
team_key - First observed
team_members - First observed
team_revoke - First observed
team_role_set - First observed
unrelate - First observed
updateEntity - First observed
waitForIdle - First observed
writeDocument
TDQS
Scored across 64 tools
Most tools target distinct resources or lifecycle steps, and the long descriptions carefully distinguish read/write/close semantics (fact vs relate, forget vs retractFact vs unrelate). However, several clusters overlap enough to require careful reading: captureExternal/recordSourceRef/reference/connectSource/ingestSource/getSourceRef for provenance, and idleStatus/waitForIdle/getUsageSnapshot/getCapacity/listJobs for observability. Retrieval surfaces (recall, get, entities, query, getContext, getEntityContext) are differentiated but easy to misselect without the descriptions.
The set mixes camelCase verbs (listPresets, getEntityContext, defineEntityKind), bare verb names (get, fact, relate, query, remember, forget, reference), and a snake_case team_* block (team_create, team_device_revoke, team_role_set). The team_ namespace is a readable exception, but over 64 tools the overall convention is inconsistent. Readability is preserved only because most names are still self-describing.
64 tools is very heavy for any single MCP surface, even a broad memory/graph kernel covering entities, documents, ontology, provenance, team sync, jobs, and observability. Each subsystem has a plausible reason to exist, but the total surface is large enough to burden tool selection and context. It sits well above the 25+ threshold for 'too many' rather than being an extreme 50+ mismatch only because the stated domain is genuinely wide.
The surface covers a lot: entity CRUD and merge, relation/fact creation, retraction, forgetting, document read/write/edit/lint, ontology definition and introspection, insights, jobs, sources, provenance, team ACLs, and context briefs. Only minor lifecycle gaps are apparent, such as no explicit document delete tool and no direct relation update beyond unrelate/re-relate. These are workable for agents but leave a few dead ends.
Maintenance
Related MCP Connectors
Governed local-first memory and continuity for AI agents — signed receipts, optional hosted lane.
Local-first long-term memory for AI agents, with byte-recomputable signed verification receipts.
Persistent memory for AI agents. Semantic search, memory graph, W3C DID identity.
Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceLocal-first, multi-user shared memory for AI agents with semantic search, offline support, and team synchronization.MIT
- AlicenseAqualityBmaintenanceLocal-first memory engine for AI-agent teams: private/team/project ACL, associative recall, and federated sync across nodes. One SQLite file, no LLM required.127Apache 2.0
- FlicenseNot gradedqualityAmaintenanceLocal-first memory for AI agents with evidence-backed recall, deterministic trust verdicts, self-inspection, and a tamper-evident audit history.3-

Lians Agent Memoryofficial
AlicenseAqualityCmaintenanceLocal-first bitemporal memory for AI agents with deterministic supersession, point-in-time recall, erasure proofs, and tamper-evident audit history.916Apache 2.0