Agent instructions
Connecting the Engrym MCP server hands your agent the tools. Agent instructions tell it how to use them — a short, stable contract written into the config files your AI tools already read, so every agent that opens the repo follows the same four practices.
This page is organized in three tiers. Read only as far as you need: the first command gets a beginner running, the middle section is for an intermediate user with a config they've already tuned, and the last section is the full picture for power users and teams.
Tier 1 — The fastest path
If you just want it to work, run one command at your repo root — the folder where your .git lives. You'll need Node.js 18 or newer (node --version to check):
npx @engrym/cli@latest init --write-instructions
This writes the Engrym contract as a managed block into every agent config it detects — CLAUDE.md (Claude Code), AGENTS.md (Codex), GEMINI.md (Gemini CLI), .cursor/rules/engrym.md (Cursor) — plus a deep ENGRYM.md reference at your repo root. The terminal reports each file as created or updated and prints a one-line summary; from then on, every agent that opens the repo works from the same four practices.
It is non-destructive. The contract lives inside delimited markers; everything you've written outside those markers is preserved untouched. Run it again any time and it refreshes the block in place rather than duplicating it. One more step makes it useful: pair it with the Engrym MCP server so your agents actually have the tools the contract tells them to call.
Tier 2 — I already have a tuned config
If you'd rather place the block yourself — say you keep your config files just so — print it instead of writing it:
npx @engrym/cli@latest setup --print
That prints the contract block — copy it and paste it where you want. Add --copy to send it straight to your clipboard:
npx @engrym/cli@latest setup --print --copy
(engrym init takes the same flags — --print-instructions and --print-instructions --copy — if you prefer one command for everything.)
The block itself
Here is the exact block the CLI prints, so you can grab it without running anything. Paste it inside whichever config file your tool reads.
<!-- BEGIN ENGRYM MANAGED BLOCK — auto-generated, do not edit by hand -->
<!-- engrym-contract v1 38af5859d3de -->
<!-- This block is managed by Engrym (`engrym setup`). Edits inside it are overwritten on the next refresh. Add your own instructions OUTSIDE the markers. -->
# ENGRYM — the shared knowledge contract
This project keeps its decisions, conventions, and constraints in Engrym, so
every agent that touches the code works from the same source of truth. You are
one of those agents. Four practices keep that source of truth honest — follow
all four.
1. **Query before you decide.** Before any non-trivial decision, read what the
project already settled (call `get_project_brief`, then `get_relevant_knowledge`
for the area you are in). It is fail-soft: if the brain is empty or a call
fails, proceed on your best judgment — the brief informs your work, it never
gates it.
2. **Write what you learn back.** When your work produces durable knowledge,
persist it through `write_document` (plain markdown; the brain re-derives it,
born provisional, a human ratifies it) so the next session inherits it.
3. **Scope by folder.** Ask for the knowledge that bears on the files in front of
you, not the whole project — a narrow, on-point answer keeps the signal sharp.
4. **Declare your intents.** Before a substantial change, call `broadcast_intent`
to tell other agents what you are taking on, and release it when you are done.
The live tool list comes from the Engrym MCP server — connect it and the current
tools are available to you every session, always in sync.
<!-- END ENGRYM MANAGED BLOCK -->
Where the block goes
Each agent reads its instructions from a different file. init --write-instructions writes to all of them; if you're pasting by hand, here's the destination per tool:
| Tool | Config file |
|---|---|
| Claude Code | CLAUDE.md |
| OpenAI Codex | AGENTS.md |
| Gemini CLI | GEMINI.md |
| Cursor | .cursor/rules/engrym.md |
Managed-block semantics
- Delimited. The block is bounded by
<!-- BEGIN ENGRYM MANAGED BLOCK -->and<!-- END ENGRYM MANAGED BLOCK -->markers. - Non-clobbering. Anything outside those markers — your own house rules, notes, prompts — is left exactly as you wrote it.
- Refreshed in place. Re-running
engrym setup(orengrym init --write-instructions) re-renders the contract between the markers to the latest version. It never appends a second copy.
Tier 3 — Understand it
What ENGRYM.md is
ENGRYM.md is the deep reference file Engrym writes at your repo root. The managed block (above) is the short contract that goes into each tool's config; ENGRYM.md is the longer version — the same four practices spelled out, followed by the full tool taxonomy. An agent that wants the detail behind a practice reads ENGRYM.md; an agent that just needs the contract reads the block in its own config file.
The four practices
The contract is four practices — verbatim from the block the CLI ships:
- Query before you decide. Before any non-trivial decision, read what the project already settled (call
get_project_brief, thenget_relevant_knowledgefor the area you are in). It is fail-soft: if the brain is empty or a call fails, proceed on your best judgment — the brief informs your work, it never gates it. - Write what you learn back. When your work produces durable knowledge, persist it through
write_document(plain markdown; the brain re-derives it, born provisional, a human ratifies it) so the next session inherits it. - Scope by folder. Ask for the knowledge that bears on the files in front of you, not the whole project — a narrow, on-point answer keeps the signal sharp.
- Declare your intents. Before a substantial change, call
broadcast_intentto tell other agents what you are taking on, and release it when you are done.
Lean by design: the tool list stays live
The block written into your host config stays lean on purpose. It carries the stable contract — the four practices — and nothing that churns. The volatile part, the list of tools, is discovered live from the Engrym MCP server at session start, not baked into your config.
That separation is the whole point: when Engrym ships a new MCP tool, your agent picks it up the next session automatically. Adding a tool never forces you to hand-edit ENGRYM.md or re-paste a block. Your config holds the contract that rarely changes; the server holds the roster that does.
Refresh and staleness
The contract evolves slowly, but it does evolve. After you upgrade the CLI, refresh the block:
engrym setup
That re-renders the managed block in every host config to the latest version, preserving your out-of-marker content. The block carries a version stamp (the engrym-contract v1 … line), and the MCP server nudges you when the block you have is behind. Paste users who get nudged re-grab it with engrym setup --print.
One Brain, many agents
The contract is the same wherever you write it — CLAUDE.md, AGENTS.md, GEMINI.md, or .cursor/rules/engrym.md. So Claude, Codex, Gemini, and Cursor all work the same project through one contract: they read the same decisions before acting, write what they learn back the same way, and declare intents the others can see. Many agents, one Brain, one set of rules — that's how their work corroborates instead of colliding.
The full ENGRYM.md
This is the complete deep reference, copy it to your repo root if you'd rather place it by hand than run init --write-instructions. The tool taxonomy at the end is generated from the canonical registry, so it stays in sync with the server.
# ENGRYM — the shared knowledge contract
This project keeps its decisions, conventions, and constraints in Engrym, so
every agent that touches the code works from the same source of truth. You are
one of those agents. Four practices keep that source of truth honest. Follow all
four.
## 1. Query before you decide
Before any non-trivial decision — an architecture choice, a convention, a
dependency, a data shape — read what the project already decided. Call
**`get_project_brief`** and read its five sections: the north star, the active
constraints, the active conventions, the recent decisions, and the current
focus. When you need the detail behind a specific area, call
**`get_relevant_knowledge`** for the knowledge scoped to that topic. Let what is
already settled shape what you do next.
This consult is **fail-soft**. If the brain is empty, or the call fails, do not
block — proceed on your best judgment and capture what you learn below. The brief
informs your work; it never gates it.
## 2. Write what you learn back
When your work produces durable knowledge — a decision and its rationale, a
convention, a constraint, a piece of orienting context — write it back, so the
next session (yours, or a teammate's agent) inherits it instead of relearning it.
Persist through **`write_document`**: author plain markdown, and the brain
re-derives the knowledge from it. What you write is born **provisional**; a human
ratifies it before it becomes canonical. That review is the point, not a delay —
it is what lets the next agent trust this source of truth.
Do **not** reach for `add_brain_entry` to record your work. That tool writes a
single raw entry that skips the document-and-review loop; it is for narrow,
already-structured facts, not for the knowledge your work produces as you go.
## 3. Scope your queries to the work in front of you
Ask for the knowledge that bears on the files you are actually changing, not the
whole project at once. Scope your retrieval to the relevant folder or topic. A
narrow, on-point answer beats a broad one you have to wade through, and it keeps
the brain's signal sharp.
## 4. Declare what you are about to do
Before you start a substantial change, tell the other agents working this
project what you are taking on. Call **`broadcast_intent`** to declare your
intent, and release it when you are done. Coordination only works if intents are
visible — a declared intent is how two agents avoid editing the same surface into
a conflict.
<!-- BEGIN GENERATED ENGRYM TOOL TAXONOMY — do not edit; run `pnpm codegen:engrym-md` -->
## Available Engrym tools
These are the 21 tools the Engrym MCP server exposes. This list is generated from the canonical tool registry — it is always in sync with the server you are connected to.
### `get_team_context`
Call this at the START of every session and before any significant task. Returns the team's accumulated knowledge — conventions, constraints, recent decisions, active work by teammates. This context should inform all your subsequent work.
### `query_brain`
Search the team's Brain for atoms matching a keyword, category, or scope. Use this when you need a specific convention, constraint, decision, or context fragment that get_team_context may have truncated. Returns matching atoms ordered by relevance.
### `add_brain_entry`
Create a new Brain atom with full metadata. Use this to record a convention, constraint, or context fragment the team should remember. Provide a clear title, the content body, the appropriate category, and a relevant scope so the atom is discoverable. Prefer log_decision for architectural decisions.
### `log_decision`
Call this whenever you make a significant architectural, design, or convention decision. Log the decision with rationale and alternatives so future sessions and other team members understand WHY. Be specific about scope.
### `broadcast_intent`
Call this BEFORE starting any task that modifies files. Broadcasts what you are about to work on so other team members' agents are aware. Include a description and the files you expect to modify. This prevents conflicts with other agents.
### `release_intent`
Call this when you complete an intent you previously broadcast. Marks the intent as done so other agents see your work-in-progress signal as resolved. Pair with the intentId returned from broadcast_intent.
### `check_conflicts`
Call this BEFORE editing files to see if any other team members' agents are currently working on the same files. Returns the set of active intents whose file lists overlap with your input. Pure read — does not create durable conflict records.
### `get_active_intents`
List the currently active intents in the project so you can see what other agents are working on. Use this for situational awareness, not as a substitute for check_conflicts (which filters by your file list).
### `save_session_state`
Persist your session state (last task description, recently modified files, recently authored atom IDs, unfinished work, optional custom MCP state) so the next session — possibly on a different machine — can resume from where you left off. Call this near the end of meaningful work.
### `get_session_state`
Retrieve the latest persisted session state for the current user. Use this at session start (after get_team_context) to resume continuity from a prior session — including across machines.
### `get_related_atoms`
Walk the knowledge graph from one atom outward. Call this when you want to see everything connected to a decision, constraint, or context atom — what it was DERIVED FROM, what EXTENDS it, what CONTRADICTS it, and what is otherwise RELATED — so you understand the reasoning around it instead of reading it in isolation. Pass the atomId (e.g. from query_brain or get_team_context). Returns one entry per connecting edge: the neighbour atom plus the edge's kind (derived-from | contradicts | extends | related), direction (outgoing = this atom points at the neighbour; incoming = the neighbour points at this atom), and a confidence band + score. Read the kind and direction to follow the chain (derived-from + incoming traces what LED TO a decision; contradicts flags tension to resolve), and weigh each edge by its confidence. An atom with no connections returns an empty list — that is a normal answer, not an error. Read-only.
### `get_atom_source`
Get the citation for an atom — the exact source it came from — before you rely on a claim or repeat it to the user. Call this when you need to attribute or verify a specific atom: pass its atomId and get back the source document (as a human-readable path you can cite, not a bare ID) plus the grounding section. The grounding section is a HEADING TRAIL (e.g. "## Authentication > OAuth Flow") naming the part of the document the atom paraphrases — it is present for atoms extracted from documents, and it lets you point at the right section. For atoms written directly by a human or an agent (authorKind "human" or "agent"), the section is null: cite the document itself and do NOT invent or imply a line range or section that was never recorded. Read-only.
### `get_timeline`
See how the project's knowledge changed over time — this is a changelog over events, NOT a content search (use query_brain to find atoms by topic). Two modes, set by the `mode` field. Use mode "changelog" to answer "what changed since I last worked here / this week": pass a `since` (and optional `until`) ISO-8601 bound and get the ordered events in that window — decisions made or superseded, questions ratified, drift resolved — so you can catch up before building on stale assumptions. Use mode "history" to answer "how did this decision evolve / why is it where it is": identify a subject by atomId or conceptKey and get its supersession arc, original first then each re-decision after, so you can see the debate behind the current state instead of treating it as settled. Read-only over an append-only stream.
### `get_project_brief`
Call this FIRST whenever you connect to a project you don't already know. One fast, read-only call returns the cold-start orientation pack — the five things you need before touching anything: (1) the north-star (what this project IS, in one line), (2) active constraints (the hard limits you must not violate), (3) active conventions (how this team does things), (4) recent decisions (what was settled lately, and why), and (5) current focus (what the work is right now). Read all five before you plan or write anything; they should shape every later step. This is structured orientation, NOT search — it hands you the project's shape up front. To then dig into a specific topic, use query_brain; to load full live team state and teammates' in-flight work, use get_team_context. Each section is a short, most-recent-first list of lightweight atom summaries (title + category, not the full body) with a `truncated` flag when there's more; fetch a specific atom's body with a brain read if you need it. Optional `scopeHint` narrows every section to the area you're working in (e.g. "packages/api/**"); the optional per-section caps (maxConstraints, maxConventions, maxRecentDecisions, maxCurrentFocus) are smaller-only — you can ask for a leaner brief, never a larger one. Assembled deterministically with no model calls; pure read, mutates nothing.
### `get_init_brief`
Call this ONCE on first run — the moment you arrive in a project and want an honest, populated-on-arrival summary of what the Brain already knows AND what it doesn't. One fast, read-only call returns: a plain `headline` (e.g. "Your Brain already knows 12 decisions, 3 conflicts, 5 constraints — and here are 4 decisions nobody explained"); truthful `counts` of active decisions, unresolved conflicts, and active constraints (read, never estimated); the composed `brief` orientation pack (the same five-section north-star + constraints + conventions + recent-decisions + current-focus shape as get_project_brief); the honest `rationaleGaps` list — one `{ decisionRef, title }` entry per decision that has NO recorded rationale; the `retrievalMode` the Brain is on (`semantic` or `fts-only`, reported, never something you set); and an optional `importSummary` if a recent import is associated. The rationaleGaps list reports ABSENCE — it is the set of decisions nobody wrote down the WHY for. It carries no "why" field by design: do NOT invent, infer, or fill in a rationale for any gap; treat each as an open question for a human (or, if you genuinely know why, log it with log_decision). A greenfield project returns zero counts, an empty gap-list, and a greenfield headline — that is a normal answer, not an error. This is the FIRST-RUN orientation brief; for ongoing orientation on a project you don't know use get_project_brief, to browse a topic use query_brain, and for live team state use get_team_context. Assembled deterministically with no model calls; pure read, mutates nothing.
### `get_relevant_knowledge`
Call this the moment you START working in a file or on a topic — BEFORE you write or change anything there — to load the team's rules that apply to that exact spot. Pass the `file` you just opened (e.g. "packages/auth/src/byok.ts") OR a free-text `topic` (e.g. "auth token refresh"); pass EXACTLY ONE of the two, never both. You get back a tight, high-signal pack of the most relevant atoms — the conventions, constraints, and context that govern this area — ranked best-first, so you inherit the local rules unprompted instead of guessing and getting corrected later. Treat what comes back as binding for this work: honor the constraints, follow the conventions. This is targeted ambient context, NOT a full search (use query_brain to browse a subject broadly) and NOT the whole-project picture (use get_project_brief to orient on a project you don't know, or get_team_context for live team state). Optional `scope` (a comma-joined glob string, e.g. "packages/auth/**") narrows the result to a sub-area; optional `limit` is smaller-only — you can ask for a leaner pack, never a larger one. An empty result means nothing on record applies here yet — a normal answer, not an error. Read-only; mutates nothing.
### `find_contradictions`
Call this to SURFACE places where the team's knowledge disagrees with itself — a decision that violates a constraint, or two atoms asserting opposite things — so a HUMAN can review them. This is a RECOMMENDER, not an actor: it only flags candidate contradictions for a person to judge. It does NOT resolve anything, does NOT pick a winner, does NOT edit, deprecate, or link any atom, and does NOT mint a `contradicts` edge. Surface what you find and let the human decide; never act on it autonomously. This is DISTINCT from check_conflicts: check_conflicts is file-edit coordination (are other agents touching the same files right now), whereas find_contradictions is about the CONTENT of the knowledge disagreeing — it never looks at who is editing what. Each result pairs the two evidence atoms with a one-line reason they conflict, a confidence tier (high | medium | low), and the similarity that made them a candidate; weigh each by its confidence and present the strongest for human review. Optional `scope` (a comma-joined glob string) narrows the seed set; the cost knobs (maxSeeds, maxCandidatePairs, maxJudgeCalls, minSimilarity) are smaller-only — you can ask for a cheaper sweep, never a more expensive one. An empty result is a normal, common answer: it means no contradictions were found, or the project has no embeddings/judge wired to detect them — not an error. Read-only; mutates nothing.
### `get_reconciliation_claims`
Call this to run the knowledge-truth check: fetch the project's documented CLAIMS so you can verify whether the actual CODE still honors them. The team's Brain records decisions, conventions, and constraints — "we enforce RLS on every project route", "BYOK keys never leave the device" — that were true when written but quietly drift as the code changes. This tool hands you those claims; your job is to READ THE ACTUAL CODE YOURSELF (you have the repo in this session; Engrym does not and never will) and judge, per claim, whether the code still upholds it. Each returned claim carries its `atomId` (you will quote this back when you submit a verdict), its `kind` (decision | convention | constraint), its `title` and full `content` (WHAT to check), and its `scope` globs (WHERE in the tree it applies — point your reading there). After you read the code, report your findings with submit_reconciliation_verdict, one verdict per claim. Optional `scope` (a comma-joined glob string, e.g. "packages/api/src/routes/**") narrows the served claims to one area so you can reconcile a slice at a time; optional `kinds` narrows to specific atom kinds (defaults to the code-checkable set: decision, convention, constraint); optional `limit` is smaller-only — you can ask for a leaner pack, never a larger one. An empty result means nothing on record applies to that scope yet — a normal answer, not an error. This tool reads claims only; it reads NO code and is best used in Claude Code or any client that actually holds the repo (on a repo-less surface you can fetch claims but cannot ground a verdict against code). Read-only; mutates nothing.
### `submit_reconciliation_verdict`
Call this to report ONE knowledge-truth verdict after you have READ THE ACTUAL CODE YOURSELF for a claim served by get_reconciliation_claims. Read this contract before calling — it is strict and the wire enforces it. YOU read the code locally: you have the repo in this session, Engrym does NOT and never will see the source. You return ONLY a verdict plus a pointer to where you looked — NEVER the code itself. Fields: `atomId` (the claim's id, quoted back from get_reconciliation_claims); `verdict` — exactly one of `upheld` (the code still honors the claim), `violated` (the code no longer honors it), or `uncertain` (you could not confidently judge — use this honestly instead of guessing); `evidencePointer` — a short LOCATOR string naming WHERE you looked, e.g. "packages/api/src/routes/brain.ts:142", a path-and-line POINTER and nothing more; and an optional short prose `note` for the human reviewer, e.g. "route handler skips the requireProjectAccess guard". CRITICAL — NEVER paste code, a snippet, a diff, an AST, a call graph, or any code text into `evidencePointer` or `note`. The `evidencePointer` is a pointer to a location, not the contents of that location; the `note` is plain-English rationale, not source. The API REJECTS (400) any payload whose `evidencePointer` looks like code (it is multi-line, fence-marked, or punctuation-dense), and rejects any extra field — so a verdict carrying code text simply fails. This is a RECOMMENDER, not an actor: a `violated` or `uncertain` verdict routes the claim into the human review queue for a person to triage (deprecate, supersede, or dismiss); an `upheld` verdict affirms the claim. You never auto-fix code, never mutate or deprecate the atom yourself, and never open a PR — you submit a recommendation and a human decides. If you do NOT have the repo in this session (e.g. a repo-less Desktop connection), do NOT fabricate a verdict — say you cannot ground one against code rather than guessing. Best used in Claude Code, where you actually hold the repo.
### `list_projects`
Call this to discover which Engrym projects you can reach, so you can read knowledge from a project other than the one you're connected to by default. It returns the list of projects your credential is a member of; each entry includes the project's `id`, `name`, `slug`, `teamId` (null for personal projects), `description`, and timestamps. Take the `id` of the project you want and pass it as the `projectId` argument to the read tools (query_brain, get_relevant_knowledge, get_team_context, get_project_brief, get_active_intents, etc.) to pull that project's Brain — the read tools default to your connected project when `projectId` is omitted, and read the project you name when it is supplied (you can only reach projects you're a member of; others are fenced server-side). By default this lists your personal-scoped projects; pass an optional `teamId` to list the projects in a team you belong to instead. Use this for cross-project orientation — e.g. before you start work that may need a sibling repo's conventions, or when the user names a project you aren't currently pointed at. This is READ-ONLY discovery: it lists projects, it does not create, rename, or delete them, and it mutates nothing.
### `write_document`
Call this to WRITE a project document — the way knowledge enters the Brain. Use it to author the first canonical docs of an empty project (the genesis loop), or to keep an existing doc current as you learn. You write PLAIN MARKDOWN only: a `path` (e.g. "docs/architecture/auth.md") and the document `content` as a markdown string. Do NOT send rich text, HTML, embeds, comments, or formatting widgets — this is a document store, not a document editor; anything beyond plain markdown is rejected. CREATE vs UPDATE is automatic from what you pass: OMIT `docId` to CREATE a brand-new document at `path` (first write); pass the `docId` AND the `expectedVersion` you last saw to UPDATE that document. `expectedVersion` is optimistic concurrency — if someone else wrote since you read, your update is rejected (409) so you re-read and retry rather than clobber; on CREATE leave it out. The response returns the document's `id` and its new `currentVersionNumber` — KEEP BOTH: pass them back as `docId` + `expectedVersion` on your next update to the same doc. What happens after you write is the important part: your prose is NOT stored as Brain knowledge directly. The document is saved, a new version is recorded, and the Brain RE-DERIVES atoms from your markdown asynchronously — so a write here is a PROPOSAL, not a publication. Every atom your document produces is born PROVISIONAL (in review, low confidence, agent-authored) and bound to the version you just wrote; NOTHING you write becomes canonical team knowledge until a HUMAN ratifies it in the dashboard. This is a RECOMMENDER, not an actor: you draft, a person promotes. For a single fact or convention, prefer add_brain_entry or log_decision; reach for write_document when the unit of work is a DOCUMENT (a page of related knowledge the team will read and the Brain will mine). Set `genesis: true` ONLY on the very first docs of an empty, never-before-populated project — it marks those atoms for the stricter cold-start ratification bar (every genesis atom reviewed individually, never in batch), since at cold start there is no prior knowledge to check the agent's first guesses against. Leave `genesis` unset for all ordinary work. Optional `scope` (a glob list, e.g. ["packages/auth/**"]) ties the document to the part of the tree it governs. Mutates: creates or updates a document and enqueues re-derivation.
<!-- END GENERATED ENGRYM TOOL TAXONOMY -->
Flag reference
| Command | What it does |
|---|---|
engrym init --write-instructions | Writes the managed block into every detected host config + an ENGRYM.md at the repo root |
engrym init --print-instructions | Prints the block (writes nothing) so you can paste it yourself |
--copy | Pairs with a print flag — also copies the block to your clipboard |
engrym setup --print | Prints the latest block for paste users (same output as init --print-instructions) |
engrym setup | Refreshes the managed block in place in every host config, preserving your out-of-marker text |
Next steps
- MCP setup — wire the Engrym MCP server into your tool first; that's what makes the live tool list available.
- Getting started — the five-minute on-ramp.
- CLI reference — the full command and flag reference.