<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ripon C Malo</title>
    <description>The latest articles on DEV Community by Ripon C Malo (@riponcm).</description>
    <link>https://dev.to/riponcm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3943129%2Fd37c3122-26cb-40b9-a3fe-0e0bbc19fea5.jpeg</url>
      <title>DEV Community: Ripon C Malo</title>
      <link>https://dev.to/riponcm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/riponcm"/>
    <language>en</language>
    <item>
      <title>How I built projectmem — an MCP server that gives Claude, Cursor, and Codex persistent memory</title>
      <dc:creator>Ripon C Malo</dc:creator>
      <pubDate>Thu, 21 May 2026 02:30:29 +0000</pubDate>
      <link>https://dev.to/riponcm/how-i-built-projectmem-an-mcp-server-that-gives-claude-cursor-and-codex-persistent-memory-54b3</link>
      <guid>https://dev.to/riponcm/how-i-built-projectmem-an-mcp-server-that-gives-claude-cursor-and-codex-persistent-memory-54b3</guid>
      <description>&lt;p&gt;Few months back, my AI coding agent confidently suggested this fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.header-preview&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'd tried that exact thing the previous Friday. It didn't work. The agent had no memory of the failure — different chat, fresh context, same dead-end.&lt;/p&gt;

&lt;p&gt;This happens every Monday. Across Claude, Cursor, Codex, Antigravity — agents are stateless between sessions. Each new conversation pays 5,000–20,000 tokens to rebuild context that existed yesterday. The model isn't broken; &lt;strong&gt;the architecture is.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I built &lt;code&gt;projectmem&lt;/code&gt;. This post walks through what it actually does — five killer features, a four-view D3 dashboard, the architecture, and the conda/venv hook bug that nearly shipped v0.1.3 broken. It's open source, MIT, runs 100% local, ships as a single &lt;code&gt;pip install&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What projectmem is, in 60 seconds
&lt;/h2&gt;

&lt;p&gt;A small Python package that does three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Captures development events&lt;/strong&gt; — bugs, fix attempts, fixes, decisions, gotchas — into plain-text JSONL inside your repo (&lt;code&gt;.projectmem/events.jsonl&lt;/code&gt;). You commit it. You can &lt;code&gt;git diff&lt;/code&gt; it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exposes 14 MCP tools&lt;/strong&gt; so any MCP-capable AI client (Claude Desktop, Claude Code, Cursor, Antigravity, Codex) reads and writes that memory directly. One config block per client, works in all of them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Runs git hooks&lt;/strong&gt; that warn you at commit time before you repeat a logged failed approach.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;projectmem
pjm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the install. &lt;code&gt;pjm init&lt;/code&gt; writes the memory directory, drops a &lt;code&gt;CLAUDE.md&lt;/code&gt; bridge file, installs the git hooks, pre-populates &lt;code&gt;PROJECT_MAP.md&lt;/code&gt; from your stack manifests, and prints a ready-to-paste MCP client config block. No cloud, no daemon, no telemetry.&lt;/p&gt;




&lt;h2&gt;
  
  
  The five killer features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Pre-commit warnings (the differentiator)
&lt;/h3&gt;

&lt;p&gt;The git pre-commit hook checks your staged file against memory. If there's a logged failed approach on that file, it warns you before the commit lands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;projectmem: Pre-Commit Check
────────────────────────────────────────────────────────────

  styles.css
    WARN  1 failed attempt on this file
           Last failure: tried contain: layout — preview still jumps
             (3 days ago)

────────────────────────────────────────────────────────────
1 warning(s). Review before committing.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most "AI memory" tools are &lt;em&gt;retrieval engines&lt;/em&gt; — they store conversations and surface them when asked. projectmem is a &lt;em&gt;judgment layer&lt;/em&gt; — it captures events with explicit outcomes (&lt;code&gt;worked&lt;/code&gt; / &lt;code&gt;failed&lt;/code&gt; / &lt;code&gt;partial&lt;/code&gt;) and uses git context to interrupt you before you waste another afternoon. &lt;strong&gt;The pre-commit hook is the unlock.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cross-project memory
&lt;/h3&gt;

&lt;p&gt;Lessons in one repo automatically surface in others on the same stack. Library gotchas, framework decisions, patterns you only had to learn once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.projectmem/global/
├── library_gotchas.jsonl
├── patterns.jsonl
└── .promotable.json    ← self-curating cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you &lt;code&gt;pjm init&lt;/code&gt; a new project, projectmem detects your stack from &lt;code&gt;pyproject.toml&lt;/code&gt; / &lt;code&gt;package.json&lt;/code&gt; / &lt;code&gt;Cargo.toml&lt;/code&gt; / &lt;code&gt;go.mod&lt;/code&gt; and injects relevant cross-project gotchas into &lt;code&gt;AI_INSTRUCTIONS.md&lt;/code&gt;. Stack-aware filtering, so a &lt;code&gt;vite&lt;/code&gt; project's mention of "next" doesn't pollute Next.js gotchas in your actual Next.js repos.&lt;/p&gt;

&lt;p&gt;100% local — &lt;code&gt;~/.projectmem/global/&lt;/code&gt; stays on your machine. No cloud sync, no account, no telemetry. A &lt;code&gt;gin&lt;/code&gt; gotcha you log in &lt;code&gt;proj-go&lt;/code&gt; shows up in your next Go repo. A &lt;code&gt;vite&lt;/code&gt; gotcha in &lt;code&gt;proj-react&lt;/code&gt; shows up in your next React repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Provable ROI (&lt;code&gt;pjm score&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;An A+ → F letter grade backed by concrete numbers. The first AI memory tool with metrics a CTO can verify.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pjm score

projectmem Prevention Score: A- &lt;span class="o"&gt;(&lt;/span&gt;87/100&lt;span class="o"&gt;)&lt;/span&gt;
  Failed approaches on record: 8
  Decisions documented: 14
  Fixes with context: 12
  Debugging hours saved: ~12h
  Tokens saved: 47,500
  Estimated USD saved: &lt;span class="nv"&gt;$4&lt;/span&gt;.75
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output as terminal, JSON for CI (&lt;code&gt;pjm score --format json&lt;/code&gt;), or a shields.io badge for your README. Lets you put a number on the value the memory layer is actually producing — instead of a marketing claim.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Smart context injection (&lt;code&gt;pjm wrap&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Launches your AI agent with a token-budgeted context block already loaded — so the agent starts with your project memory inherited, instead of blank.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pjm wrap claude &lt;span class="nt"&gt;--tokens&lt;/span&gt; 2000
&lt;span class="c"&gt;# launches Claude with a 2000-token context block of:&lt;/span&gt;
&lt;span class="c"&gt;# - your project summary&lt;/span&gt;
&lt;span class="c"&gt;# - recent decisions&lt;/span&gt;
&lt;span class="c"&gt;# - relevant cross-project gotchas&lt;/span&gt;
&lt;span class="c"&gt;# - any failed approaches on files you'll likely touch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works with Claude Code, Cursor (writes to &lt;code&gt;.cursorrules&lt;/code&gt;), Aider, and clipboard-paste for everything else. The AI session begins &lt;em&gt;experienced&lt;/em&gt;, not from zero.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Real-time file watcher (&lt;code&gt;pjm watch&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Auto-starts on &lt;code&gt;pjm init&lt;/code&gt; in interactive terminals. Detects rapid edits to the same file (debugging sessions) and logs churn events automatically. Battery-aware, gitignore-aware. Catches what AI silently misses — the &lt;em&gt;between-commits&lt;/em&gt; iteration where most actual debugging happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pjm watch &lt;span class="nt"&gt;--status&lt;/span&gt;
projectmem watcher: active &lt;span class="o"&gt;(&lt;/span&gt;PID 47891&lt;span class="o"&gt;)&lt;/span&gt;
  Watching: /Users/me/repos/your-project
  Events captured today: 12 churn, 3 commit
  Battery: AC power &lt;span class="o"&gt;(&lt;/span&gt;full speed&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The visualization: four D3 dashboards from one command
&lt;/h2&gt;

&lt;p&gt;This is the part I think most projects skip and shouldn't.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pjm visualize
&lt;span class="c"&gt;# opens localhost:8765 in your browser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get an interactive D3 dashboard with four views, all auto-generated from your memory — &lt;strong&gt;zero extra AI tokens.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Story Map
&lt;/h3&gt;

&lt;p&gt;The complete narrative of your project — every decision, milestone, and failure visualized as an interactive force-directed graph. Failed files glow red in the heatmap. Drag nodes around. Zoom into problem areas. &lt;strong&gt;Your AI reads this to understand not just what your project is, but how it got here.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ROI Dashboard
&lt;/h3&gt;

&lt;p&gt;Live visualization of how much projectmem actually saves you. Animated counters for tokens prevented and USD protected. Capture-source donut showing manual vs auto-captured events. File churn heatmap surfacing your most-debugged files. Cumulative savings area chart over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Map
&lt;/h3&gt;

&lt;p&gt;Toggle between a horizontal dendrogram (clean, hierarchical) and a force-directed graph (relationships, churn). Both auto-generated from &lt;code&gt;PROJECT_MAP.md&lt;/code&gt;. Zoom, pan, color-coded by folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Timeline
&lt;/h3&gt;

&lt;p&gt;Every event in your memory rendered chronologically — with &lt;code&gt;AUTO&lt;/code&gt; badges distinguishing auto-captured events from manual ones. Filter by Manual / Auto-captured / event type. Activity bar chart shows the rhythm of your project.&lt;/p&gt;

&lt;p&gt;The whole thing is one HTTP server, vanilla D3.js, no React, no framework. Loads instantly. The view your AI agent reads in &lt;code&gt;summary.md&lt;/code&gt; is the same view you can scrub through interactively when you open the dashboard.&lt;/p&gt;




&lt;h2&gt;
  
  
  The architecture (for the engineers in the room)
&lt;/h2&gt;

&lt;p&gt;Stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python 3.10+&lt;/strong&gt;, ~600 LOC core&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies:&lt;/strong&gt; &lt;code&gt;mcp&lt;/code&gt;, &lt;code&gt;typer&lt;/code&gt;, &lt;code&gt;watchdog&lt;/code&gt;. That's it. No frameworks, no daemon, no port.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; append-only JSONL inside the repo, distilled into Markdown.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport:&lt;/strong&gt; stdio MCP. The AI client spawns the server as a subprocess; no network, no localhost binding, no process to babysit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 14 tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_instructions     get_summary        get_project_map
get_context          get_score          get_global_gotchas
get_issue            search_events      precheck_file
log_issue            record_attempt     record_fix
add_decision         add_note
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every parameter has a Pydantic &lt;code&gt;Field(description=…)&lt;/code&gt; annotation, and where it matters, a schema-level constraint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;record_attempt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;One-line description of what you tried.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Result of the attempt.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^(worked|failed|partial)$&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The schema literally rejects &lt;code&gt;outcome="maybe"&lt;/code&gt; before the tool body runs. Cleanest way I've found to add real guardrails to LLM-generated tool calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why stdio, not HTTP
&lt;/h3&gt;

&lt;p&gt;agentmemory (the most-starred competitor) runs a Node daemon on three ports (3111 / 3112 / 3113) with a separate iii-engine binary and ~21,800 LOC. Excellent retrieval. Heavy install.&lt;/p&gt;

&lt;p&gt;projectmem stays stdio-only on purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No port to babysit&lt;/li&gt;
&lt;li&gt;No daemon to remember to start&lt;/li&gt;
&lt;li&gt;No conflict with existing infra&lt;/li&gt;
&lt;li&gt;The AI client manages the subprocess lifecycle for free&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tradeoff: no cross-process state. For single-developer-per-project workflows, that's not a real tradeoff — every benefit goes to "one less thing to debug."&lt;/p&gt;




&lt;h2&gt;
  
  
  The privacy guardrail
&lt;/h2&gt;

&lt;p&gt;projectmem stores event text verbatim in your repo. That's the whole point — the memory is plain text you can &lt;code&gt;git diff&lt;/code&gt;. The downside: a careless paste in an AI chat — &lt;em&gt;"the bug repros when I set &lt;code&gt;OPENAI_API_KEY=sk-...&lt;/code&gt;"&lt;/em&gt; — would otherwise land that key on disk.&lt;/p&gt;

&lt;p&gt;v0.1.3 closes that hole. Before any event hits disk, &lt;code&gt;storage.append_event&lt;/code&gt; runs a conservative pattern scrubber across the user-supplied text fields. Matches against high-confidence patterns get replaced with &lt;code&gt;[REDACTED:&amp;lt;kind&amp;gt;]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Patterns: OpenAI sk-, GitHub PAT, AWS AKIA, Google AIza,
          Slack tokens, Stripe live/test keys, JWTs (eyJ...),
          Bearer tokens, PEM private-key blocks.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Patterns are intentionally narrow. Ordinary debugging prose — &lt;em&gt;"tried contain: layout"&lt;/em&gt;, &lt;em&gt;"forgot password reset flow"&lt;/em&gt; — is never touched. &lt;strong&gt;29 unit tests&lt;/strong&gt; pin both true-positive and false-positive behavior.&lt;/p&gt;

&lt;p&gt;Default-on. &lt;code&gt;PROJECTMEM_NO_REDACT=1&lt;/code&gt; opts out for the rare contexts where you genuinely want the raw text.&lt;/p&gt;

&lt;p&gt;Either it's there from day one or users learn not to trust the tool. v0.1.3 makes it day one.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;projectmem
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project
pjm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pjm init&lt;/code&gt; ends by printing a ready-to-paste MCP config block (absolute &lt;code&gt;sys.executable&lt;/code&gt; baked in to dodge the Claude-Desktop / Cursor PATH-inheritance gotcha). Paste it into your client's config file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude Desktop:&lt;/strong&gt; &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor:&lt;/strong&gt; &lt;code&gt;~/.cursor/mcp.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Antigravity legacy IDE:&lt;/strong&gt; &lt;code&gt;~/.gemini/antigravity/mcp_config.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codex&lt;/strong&gt; (TOML, not JSON): &lt;code&gt;~/.codex/config.toml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cold-start your client and the 14 projectmem tools appear in the MCP panel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/riponcm/projectmem" rel="noopener noreferrer"&gt;https://github.com/riponcm/projectmem&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;60-second demo: &lt;a href="https://youtu.be/YCqfJ8-XVqY" rel="noopener noreferrer"&gt;https://youtu.be/YCqfJ8-XVqY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Step-by-step tutorial: &lt;a href="https://github.com/riponcm/projectmem/blob/main/TUTORIAL.md" rel="noopener noreferrer"&gt;https://github.com/riponcm/projectmem/blob/main/TUTORIAL.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PyPI: &lt;a href="https://pypi.org/project/projectmem" rel="noopener noreferrer"&gt;https://pypi.org/project/projectmem&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Official MCP Registry: &lt;a href="https://registry.modelcontextprotocol.io" rel="noopener noreferrer"&gt;https://registry.modelcontextprotocol.io&lt;/a&gt; (search &lt;code&gt;projectmem&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The v0.2 roadmap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stale-memory detection&lt;/strong&gt; — flag, never delete. Cross-reference each decision's referenced file against recent git activity; surface decisions that predate heavy churn as "possibly stale, confirm or supersede."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit &lt;code&gt;--supersedes&lt;/code&gt;&lt;/strong&gt; on &lt;code&gt;add_decision&lt;/code&gt; — the honest version of memory decay. Old decision retired with a back-reference; nothing destroyed; full audit trail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic search&lt;/strong&gt; as an opt-in extra (sentence-transformers + sqlite-vec). Default install stays dependency-light.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Honest about the rough edges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Search is exact substring today, not semantic&lt;/li&gt;
&lt;li&gt;API may still shift before 1.0&lt;/li&gt;
&lt;li&gt;The precheck heuristics are simple right now (file-name match → surface failed attempts)&lt;/li&gt;
&lt;li&gt;Recall benchmarks are unpublished (the equivalent for "judgment accuracy" hasn't been defined yet)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But: &lt;strong&gt;58 unit tests&lt;/strong&gt;, end-to-end verified across Claude Desktop / Claude Code / Cursor / Antigravity / Codex, the conda gotcha properly fixed, the privacy guardrail real and tested, the visualization dashboard genuinely useful.&lt;/p&gt;

&lt;p&gt;If you build with AI coding agents every day, try it once on a real project. The pre-commit hook usually catches its first real failure within the first week.&lt;/p&gt;

&lt;p&gt;What's the worst &lt;em&gt;"I already told you this last week"&lt;/em&gt; moment you've had with your AI agent? Reply below — that's exactly the pattern the precheck heuristics need to learn from.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;— Ripon&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>mcp</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
