infernoflow
Use infernoflow's MCP server to persist, retrieve, search, and resume AI session memory for a project.
Read memory entries with filters for file, type, query, and limit (
amp_read).Log new memory entries such as gotchas, decisions, attempts, notes, detections, patterns, or preferences, with optional file/line/tags/detail (
amp_write).Search memory by keyword, optionally filtered by entry type (
amp_search).Create named session bookmarks/resume points, optionally auto-capturing the current session transcript (
amp_bookmark).Get a βwhere were we?β resume summary with the latest resume point, open dead ends, recent decisions, uncommitted changes, and optional file ranking (
amp_resume).Generate a next-session handoff document in markdown or JSON (
amp_handoff).Check session health and project memory/contract status (
amp_health,infernoflow_status).Detect recent code changes and possible git drift affecting capabilities (
infernoflow_git_drift).
Keeps memory alongside code in version control: entries live in git-tracked JSONL files, teammate-added memory is flagged for review, and a GitHub Action surfaces memory changes in each pull request.
Provides persistent memory to GitHub Copilot Chat in VS Code (1.102+) by exposing the amp_* tools over MCP and through the extension's Language Model Tools, so Copilot can log gotchas/decisions and start sessions with prior context already loaded.
π₯ infernoflow
Every new AI session starts cold β the gotchas you found, the decisions you made, don't survive. infernoflow makes them stick.
Persistent memory for AI coding sessions. Captures the gotchas, decisions and dead ends your code can't tell an agent β and replays them into your next Cursor / Claude Code / Copilot chat so the same wrong turn never happens twice.
You spent 90 minutes yesterday teaching Claude that your auth API returns 200 even on errors β check the response body, not the status code. Today you ask the same kind of question and watch it write if (response.ok) { return data } all over again. The AI didn't get worse overnight. It just doesn't have memory.
infernoflow is a local-first CLI + VS Code extension + open protocol (AMP) that gives your AI persistent context across sessions. No SaaS. JSONL on disk. Three rule files your IDE already reads.
What's new in 0.46
Fresh memory every Claude Code session β a SessionStart hook injects current memory (framed as information to verify, not instructions);
CLAUDE.mdno longer carries a copy that goes stale.infernoflow resumeβ "where were we?" in one call. Claude Code also leaves an automatic local resume point when a session ends.Stale and resolved entries β entries about a file that changed since are marked may be stale;
infernoflow resolve <id>retires one from AI context.Review what arrives through git (0.46.1) β memory added by teammates is listed until you review it, and the GitHub Action shows memory changes in each PR.
Safer by default β only read-only MCP tools are pre-approved; the memory-keeper agent is limited to single
infernoflowcommands; secrets are redacted; MCP is registered per project.infernoflow doctor --e2e(0.46.3) β an end-to-end self-test in a throw-away sandbox: CLI, the MCP server with every tool called, the prompt and session hooks, git drift, attribution. Also: prompt hooks ignore agent/tool text, memory-mode projects aren't offered contract tools, git drift reports git failures, and every entry names who wrote it.
Full list: CHANGELOG.md.
Related MCP server: MemoV
Session bookmarks
Drop a named resume point mid-session. When the context window fills up or you're about to make a risky change, one command captures the current session's transcript and stores it as a jumpable checkpoint:
infernoflow bookmark "before the SP refactor"Or just say it in chat β the Cursor beforeSubmitPrompt hook catches phrases like "bookmark this" / "mark this point" / "save this checkpoint" and drops the bookmark itself, no AI cooperation required. Or let the AI do it via the amp_bookmark MCP tool when it notices the session is getting long.
No --note? infernoflow reads Claude Code's own on-disk transcript (~/.claude/projects/β¦/*.jsonl), distills the last 40 turns to markdown, and stores it as the bookmark's context. Fully deterministic β no model call. Recall any time:
infernoflow bookmark list # β has context, β marker only
infernoflow bookmark show "SP refactor" # jump back β see the whole snapshotBookmarks are never auto-pruned, and they surface in infernoflow switch under a ## π Bookmarks β Resume Points section so the next session opens right where work paused.
π Proactive capture β a Claude skill + a memory-keeper agent
init now installs two things into .claude/ so the loop runs itself on Claude Code:
infernoflow-memoryskill (.claude/skills/) β teaches the agent to start warm (resume), then proactivelylogreal gotchas, decisions-with-a-because, dead ends, and durable preferences, and drop abookmarkat stopping points or when you say "bookmark this". Capture is balanced β it skips routine steps, anything obvious from the code, secrets, and duplicates.memory-keepersubagent (.claude/agents/) β a specialist you can delegate to. It sweeps the session, dedupes against what's already stored, logs what's worth keeping, drops bookmarks, and reports back. It never edits code or logs secrets, and a guard limits its shell to singleinfernoflowread/log commands (blocked if the guard can't run).
Both are installed automatically by infernoflow init (fresh and on re-run of an existing project) and ship in the package β nothing to set up by hand.
The loop
Every new AI session today starts cold. The agent re-reads your code, re-derives the obvious, and re-makes the same wrong move someone else made yesterday. infernoflow closes that loop in four stages:
Capture β while you and the agent work, moments worth saving get logged automatically: a gotcha hit, a decision made, an attempted fix that failed, a pattern noticed, a resume point marked. The AI writes them via the
amp_writeMCP tool. A protocol block injected into the rule files teaches it exactly when. Prompt hooks (Claude CodeUserPromptSubmit, CursorbeforeSubmitPrompt) backstop the AI by scanning the text you typed β subagent hand-backs, system reminders, fenced or indented code, quotes and stack traces are skipped β for trouble signals (not working,still broken,same error;!!/retryonly in short prompts) and writing the entry deterministically when the AI doesn't. The Cursor hook also turns "bookmark this" into a bookmark.Link β each captured moment becomes a structured AMP entry (
gotcha | decision | attempt | note | detection | pattern | bookmark) with timestamp,file:line, tags, and a stable AMP id.Persist β entries land in
.ai-memory/branches/<branch>.jsonl(git-tracked, travels with your branch β teammates inherit it) plus.ai-memory/global.jsonl(personal preferences, gitignored, synced across your machines via any OS-synced folder).Restore β when a new session starts, the agent reads
CLAUDE.md/.cursorrules/copilot-instructions.mdat boot. The most relevant entries are already there. Warm start; no cold derivation.
No service to log into. No SaaS. JSONL on disk, an MCP server, and three rule files your IDE already reads.
Install
npm install -g infernoflow
infernoflow init --yesZero runtime dependencies. Works on Node β₯ 18 β macOS, Linux, Windows.
init --yes does the whole setup: creates .ai-memory/, writes rule files for every supported IDE, wires the MCP server for Cursor / VS Code Copilot / Claude Code in one shot, installs the infernoflow-memory skill + memory-keeper agent into .claude/, applies the clean-tree git policy, and drops a visible demo entry so you can confirm the loop is alive with:
infernoflow statusThe 5-command core + 4
These cover 95% of usage:
Command | What it does |
| Remember a gotcha / decision / attempt / note. |
| π 0.46 "Where were we?" in one call β last resume point, open dead ends, recent decisions, uncommitted work. |
| Search your memory by keyword β gotchas surface first. |
| Generate a handoff for the next session. |
| End-of-session summary with health score + unlogged-change detection; lists memory that arrived through git and marks it reviewed |
| Quick health check β entries, gotchas, decisions, last activity |
| π Drop a named resume point β auto-captures the session transcript as its context. |
| Manually rebuild |
| Delete a memory entry without hand-editing JSONL. |
| Archive stale |
| π 0.46 Mark an entry fixed/outdated β stays searchable, no longer injected. Entries whose file changed since they were written show "may be stale" |
| π 0.46 Remove noise: old commit notes, duplicates, raw frustration prompts. Dry-run; |
| π 0.46 Move misfiled entries to another project's memory. Dry-run; |
Any command takes --project <dir> to work on another project's memory (multi-folder workspaces, hooks, agents).
In practice you barely run any of these β the MCP-aware AI does it for you. The CLI is for grep-style introspection.
infernoflow commands shows the full list (~23 commands, grouped by purpose).
Works with GitHub Copilot Chat β via LMT + MCP
Copilot Chat has supported MCP servers since VS Code 1.102 (GA July 2025), so any MCP-based memory tool can plug in. infernoflow ships two transports side by side so Copilot picks up the same six amp_* tools whichever path is available:
VS Code Language Model Tools (LMT). The infernoflow VS Code extension registers
amp_writeandamp_readas native LMT tools. No per-project config, no MCP client setup β install the extension and Copilot's tool picker showsπ₯ amp_write. Call by hand with#amp_write/#amp_readin the chat box.MCP server.
infernoflow initwires the MCP server into.vscode/mcp.jsontoo, so Copilot's MCP client can call the same tools if you prefer that route (or want them available to agent mode).
Cursor, Claude Code, and any MCP-capable client use the same MCP server. One product, one disk file, multiple transports β pick whichever fits your setup; both write to the same .ai-memory/.
Keeping it lean: token budget + rotation
The injected memory block is paid for on every AI turn (and twice when a tool loads both CLAUDE.md and copilot-instructions.md). infernoflow ships lean defaults β 4 entries, 5 commits, 200-char truncation, and a compact ~3-line protocol (the full trigger table is redundant with the amp_* tool descriptions, so it's off by default: ~430 tokens/file/turn saved). Tune further in .ai-memory/amp.json:
"config": {
"injection": {
"maxEntries": 4, // memory entries injected
"maxCommits": 5, // git commits injected
"maxEntryChars": 200, // per-entry truncation
"targets": ["CLAUDE.md", ".cursorrules"], // drop a file from the list and its stale block is stripped automatically
"protocolStyle": "compact" // "compact" (default) Β· "full" (restore the trigger table) Β· "off"
},
"rotation": {
"archiveAfterDays": 30,
"archivableTypes": ["note", "attempt", "detection"],
"auto": false // true β silent prune on every `log`
},
"maintenance": "suggest" // "suggest" (default) Β· "auto" Β· "off"
}Or write the same values via CLI flags:
infernoflow setup --max-memory 3 --max-commits 5 --max-entry-chars 200 --protocol-style compact
infernoflow refresh --targets CLAUDE.md,.cursorrules # only these get the block; the rest are stripped
infernoflow refresh --targets auto # canonical file for the IDE you're in (kills Copilot's double-load)
infernoflow prune --apply --max-age-days 14 # one-off cleanupRotation archives stale note / attempt / detection entries to .ai-memory/archive/sessions-YYYY-MM.jsonl β invisible to the merged read (so the AI, sidebar, ask, and refresh stop surfacing them) but still on disk if you want them back. gotcha, decision, pattern, and bookmark entries are never auto-pruned β that's the knowledge you logged infernoflow FOR.
Maintenance hints (0.46.5): when memory collects noise (duplicates, old commit notes, machine text), entries about files that changed since, or a pile of old notes, status, recap and the session-start context say so and name the command (curate --apply, resume, prune --apply). The session-start hint shows at most once a day and tells the AI to ask before running anything. "auto" does the safe part itself once a day (noise is archived then removed, old notes go to the archive); entries about changed files are still only suggested, because a person decides whether they're outdated. Thresholds are adjustable: "maintenance": { "mode": "suggest", "thresholds": { "curate": 3, "stale": 3, "prune": 20 } }.
Two-tier bodies: any entry can carry a rich detail β stored in a single .ai-memory/details.jsonl (consolidated in 0.44.18; older per-entry details/<id>.md sidecars auto-migrate on the next write), loaded on demand via readDetail(), and never injected into rule files. The lean index stays lean; you pay for the body only when you open it. log --detail, --detail-file, MCP amp_write detail, and the new amp_bookmark tool all feed it.
Branch-aware memory + cross-machine sync
Your teammate takes your branch β they inherit your memory.
.ai-memory/
βββ branches/
β βββ main.jsonl β project-wide truths (git-tracked)
β βββ feature-auth.jsonl β your current branch's work (git-tracked)
βββ details.jsonl β long-form entry bodies (git-tracked, loaded on demand)
βββ details.local.jsonl β bookmark transcript snapshots (gitignored, this machine only)
βββ global.jsonl β your personal preferences (gitignored)
βββ sessions.jsonl β everything this machine wrote (gitignored mirror)Captures on a feature branch travel with that branch via git. When a teammate runs
git checkout feature-auth, the JSONL is there. Their MCP server boots, reads it, regenerates their rule files β their AI is warm-started on your findings without you sending a message.You see what arrives. Entries that reach your machine through git and that you haven't reviewed are listed by
infernoflow resume(and in Claude Code's session-start context);infernoflow recapshows them and marks them reviewed. Tracked locally per machine, from the entry's content β not from the author it claims. Retire a wrong one withinfernoflow resolve <id>.Review memory in pull requests. The GitHub Action (
action/) comments on each PR with the memory entries it adds, edits or deletes, so they are reviewed like code before they reach everyone's AI.Personal preferences travel between your own machines. Point at any OS-synced folder once:
infernoflow sync set ~/Dropbox/infernoflow-memoryHome β work β home. No infra to stand up; the OS does the sync.
merge=unionon branch JSONLs means concurrent commits from different machines merge cleanly β no manual conflict resolution.Branch switching never blocked. Rule files refresh only at MCP server boot or via explicit
infernoflow refresh, not on every entry β your working tree stays clean while you log.
Cross-IDE β same memory, every tool
Tool | Reads from | Writes via |
Claude Code |
| MCP ( |
Cursor |
| MCP ( |
GitHub Copilot Chat (VS Code) |
| VS Code LMT (from the extension) + MCP (from |
GitHub Copilot (JetBrains) |
| MCP ( |
Windsurf |
| MCP ( |
The MCP server is wired by infernoflow setup / init into each tool's config file. No per-tool setup.
MCP tools (for AI agents)
When the MCP server is wired, your AI agent can call these directly in chat:
Tool | What it does |
| Log an entry ( |
| π 0.46 "Where were we?" β last resume point, open dead ends, recent decisions, uncommitted changes |
| Read entries with optional filters ( |
| Keyword search across entries |
| π Drop a named resume point β auto-captures the current session transcript when no |
| Generate the handoff document for the next AI session |
| Session health score (AβF) |
| Memory + project health at a glance |
| Validate the capability contract (read-only). Full mode only β not listed in memory-mode projects |
| Generate AI-ready context for a task. Full mode only |
| Files changed in the last commits and working tree β and, in full mode, which capabilities they affect. Says so when git is unavailable instead of reporting "no changes" |
Entries are stamped with who wrote them: the MCP client that called the tool (Claude, Cursor, Copilot, Windsurfβ¦), claude for CLI calls from Claude Code, memory-keeper / hook for the agent and the prompt hooks, human for you. Set INFERNOFLOW_AGENT to override the automatic detection. Like the author, this is what the writer claims β useful for triage, not proof.
The amp_* tools follow the AMP MCP spec Β§7.3 β vendor-neutral. Any AMP-Full client only needs to know those six names. The same six are also available as CLI aliases (infernoflow amp read | write | search | bookmark | handoff | health) so the CLI and MCP surfaces match name-for-name.
Every memory line injected into the rule files is prefixed with π₯ so the AI (and you) can tell at a glance that a line came from infernoflow even when it's quoted out of the managed block. When the AI uses one, the protocol tells it to briefly cite the source β e.g. π₯ (from infernoflow memory) gotcha at src/api.js:42: API returns 202 not 200.
What it has caught (real dogfood)
infernoflow was developed by building a multi-tenant kanban (infernotest_01) and capturing what it surfaced. A sample of real entries from that dogfood:
gotcha (
vite.config.ts): "Vite proxy withchangeOrigin: truerewrites the Host header β server-side URL construction produces URLs pointing at the BACKEND port. Build user-facing URLs client-side viawindow.location.origin."gotcha (
server/prisma/schema.prisma): "Prisma 6query_engine.dll.nodeis locked while tsx watch is running;prisma migrate devfails with EPERM on rename. Stop the dev server before migrating."gotcha (
server/src/routes/members.ts): "Invite accept must NOT burn the token when the caller is already a member of the workspace β return early with the existing membership before marking acceptedAt."pattern (
server/src/routes/columns.ts): "Position assignment for ordered children: next position = max(existing) + 1024. The 1024 step leaves room for ~10 inserts between two siblings without renumbering."pattern (
server/src/access.ts): "Cross-entity auth helpers dowhere: { memberships: { where: { userId } } }via Prisma nested-select β one DB hop per assertion. Return 404 not 403 when not a member to avoid leaking existence."decision (
server/src/auth.ts): "Opaque session tokens in a Session table (not JWTs) β chosen so we can revoke per-session (deleteManyon Session). bcryptjs over native bcrypt to avoid platform-specific binaries."
These are the things you'd otherwise forget by next Tuesday and re-derive at 11pm on a Friday. They live in .ai-memory/branches/*.jsonl forever.
VS Code extension
The companion extension is the visual surface over your memory:
Live sidebar β ranked-by-relevance gotchas / decisions / attempts for whatever file you're editing.
Gotchas as Problems β logged with a
file:line? They appear as yellow squigglies in the editor and rows in the Problems panel, right next to your TypeScript errors. Both you and Copilot see the warning before making the same mistake again.Status bar health score β always visible:
π₯ B 65 Β· β 3 Β· β2 Β· β1 Β· π Switch. ClickSwitchto copy the handoff.Copilot Chat integration β
#amp_write/#amp_readin the chat box; Copilot picks them up via VS Code Language Model Tools registered by the extension (works even without an MCP client configured).Keyboard-first logging β
Ctrl+Alt+G(gotcha) /Ctrl+Alt+D(decision) /Ctrl+Alt+A(ask) /Ctrl+Alt+S(switch) /Ctrl+Alt+R(recap). Right-click in the editor to log a gotcha for the current line.
ext install infernoflow.infernoflowOr in the Marketplace: infernoflow.infernoflow. Activates on any project with .ai-memory/ (or legacy inferno/).
The extension is window only in v0.7.9+ β the CLI is the single canonical writer of rule files. No race between extension and CLI; the extension watches .ai-memory/**/*.jsonl and renders.
Troubleshooting
I upgraded infernoflow but
amp_writeentries still look wrong. Your IDE's MCP server is loaded into memory at session start and doesn't reload from disk. Quit and reopen Cursor / Claude Code / VS Code.infernoflow doctorwill flag this with a "MCP runtime vβ¦ but CLI vβ¦" warning.infernoflownot found. Usenpx infernoflowuntil the global install resolves on your PATH.PowerShell script execution blocked.
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass.Box-drawing chars look broken. Force UTF-8 first:
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8. Should auto-fall-back to ASCII on legacy PowerShell. If not, open an issue.infernoflow doctorβ full diagnostic if anything looks wrong. Includes the MCP runtime stamp check + AI provider detection + git hooks status.infernoflow doctor --e2eβ if memory isn't being captured or a tool fails, this runs the whole chain in a temporary sandbox (your project and settings aren't touched): log β ask β forget, the MCP server with every tool called, the prompt and session hooks with sample input, git drift, and attribution. Paste its output into an issue.infernoflow checksays memory mode. That's expected after a plaininit: capability contracts are optional. Enable them withinfernoflow init --mode full --adopt. In CI useinfernoflow check --strict, which fails when the contract is missing.
Why this matters
Code changes daily. What the system actually does under all those edits β the invariants, the constraints, the things that bit you last week β code can't tell you. infernoflow keeps that current and feeds it to the agent so the agent stops re-deriving from scratch.
That's the whole product. No vendor lock-in (it's JSONL on disk). No SaaS. One CLI, one VS Code extension, one open protocol, three rule files your IDE was reading anyway.
Security & privacy
Local-first by design:
β Telemetry is opt-in and off by default. After a few runs in an interactive terminal infernoflow asks once; nothing is sent unless you answer yes. It never sends code, file paths or memory content. Check or change it with
infernoflow telemetry status.π« No
postinstallscript.npm install -g infernoflowruns no code β it only copies files.π« No network calls in any default command path (with telemetry off, which is the default).
π« No auto-updates of the package, no background processes, no cloud sync.
β MCP is registered per project. Claude Code gets the project's own
.mcp.json(gitignored β it holds this machine's paths); Cursor and VS Code get.cursor/mcp.json/.vscode/mcp.json. All of them run the server from the installed package (infernoflow mcp), not a copy inside the repo.β οΈ Writes outside the project: Claude Desktop has no per-project config, so
setupadds one entry per project there (infernoflow-<repo>). Pre-0.45 versions left a singleinfernoflowentry in~/.claude.json/ the Desktop config that pinned every project to one repo; it is removed automatically (backup in~/.infernoflow/backups/). Personal settings and API keys live in~/.infernoflow/.β Auto-injected content is wrapped in markers (
<!-- infernoflow:start -->/<!-- infernoflow:end -->) β your manual edits outside the block are never touched.β Secrets are redacted before anything is written β GitHub/npm/OpenAI/Anthropic/AWS/Google/Slack/Stripe tokens, JWTs, private keys, URL credentials and
password=-style values become[REDACTED:<kind>]. Memory files are still plain text committed with your repo, so treat them like code: review.ai-memory/diffs.β Bookmark transcript snapshots stay on your machine (
.ai-memory/details.local.jsonl, gitignored). Only context you write explicitly (--note,detail) is shared with the team.β API keys never live in the project β environment variables are used as-is; pasted keys go to
~/.infernoflow/ai-credentials.json(owner-only).β No shell is used to run commands from the MCP server or the prompt hooks (since 0.44.20), and MCP tool arguments are validated against their schema.
β Only read-only tools are pre-approved in Claude Code (
permissions.allowin.claude/settings.json). Tools that write memory ask for your permission like any other tool, so text the AI reads can't silently write to shared memory.β Memory is data, not instructions. Injected memory is framed that way, each entry records its author and the tool that wrote it, entries about a changed file are marked may be stale, and memory that arrived through git is listed until you review it (
resume/recap).β The frustration hook keeps only a 60-character prefix of the prompt that triggered it, and skips agent hand-backs, system reminders, code, quotes and stack traces in it.
The optional infernoflow ai setup command wires an AI provider (Anthropic / OpenAI / Google / Ollama) for a few enrichment commands β same trust model as using that provider directly. Off by default.
Full policy: SECURITY.md. Vulnerability reports: hello@infernoflow.dev or GitHub Security Advisory.
Community
π¬ GitHub Discussions β Q&A, ideas, show and tell. First stop for questions.
π Issues β bugs only. Feature requests go in Discussions β Ideas.
π Security Advisories β private disclosure for vulnerabilities.
License
MIT β see LICENSE.
Links
GitHub Β· Discussions Β· npm Β· VS Code Marketplace Β· infernoflow.dev
AMP protocol spec β vendor-neutral memory format
[Dogfood: what infernoflow caught
Available Tools
9 toolsamp_bookmarkA
AMP: drop a named session bookmark β a resume point. Required: label (short name). Optional: note. If note is OMITTED, the current session transcript is auto-captured as the bookmark's context (the 'save everything here' resume point). Use when the user says 'bookmark this' / 'mark this point', or before a risky change / when the context window is filling up, so the exact state can be recalled later and appears in the next session's handoff. Bookmarks are never auto-pruned.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | Optional explicit context. Omit to auto-capture the session transcript instead. Stored in a sidecar; not injected into rule files. | |
| label | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full load and does disclose the non-obvious behavior: omitting note auto-captures the transcript, and bookmarks are never auto-pruned (a durability guarantee). It does not state what is returned on success or how duplicate labels are handled, leaving a small gap for a mutation with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the identity and the resume-point framing, then requirements, then behavior, then triggers β a sensible order. It is dense but every clause carries information; only the phrasing is slightly em-dash heavy rather than wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with no annotations and no output schema, the description covers purpose, required/optional inputs, the conditional behavior of note, durability, and when to call it. The remaining gap is return-value/error behavior, which is modest given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50% (label is undocumented in schema), and the description compensates by labeling it "short name" and marking it required. The most valuable addition is the note-omission semantics, which materially changes what the call does and is not fully conveyed by the schema text alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource β "drop a named session bookmark β a resume point" β and immediately clarifies the abstract concept with a concrete gloss. It also implicitly separates itself from amp_handoff by noting bookmarks surface in the next session's handoff, so an agent can distinguish it from the sibling tools without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete triggering conditions: user says "bookmark this" / "mark this point", before a risky change, or when the context window is filling up. That is clear positive guidance, but no explicit when-not or named-alternative routing (e.g. vs amp_handoff or amp_resume) is offered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
amp_handoffB
AMP: generate the handoff document for the next AI session. format=markdown|json (default: markdown).
| Name | Required | Description | Default |
|---|---|---|---|
| format | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does not say whether generating a handoff persists anything (writes a file, mutates state) or merely returns text, nor whether the operation is idempotent, what permissions it needs, or how large the output is. For an operation named 'handoff' whose side effects matter, this is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action, with the format/default detail following. No wasted words, though the brevity edges toward under-specification rather than pure efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, no annotations, and no description of what the handoff document contains, where it goes, or what the agent receives back. For a tool whose entire value is the artifact it produces, the description leaves the agent unable to predict or verify the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the single parameter is an enum whose allowed values are visible in the schema. The description adds real value by specifying the default (markdown), which the schema does not declare. It does not explain any behavioral difference between markdown and json output beyond the surface format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'generate the handoff document for the next AI session.' The purpose is clear and distinct from siblings like amp_resume or amp_read, though it never explicitly names or contrasts those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for the next AI session' implies this is called at the end of a session, giving implied usage context. However, there are no explicit when-to-use/when-not rules and no mention of alternatives such as amp_resume, leaving the agent to infer the trigger condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
amp_healthA
AMP: get the session health score (0-100, A-F grade).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. 'Get' implies a read-only operation and the score range/letter grade hints at the return payload, but it says nothing about what 'health' measures, whether it requires an active session, cost, or what happens when no session exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the resource and the return format front-loaded; no filler and nothing repeated from structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully discloses the return format (0-100 score, A-F grade). It is nearly complete for a zero-parameter read tool; the remaining gap is that 'session health' itself is never defined.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline for a parameterless tool is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb ('get') and a specific resource ('session health score'), and even names the return shape (0-100 plus an A-F grade). That is enough for an agent to tell it apart from siblings like amp_read, amp_search, or infernoflow_status, though it never explicitly contrasts with those tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this rather than infernoflow_status or amp_read, no preconditions, and no exclusions. The agent must infer usage purely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
amp_readC
AMP: read session memory entries with optional filters.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | ||
| type | No | ||
| limit | No | ||
| query | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. It conveys read semantics through the verb "read" but says nothing about what is returned (fields, ordering), default behavior with no filters, or the 200-entry cap enforced by the schema β real gaps for a memory-retrieval tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or repetition. It is efficient, though the brevity comes at the cost of substance rather than being paired with useful detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Four parameters, zero schema descriptions, no annotations, and no output schema means the description is the only source of semantics β and it supplies almost none. An agent cannot confidently choose filter values or predict results from this definition.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across all four parameters, so the description must compensate and does not. It never explains what "file" scopes to, whether "query" is substring or semantic matching, how "query" differs from "file", or what "limit" defaults to β the enum of seven memory types is likewise never mentioned.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (read) and resource (session memory entries), so an agent can tell it retrieves rather than mutates. However it does not distinguish this from the sibling amp_search, which by name also retrieves memory entries β the read/search boundary is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"With optional filters" implies a retrieval use case but never says when to prefer this over amp_search, amp_resume, or amp_bookmark, nor when filtering is unnecessary. No prerequisites, no exclusion cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
amp_resumeA
AMP: 'where were we?' in one call β the latest resume point with its note, open dead ends (don't repeat them), recent decisions/notes, uncommitted changes, and which memory store this is. Call it at the start of work in a session. Optional: file (rank entries about that file first).
| Name | Required | Description | Default |
|---|---|---|---|
| file | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it enumerates exactly what comes back, including uncommitted changes and memory-store identity, which the agent could not infer elsewhere. It stops short of stating read-only safety, cost, or volume limits, which matters for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core value ('where were we?' in one call), followed by the payload list, then usage timing, then the single optional parameter. No filler sentences and nothing repeated from structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-param, no-output-schema, no-annotation tool, the description covers purpose, timing, and payload contents sufficiently to invoke it correctly. Gaps are secondary: no indication of result size, truncation, or what happens when no resume point exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does: 'file' is described as optional and as a ranking hint ('rank entries about that file first') rather than a hard filter β semantics the bare string/maxLength schema cannot convey. It doesn't specify accepted path formats or matching behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource and scope: it returns the latest resume point, open dead ends, recent decisions/notes, uncommitted changes, and the active memory store. The 'in one call' framing implicitly distinguishes it from granular siblings like amp_read and amp_search, though no sibling is named outright.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Call it at the start of work in a session' gives a clear triggering condition, and the dead-ends note ('don't repeat them') tells the agent how to act on the output. There is no explicit when-not or named alternative (e.g., versus amp_search for targeted lookups).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
amp_searchC
AMP: search entries by keyword. Optional type filter.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | ||
| query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden, yet it discloses nothing beyond 'search': not what a match covers (title, body, tags), whether results are ranked or capped, case sensitivity, or whether full entry bodies are returned. For a tool with zero annotation coverage this is a substantial gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short front-loaded sentences with no padding, and the core purpose leads. The terseness comes at the cost of substance rather than being padded, so it is efficient but slightly under-specified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations, no output schema, and 0% schema description coverage, the description should compensate with match semantics, result limits, and the meaning of the type enum β none of which are present. The tool is simple, but what an agent needs to call it well is still missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description only restates the parameter surface: 'keyword' maps to query and 'optional type filter' maps to the type enum. It adds that type is optional, but never explains what the seven enum values (gotcha, decision, attempt, note, detection, pattern, preference) mean or what text query matches against.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (search) and resource (entries) qualified by 'by keyword', so an agent knows this is a keyword lookup rather than a direct fetch. It never distinguishes itself from amp_read or amp_resume, so the sibling differentiation needed for a 5 is absent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only usage hint is that the type filter is optional; there is no statement of when to search versus using amp_read/amp_resume, no prerequisite or scope conditions, and no exclusions. An agent must infer the routing decision entirely on its own.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
amp_writeA
AMP: log a new entry. Required: type + msg (one sentence). Optional: file, line, tags, detail. Use 'detail' for a rich multi-paragraph body (repro steps, code, full reasoning, or a session snapshot) β it's stored in a sidecar and loaded on demand, so it never bloats the always-on memory index.
| Name | Required | Description | Default |
|---|---|---|---|
| msg | Yes | ||
| file | No | ||
| line | No | ||
| tags | No | ||
| type | Yes | ||
| detail | No | Optional rich body (Tier-2). Stored in the consolidated details store; NOT injected into rule files. Put the long-form context here; keep 'msg' to one summary sentence. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It adds valuable context by explaining that 'detail' is stored in a sidecar and loaded on demand without bloating the always-on memory index. However, it does not state whether entries are immutable, whether writes require confirmation, or what the response looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tight sentences with zero waste. The core purpose is front-loaded, followed by required/optional parameters and then the most important behavioral nuance about 'detail', in a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter write tool with no annotations and no output schema, the description covers the core logging behavior and the sidecar storage model. It remains incomplete regarding the 'type' enum semantics, the meaning of 'file' and 'line', and any return or confirmation behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 17%, so the description must compensate. It lists all parameters at a high level and gives strong semantics for 'msg' (one sentence) and 'detail' (rich multi-paragraph body stored in sidecar), but it does not explain the meaning of 'file', 'line', 'tags', or the 'type' enum values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'log a new entry'. This clearly identifies a write/logging operation, distinguishing it implicitly from read/search siblings like amp_read and amp_search. It does not explicitly differentiate itself from write-adjacent siblings such as amp_bookmark or amp_handoff.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'log a new entry' and the required/optional parameter breakdown. The description adds useful guidance on when to use 'detail' versus 'msg', but offers no explicit when-to-use conditions, exclusions, or comparison to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
infernoflow_git_driftB
Detect which capabilities may be affected by recent code changes β useful when memory needs branch-aware revalidation.
| Name | Required | Description | Default |
|---|---|---|---|
| sinceCommits | No | How many commits back to check (default: 1, max: 100) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. 'Detect' implies a read, but it never states whether this is read-only, whether revalidation mutates memory state, what the cost/scope is, or what the response looks like β all critical for a tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with no wasted clauses. The trailing 'β useful when...' clause is somewhat jargon-heavy but does add a usage hint rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter detection tool with a well-documented schema, the definition is largely sufficient. But with no output schema, the description should hint at what 'affected capabilities' results look like, and it doesn't, leaving the return shape opaque.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter is fully documented with type, default, and max. The description adds nothing about sinceCommits, so the baseline 3 applies β the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (detect) and resource (capabilities affected by recent code changes), which is more than a name restatement. However, it doesn't distinguish this from any sibling tool, and 'capabilities' is left undefined, so an agent can't fully tell what domain it operates in.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'useful when memory needs branch-aware revalidation' gives an implied usage context but no explicit when-to-use/when-not, no prerequisites, and no alternatives among the siblings. The agent must infer the trigger condition from vague jargon.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
infernoflow_statusC
Show project memory + contract health at a glance.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. "Show" weakly implies a read-only operation, but nothing confirms it, and there is no mention of cost, auth requirements, or whether the summary is cached/live β meaningful gaps for a memory-and-health dashboard tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single eight-word sentence with no filler, and the core purpose is front-loaded. It is arguably under-specified rather than bloated, but it wastes nothing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and no annotations, so the description is the only source of information about what comes back. It never says what "at a glance" contains β memory counts, contract violations, pass/fail state β leaving the agent unable to predict the return value before calling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and the schema is empty, so there is nothing for the description to disambiguate. Baseline 4 applies; no parameter-level information is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a verb ("Show") and two resources ("project memory" and "contract health"), so the general domain is graspable. But "contract health" is unexplained jargon, and nothing distinguishes this from siblings like amp_health or infernoflow_git_drift, which sound like they surface overlapping health signals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus amp_health, infernoflow_git_drift, or amp_resume. The agent is left to infer usage entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
- First observed
amp_bookmark - First observed
amp_handoff - First observed
amp_health - First observed
amp_read - First observed
amp_resume - First observed
amp_search - First observed
amp_write - First observed
infernoflow_git_drift - First observed
infernoflow_status
TDQS
Scored across 9 tools
Most tools target clearly distinct operations: bookmark, resume, write, search, handoff. However amp_health and infernoflow_status both report health/status and could be confused, and amp_read vs amp_search vs amp_resume have partially overlapping 'retrieve memory' purposes that rely on descriptions to separate.
Consistent snake_case verb_noun style throughout. The only deviation is the two-prefix split (amp_* for memory ops, infernoflow_* for status/drift), which is readable but slightly inconsistent β infernoflow_status is conceptually an amp operation.
Nine tools is well within the ideal 3-15 range and each maps to a distinct phase of the memory lifecycle (write, read, search, resume, bookmark, handoff, health, drift). No filler tools.
Covers the capture-and-recall lifecycle well, but there is no update or delete/prune operation for memory entries β bookmarks are explicitly never pruned, and stale or erroneous entries cannot be corrected. Agents must work around this by writing corrective entries.
Maintenance
Related MCP Connectors
One memory for every AI you work with: your rules, notes and decisions in your own Git repo.
Shared memory for coding agents. Stop re-explaining your codebase every session.
Private memory for AI agents: save and recall facts across Claude Code, Codex, Cursor and ChatGPT.
Shared memory for AI coding agents. Save once, reuse from Cursor, Claude Code, Codex.
Related MCP Servers
- AlicenseAqualityAmaintenanceLocal-first memory layer for AI coding agents β captures issues, attempts, fixes, and decisions, and warns at git commit before you repeat a mistake.17534 PyPI866MIT
- AlicenseNot gradedqualityCmaintenanceProvides a memory layer for AI coding agents with Git-powered version control, enabling automatic tracking of prompts, context, and code diffs.194MIT
- AlicenseNot gradedqualityCmaintenanceGives AI coding agents persistent, branch-aware memory and a dependency-tracked task graph by storing decisions, lessons, and tasks as plain JSON and Markdown committed directly into the repository. Agents can record and fuzzy-search past decisions, dump instant project context, and create, claim, complete, and query tasks whose completion automatically unblocks downstream work.MIT
- AlicenseNot gradedqualityBmaintenanceProvides AI coding agents with git-native persistent memory and a dependency-aware task graph, letting them record and fuzzy-recall architectural decisions, lessons, and gotchas while creating, claiming, and completing tasks that auto-unblock downstream work. Stores everything as plain JSON and Markdown committed inside the repository, so context stays branch-aware, team-shared, and reviewable in pull requests.9 npmMIT