Knowledge-lifecycle MCP: distill agent work into memory, recall it from any agent, promote it local->team->org as it earns trust. Bridges agentsync + context-keeper.
claude mcp add cambium -- python -m -r{
"mcpServers": {
"cambium": {
"command": "python",
"args": ["-m", "-r"]
}
}
}MCP Servers overview
# cambium
<!-- mcp-name: io.github.jarmstrong158/cambium -->
_Part of the [xylem](https://github.com/jarmstrong158/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](https://github.com/jarmstrong158/agentsync) (what happened:
claims, finishes, notes, changed files) and
[context-keeper](https://github.com/jarmstrong158/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.
## Install
```bash
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:
```json
{
"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:
```jsonc
{
"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, scopWhat people ask about cambium
What is jarmstrong158/cambium?
+
jarmstrong158/cambium is mcp servers for the Claude AI ecosystem. Knowledge-lifecycle MCP: distill agent work into memory, recall it from any agent, promote it local->team->org as it earns trust. Bridges agentsync + context-keeper. It has 0 GitHub stars and was last updated today.
How do I install cambium?
+
You can install cambium by cloning the repository (https://github.com/jarmstrong158/cambium) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is jarmstrong158/cambium safe to use?
+
jarmstrong158/cambium has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains jarmstrong158/cambium?
+
jarmstrong158/cambium is maintained by jarmstrong158. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to cambium?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy cambium to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/jarmstrong158-cambium)<a href="https://claudewave.com/repo/jarmstrong158-cambium"><img src="https://claudewave.com/api/badge/jarmstrong158-cambium" alt="Featured on ClaudeWave: jarmstrong158/cambium" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!