Skip to main content
Glama

cambium

Part of the xylem stack.

The knowledge-lifecycle MCP that turns work your agents already did into compound, org-wide knowledge. cambium bridges two substrates that already exist — agentsync (what happened: claims, finishes, notes, changed files) and context-keeper (why: decisions, constraints) — and adds the three things neither has:

  1. distill() — turn events into memory automatically (passive capture)

  2. recall() — one federated read endpoint for every agent type (coding agent, Slack KB bot, SRE bot — same store, same call)

  3. promote() — graduate knowledge local → team → org as it earns trust

Named for the cambium layer of a tree: the thin living tissue where all growth happens.

Why a third MCP (and not a database)

Knowledge layers fail because they're a side system nobody calls. cambium's bet: capture and recall must be native tools in the agent's loop, and state must live in the substrate the work already lives in — git — not a separate service. Storage is an implementation detail behind recall():

Scope

Lives in

Trust gate

local

<repo>/.cambium/knowledge.json

none — it's yours

team

knowledge.json on a dedicated cambium branch of the shared repo

recalls ≥ N or an endorsement

org

knowledge.json in a dedicated org knowledge repo

an endorsement required; optionally lands as a pull request — review is the gate, git revert is the undo

Team writes use the agentsync pattern: a private worktree under .git/ and git push as compare-and-swap, so concurrent agents never clobber each other.

Related MCP server: agentbay-mcp

Install

pip install -r requirements.txt      # just `mcp`

gh (GitHub CLI) is only needed for pull-request-mode org promotion.

Configure

Point an MCP client at the server — no env required to start:

{
  "mcpServers": {
    "cambium": {
      "command": "python3",
      "args": ["/abs/path/to/cambium_server.py"]
    }
  }
}

First contact is helpful, not cold. MCP servers can't start a conversation, so cambium teaches you through its own responses. Call status() (or any tool) before it's configured and instead of a bare env error you get structured guidance — what's set, what's missing, what each gap costs in plain terms, and the exact setup() call that fixes it:

{
  "configured": false,
  "gaps": [
    {"setting": "CAMBIUM_REPO",
     "cost": "no project repo → cambium has no substrate; every tool is unavailable",
     "fix": "setup(project_repo=\"/abs/path/to/your/clone\", agent_id=\"your-id\")"},
    {"setting": "CAMBIUM_ORG_REPO",
     "cost": "org scope off → promotions stop at team; org-wide recall unavailable",
     "fix": "setup(project_repo=…, agent_id=…, org_repo=\"owner/knowledge or /abs/path/to/clone\")"}
  ],
  "next_step": "setup(project_repo=\"/abs/path/to/your/clone\", agent_id=\"your-id\")"
}

setup(project_repo, agent_id, org_repo?, org_pr?, team_branch?) finishes the job: it validates the paths, scaffolds .cambium/ (and adds it to the repo's .gitignore), and writes a fallback config at ~/.cambium/config.json that the server reads when env vars are absent. It takes effect immediately — no restart. No secrets are written: the file holds only paths, ids, and flags, and lives outside any repo. If org_repo is a GitHub owner/name you haven't cloned locally, setup offers the exact gh/git commands to stand it up and leaves org scope off — it never creates or pushes a repo for you.

Env still wins. Any of the variables below, set in the MCP client config, overrides the config file per-key — the table is the full reference layer:

env var

required

default

meaning

CAMBIUM_REPO

yes

your project clone (local scope, agentsync + context-keeper substrates)

CAMBIUM_AGENT_ID

yes

your unique agent id

CAMBIUM_REMOTE

no

origin

git remote

CAMBIUM_GIT_TIMEOUT

no

25

per-invocation git/gh timeout (seconds) so a stuck call fails fast instead of hanging the server

CAMBIUM_TEAM_BRANCH

no

cambium

team-scope branch

CAMBIUM_AGENTSYNC_BRANCH

no

agentsync

coordination branch name distill reads

AGENTSYNC_BOARD_REPO

no*

which repo holds the board — the same setting agentsync reads, so the two servers cannot disagree (see below)

CAMBIUM_ORG_REPO

no

path to the org knowledge repo clone (org scope off without it)

CAMBIUM_ORG_PR

no

direct push

1 = org promotion opens a pull request

CAMBIUM_PROMOTE_RECALLS

no

3

recalls needed for local→team

CAMBIUM_RELEASE_CAPTURE

no

off

1 = also capture agentsync claims at their done/released transition (see below)

CAMBIUM_CONFIG_FILE

no

~/.cambium/config.json

override the fallback config path (mainly for tests)

Where the agentsync board lives (board addressing)

* distill() reads finished agentsync claims off a coordination board. That board is a shared, long-lived team artifact — not a property of whichever project this session happens to be in — so cambium resolves its address independently of the session, using exactly the order agentsync itself uses:

  1. AGENTSYNC_BOARD_REPO — the explicit board address (env, or the same key in ~/.cambium/config.json). One setting configures both servers.

  2. AGENTSYNC_REPO — agentsync's legacy explicit pin.

  3. CAMBIUM_REPO — but only if that repo actually holds the coordination branch (real ref lookup: local head → remote-tracking ref → ls-remote).

  4. Otherwise: no board, reported loudly (next section) — never silently.

Why. Before this, cambium looked for the coordination branch in CAMBIUM_REPO while agentsync (unpinned) followed ~/.xylem/active_project.json. The two could point at different repos, and whenever the current project had never been provisioned neither found anything. distill() reported that as the bland string "no coordination branch found", callers treated it as normal, and the result was that distill imported zero agentsync claims across its entire lifetime — a three-legged design silently running on two legs.

A skipped source does not look like a completed one

distill()'s return now makes a miss impossible to read as a success:

  • top-level status becomes "distilled_with_warnings" (not "distilled");

  • top-level warnings carries a plain-language line per skipped substrate;

  • sources.agentsync is an object — {status, board_repo, board_source, branch, claims_seen, done_claims, imported, reason, fix} — so "there is no board", "the board is here and nobody has finished anything", and "imported 3" are three visibly different results rather than one empty number.

status() reports the same under substrates.agentsync_board.

Org setup: create one (private) repo, e.g. github.com/you/knowledge, with an empty {"items": []} in knowledge.json; everyone who should read org knowledge clones it and points CAMBIUM_ORG_REPO (or setup(org_repo=…)) at their clone. cambium manages that clone (it hard-syncs it) — dedicate it, don't work in it.

Tools

capture(content, type, kind, why, tags, valid_while) — save a knowledge item to local scope (types: memory | need | skill). Manual path. valid_while optionally names the premise the item depends on, so a dead assumption is spottable later (see Machine-maintained documentation entropy).

record_need(content, why, tags) — first-class needs ("we're missing X"), promotable like anything else so recurring wants surface at team/org level.

distill() — the automatic path. Reads agentsync's coordination branch (every currently done claim: task + note + changed files → an outcome memory) and context-keeper's .context/ (active decisions & constraints, rationale and dec-NNN provenance preserved). Idempotent — wire it to a session-end or post-commit hook and capture becomes passive.

Release-time capture (opt-in, CAMBIUM_RELEASE_CAPTURE=1). agentsync keys claims by agent id and deletes a claim from live state the instant it is released or re-claimed — it exposes no hook or event, only the rewritten claims.json on the branch. So a claim that completes and then churns before a full distill runs against it is silently lost. With the flag on, each distill also remembers the last-seen claim per agent and captures any that has churned away since the previous run — reconstructing it from that snapshot, through the same dedupe watermark, so a claim captured at release time and again in a later full distill never double-imports. Fire distill() on completion events (a post-commit / session-end hook) and completed work is captured at its transition instead of only when a distill happens to catch it live.

What this is not: it is passive capture at the moments distill runs, not exhaustive reconstruction. The guarantee is precise — if a distill sweep observes a claim while it is done (or carries a note), that knowledge is captured even if the claim later churns. The residual gap: a done state that is created and churned away entirely between two sweeps (e.g. cambium wasn't running) is never observed, and only agentsync's git log still holds it. Walking that log to reconstruct such claims exhaustively is a possible follow-up (the history survives — agentsync's history() reads it), deliberately left out of this change.

import_memory(source, path) — ingest an external memory export into cambium as local-scope, provenance-tagged knowledge items (see Import below). Read-only against the source; imported items are not auto-promoted.

recall(query, scope, limit) — federated search across local+team+org. Every hit increments the item's recall counter (the trust signal promotion feeds on) and records cross-project use. Abstains honestly: below the relevance floor it returns no_confident_match: true instead of confident-looking noise. Each result carries endorsed_as — the item's endorsement notes surfaced as first-class context, since for a promoted item that is where its cross-project meaning was written.

endorse(item_id, note) — vouch for an item. Fast-tracks local→team; required for team→org.

promote(item_id, to_scope, force, org_content) — no args: scan-and-promote all eligible local items to team. With to_scope="org": push to the org repo, or open a PR when CAMBIUM_ORG_PR=1 (the team copy stays, annotated, until the PR merges). Promotion stamps last_verified — promotion is a verification. Generalization gate: org scope is read by every project, so a body that reads project-specific (names a file, a test_* id, a dec-/con-NNN ref, or its own origin project) is refused at the org boundary — restate it as the cross-project rule via org_content= (the concrete body is kept as example) or force=True to override. The refusal hands back the endorsement note as a ready draft. Mirrors the endorsement gate; the safe path is the easy path.

generalize(item_id, org_content, note) — the remediation counterpart of the gate: restate an already-promoted item's body as the cross-project rule in place, keeping the concrete version as example. For items that reached org before the gate (or were forced past it) — the ones review_promotions() lists under org_needs_generalization. Omit org_content to fall back to the item's latest endorsement note. Writes through the org CAS path (direct, or a single shared cambium/generalize PR branch when CAMBIUM_ORG_PR=1, so repeated calls batch into one reviewable PR); idempotent.

verify_entry(item_id, note) — confirm an entry still holds; stamps its last_verified to now (optional note). The event that keeps promoted knowledge from silently going stale (see Machine-maintained documentation entropy).

stale_report(project, older_than_days) — promoted (team + org) entries sorted oldest-verified-first, never-reverified ones flagged, each entry's valid_while premise surfaced. Reports staleness; never auto-downgrades.

review_promotions() — what's eligible for team, what's endorsed for org, which org PRs are pending, and org_needs_generalization — org items whose body still reads project-specific (crossed before the gate, or forced), each with the tells found and the endorsement note as a suggested restatement.

export_markdown(scope) — render knowledge to a human-readable KNOWLEDGE.md, grouped by scope then project (each item: summary, kind, provenance dec-NNN/claim origin, recall count, promoted date; cp1252 mojibake normalized). scope="org" (default) re-renders and pushes the org repo's KNOWLEDGE.md beside its knowledge.json; local/team/all return the markdown without publishing. It also runs automatically after any org promotion — direct-push commits both files together, PR mode puts both on the same PR branch — so the org repo's docs are always current.

setup(project_repo, agent_id, org_repo?, org_pr?, team_branch?) — finish configuration from a cold start (see Configure). Validates paths, scaffolds .cambium/, writes the fallback config; offers gh commands for an org repo rather than creating one. No secrets written.

status() — config state first: what's set, what's missing, each gap's cost and the setup() that fixes it (never raises when unconfigured). Once configured, also counts per scope/type, import watermarks, and wired substrates.

The compound-growth loop

stobie's agent finishes work ──agentsync──▶ done claim + note + files
                                                 │
jonny's cambium: distill()  ◀────────────────────┘
        │ outcome memory (local)
jonny + teammates: recall() ×N  ──▶ trust grows ──▶ promote() → team
        │ visible to every collaborator's agent
someone: endorse()  ──▶ promote(to_scope="org")  ──▶ org repo / PR
        │
ANY agent, ANY project, ANY type (SRE bot, KB bot): recall(scope="org")

Passive capture: add a Claude Code hook that runs distill at session end — capture then costs zero per-note effort. Run it on completion events too (a post-commit hook) with CAMBIUM_RELEASE_CAPTURE=1 and finished agentsync work is captured at the moment it completes, before a release or re-claim can erase it.

Import

import_memory(source, path) ingests knowledge from an external memory system into cambium. It is import/ingest only — it reads the external store and writes cambium items; it never writes back to the source (export is a separate, riskier feature and is deliberately out of scope). Import is modelled as a source adapter, the same shape as distill's substrate readers: an adapter reads records from a source location and yields normalized cambium knowledge items, which land through the same normalize-and-write/dedupe path distill uses — no second mechanism.

What import guarantees:

  • Local scope, always. Imported items enter at local scope. They have not earned promotion inside cambium and are not auto-promoted — team/org is still earned the normal way, through recall() usage and endorse().

  • Provenance, always. Every imported item is stamped source: {system, ref, imported: true, source_ts} and tagged imported, so imported knowledge is distinguishable from natively-distilled capture and auditable back to its origin (system + original id + original timestamp).

  • Idempotent. Re-importing the same records adds nothing — dedupe is by the source record's stable id when present, else by a content hash, routed through the shared watermark path.

  • Read-only against the source, and dependency-free (stdlib, local files only — no network, no external auth).

The json adapter (reference)

The one bundled adapter reads a generic JSON / JSONL memory export from a local file — no service-specific coupling. It accepts a top-level array, an object wrapping a list under memories/items/records/data/entries, or JSONL (one JSON object per line). Each record maps as:

cambium field

source keys (first present wins)

if absent

content (body)

content, text, body, memory, note

record skipped (no body)

— folded into body

title, name, summary

omitted

why

why, reason, rationale, context

empty

kind

kind, type, category

"note"

tags

tags (list or comma/space string)

just imported, json

source.ref

id, uuid, _id, key

content-hash dedupe instead

source.source_ts

timestamp, created_at, ts, time, date

omitted

type is always memory; malformed lines and records with no usable body are counted as skipped, never crash the import. The return value summarizes imported / skipped / duplicates.

# import_memory(source="json", path="/abs/path/to/export.jsonl")

Adapters are the extension point. json is the only format shipped — this is not a claim of support for any particular memory product. To ingest another system, add one adapter (a generator yielding normalized items) to IMPORT_ADAPTERS; core logic doesn't change. Adapters that require network access or credentials are intentionally not included here.

Machine-maintained documentation entropy

Trust-gated promotion defends knowledge on the way in: an entry only reaches team or org after it earns recalls or an endorsement. But nothing marked it going stale afterward. A fact that was true when it cleared the gate — "billing runs on NetSuite", "the staging DB caps at 90 connections" — stays trusted long after the premise dies. Worse, agents recall it, act on it, and cite it, so a wrong assumption doesn't just persist; it gets institutionalized, and the more it's used the more authoritative it looks. Promotion raises the stakes of being wrong without adding any way to notice you've become wrong.

cambium closes this with verification events and premise linkage, not confidence scores or time decay — both of which manufacture false precision. A 0.62-confidence memory implies a measurement nobody took, and "trust halves every 90 days" would quietly demote knowledge that is simply stable and correct. Instead every entry carries an optional last_verified timestamp (promotion counts as the first verification; verify_entry records later ones) and an optional valid_while premise naming the condition it depends on. Staleness is event-driven: stale_report sorts promoted entries oldest-verified-first and flags the never-reverified, and distill's release-time path surfaces the oldest-verified relevant entries right when work completes — so re-checking rides an existing workflow beat. Absent or old last_verified is a signal to a human, never an automatic downgrade. cambium reports the smell; a person decides.

Seeing it: tools/dashboard.py

python tools/dashboard.py --open

Builds a single self-contained HTML view of the whole mesh — every project's context-keeper log and the cambium layer distilled from them. Four views:

  • Overview — the distillation funnel: recorded → active → distilled → recalled → promoted. Each stage a subset of the one above.

  • Projects — sortable table of every store; click through to one project's full log, its supersession chains, its constraint scopes and its health flags.

  • Knowledge — what distillation produced, what actually gets recalled, and where things sit on the local → team → org ladder.

  • Health — mojibake, thin rationale, untagged, stale and never-recalled, each as a share of the population it is drawn from so a big store does not look unhealthy merely for being big.

It exists because counting was already possible and understanding was not. The first run answered a question no single tool could:

scope

items

recalled

recalls

local

229

15 (7%)

117

team

136

134 (99%)

774

Promotion is what makes knowledge get read. Local is a staging area and its low recall rate is the system working, not failing — a conclusion only visible with both scopes in one view. The first version of this tool read .cambium/knowledge.json alone (local scope only) and reported "nothing has left local"; team knowledge lives on a git branch, and 136 promoted items were being recalled 774 times.

It also surfaced 84 items carrying cp1252 mojibake distilled before context-keeper fixed the transport — concentrated on the team branches that are recalled most. tools/repair_mojibake.py fixes the local stores; the team branches are shared git state and are left to a deliberate push.

Local by design. The output is gitignored. The mesh spans private repos and ones with no remote at all, so a published version could honestly show aggregates and nothing more; this one shows everything, because it is yours. Read-only, and test_dashboard.py asserts that byte-for-byte.

Test

python3 test_cambium.py      # server integration suite
python3 test_dashboard.py    # the mesh dashboard

62 cases against real git repos: markdown export (KNOWLEDGE.md grouped by scope then project with provenance/recalls/promoted-date, cp1252 mojibake normalized, auto-written alongside knowledge.json on org promotion in both direct-push and PR modes), write-time normalization (a substrate that feeds distill a cp1252-mangled em-dash lands clean in the canonical store, so recall() serves repaired text, not just the rendered .md), onboarding (unconfigured status() reports gaps with costs and fixes, every tool fails helpful when unconfigured, setup() configures from a cold start and its config takes effect in-process, env overrides the file, org names are offered as gh commands not created, non-git and missing paths rejected), capture/recall (+ honest abstention), distill from both substrates (exact agentsync claims format; exact context-keeper .context/ schema) with idempotency, post-promotion staleness (optional last_verified/valid_while fields, absent-field back-compat, verify_entry local + team round-trips, promotion stamps verification, stale_report oldest-first ordering + never-verified flag + age and project filters, release distill surfaces the verification prompt), release-time capture (off by default; a done claim survives a re-claim churn captured exactly once; a noted claim released before it reaches done is kept where a full distill would miss it), import (JSON + JSONL export → provenance-tagged local items, re-import dedupes, content-hash fallback without ids, malformed/missing fields skipped not crashed, imported items stay local and unpromoted, source left untouched), the full promotion lifecycle (recall-threshold, endorsement fast-track, org-requires-endorsement, PR-mode with gh stubbed), the org generalization gate (a project-specific body is refused at the org boundary with its tells and a suggested restatement; org_content= generalizes and preserves the concrete body as example; force=True overrides; a clean universal body is not over-blocked; recall surfaces endorsed_as; review_promotions self-reports org_needs_generalization; generalize() restates an already-promoted body in place, keeps the concrete as example, clears the flag, and is idempotent), a distill legacy-field fallback (a pre-v0.4 context-keeper decision carrying only rationale still distills its WHY), cross-project trust tracking, team-write CAS under a concurrent peer push, two real-agentsync integration tests (drive the actual agentsync claim / finish / release tools when the sibling repo is present — including the release-capture seam), and a real MCP stdio transport test. CI runs it on every push.

Limitations (honest ones)

  • Lexical recall, not semantic. The scorer is token/substring overlap — deterministic and dependency-free. Swappable for embeddings later; the tool contract doesn't change.

  • Org usage isn't tracked (recalls at org scope don't increment counters) — org items have already finished climbing.

  • PR-mode promotion isn't transactional — the team copy stays (annotated with the PR URL) until a human merges. That's the point: review is the gate. A direct consequence: promote to org one item at a time in PR mode. Every promote(item_id, to_scope="org") branches off origin/main and appends to the same items array in knowledge.json, so two concurrently-open promotion PRs edit the same region of that file and the second can't merge cleanly until the first lands. (Observed: two knowledge PRs opened back-to-back on 2026-07-10; the second needed manual conflict resolution against knowledge.json.) Open a PR, merge it, then promote the next — serializing avoids the conflict entirely.

  • Distill reads exactly ONE board per run. distill() git fetches claims.json from <CAMBIUM_REMOTE>/<CAMBIUM_AGENTSYNC_BRANCH> of the repo resolved by board addressingAGENTSYNC_BOARD_REPO if set, else CAMBIUM_REPO when it genuinely holds the branch. It is no longer pinned to the project repo, but it still does not merge several boards: work coordinated on a different board, or through the agentsync-remote transport against a different backing store, is invisible to that run. Distill once per board.

  • Distill captures at the moments it runs, not exhaustively. By default it imports agentsync's currently done claims; a claim released or re-claimed before any distill catches it live is lost. CAMBIUM_RELEASE_CAPTURE=1 closes most of that gap by capturing claims at their done/released transition (via a last-seen snapshot), but a done state created and churned away entirely between two sweeps is still only recoverable from agentsync's git log — a history walk that is not built here.

License

PolyForm Noncommercial License 1.0.0 — free for any noncommercial use.

Part of the xylem stack.

Available Tools

14 tools
captureA

Save a knowledge item to your LOCAL scope: a fact, design note, gotcha, or troubleshooting step worth remembering. This is the manual capture path; distill() is the automatic one.

type : memory | need | skill kind : freeform subtype (note, decision, constraint, runbook, ...) why : the rationale — makes the item far more useful at recall time tags : comma/space-separated keywords (boost recall matching) valid_while : optional premise this knowledge depends on, e.g. "while we're on NetSuite" — surfaced later so a dead assumption is spottable

ParametersJSON Schema
NameRequiredDescriptionDefault
whyNo
kindNonote
tagsNo
typeNomemory
contentYes
valid_whileNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden but fails to disclose behavioral traits such as mutability, side effects, authentication needs, or persistence behavior. Mentioning 'LOCAL scope' hints at scope but does not clarify safety or limitations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with bullet-like lines for parameters after an initial clear statement. It is slightly verbose but every sentence adds value, making it efficient and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 6 parameters and an output schema (not shown), yet the description omits the return format or response behavior. It explains input well but lacks completeness about what the caller receives after execution.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 0%, but the description compensates fully by explaining each parameter's meaning: 'type' as memory|need|skill, 'kind' as note/decision/etc., 'why' as rationale, 'tags' as keywords, and 'valid_while' as dependency premise. This adds significant value beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool saves a knowledge item to 'LOCAL scope' using a manual capture path, distinguishing it from the automatic sibling 'distill()'. The verb 'save' and resource 'knowledge item' are specific, and the scope is explicitly defined.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool ('manual capture path') vs. the alternative 'distill()' (automatic). It does not address other siblings like 'record_need' or 'recall', so it is not exhaustive but is clear enough for the primary distinction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

distillA

Automatically turn work that already happened into knowledge. Reads two substrates natively — no export step, no copy-paste:

  1. agentsync: every DONE claim on the coordination branch (task + partner note + changed files) becomes an 'outcome' memory. The note your partner left for reconciliation is exactly the knowledge worth keeping.

  2. context-keeper: every active decision and constraint in .context/ becomes a memory with its rationale, preserving the dec-NNN/con-NNN provenance.

Idempotent — each source record imports at most once; re-run freely (e.g. from a session-end or post-commit hook for passive capture).

Release-time capture (opt-in, CAMBIUM_RELEASE_CAPTURE=1): agentsync erases a claim from live state the moment it is released or re-claimed, so a claim that completes and churns before the next full distill is lost. With the flag on, distill also remembers the last-seen claim per agent and captures any that has churned away since the previous run — from that snapshot, via the same watermark, so nothing double-imports. Wire distill to fire on completion events and captured-once-at-completion is the result. The residual gap: a done state that lives and dies entirely between two runs is never observed (only the agentsync git log holds it).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It thoroughly discloses idempotent behavior, the release-time capture mechanism, and a residual gap where work might be lost. This level of transparency is exceptional.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is quite long and packed with information, but it could be more concise. It uses paragraph structure rather than bullet points, which trades some clarity for detail. Still, every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has no parameters and an output schema exists, the description covers behavior, limitations, use cases, and mechanisms thoroughly. It is complete and leaves little ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and schema coverage is 100% trivially. The description does not need to add parameter information, and it provides extensive context beyond parameter semantics. Baseline for 0 params is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that distill turns completed work into knowledge, detailing two specific native substrates (agentsync and context-keeper). It distinguishes itself from sibling tools by focusing on automated capture from already completed tasks, unlike capture or generalize.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use the tool (re-run freely, from session-end or post-commit hook) and explains the opt-in release-time capture. It does not explicitly state when not to use, but the context implies it's for automated knowledge capture, and the residual gap is noted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

endorseB

Vouch for an item — the strong trust signal. One endorsement fast-tracks local->team promotion and is REQUIRED for team->org (usage alone never reaches org; someone has to deliberately say 'this is right').

ParametersJSON Schema
NameRequiredDescriptionDefault
noteNo
item_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but only explains the tool's role in promotions. Lacks disclosure of side effects, reversibility, permissions, or constraints beyond the promotion context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no waste; purpose is front-loaded. Every word earns its place, efficiently conveying the tool's unique value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While output schema exists so return values are covered, the description misses parameter semantics and behavioral details. Adequate but incomplete for a tool with no annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description provides no explanation of 'item_id' or 'note' parameters. Fails to add meaning beyond the schema, leaving agents uninformed about required inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states 'vouch for an item' as the action, specifying it as the strong trust signal. Distinguishes from sibling tools like 'promote' and 'review_promotions' by explaining its role in promotion workflows.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit context on when endorsement is needed (required for team->org promotion, fast-tracks local->team). While it doesn't enumerate when not to use, the promotion flow guidance effectively signals appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_markdownA

Render knowledge to a human-readable KNOWLEDGE.md — grouped by scope then project, each item showing summary, kind, provenance (dec-NNN / claim origin), recall count and promoted date. cp1252 mojibake (em dashes, curly quotes) is normalized so the text is clean.

scope='org' (default): re-render the org knowledge repo's KNOWLEDGE.md from its knowledge.json and commit + push it beside the JSON, so the org repo's docs are always current. (This also runs automatically after any org promotion — direct-push commits both files together; PR mode puts both on the same PR branch.)

scope='local'|'team'|'all': render those scope(s) and RETURN the markdown without publishing — there is no repo to publish local/team docs to.

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNoorg

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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 discloses key behavioral traits: rendering process, mojibake normalization, and the publishing vs. return-only behavior for different scopes. However, it omits potential side effects like file overwriting or permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise yet informative, using structured bullet points to organize information efficiently. Every sentence adds value, and the key action is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple single-parameter tool and the existence of an output schema, the description covers the main functionality and outcomes well. It lacks error handling details but is sufficient for the complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, 'scope', is thoroughly explained in the description with three valid values and their corresponding effects. Even though schema coverage is 0%, the description fully compensates by detailing each option and its default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool renders knowledge to a human-readable markdown file, grouped by scope and project, with details per item. It distinguishes between scope='org' (publishes to repo) and other scopes (returns markdown without publishing), which differentiates 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly defines when to use each scope value, including default behavior. It provides clear context for usage but does not explicitly compare to sibling tools or state when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generalizeA

Restate an ALREADY-PROMOTED item's body as the cross-project rule, in place, keeping the concrete version as example. The remediation counterpart of the org generalization gate: items that reached org (or team) before the gate — or were forced past it — are listed by review_promotions() under org_needs_generalization; this rewrites one to its general form.

org_content : the cross-project rule to become the body. If omitted, the item's latest endorsement note is used (that is where the generalization was usually already written). note : optional note recorded as a verification stamp.

Writes through the org store's CAS path (direct push, or the shared cambium/generalize PR branch when CAMBIUM_ORG_PR=1 — repeated calls batch into one reviewable PR), re-rendering KNOWLEDGE.md alongside. Team-scope items are edited via the team CAS path.

ParametersJSON Schema
NameRequiredDescriptionDefault
noteNo
item_idYes
org_contentNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so description must cover behavioral traits. It details write operations via CAS paths, PR batching, and side effects on KNOWLEDGE.md. Differentiates between org and team scope. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with main purpose; parameter details follow. Some redundancy (e.g., 'in place' and 'rewrites one to its general form') but overall efficient. Minor wordiness does not harm clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given annotations are absent and parameter count is 3, the description provides comprehensive context: usage, parameters, write behavior, and output side effects. Output schema exists, so return value details are not needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but description explains `org_content` (with default behavior) and `note`. `item_id` remains implicit but is required. Adds meaning beyond schema for two of three parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: 'Restate an ALREADY-PROMOTED item's body as the cross-project rule' and distinguishes it from sibling tools like 'promote' by specifying it is the remediation counterpart of the org generalization gate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes when to use: for items listed under `org_needs_generalization` by `review_promotions()`. Provides context for `org_content` defaulting to the endorsement note. However, lacks explicit when-not-to-use or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

import_memoryA

Ingest an external memory export into cambium as LOCAL-scope, provenance- tagged knowledge items — a source adapter alongside distill's substrate readers. Import/ingest only: it reads the source READ-ONLY and never writes back to it.

source : adapter name. 'json' = a generic JSON/JSONL export — a list of records (or an object wrapping one under memories/items/records), each with a text body (content/text/body/memory/note) plus optional title, why, kind, tags, id, timestamp. It's the extension point: new formats are new adapters, no core changes. path : local file path to read (no network, no external auth).

Every item is stamped with provenance (source.imported=True, the origin system, original id + timestamp) so imports never masquerade as native capture. Idempotent — re-importing the same records adds nothing (dedupe by source id, or content hash when no id). Imported items are NOT auto-promoted; they earn team/org the normal way, through recall usage and endorsement.

Returns a summary: imported / skipped / duplicates.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYes
sourceYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, description fully discloses all behavioral traits: read-only source, no network/auth, idempotency, deduplication by source ID or content hash, provenance stamping, and that imported items are not auto-promoted. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear sections, but slightly verbose. Front-loads purpose and constraints. Each sentence is valuable, but minor redundancy in parameter explanations could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers all essential aspects: purpose, parameters, behavioral nuances, idempotency, provenance, and return format. Output schema exists, so return description is sufficient. Complete for its complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but description compensates fully by defining each parameter: 'source' explains the 'json' adapter format and structure, 'path' specifies local file path. Adds critical meaning beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Explicitly states it ingests external memory exports as provenance-tagged items, distinguishing itself from sibling tools like 'capture' (native capture) and 'distill' (substrate reading). Clearly identifies it as an import/ingest-only, read-only operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: read-only on source, idempotent, no auto-promotion, and local file path only. Lacks explicit exclusion guidance or when to use alternatives like 'capture', but the context is sufficient for correct usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

promoteA

Graduate knowledge up a scope as it earns trust — the compound-growth step. With no arguments, scans your local items and promotes every one that qualifies to team. With an item_id, promotes that item one level (local->team, or team->org with to_scope="org").

Thresholds: local->team needs recalls >= CAMBIUM_PROMOTE_RECALLS or one endorsement; team->org always needs an endorsement (force=True overrides, use deliberately). Org promotion lands as a direct push, or as a pull request when CAMBIUM_ORG_PR=1 — the PR review is the org trust gate.

org_content : the cross-project restatement of a body that is specific to one repo. Promotion to org changes the readership to everyone, so a project-local runbook ("append to dashboard.py REGIMES") must become the general rule ("annotate a regime boundary when a metric's computation changes"). If the body reads project-specific and no org_content is given, promotion is refused (with the tells and a suggested draft) unless force=True. When supplied, org_content becomes the org body and the original is preserved as example.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNo
item_idNo
to_scopeNo
org_contentNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It thoroughly discloses all behavioral traits: promotion conditions, scope transitions, readership changes, the need for org_content for cross-project restatement, the fallback response (refusal with tells and suggested draft), and the effect of force and environment variables (CAMBIUM_ORG_PR). This is highly transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is lengthy and dense, containing multiple paragraphs with example scenarios and conditional logic. While it is well-organized and covers necessary details, it could be more concise. For instance, the first sentence 'Graduate knowledge up a scope as it earns trust — the compound-growth step.' is verbose. A tighter rewrite would improve score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of the tool (multiple promotion paths, thresholds, environment variables, PR vs direct push, org_content requirement), the description covers every aspect. It explains the escalation process, failure modes, and side effects. An output schema exists but is not shown; the description references it indirectly (direct push vs pull request). No gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description adds rich meaning to each parameter: force overrides conditions, item_id specifies the item, to_scope sets target scope, org_content provides the restated body. It explains how org_content becomes the org body and preserves original as 'example'. Without any schema help, the description fully compensates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: graduate knowledge up a scope (local->team->org) as trust earns. It explains the verb 'promote' and the resource (knowledge items). However, the phrasing is somewhat convoluted (e.g., 'compound-growth step'), and it could be more straightforward. It distinguishes between usage without arguments (scan and promote all) and with item_id (single item). Siblings like 'generalize' or 'distill' are not explicitly differentiated, but the scope promotion is unique.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use scenarios: with no arguments to promote all qualifying local items, with item_id to promote one level, and with to_scope to target org. It explains thresholds (recalls/endorsements) and when force is needed. It also covers failure modes (refusal when org_content is missing) and suggests alternatives (review promotions, force). The guidelines are comprehensive and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recallA

Search knowledge across scopes and return the best matches. THE read endpoint for every agent type — a coding agent, a Slack KB bot, an SRE bot — they all ask here, so knowledge captured once serves them all.

scope : auto (local+team+org, the default) | local | team | org limit : max results

Every returned item's recall counter is incremented (local directly, team best-effort via the shared branch) — usage is the trust signal promotion feeds on. If nothing clears the relevance floor the response says no_confident_match: true — don't present weak matches as established fact.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
scopeNoauto

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even without annotations, the description transparently discloses side effects (recall counter increment, trust signal promotion) and response behavior (no_confident_match flag), providing critical behavioral context 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is front-loaded with purpose and well-structured across a few sentences, though it could be slightly more concise. Still efficient for the information provided.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers all key aspects: purpose, parameters, side effects, error behavior. Does not describe output schema, but output schema exists. Nearly complete for a search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description fully compensates by explaining 'scope' values (auto, local, team, org), 'limit' as max results, and defaults, adding essential meaning beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description explicitly states 'Search knowledge across scopes and return the best matches' and identifies it as 'THE read endpoint for every agent type', clearly distinguishing it from sibling tools that are write/management oriented.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clarifies when to use the tool (read/search) by explaining scope options and limit, and implicitly contrasts with siblings like 'capture' or 'endorse'. Could be more explicit about when not to use, but adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

record_needB

Record a NEED — something missing, wanted, or blocking (a first-class citizen alongside memories: 'we need staging seeds', 'docs for X are missing'). Needs surface in recall like any knowledge and can be promoted so the team/org sees recurring wants.

ParametersJSON Schema
NameRequiredDescriptionDefault
whyNo
tagsNo
contentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that needs are first-class citizens that surface in recall and can be promoted. However, it omits details like side effects, authentication requirements, or idempotency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long with no fluff. It is front-loaded with the action and efficiently conveys the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core purpose and a bit of the lifecycle (recall, promotion). However, it lacks details on optional parameters, usage context, and return values (though output schema may cover the latter).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description does not explain any parameters beyond the implicit 'content'. The optional 'why' and 'tags' parameters are not described, leaving the agent uninformed about their purpose.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb-resource pair ('Record a NEED') and provides concrete examples. However, it does not explicitly distinguish this tool from siblings like 'capture' or 'generalize', which might overlap in functionality.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what a need is but gives no guidance on when to use this tool versus alternatives. There are no when-not-to-use conditions or references to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

review_promotionsA

What's ready to move up? Lists local items eligible for team, team items eligible for org (endorsed), and org PRs already opened. The human-readable checkpoint before running promote().

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must bear the full burden. It transparently explains the tool lists eligible items and opened PRs, implying a read-only action. It doesn't discuss auth or rate limits, but for a list tool this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences are front-loaded with a hook ('What's ready to move up?') and efficiently convey purpose and context. Every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, an output schema (not shown but present), and clear description of three item categories and its role as a checkpoint, the description is fully complete for this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are no parameters, and the schema coverage is 100% (trivially). The description doesn't need to add parameter meaning; a baseline of 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists items eligible for promotion at local, team, and org levels, acting as a checkpoint before promote(). It uses a specific verb 'lists' and resource 'items eligible', and differentiates from sibling tools like promote.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says it's a 'human-readable checkpoint before running promote()', guiding when to use it. It could be improved by noting when not to use or alternatives, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

setupA

Finish cambium's setup in one call — the tool status() and every unconfigured error point you to. Validates paths, scaffolds .cambium/ (and gitignores it), and writes a local fallback config the server reads when env vars are absent (env still wins when set, and it takes effect immediately — no restart).

project_repo : absolute path to your project's git clone (required) agent_id : your unique agent id (required) org_repo : optional — a local clone path, OR a GitHub 'owner/name'. If a name isn't cloned locally, setup OFFERS the exact gh/git commands to stand it up and leaves org scope off; it never creates or pushes a repo for you. org_pr : optional — org promotion opens a pull request instead of a direct push. team_branch : optional — override the team-scope branch (default 'cambium').

No secrets are written anywhere; the config file holds only paths, ids, and flags, and lives outside any repo.

ParametersJSON Schema
NameRequiredDescriptionDefault
org_prNo
agent_idYes
org_repoNo
team_branchNo
project_repoYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses behavioral details: validates paths, scaffolds a directory, writes config, env vars override, no restart needed, org_repo only suggests commands, never creates/pushes, and no secrets written.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a summary sentence followed by parameter details. It is informative without being overly verbose, though slightly lengthy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema, the description covers all necessary aspects: parameter behaviors, side effects, and constraints. It is complete for a setup tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description provides detailed explanations for all 5 parameters, including their purpose, requiredness, and special behavior (e.g., org_repo offering commands if not cloned). This adds significant meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool 'finish[es] cambium's setup in one call' and enumerates specific actions like path validation, scaffolding .cambium/, and writing config. It distinguishes itself from sibling tools like status and capture by focusing on setup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when status or errors indicate incomplete setup, and explains optional parameters' behavior. However, it does not explicitly state when not to use it or mention alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stale_reportA

Which promoted knowledge might be going stale? Lists team + org entries (the ones that cleared the trust gate) sorted OLDEST-VERIFIED-FIRST, with never-reverified entries flagged at the top and each entry's valid_while premise surfaced so a reader can spot dead assumptions ("while we're on NetSuite" long after the NetSuite migration).

project : limit to one project's entries (default: all) older_than_days : only entries last verified more than N days ago (plus every never-verified one); 0 = no age filter.

Event-driven, not clock-driven: this reports absent/old verification events, it does NOT compute a decaying confidence score. Re-confirm with verify_entry(); promotion also counts as a verification.

ParametersJSON Schema
NameRequiredDescriptionDefault
projectNo
older_than_daysNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, but the description fully discloses behavior: sorting order, flagging of never-reverified entries, surfacing of valid_while premises, and the event-driven nature. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured, starting with a question to introduce purpose, then explaining output, parameters, and behavioral notes. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the existence of an output schema, the description covers all necessary aspects: purpose, parameters, behavioral traits, and differentiation from siblings. It is complete and informative.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 0% schema description coverage, the description explains both parameters in detail: project for limiting to one project (default all) and older_than_days for age filter (0 means no filter, includes never-verified). Defaults and behavior are clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists promoted knowledge that might be stale, sorted oldest-first, with flagged never-reverified entries and surfaced valid_while premises. It distinguishes itself from siblings like verify_entry.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states it is event-driven and not clock-driven, advises against using it for decaying confidence scores, and directs to verify_entry for re-confirmation. It also mentions that promotion counts as verification.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

statusA

First thing to call — especially when cambium looks broken. Returns structured config state: what's set, what's missing, what each gap costs in plain terms, and the exact setup() call that fixes it. NEVER raises on missing config. When fully configured it also reports item counts per scope/type, distill watermarks, and which substrates are actually wired.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, but description fully discloses behavior: never raises on missing config, reports config state, item counts, watermarks, and wired substrates. Transparent about what it does and does not do.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with key purpose, no wasted words. Every sentence provides essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters, no annotations, and presence of output schema, the description covers all needed context: purpose, output details, and behavior on missing config. Fully complete for a status tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, schema coverage 100%. Description adds value by explaining what the tool accomplishes without needing parameters, exceeding the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'First thing to call' and returns structured config state, distinguishing it from siblings by positioning it as the initial diagnostic tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'First thing to call—especially when cambium looks broken' and notes it never raises on missing config, providing clear context. Lacks explicit when-not or alternative names but is strong overall.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_entryA

Confirm a knowledge entry still holds — stamp its last_verified to now. This is the event that keeps promoted knowledge honest: promotion's trust gate defends what comes IN, verification keeps an entry from silently going stale after. An optional note records what was confirmed. Absent/old last_verified is a signal (see stale_report), never an automatic downgrade. Works on local and team entries; find stale ones with stale_report().

ParametersJSON Schema
NameRequiredDescriptionDefault
noteNo
item_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses behavior: it stamps 'last_verified' to now, supports an optional note, works on local and team entries, and does not automatically downgrade when stale. This covers all relevant behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise (4-5 sentences) and front-loaded with the core action. Every sentence adds distinct value: purpose, rationale, optional note, behavioral nuance, and scope. No redundant or vague statements.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, usage, behavior, and scope well. For a simple tool with 2 params and no annotations, it is nearly complete. It does not describe the return value (output schema exists but not mentioned), which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description adds meaning: 'note' is documented as optional record, 'item_id' is implied to identify entries, and scope ('local and team') is provided. It lacks explicit format or constraints for 'item_id', but still adds value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verbs ('Confirm', 'stamp') and clearly identifies the resource ('knowledge entry'). It distinguishes this tool from siblings like 'stale_report' and 'promote' by explaining the verification role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use this tool (after promotion, to prevent staleness) and explicitly points to 'stale_report' for finding stale entries. It also clarifies that verification does not automatically downgrade, providing clear usage context.

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.

  1. 14 tool updatesv0.1.0
    • First observedcapture
    • First observeddistill
    • First observedendorse
    • First observedexport_markdown
    • First observedgeneralize
    • First observedimport_memory
    • First observedpromote
    • First observedrecall
    • First observedrecord_need
    • First observedreview_promotions
    • First observedsetup
    • First observedstale_report
    • First observedstatus
    • First observedverify_entry

TDQS

A4.2/5.0

Scored across 14 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: capture (manual save), distill (automatic import), endorse (vouch), export_markdown (render), generalize (restate as cross-project rule), import_memory (ingest external exports), promote (graduate scopes), recall (search), record_need (record a need), review_promotions (list eligible items), setup (initial config), stale_report (find stale entries), status (check config), verify_entry (confirm entry). Only minor overlap between capture and distill, but descriptions clarify the difference.

Naming Consistency5/5

Tool names follow a consistent verb_noun pattern with underscores (e.g., record_need, review_promotions, export_markdown, verify_entry). Some are single verbs (capture, distill, endorse, generalize, promote, recall, setup, status), which is also consistent. No mixing of camelCase or other conventions.

Tool Count5/5

14 tools is well-scoped for a knowledge management server covering capture, import, search, promotion, verification, reporting, and configuration. The number feels appropriate—not too few to miss functionality, not too many to be overwhelming.

Completeness4/5

The tool set covers the knowledge lifecycle comprehensively: creation (capture, distill, import_memory), search (recall), promotion (promote, review_promotions), endorsement (endorse), verification (verify_entry, stale_report), rendering (export_markdown), generalization (generalize), and setup. Missing explicit delete or update tools, but the domain may not require them (items can become stale). Minor gap.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers