Skip to content
virlingPublic

About

Persistent project memory shared by every AI coding agent: Claude Code, Cursor, Codex, Gemini CLI, Windsurf and any MCP client. Auto-captures decisions, injects them back next session.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

agentmem

Memory that lives with your code: reviewed in pull requests, enforced as guardrails, readable by every AI coding agent. Zero dependencies, no daemon, no account.

  • Zero dependencies. Plain Node.js, MCP over stdio, memories stored as Markdown files.
  • Per project. Memory is keyed by the git remote URL, so every clone of the same repo shares one memory.
  • Works across agents. Claude Code, Cursor, Windsurf, Codex, Gemini CLI, VS Code (Copilot), OpenCode, or anything with MCP support.
  • Handoffs. Stop mid-task in one agent, continue in another: the next session starts with what was done and what is next.
  • Automatic in Claude Code. Hooks inject memory at session start, surface notes when a linked file is opened, and auto-capture new facts when a session ends.
  • Team memory in git. Team memories live in .agentmem/ in your repo, so they are reviewed in PRs and shared on git pull.
  • Guardrails. Turn a memory into a rule: agents are blocked or asked before editing matching files.
  • Code-aware. Memories linked to files are flagged when those files change, so outdated knowledge does not linger.
  • Export to rule files. Compile team memories into AGENTS.md, CLAUDE.md, Copilot and Cursor rules for agents without MCP.
  • Contradiction checks. New memories come back with related ones to compare, and agentmem check finds conflicts.
  • PR memory Action. A GitHub Action turns decisions from merged pull requests into team memories, opened as a PR for review.
  • Safe by default. Writes that look like secrets are refused. Near-duplicate titles are refused unless forced.

Contents

How it works

Claude Code ─┐                      ┌─► ~/.agentmem/<repo>-<hash>/*.md   local, private
Cursor ──────┼── MCP (stdio) ──► agentmem
Other agent ─┘                      └─► <repo>/.agentmem/*.md            team, committed
  1. An agent starts agentmem as an MCP server from inside a project folder.
  2. agentmem finds the project with git remote get-url origin (falls back to the repo root path, then the current folder) and hashes it into a project id like my-app-1a2b3c4d5e6f.
  3. Every memory is one Markdown file, either local (~/.agentmem/<project-id>/) or team (<repo>/.agentmem/).
  4. Any agent opened in the same repo reads both layers.

Requirements

  • Node.js 18 or newer
  • git (optional, used to identify the project)
  • Claude Code CLI (optional, only for hooks and auto-capture)

Changelog

See CHANGELOG.md and GitHub releases.

Install

One line. Detects Claude Code, Cursor, Windsurf, Gemini CLI, Codex, VS Code and OpenCode on your machine and configures each one:

npx -y @virling/agentmem install

Or install globally first (faster hooks, agentmem on your PATH):

npm i -g @virling/agentmem && agentmem install

Configure only specific agents:

agentmem install claude cursor

Restart your agents afterwards. Running install again is safe: it updates existing entries instead of adding duplicates.

As a Claude Code plugin

/plugin marketplace add virling/agentmem
/plugin install agentmem@virling

The plugin brings the MCP server and all hooks. Use either the plugin or agentmem install claude, not both, or every hook runs twice.

Connect your agents

agentmem install writes these for you. The details are here if you prefer to do it by hand.

Agent What install changes
Claude Code claude mcp add agentmem --scope user, plus four hooks in ~/.claude/settings.json
Cursor mcpServers.agentmem in ~/.cursor/mcp.json
Windsurf mcpServers.agentmem in ~/.codeium/windsurf/mcp_config.json
Gemini CLI mcpServers.agentmem in ~/.gemini/settings.json
Codex [mcp_servers.agentmem] in ~/.codex/config.toml
VS Code (Copilot) servers.agentmem in the user mcp.json (~/Library/Application Support/Code/User/ on macOS, ~/.config/Code/User/ on Linux, %APPDATA%\Code\User\ on Windows)
OpenCode mcp.agentmem in ~/.config/opencode/opencode.json

Other keys and other MCP servers in those files are left as they are.

Any other MCP client

Any client that can launch a stdio MCP server works:

{
  "mcpServers": {
    "agentmem": { "command": "npx", "args": ["-y", "@virling/agentmem", "mcp"] }
  }
}

Editors that start servers outside the project

If memories land under the wrong project, the editor started the server outside your project folder. Ask the agent to pass project_path (the absolute project path) on its tool calls, or use the editor's per-project MCP config.

From source

git clone https://github.com/virling/agentmem.git
cd agentmem
npm test
node bin/agentmem.js install

There are no dependencies, so no npm install is needed.

Tell the agent to use it

Agents without hooks do not read memory on their own. Add a line like this to your AGENTS.md, .cursor/rules, or equivalent:

At the start of each task call memory_list. Save durable decisions, conventions and gotchas with memory_write.

MCP tools

Tool Arguments What it does
memory_list List all memories for the project (id, type, title, flags)
memory_search query Keyword search across title, type, tags, files and body
memory_read id Full text of one memory
memory_write title, content, type, files, tags, pinned, guard, scope, agent, force Save one fact. Returns related memories to check for contradictions
memory_update id plus any field to change Edit a memory in place. With only id, re-verifies it against its files
memory_promote id Move a local memory into the repo's .agentmem/ folder
memory_handoff summary, next_steps, files, agent Leave a note for the next session in any agent. Replaces the previous handoff
memory_delete id Remove a memory

Every tool also accepts an optional project_path.

Types: decision, convention, gotcha, todo, note, handoff. Scopes: local (default), team. Guards: warn, block.

CLI

Run inside any project folder:

agentmem list
agentmem search "auth token"
agentmem show 2026-10-31-use-pnpm
agentmem add "Use pnpm" "This repo uses pnpm 9, not npm" --type convention --files package.json --pin
agentmem edit 2026-10-31-use-pnpm --content "pnpm 9 only"
agentmem pin 2026-10-31-use-pnpm
agentmem unpin 2026-10-31-use-pnpm
agentmem rm 2026-10-31-use-pnpm
agentmem add "Generated code" "Run pnpm codegen" --files "src/gen/**" --guard block --team
agentmem promote 2026-10-31-use-pnpm
agentmem verify 2026-10-31-api-returns-json
agentmem handoff "Refactored auth middleware" "1. Add tests 2. Update docs"
agentmem export agents cursor
agentmem check
agentmem stats       # how often each memory was used
agentmem guard-check --base origin/main
agentmem org add git@github.com:acme/.agentmem.git
agentmem path        # prints this project's local, team and org folders

Run agentmem with no arguments in a terminal to see the full help.

Claude Code hooks

agentmem install registers these:

Hook What it does
SessionStart Injects the latest handoff and pinned memories in full, plus an index of the 50 most recent others. Flags stale and changed memories.
PreToolUse (Edit, Write, MultiEdit, NotebookEdit) Enforces guardrails: denies edits to files under a block memory, asks first for warn.
PostToolUse (Read, Edit, Write, MultiEdit) When a file is touched, injects memories whose files list includes it. Each memory is shown once per session.
SessionEnd Starts auto-capture in the background. Does not block exit.

Auto-capture

When a Claude Code session ends, agentmem:

  1. Reads the session transcript (user and assistant text only, last 40k characters).
  2. Sends it to claude -p --model haiku with no tools and no MCP servers.
  3. Points out commands that failed and then passed after a file was edited, so the fix can be saved as a gotcha linked to those files.
  4. Saves up to 5 durable facts with agent: auto-capture. Secrets and near-duplicates are skipped. If work was left unfinished, it also writes a handoff.
  5. Appends the result to capture.log in the project's storage folder.

Run it by hand on any transcript:

agentmem capture ~/.claude/projects/<project>/<session-id>.jsonl

Auto-capture uses your logged-in Claude Code account. Each run is one small Haiku call.

Team memory

Memories have two scopes:

  • local (default): ~/.agentmem/<project-id>/, private to your machine.
  • team: <repo>/.agentmem/, committed with your code.
agentmem add "API errors use RFC 7807" "Return problem+json bodies" --type convention --team
agentmem promote <id>      # move an existing local memory into the team folder
git add .agentmem && git commit -m "Add API error convention"

Team memories are plain Markdown, so they show up in pull requests like any other change. Reviewers can correct or reject them before they reach the rest of the team, and everyone gets them on git pull. Agents call memory_write with scope: "team" or memory_promote to do the same.

Org memory

Share rules across every repo of the same owner, such as "timestamps are UTC" for a whole GitHub org. Put team memories in the .agentmem/ folder of one repo, then add it once:

agentmem org add git@github.com:acme/.agentmem.git
agentmem org pull         # fetch the latest org memories
agentmem org list
agentmem org rm git@github.com:acme/.agentmem.git

The repo is cloned into ~/.agentmem/_org/. Its memories show up, marked (org), in every project whose origin remote has the same owner (here github.com/acme/). They are read-only: change them with a pull request to the org repo.

Guardrails

A memory with guard and a files pattern becomes a rule that the PreToolUse hook enforces in Claude Code:

agentmem add "Generated client" "Run pnpm codegen instead" --type convention --files "src/gen/**" --guard block --team
agentmem add "Migrations are append-only" "Add a new migration file" --files "db/migrations/*.sql" --guard warn --team
  • block: the edit is denied, and the agent sees the memory as the reason.
  • warn: you are asked to approve the edit, with the memory shown.

Patterns support *, ** and ?. Agents without hooks get guardrails through exported rule files.

In pull requests

agentmem guard-check lists files changed since a ref (default HEAD^1) that are covered by a guardrail, and exits with an error if any are block. To run it on every pull request, add .github/workflows/agentmem-guard.yml:

name: agentmem guardrails
on: pull_request

jobs:
  guard:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2
      - uses: virling/agentmem/guard@v0

block guardrails fail the check and warn guardrails add a warning on the file. Only team memories are in the repo, so only team guardrails apply.

Code-aware staleness

When a memory lists files, agentmem stores a content hash of each file. Later:

  • If a file is deleted, the memory is flagged stale.
  • If a file's content changed, the memory is flagged changed since written.

Both flags appear in list, search results and the session-start index, so the agent knows to double-check. After checking, run agentmem verify <id> (or memory_update with just the id) to record the current file versions.

Usage stats

agentmem counts a memory as used when it is shown at session start (handoff and pinned), injected for a touched file, hit by a guardrail, or read with memory_read or agentmem show.

agentmem stats

It lists memories by use count, then the ones not used in 14 or more days so you can delete what no longer helps. Counts are stored in usage.json in the project's local folder.

Export to rule files

Agents that do not speak MCP still read rule files. agentmem export compiles team conventions, decisions, gotchas and guardrails into them:

agentmem export                       # AGENTS.md
agentmem export agents claude copilot cursor
agentmem export --include-local       # also include your local memories
Target File
agents AGENTS.md
claude CLAUDE.md
copilot .github/copilot-instructions.md
cursor .cursor/rules/agentmem.mdc

agentmem only rewrites the block between <!-- agentmem:start --> and <!-- agentmem:end -->. Everything else in the file is left as it is. The Cursor file is fully managed.

Contradiction checks

  • memory_write and agentmem add return related memories (same files or similar wording) so the agent can spot a conflict right away.
  • agentmem check sends all memories to claude -p --model haiku and lists pairs that contradict each other.
$ agentmem check
- 2026-10-31-package-manager-is-pnpm vs 2026-10-31-use-npm-for-installs: One says always use pnpm, the other says run npm install in CI.

Handoffs between agents

Stop in one agent and continue in another without re-explaining:

  • In Claude Code, auto-capture writes a handoff when a session ends with work unfinished.
  • Any agent can call memory_handoff (for example when you say "hand this off, I'm switching to Cursor").
  • From the terminal: agentmem handoff "<what is done>" "<next steps>".

The latest handoff from the last 7 days is shown first at the next session start, and at the top of memory_list in agents without hooks. Writing a new handoff replaces the old one.

PR memory GitHub Action

Turn decisions made in pull request reviews into team memories. Add this workflow to your repo as .github/workflows/agentmem.yml:

name: agentmem
on:
  pull_request:
    types: [closed]

permissions:
  contents: write
  pull-requests: write

jobs:
  memories:
    if: github.event.pull_request.merged
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.base.ref }}
      - uses: virling/agentmem@v0
        with:
          anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}

When a pull request is merged, the action reads its description, reviews and comments, asks Claude for decisions, conventions and gotchas worth keeping, and opens a pull request that adds them to .agentmem/. Your team reviews that pull request like any other.

Input Default Purpose
anthropic-api-key required Anthropic API key, stored as a repository secret
model claude-opus-5-5 Claude model used for extraction
github-token github.token Reads the pull request and opens the memory pull request

Your repository must allow GitHub Actions to create pull requests (Settings, Actions, General, Workflow permissions).

Memory format

---
title: Use pnpm
type: convention
agent: claude-code
date: 2026-10-31
updated: 2026-11-02
pinned: true
guard: warn
files: package.json, pnpm-lock.yaml
tags: tooling
hashes: package.json@3f2a9c1b7d4e, pnpm-lock.yaml@a91c03e5f2b8
---

This repo uses pnpm 9, not npm.
  • files: repo-relative paths. Used for file-linked hints and stale detection.
  • stale: if a listed file no longer exists, the memory is shown with stale: <file> missing so an agent can verify and fix it.
  • pinned: always shown in full at session start.
  • guard: warn or block. See Guardrails.
  • hashes: written by agentmem. See Code-aware staleness.

You can edit these files by hand. agentmem reads them fresh on every call.

Configuration

Variable Default Purpose
AGENTMEM_HOME ~/.agentmem Where all project folders live
CLAUDE_CONFIG_DIR ~/.claude Where agentmem install writes hooks

Sharing with a team

The recommended way is team memory in git. To share local memories without git, point AGENTMEM_HOME at a synced folder (Dropbox, iCloud Drive, Google Drive). Every teammate who opens the same repo gets the same project id, so they read the same memories. One fact per file keeps sync conflicts rare.

Project structure

agentmem/
├── bin/agentmem.js    CLI and MCP entry point
├── src/               store, MCP server, hooks, auto-capture, installer, export, PR capture
├── test/              one test file per module (node:test)
├── hooks/             Claude Code plugin hooks
├── .claude-plugin/    Claude Code plugin and marketplace manifests
├── action.yml         PR memory GitHub Action
├── guard/action.yml   Guardrails GitHub Action
└── .github/           CI, release workflow, issue and PR templates

See CONTRIBUTING.md for what each module does.

Troubleshooting

  • Agent does not see the tools. Run claude mcp list and check that agentmem shows as connected. Restart the agent after config changes.
  • Memories saved under the wrong project. Run agentmem path inside the project to see the expected folder. Pass project_path from editors that start servers elsewhere.
  • Nothing is captured and no handoff appears. The hooks are missing. Run agentmem install claude, or check ~/.claude/settings.json for the four agentmem ... hook entries. When they are missing, the MCP server tells Claude Code to say so.
  • Auto-capture saved nothing. Check capture.log in the folder from agentmem path. Short sessions (under 500 characters of conversation) are skipped.
  • "similar memory exists". Update the existing memory, or pass force: true / --force.
  • "looks like it contains a secret". Remove the key from the text. Store the name of the env var instead.

Uninstall

  1. Remove the four agentmem hook entries from ~/.claude/settings.json, or /plugin uninstall agentmem@virling if you used the plugin.
  2. claude mcp remove agentmem --scope user
  3. Remove the agentmem entry from each other agent's MCP config listed in Connect your agents.
  4. npm rm -g @virling/agentmem if you installed it globally.
  5. Optional: rm -rf ~/.agentmem deletes all memories.

Contributing

See CONTRIBUTING.md.

License

PolyForm Noncommercial 1.0.0. Free for personal, research, educational and other noncommercial use. Selling agentmem or using it commercially requires a separate license from the author: open an issue or contact Virling.

About

Persistent project memory shared by every AI coding agent: Claude Code, Cursor, Codex, Gemini CLI, Windsurf and any MCP client. Auto-captures decisions, injects them back next session.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages