Skip to main content
Glama

Why

Your agents settle choices all day: a library, an approach, an option turned down. Those choices usually live in a chat that ends, in one tool's memory or in somebody's head, where nobody can check who decided them or whether they were changed since. mnema writes them down in the repository, next to the code, with their reasons and what was turned down. The record is signed and only grows: a change of mind is a new entry that supersedes the old one, never an edit. Where the host runs hooks, each session opens with the decisions in force, and anyone can check offline that what it holds was not changed since it was signed. What is measured, and what is not, is on the evidence page.

Related MCP server: horizon-ledger

Status

  • On npm. @mnema/code is published: install it with npm i -g @mnema/code (docs/install.md); to run the main branch instead, see Build from source.

  • In the editor stores. The VS Code extension is on the Visual Studio Marketplace and Open VSX as mnema.mnema, and still needs the mnema command from @mnema/code.

  • These pages describe the next version (the main branch). What has not reached npm yet is listed under Unreleased in the Changelog.

  • Node. Requires Node 24.15.0 or a later 24, or 26.0.0 or later.

  • From a checkout. The GitHub Action and the SDK are not published, and run from a clone of this repository (Packages).

Quick start

npm i -g @mnema/code                              # the binary
cd your-repository
mnema init                                        # founds the record in .mnema/
mnema decision record "Keep money as integer cents" "Float sums drift; cents are exact."
mnema decision move accept ADR-1 --note "Agreed in review."   # a decision enters proposed; accepting puts it in force
mnema link ADR-1 src/billing --rel refuses-a-write             # the rule, addressed at a path
mnema verify   # reads the signed record; one line saying it is intact is the green

No agent has run yet: that is the record, a rule in force, and the proof. ADR-1 names the first decision of a new record. To hand the record to an agent, install the plugin for your host; in Claude Code:

claude plugin marketplace add mnema-work/mnema
claude plugin install mnema@mnema

Every other host is in Hosts. mnema init also writes the mnema instructions into AGENTS.md and the other files agent hosts read, naming each; at a terminal it first asks which hosts, and shows everything it will write before it writes it, and mnema instructions --remove takes them out. The first record, step by step, is Your first record.

How it works

  1. Record. An agent over MCP, or you at the command line, writes a decision with its reasoning and the options turned down, and a task with its description and a handoff with its brief.

  2. Rule. A person accepts it, or an agent where agent-accepts is on (the default; an agent's acceptance is marked as its own), and mnema link addresses it at a path. The rule can govern that path, ask for a person there, or refuse a write.

  3. Hand over. With the plugin, each session opens with what is in force (in Claude Code, so does each subagent), and each edit meets the rules for its file. In Claude Code, a note of the host's own memory is also copied into this machine's private tree, until you switch that off.

  4. Verify. Every write ends in a signed checkpoint and is hash-chained; a reader's guarantee runs up to the last checkpoint. mnema verify, a second reader in Python, or the page mnema site writes checks it.

More in docs/how-it-works.md; what a session is handed, word for word, is in docs/agent-hosts.md, and how far each host goes is under Hosts.

Hosts

mnema works with any agent host that has an MCP client, and how much more a host gets depends on what its hooks allow, one rung at a time: (a) the MCP server and rules in a file, (b) the opening of a session, (c) a refusal before a write, (d) a pause for a person.

Host

Rung

What it gets

Install

Claude CodeAnthropic · terminal and editors

(d)

MCP server · rules file · opening · refusal · pause · rules at an edit

Plugin

VS CodeMicrosoft · the agent of the editor

(d)

rules file · refusal · pauseMCP server · opening: read once

Plugin

Cursor CLICursor · command line

(c)

rules fileMCP server · opening · refusal: read once

Plugin

CodexOpenAI · command line

(c)

MCP server · rules file · opening · refusal · rules at an edit

Plugin

Copilot CLIGitHub · command line

(d)

MCP server · rules file · opening · refusal · pause · rules at an edit

Plugin

OpenCodeAnomaly · command line

(c)

MCP server · rules file · opening · refusal · rules at an edit

Plugin

Gemini CLIGoogle · command line

(c)

MCP server · rules file · opening · refusal · rules at an edit

Plugin

Qwen CodeQwen · command line

(c)

MCP server · rules file · opening · refusal · rules at an edit

Plugin

CursorCursor · editor

(a)

MCP server · rules filedocumented, not measured

MCP server

Antigravity CLIGoogle · command line (agy)

(a)

MCP server · rules filedocumented, not measured

MCP server

Factory DroidFactory · command line

(a)

MCP server · rules filedocumented, not measured

MCP server

GooseAgentic AI Foundation · desktop and command line

(a)

MCP server · rules filedocumented, not measured

MCP server

Each cell of the full table, how each one is known (held by a test, read once on a real host, or documented and not measured), and the notes on each host are in How each claim is held.

The mnema family

@mnema/code holds the record, and the command line and the MCP server that read and write it. The rest stand around it. The detail of most of them is in Features; for the rest, the Link column leads to the page that has it.

Product

What it is for

Status

Link

@mnema/codethe core

The signed, append-only record, with the command line and the MCP server over it.

npm i -g @mnema/code (Install).

Package

GitHub Action

On a pull request, comments what the change does to the record and fails the check when it is not signed.

Not published; runs from a clone of this repository.

Package

SDK

A library door to the record, for a program that records, reads and verifies.

Not published; runs from a clone of this repository.

Package

VS Code extension

Shows the rules in force over the open file, the decisions waiting for a judgment and the stacks adopted.

On the Visual Studio Marketplace and Open VSX as mnema.mnema (code --install-extension mnema.mnema); it runs the mnema command, so @mnema/code stays a prerequisite.

Package

Stacks

Installs a set of skills and agents from a plan shown whole, and records the adoption as a signed fact.

Commands of mnema, not a package of their own; the contract they check against, @mnema/stacks, ships with @mnema/code.

Stacks

An agent in CI

A pipeline's agent records with a key of its own, so what it records is signed as that agent.

A recipe, not a package.

The recipe

A page that verifies itself

mnema site writes one HTML file, and the reader's browser checks it.

A command of @mnema/code, not a package.

The page

Watch it

A case in the suite runs the scripts again against the built binary and fails when a recording no longer shows what the binary draws, so none of them can go on showing an older product in silence (the-recordings-are-what-the-binary-draws.test.ts).

What it is not

Each of these is a choice with a reason, and the reasons are in Where it fits.

  • Not a semantic memory. Search is by the words written in a record; there are no embeddings.

  • Not an agent runner. It calls no model and runs no tool for the agent.

  • Not a copy somewhere else. The committed record travels with the repository, and what you record privately stays on this machine, apart from the notes and the private rules your agent's host receives, when a session opens through the plugin and when the agent asks for them, which the host sends to its model; the witness verbs send a digest out, and with Sigstore the identity too, only when you run them.

  • Not access control. The gate refuses an illegal move; it does not decide who may write.

What it proves, and what it does not

mnema verify reads the events and the committed public keys of a project's trees (no private key, no network) and prints each verdict verbatim, naming the level it reached.

  • What holds. A changed or reordered event breaks the hash chain, and an edit made without the signing key is caught where the signed checkpoints remain; verify --require=signed fails when they were taken out.

  • What does not hold. Nothing proves that nothing was removed: a hash chain shows what changed, never what is gone, and the history a git remote keeps is what covers omission. A record forged whole under a fresh key verifies clean, a key is not proven to be the person a name says, and the agent named on a fact is the name its client announced, unless an agent key signed it (then the name the record enrolled the key under). An agent key's role and its retirement are facts of the record that holds them: verify crosses a project's trees for a retirement, and a reader of one tree does not. A refusal of a write covers a host's editing tools, not its shell: sed -i on a protected file goes round it.

  • What a green verify means. That nothing verifiable is broken, not that the record is honest, and the gate protects the shape of a change, not who may make it.

The whole table, claim by claim, is in docs/what-it-proves.md; how each claim about the agent hosts is held, and which are not held yet, is in docs/evidence.md.

Docs

License

Apache-2.0. See LICENSE and NOTICE.

Available Tools

27 tools
audit_accountabilityAudit: who authorized whatA
Read-onlyIdempotent

Show who authorized what and which agent executed it, across ALL trees of ALL projects in this workspace. Use it to answer "who did what" over the whole record: with no filter it accounts for everything (like git shortlog). Optionally narrow by a time window (from/to), a single author (who), or a single executing agent (which). The answer is ONE ACCOUNT PER PROJECT (plus the machine-global tree, which belongs to none), each with its own total and per-author breakdown (counts by kind and by executing agent) and, beside each author, foundedBeside: every tree of that record where the identity was founded after others already were, with when and which identities were there (somebody new to the record, or one person under a second key); empty when it founded first or was vouched for. There is deliberately no combined total: a count belongs to a record, and adding several projects up answers "how much have I written anywhere" under the name of "how much is in this record". Add them yourself if that is your question. A project with nothing to report is listed at zero rather than left out. Read-only.

Inputs: to, who, from, which.

audit_antipatternsAudit: recurring shapes in the recordA
Read-onlyIdempotent

Show recurring shapes across ALL trees of ALL projects in this workspace: tasks reopened, decisions superseded, skills deprecated, each with the exact events that make up the count, plus the tasks reopened more than once as skill CANDIDATES (a POINTER, not an action: this creates no skill). It also reports any ADR- label that more than one decision of the SAME chain answers to, with every id that carries it: the number is frozen when a rule is recorded, so two people deciding while apart can mint the same one, and from then on citing it by label names two rules. Nothing renumbers them: refer to those by id. It reports the shapes; it does NOT judge them good or bad. Use it to spot patterns a human might act on. The answer is ONE SET OF SHAPES PER PROJECT (plus the machine-global tree, which belongs to none): these are counts, and adding several projects up would answer a question about a workspace under the name of a question about a record: a skill candidate especially, since the pattern is distilled by whoever is doing the work that kept reopening. A project with nothing recurring is listed with empty lists rather than left out. Read-only.

Inputs: no named parameters.

audit_exposureAudit: where a credential may already be recordedA
Read-onlyIdempotent

Show which records hold something shaped like a credential (a cloud key, an API token, a private key, a password inside a URL) across ALL trees of ALL projects in this workspace. Use it to answer "is a secret already in the record?", which writing can no longer cause but the past can: values in a recognized format never reach the chain today (replaced in a body, and REFUSING the whole write in a name), and everything recorded before that was not. It reports WHERE and never WHAT: the id, the kind, the tree, the PROJECT and the instant, plus the CLASS, never the value, so reading it cannot leak what it found. A record in a public tree is committed and clones to every machine; one in the global tree is on this disk alone; and the project says which repository to go and change a key in. The remedy is to ROTATE the credential: mnema is append-only and nothing deletes a fact. scanned is ONE COUNT PER RECORD (each project and the machine-global tree), so an empty findings says which records were read and how much of each. Two limits: it recognizes FORMATS, so an empty report means nothing recognizable rather than nothing (a password in prose has no format); and it reports what is recorded: it does not prevent a value from being read back by search or read_record, which serve the record as written. Read-only.

Inputs: no named parameters.

audit_refsAudit: what an entity is connected toA
Read-onlyIdempotent

Show what one entity is connected to across ALL trees of ALL projects in this workspace: the observations about it, the links into and out of it, the decision that superseded it. Use it after search to pull on a thread: "what else is tied to this?". By default it is the NEIGHBOURHOOD (one hop, either direction); set direction to "out" (what it points at) or "in" (what points at it) with a larger depth to follow a lineage, such as a decision’s supersede chain. direction: "in" is how you answer "have I already applied this in my other projects?": the things that point at it are in THEIR records, and every edge says which project asserts it. A far end no visible tree holds comes back marked unresolved (that is legitimate, not an error), and the answer says when the depth cut it. Give it a PATH a link ends in and the answer also carries file: whether that file exists in the working tree today and the SHA-256 of its bytes. Read-only.

Inputs: id (required), depth, direction.

audit_timelineAudit: the full history of an entityA
Read-onlyIdempotent

Show the complete history of one entity (a task, decision, skill, …) across ALL trees of ALL projects in this workspace: every event where it is the subject, plus events that refer to it (an observation about it, a link whose target is it), which may live in another tree, or in another project. Use it to answer "tell me the whole story of this entity", including the part that happened in a sibling codebase; each entry says which project it came from. An id no event touches returns an empty history (a valid answer). Read-only.

Inputs: id (required).

bootstrapBootstrap the sessionA
Read-onlyIdempotent

The opening context for this session's actor: where they left off, the LIVE work, the patterns, the DECISIONS IN FORCE (settled here and not replaced) and what is AWAITING A JUDGEMENT. Derived from the chain. Every list is NAMES, never bodies: a task as id, title and state, a pattern as id and name, a decision as id, title and its ADR- label. For the rest, by id: next_actions for a task’s moves, skills for a pattern (asking records the consultation), read_record for a decision’s argument and its label. Only a decision IN FORCE is listed: proposed, rejected or superseded is left out. awaitingJudgement is one list of all three; kind says which, state what is owed: proposed the first ruling, reviewed the adoption call, IN_REVIEW the approve-or-send-back. A DONE or CANCELED task is on NEITHER list; ask search (kind task). Three lists are CUT to the freshest; workTotal, decisionsTotal and awaitingJudgementTotal say how many in all, so a total larger than its list means more is not shown, and search reaches past every cut. Every adopted pattern is listed, so it has no total. EVERY LIST HERE IS ABOUT A TASK, A DECISION OR A PATTERN, so empty lists do NOT mean the record is empty: unread names each kind not looked at, with how much, to pass to search; it is ABSENT when there is nothing to declare. Runs: thisSession is true only when THIS connection opened it: false means another session on this machine, live or abandoned, which the record cannot tell apart. An OPEN run carries ageSeconds, and idleSeconds only once it has recorded something, so NO idleSeconds means it recorded nothing; both compare this clock with the writer’s. EVERY run, open or ended, carries wrote: one {kind, count} per kind recorded in it, commonest first, never absent, EMPTY meaning nothing was recorded; the run’s own start and end are not counted, and audit_timeline serves the facts. An open run is no proof of a live session; mnema run end <id> --which <agent> closes one.

Inputs: no named parameters.

capture_memoryCapture a memoryA

Record a point-in-time fact into the mnema chain, attributed to this agent and pinned to the current session. Optionally pick the scope it lands in: public (team-visible), private (this machine, this project), or global (personal, cross-project); omitted, it follows the session default (private for an agent in a project, global outside one). Optionally pick the project it lands in, when the workspace holds more than one. The reply says which tree it landed in. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: content (required), scope, project.

create_skillPropose a skillA

Propose a reusable pattern (a skill) into the mnema chain, attributed to this agent and pinned to the current session. A skill needs both a name (a short title) and a body (the reusable pattern itself). Optionally pick the scope it lands in: public (team-visible), private (this machine, this project), or global (personal, cross-project); omitted, a pattern states how the work is done here and lands PUBLIC: committed, so the team gets it on clone (global outside a project); it is born proposed, so creating one proposes it rather than adopting it. Optionally pick the project it lands in, when the workspace holds more than one. Returns the minted id (the key to move it), the name, and which tree it landed in. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: body (required), name (required), scope, project.

create_taskCreate a taskA

Open a task in the mnema chain, attributed to this agent and pinned to the current session. A task needs a title; it starts in the workflow’s initial state and is moved from there with task_transition. Optionally pick the scope it lands in: public (team-visible), private (this machine, this project), or global (personal, cross-project); omitted, a task is the team’s work board and lands PUBLIC: committed, so a clone has the board (global outside a project). Optionally pick the project it lands in, when the workspace holds more than one. Optionally give a description (up to 64 KiB of text, refused beyond it): what the task is, recorded in the same call as an observation about it (topic description) whose id the reply names. Returns the minted id (the key to move it), the short alias a human reads, and which tree it landed in. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: title (required), scope, project, description.

decision_transitionMove a decision through the workflowA

Move an existing decision to a new state. accept and reject a proposed decision (each needs a note); supersede a proposed or accepted decision with a later one: supersede needs the successor decision id in by and a reason. by applies ONLY to supersede; accept and reject REFUSE it. An illegal move or missing proof is refused with the gate’s reason. The decision is looked for in EVERY project of this workspace and the move lands in the project that holds it: the id decides, so no project is taken. An acceptance made through this tool is recorded as an agent’s, says so in the reply, and is marked as such wherever the decision is read. The switch agent-accepts turns it off, and then an accept is refused. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: id (required), action (required), by, note, +1 more.

focusFocus: what I am touching nowA
Read-onlyIdempotent

Show the open runs of THIS session’s actor: the work in flight right now. Use it to answer "what am I in the middle of". Read-only: it derives from the chain and writes nothing. Reports only this machine’s own open runs (the actor is the session, never a supplied value). Runs: thisSession is true only when THIS connection opened it: false means another session on this machine, live or abandoned, which the record cannot tell apart. An OPEN run carries ageSeconds, and idleSeconds only once it has recorded something, so NO idleSeconds means it recorded nothing; both compare this clock with the writer’s. EVERY run, open or ended, carries wrote: one {kind, count} per kind recorded in it, commonest first, never absent, EMPTY meaning nothing was recorded; the run’s own start and end are not counted, and audit_timeline serves the facts. An open run is no proof of a live session; mnema run end <id> --which <agent> closes one.

Inputs: no named parameters.

governing_rulesWhich recorded rules govern this pathA
Read-onlyIdempotent

Show which rules of THIS project’s record are addressed at a path: a decision or a pattern linked to it with rel: "governs", most specific first. Use it before changing a file, to find the decisions that already apply to it; the id it returns is what you cite when you follow one. An address is a PREFIX by path segment: a rule on src/collate governs src/collate/fold.ts and does NOT govern src/collate_test.rb. Every answer carries three counts, zeroes included: how many rules cover this path, how many address this project at all, and how many address something the working tree no longer holds: a rule whose file was moved or deleted has stopped governing, and the third count is how you find out. It reports each rule’s state and decides nothing: it refuses nothing, blocks nothing, and does not judge whether a rule still holds. Addresses come from THIS project only, because an address is relative to a project root. A relative path is resolved against the project root, not a working directory. Read-only.

Inputs: path (required).

guardGuard: would a move be allowed?A
Read-onlyIdempotent

Simulate whether a task transition would be permitted BEFORE trying it: a dry-run of the workflow gate that writes NOTHING. Use it to answer "may I approve/complete/… this task, and if not, why?" without making the move. It reads the task’s current state and returns the gate’s own verdict: ALLOWED (with the state the move would reach) or REFUSED (with the gate’s reason: an illegal move, missing proof, or who == which). Pass the same proof you would carry (note/reason/feedback) to see if that proof suffices. It also refuses, with the write’s own code and words, what this machine’s key would be refused in the task’s tree: a key protected by a passphrase that is not set, an agent that tree does not enrol where the person’s key that would sign instead is not at hand, an agent retired (AGENT_NOT_ENROLLED, REVOKED_KEY, KEY_IS_PROTECTED, AGENT_NAME_REFUSED, AMBIGUOUS_MEMBERSHIP). It cannot know a wrong passphrase, a record busy at that moment, or another write changing the task before your move; and with no key on the machine yet it says who is missing, though the first write makes the key. The verdict is paired with your current focus. The task is looked for in EVERY project of this workspace, as task_transition looks; an id no tree of it holds is refused, naming the projects searched. Read-only. Runs: thisSession is true only when THIS connection opened it: false means another session on this machine, live or abandoned, which the record cannot tell apart. An OPEN run carries ageSeconds, and idleSeconds only once it has recorded something, so NO idleSeconds means it recorded nothing; both compare this clock with the writer’s. EVERY run, open or ended, carries wrote: one {kind, count} per kind recorded in it, commonest first, never absent, EMPTY meaning nothing was recorded; the run’s own start and end are not counted, and audit_timeline serves the facts. An open run is no proof of a live session; mnema run end <id> --which <agent> closes one.

Inputs: id (required), action (required), note, which, +2 more.

next_actionsNext actions: what moves a task allowsA
Read-onlyIdempotent

Show the transitions the workflow allows a task next, from its current state. Use it to answer "what can I do to this task": each suggestion is a real move the gate would authorize. A terminal task returns an empty list (no legal moves). The task is looked for in EVERY project of this workspace; an id no tree of it holds is refused, naming the projects searched. After the list, a line says who has the task and one the last thing that happened to it, when the record has either. Read-only.

Inputs: id (required).

read_recordRead record: one whole record by idA
Read-onlyIdempotent

Read ONE record in full (a memory’s content, a decision’s rationale and what it turned down, an observation’s text, a task) by the id an index gave you: search, or the decisions bootstrap lists (which carry the title and not the argument). This is the second half of a search: the index tells you what exists, this tells you what it says. It looks in EVERY project of this workspace, not only the one you are working in (an id is minted once and lives in one place) and the answer says which project and which tree hold it. A skill id is refused here and pointed at the skills tool, which serves a pattern’s body and records the consultation. An id no project holds is refused, in a reply that names where it looked. A decision’s ADR- label is a display name a person cites, numbered within one tree and never an identity: two trees can each hold an ADR-1, and only the id tells them apart. Read-only.

Inputs: id (required).

record_decisionRecord a decisionA

Record a decision into the mnema chain, attributed to this agent and pinned to the current session. A decision needs both a title and a rationale (why it was made). Optionally record what you considered and turned down, and why not (alternatives): the reasoning a later reader needs when somebody proposes the thing you already rejected; it is searchable, so search answers "did we already turn this down?". A decision is immutable, so it is recorded now: an option rejected later is a new decision, or supersedes this one. Optionally pick the scope it lands in: public (team-visible), private (this machine, this project), or global (personal, cross-project); omitted, a decision is a declaration about the project and lands PUBLIC: committed, so the team gets it on clone (global outside a project); it is born proposed, so recording one proposes it rather than settling it. Optionally pick the project it lands in, when the workspace holds more than one. Returns the citable ADR- label (a decision has no short alias) and which tree it landed in. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: title (required), rationale (required), scope, project, +1 more.

record_handoffRecord a handoffA

Record a handoff on a task (work passed from one agent to another) into the mnema chain, attributed to this agent and pinned to the current session. It carries the task and the two agent labels (from, to); from == to is legitimate (a chat restart). The task id is NOT checked to exist. Optionally pick the scope and the project; omitted, the handoff follows the task to the tree that holds it (a private task keeps its brief private) and lands PUBLIC (global outside a project) only when no tree holds the task, which the reply says. A handoff has no id of its own: its subject is the task. Optionally give a brief (up to 64 KiB of text, refused beyond it): what the next agent must read, recorded in the same call as an observation about the task (topic brief) whose id the reply names. The reply says which tree it landed in. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: to (required), from (required), task (required), brief, +2 more.

record_observationRecord an observationA

Record an observation ABOUT an entity (a task, decision, …) into the mnema chain, attributed to this agent and pinned to the current session. It carries the observed entity id (about), a short topic, and the observation text. The about id is NOT checked to exist: a reference to an entity in another tree is honest and resolved on read. Optionally pick the scope and the project it lands in; omitted, both follow the session default (private for an agent in a project, global outside one). Returns the observation’s own minted id, and says which tree it landed in. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: text (required), about (required), topic (required), scope, +1 more.

resumeResume: where I left offA
Read-onlyIdempotent

Show where THIS session’s actor left off: their most recent run (open OR already ended) plus their current focus. Use it at the start of a session to answer "where was I": even a run that ended carries the goal that reminds you. When this session has a run of its own here, that is the one reported. Read-only: it derives from the chain and writes nothing. Runs: thisSession is true only when THIS connection opened it: false means another session on this machine, live or abandoned, which the record cannot tell apart. An OPEN run carries ageSeconds, and idleSeconds only once it has recorded something, so NO idleSeconds means it recorded nothing; both compare this clock with the writer’s. EVERY run, open or ended, carries wrote: one {kind, count} per kind recorded in it, commonest first, never absent, EMPTY meaning nothing was recorded; the run’s own start and end are not counted, and audit_timeline serves the facts. An open run is no proof of a live session; mnema run end <id> --which <agent> closes one.

Inputs: no named parameters.

retract_noteRetract a noteA

Take back a memory or an observation that turned out to be wrong or stale. The note is NOT erased: a signed retraction carrying the reason is appended, the note stops being served by the opening read and the search, and reading it by id still returns it, saying when, by whom and why it was retracted. It follows the note to the tree it was written in. Only notes are retracted: a decision is rejected or superseded, a pattern rejected or deprecated. Only the identity that wrote a note retracts it; a note of another identity, or one already retracted, is refused. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: id (required), reason (required).

rules_before_an_editThe rules of the record for a file about to changeA

The HOST calls this one, as a PreToolUse hook, before a file is written: it hands the session the rules of this project’s record that are addressed at that path AND still in force, as one short text that lands beside the result of that write: each rule’s name, the address that matched, and the id you cite. You may call it yourself; what you get back is a HOOK REPLY, because that is the only shape this host reads, and {} when there is nothing to say. Where a rule of the record is linked to the path with rel: "asks-for-a-person", the reply also carries permissionDecision: "ask", and the host holds the write until a PERSON decides, citing that rule’s id. It cannot refuse, allow, or rewrite your input: none of the three is representable in what it returns. It WRITES: every asking is appended to the record as a fact citing the rule and the path you named, before the reply is composed, and the first service of a session is appended too. For the whole answer (every address whatever its state, whose file no longer exists, and the counts for each relation) ask governing_rules instead; this one is deliberately thin, because it is paid for on every edit. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: path (required).

skillsSkills: the patterns to work by, and the ones awaiting a rulingA

Read the patterns (skills) recorded here: the reusable recipe, checklist or convention itself, not just its name. Call it with no id (an empty argument object) to get every ADOPTED pattern: those are the ways of working this project and machine have settled on, and nothing else arrives that way. That answer carries the BODIES when they fit in one read, and their NAMES when they do not: it says which it did, and how many there are, so a list of names is an invitation to ask for the one you need by id and never a record of empty patterns. Call it with an id to get that one, which is also how you read a pattern that is still proposed or reviewed (every item bootstrap lists as awaiting a judgement), because a pattern cannot be ruled on without being read. Each answer says the state it served, and a pattern that is not adopted is not how the work is done here; it was served so the ruling can be made on its text. A rejected or deprecated pattern IS refused: a way of working the project retired is worse to hand over than nothing. Consulting a pattern is RECORDED against this session (once per skill), so the record shows which work was informed by which pattern: it records that you read it, never that you followed it. WHAT A PATTERN IS: a skill body is content from this project’s record: text the people and agents working on this project wrote; mnema records it and serves it back, and does not vet what it says. Each pattern is served with the state it is in and, when it is adopted, the agent that adopted it, or “a person” when someone adopted it directly with no agent. A pattern that is not adopted is one the project has not ruled on: it is served so the ruling can be made on its text, and it is not how the work is done here. A reply that carries only NAMES carries none of that: nothing was served to say it about, and the id beside each name is how the pattern itself is asked for.

Inputs: id.

skill_transitionMove a skill through the workflowA

Move an existing skill to a new state: review a proposed skill, adopt a reviewed one as a live pattern, reject a proposed or reviewed one, or deprecate an adopted one that fell out of use. review/adopt/reject each need a note; deprecate needs a reason. An illegal move or missing proof is refused with the gate’s reason. The skill is looked for in EVERY project of this workspace and the move lands in the project that holds it: the id decides, so no project is taken. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: id (required), action (required), note, reason.

task_transitionMove a task through the workflowA

Move an existing task to a new state (submit, start, block, unblock, submit_review, request_changes, approve, complete, cancel, reopen). The workflow gate decides whether the move is legal and carries the proof it requires: block/cancel/reopen need a reason, approve/complete a note, request_changes a feedback; an illegal move or missing proof is refused. The task is looked for in EVERY project of this workspace and the move lands in the project that holds it, so no project is taken here: the id decides where the move goes. RECORDING IS PERMANENT: mnema is append-only and nothing deletes a fact. A record in the public scope is committed to the repository and reaches every machine that clones it (published, if that repository is public). So do NOT record credentials here. Values in a recognized format (cloud keys, API tokens, private keys, a password inside a URL) are replaced with a typed placeholder before anything is written and the reply says what was replaced, but a format mnema does not recognize is written verbatim and cannot be taken back. Do not record personal data either: an email address is replaced with and reported, and the mnid already says who wrote. Each text field holds at most 65536 bytes; a longer one is refused, not truncated.

Inputs: id (required), action (required), note, reason, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

    TDQS

    A3.9/5.0

    Scored across 27 tools

    Disambiguation4/5

    Each entity kind has its own record/create/transition trio, and the read tools are explicitly cross-referenced (governing_rules vs rules_before_an_edit, search vs read_record, bootstrap vs resume vs focus). The remaining friction is mild: capture_memory vs record_observation vs record_handoff all 'write a fact' and only the descriptions separate them, and the three opening-context readers (bootstrap/focus/resume) need careful reading to pick correctly.

    Naming Consistency3/5

    Three conventions coexist: verb_noun (capture_memory, record_decision, read_record, audit_timeline), noun_verb (task_transition, decision_transition, skill_transition), and bare nouns (bootstrap, skills, focus, resume, search, guard, next_actions, governing_rules). Creation verbs also vary without reason — capture vs record vs create — so an agent cannot infer the pattern for a new entity kind.

    Tool Count3/5

    27 tools is heavy for a single server and sits above the comfortable band, even for a domain this broad (five entity kinds, a workflow gate, run/session views, and a whole audit family). Several audits (exposure, accountability, antipatterns) are legitimate but push the surface past what most agents will hold in mind at once.

    Completeness4/5

    Coverage is genuinely lifecycle-complete: create plus gated transitions for tasks, decisions and skills; record plus signed retraction for notes and links; indexing, full read, linkage and history traversal; and explicit bootstrap/resume entry points. The known gaps are deliberate (no delete, append-only) but run lifecycle is CLI-only ('mnema run end') and there is no dedicated task/decision listing tool beyond bootstrap and search.

    Maintenance

    ActivityActive
    ResponsivenessUsually handled

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      The decision system for agentic engineering: keeps your project's decisions, rationale, and rejected paths in plain files and surfaces them to AI coding agents before they plan or change code.
      11
      Apache 2.0
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI coding agents to read and manage a Git-native decision ledger, providing tools for querying decisions, evidence, cross-repository workspaces, validation, and commit tracing, all operating locally and without a cloud service.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables a coding agent to keep a persistent, self-signed record of itself through stdio tool calls: waking to read back its positions, pending decisions and recent entries, pushing signed notes, decisions and outcomes, spawning sub-agents that start from its own record, and exporting the whole signed record for offline checking. Everything is signed locally with the agent's own key, so it works inside a sandbox with no shell network.
      14 npm
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI coding sessions to persist the reasoning behind work — decisions and their justifications, rejected options, side findings and nuances — as append-only Markdown records with reversible review, archive and human-confirmed purge. Retrieval scores records against the current task and returns only a short, budgeted list of hits, with full text fetched on demand, plus optional session hooks and handoff support.
      MIT