# Project Memory MCP An MCP server and Claude Code plugin for persistent project memory. Allows AI agents to maintain knowledge about projects between conversations via `MEMORY.md` files. ## Features - **Store & retrieve** project knowledge in Markdown format - **Incremental updates** via SEARCH/REPLACE patches - **Auto-read hook** — automatically loads project memory on first prompt (Claude Code plugin) - **Dream consolidation** — automatic project memory cleanup and deduplication (Claude Code plugin) ## Installation ### Claude Code Plugin (recommended) Installs the MCP server, auto-read hook, and dream consolidation: ```bash /plugin marketplace add /path/to/project-mem-mcp /plugin install project-mem@cc-plugin-project-mem ``` ### Standalone MCP Server For Codex, Claude Desktop, Cursor, or other MCP clients: ```bash uvx project-mem-mcp ``` #### MCP Client Configuration ```json { "mcpServers": { "project-mem-mcp": { "command": "uvx", "args": [ "project-mem-mcp", "--allowed-dir", "/path/to/your/projects" ] } } } ``` The `--allowed-dir` argument restricts which directories the server can access. Can be used multiple times. Defaults to the current working directory if omitted. ### Install from Source ```bash git clone https://github.com/pynesys/project-mem-mcp.git cd project-mem-mcp python -m venv venv source venv/bin/activate pip install -e . ``` ## Tools ### get_project_memory Retrieves `MEMORY.md` content. With no extra args, returns the whole file. The server raises `ValueError` if the file would exceed ~20K estimated tokens (below most clients' tool-result caps); use `head_only` or `offset/limit` to pull what you need. ``` get_project_memory( project_path: str, offset: int = 0, # 1-indexed start line; 0 = from start limit: int | None = None, # max lines to return head_only: bool = False, # return only size + heading TOC ) -> str ``` Typical large-file pattern: call once with `head_only=True` to get size and a section TOC (line ranges), then fetch sections via `offset/limit`. ### search_project_memory Substring search inside `MEMORY.md`. Case-insensitive. Returns matching lines with 1-indexed line numbers; combine with `get_project_memory(offset, limit)` to fetch surrounding context for a hit. ``` search_project_memory( project_path: str, query: str, max_results: int = 50, ) -> str ``` ### set_project_memory Overwrites the entire `MEMORY.md`. Use when creating a new project memory or when patches fail. ``` set_project_memory( project_path: str, project_info: str | None = None, project_info_file: str | None = None, ) ``` Content comes from exactly one of the two sources: `project_info` is the literal Markdown text; `project_info_file` is an absolute path to a UTF-8 file the server reads itself — preferred for large rewrites drafted to a file, since the content need not be re-emitted as a parameter. Parameters are never shell-expanded, so `$(cat draft.md)` inside `project_info` does not work (the server rejects payloads that look like unexpanded substitutions). ### update_project_memory Applies a single SEARCH/REPLACE patch to `MEMORY.md`: ``` update_project_memory(project_path: str, patch_content: str) ``` Patch format: ``` <<<<<<< SEARCH Text to find in the project memory file ======= Text to replace it with >>>>>>> REPLACE ``` The search text must appear exactly once in the file. Use empty replacement to remove content. ## Plugin Features When installed as a Claude Code plugin, you also get: ### Project-memory Skill (auto-trigger) Guides Claude on when and how to save to project memory. Automatically triggers when insights worth persisting are discovered — architecture decisions, gotchas, non-obvious patterns, current work context. The skill is marked `user-invocable: false` so it does not appear in the slash command picker; the main model invokes it autonomously. ### Auto-read Hook Automatically reads `MEMORY.md` into context on the first prompt of each session. No manual tool call needed. ### Dream Consolidation Automatic project memory maintenance triggered after writes when: - File size exceeds 50KB - Last consolidation was more than 24 hours ago The dream spawns a sonnet subagent that: - Removes content duplicated in CLAUDE.md files - Collapses topics that have gone dormant, and tightens older `Recent Sessions` entries - Restructures for clarity and LLM readability - Shrinks a bloated file substantially (~30% per pass as the yardstick) rather than just holding it flat If the session that triggered the dream just wrote something that must survive untouched, it passes a short `Preserve verbatim` list of pointers to the subagent — those items are kept as-is, while the consolidation still does its work on the rest of the file. No backup is written; use `git` to recover the pre-dream state if needed. Manual trigger: `/dream` The last-dream timestamp is stored as `last_dream:` inside a YAML frontmatter block at the top of `MEMORY.md`. Projects previously using this plugin may still have a `.claude/.last-dream-timestamp` file — that file is now ignored and can be safely deleted (the first dream run after upgrade repopulates the frontmatter). ## Security - Project paths are validated against `--allowed-dir` arguments - Project memory files should never contain sensitive information - Project memory files must be in English ## Dependencies - fastmcp (>=3.2.0, <4.0.0) ## License MIT