Local memory & self-improvement engine for Claude Code and OpenCode: captures your coding sessions and distills how your patterns, habits, and knowledge evolve over time — a person-centric growth archive (file/PDF support coming), with provenance, served over MCP. Single Go binary.
git clone https://github.com/IngTian/witness{
"mcpServers": {
"witness": {
"command": "witness"
}
}
}MCP Servers overview
# witness — Let Claude Code and OpenCode witness your growth.
[](LICENSE)
[](https://www.npmjs.com/package/@witness-ai/opencode)



**witness is a local memory & self-improvement engine for Claude Code and OpenCode.** It captures
your coding sessions and distills how your patterns, habits, and knowledge **evolve over time** —
a person-centric growth archive with provenance, served over an MCP server + plain files, as a
single pure-Go binary. Think *second brain / AI memory* for how you think and grow, not project
memory for what your code did. **It also ingests your own records** — feed it notes, articles, or
any text stream with `witness ingest`, and the same engine distills how that knowledge evolves,
not just your chats.
> *"Aah, you were at my side, all along.*
> *My true mentor...*
> *My guiding moonlight..."*
> — Ludwig, the Holy Blade
A Claude Code / OpenCode plugin that quietly keeps a **person-centric archive of how you grow
and change** as you work — your thinking, workstyle, habits, the cognitive traps you fall into
and climb out of, and how all of it shifts over time. Not a record of *what your code did*
(other tools do project memory) — a record of **who you are becoming**.
It is **reflection-oriented, not clone-oriented**: the point is to let Claude understand you and
reflect you back to yourself, and to leave you a re-readable record of how you thought and grew.
It is a **pure tool, not a coach** — it captures, structures, and serves the archive (via an MCP
server and plain files). Building a *coach* on top of it (proactive reflections, "you've done this
three times…") is left to other projects that read its output.
## Is this you?
witness is the answer if you've ever wanted to:
- **Remember what you learned across your AI coding sessions** — Claude Code, OpenCode — instead of losing it when the context window resets.
- Have a **second brain / AI memory** for your thinking, workstyle, and habits, queryable by your agent.
- **Track how you grow as a developer over time** — the traps you fall into and climb out of — with provenance for every recorded change.
- Keep a **journal / retrospective** of how you thought and changed, re-readable months later.
- **Distill your own records** — feed notes, articles, or any text stream to `witness ingest` (NDJSON) and see how that knowledge evolves across documents, not just chats.
**Contents:** [How it works](#how-it-works) · [Lenses](#lenses) · [Example](#example-one-moment-end-to-end) · [Reading the archive](#reading-the-archive) · [Commands](#commands) · [Install](#install) · [Configuration](#configuration) · [Your data](#your-data-is-yours)
## How it works
Four layers — one ground-truth, three derived and **regenerable** from it:
| Layer | Kind | What it is |
|-------|------|------------|
| **raw (L0)** | ground truth | Every turn captured verbatim — from stable Claude Code hook fields (`UserPromptSubmit.prompt`, `Stop.last_assistant_message`) or OpenCode's local SQLite session DB (`message`/`part` text). Append-only, never LLM-touched. |
| **observations (L1)** | derived | A cheap per-session worker mines atomic, evidence-anchored observations about *you*, tagged by lens. Append-only. |
| **facets (L2)** | derived, bi-temporal | A periodic reviewer synthesizes observations into evolving *facets*, each keeping its **change history** (`valid_from`/`valid_to`) — so the archive answers "how did I change," not just "who am I now." Old values are never deleted. |
| **profile (L4)** | derived narrative | A short, human-readable markdown summary distilled from the facets, regenerated after each review: one per lens plus a cross-lens `unified` portrait. |
The archive is **collect-only / pull-only**: witness captures and distills everywhere, but never
injects anything into a session. Nothing is pushed — you (or an agent) read the profile on demand.
raw/observations/facets live in a single embedded SQLite database (`witness.db`); the profile is
plain markdown under `profile/`.
### Lenses
Every observation/facet carries a **lens** tag:
- **`default`** — global, runs on every session, cross-domain. This is the part no single-domain
tracker can be: it sees that "diagnoses gaps precisely" fires in math *and* coding *and* career.
- **registered lenses** (e.g. `math`) — domain-specific lenses you **register once** and **enable
globally**. `witness lens register math ./math/` adds the definition (a directory) to a central
registry; `witness lens enable math` makes it run on every session (alongside `default`). Lenses
are shared, not tied to any repo, so the same `math` lens covers all your math work.
#### Writing a lens
A lens is a **directory** of three files:
```
math/
lens.json settings: name, dimensions, optional per-lens models
extract.md per-session — mines observations (the whole file is the prompt)
review.md periodic — synthesizes observations into facets (the whole file is the prompt)
```
```json
// math/lens.json
{ "name": "math", "dimensions": ["speed", "independence", "proof_rigor", "abstraction", "confusion_tolerance"] }
```
```markdown
<!-- math/extract.md -->
You are observing one session through a MATH-LEARNING lens. Notice things about the
person as a mathematician — how they reason, get stuck, and climb out…
Return ONLY a JSON array. Each element:
[{ "dimension": "proof_rigor", "observation": "…", "evidence": "…", "poignancy": 6 }]
```
The one rule to remember: each prompt file is used **verbatim as the system prompt** and *replaces*
the built-in `default` prompts — it doesn't extend them — so each must be **self-contained,
including its output JSON schema** (the tool appends the transcript / observations as the user
message, but injects no schema for you).
A **complete, copy-paste-ready** lens lives at [`prompts/lens/example/`](prompts/lens/example) —
the fastest way to start is to copy the directory and rewrite the dimensions and prose for your
domain:
```sh
cp -R "$CLAUDE_PLUGIN_ROOT/prompts/lens/example" ./math # edit the files, then:
witness lens register math ./math # copies the definition into your store (a snapshot)
witness lens enable math # start running it on every session
```
`register` stores a **copy** — editing the original afterward has no effect until you re-register.
`enable` is the separate switch that makes it actually run.
**Per-lens models (optional).** By default every lens rides the default models (`witness config set
triage_model / distill_model`). A rare heavy lens can pin a stronger model just for itself —
without paying for it on every session — with `witness lens set math --extract-model <m>`
(and `--review-model <m>`); pass an empty value to clear it and ride the default again.
The source directory may live anywhere. As a recommended canonical location, witness keeps the
registered copy beside `config.toml` under `<witness-data-dir>/lenses/<name>/` (normally
`~/.local/share/witness/lenses/<name>/`, or `$WITNESS_HOME/lenses/<name>/`). You can edit that
registered copy directly, but this location is a convention rather than a restriction on the
directory passed to `lens register`.
## Example: one moment, end to end
Say a session contains this exchange (fictional):
> **you:** the migration keeps failing on prod but passes locally — I'll just run it by hand and move on
>
> **you:** …wait, what's actually *different* about prod? let me diff the two schemas before I touch anything
Here's what each layer makes of it.
**raw (L0)** — captured verbatim, nothing interpreted:
```
user the migration keeps failing on prod but passes locally — I'll just run it by hand and move on
user wait, what's actually different about prod? let me diff the two schemas before I touch anything
```
**observations (L1)** — the worker mines one atomic, evidence-anchored noticing:
```
[thinking] Caught the urge to hand-patch around a failure and redirected to isolating the
prod/local difference before acting.
evidence: "run it by hand and move on" → "what's different about prod? diff before I touch anything"
poignancy: 6 lens: default
```
**facets (L2)** — after several such moments the reviewer synthesizes an evolving attribute, and
**keeps the history** (the whole point — it shows *change*, not just current state):
```
default · thinking · diagnoses_before_acting confidence 0.82
2026-05 → now Catches the reflex to work around a failure and isolates the
mechanism first; gates action on understanding the cause.
2026-02 → 2026-05 Tended to apply the first workaround that unblocked the task. (superseded)
```
**profile (L4)** — the narrative you actually read (`witness profile`):
> ## default
>
> You've been converging on a diagnose-first way of working. A few months ago the pattern was to
> reach for whatever unblocked the task; now you routinely catch that urge and turn to isolating the
> mechanism before you touch anything…
Nothing here is pushed into your sessions — you read it when you want it (`witness profile`), or an
agent pulls the relevant facet on demand.
## Reading the archive
Humans read the **narrative**; agents read the **structured** data. Over MCP:
- `get_profile(lens)` — the narrative profile (prose); omit `lens` for the unified portrait.
- `get_facets(lens)` — the current structured facets.
- `search_observations(query, lens)` — local vector search over observations.
- `record_observation(...)` — an in-session agent writes a decision-aware observation direWhat people ask about witness
What is IngTian/witness?
+
IngTian/witness is mcp servers for the Claude AI ecosystem. Local memory & self-improvement engine for Claude Code and OpenCode: captures your coding sessions and distills how your patterns, habits, and knowledge evolve over time — a person-centric growth archive (file/PDF support coming), with provenance, served over MCP. Single Go binary. It has 8 GitHub stars and was last updated today.
How do I install witness?
+
You can install witness by cloning the repository (https://github.com/IngTian/witness) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is IngTian/witness safe to use?
+
IngTian/witness has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains IngTian/witness?
+
IngTian/witness is maintained by IngTian. The last recorded GitHub activity is from today, with 5 open issues.
Are there alternatives to witness?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy witness 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/ingtian-witness)<a href="https://claudewave.com/repo/ingtian-witness"><img src="https://claudewave.com/api/badge/ingtian-witness" alt="Featured on ClaudeWave: IngTian/witness" 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!