<?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: Sri</title>
    <description>The latest articles on DEV Community by Sri (@smara).</description>
    <link>https://dev.to/smara</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%2F3854601%2Fe6a2edcc-fabb-4495-b869-c4b5112872fc.png</url>
      <title>DEV Community: Sri</title>
      <link>https://dev.to/smara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/smara"/>
    <language>en</language>
    <item>
      <title>How I Built a Persistent Memory Layer for AI Coding Tools</title>
      <dc:creator>Sri</dc:creator>
      <pubDate>Wed, 08 Apr 2026 21:49:18 +0000</pubDate>
      <link>https://dev.to/smara/how-i-built-a-persistent-memory-layer-for-ai-coding-tools-39ha</link>
      <guid>https://dev.to/smara/how-i-built-a-persistent-memory-layer-for-ai-coding-tools-39ha</guid>
      <description>&lt;p&gt;If you use AI coding assistants daily, you have felt this pain. You open a new session with Claude Code, Cursor, or Copilot, and you spend the first twenty minutes re-explaining your project structure, your preferences, the bug you fixed yesterday, the architectural decisions you made last week. The AI has no idea. Every session starts from absolute zero.&lt;/p&gt;

&lt;p&gt;I started measuring this. In my own workflow, I was burning 20-25 minutes per session on context restoration alone. That is not the worst part. MCP servers — the tools that extend these AI assistants — consume tokens just by loading. I have watched 67,000 tokens disappear before I even typed my first prompt. That is roughly half the context window on most models, gone before any actual work begins.&lt;/p&gt;

&lt;p&gt;Context fills up. The conversation dies. You start a new one. The cycle repeats.&lt;/p&gt;

&lt;p&gt;Now multiply this across a team. Five developers, each running four AI sessions per day, each losing twenty minutes to context re-establishment. That is nearly seven hours of developer time evaporating every single day. Over a month, that is 140 hours — three and a half work weeks — spent telling AI tools things they already knew yesterday.&lt;/p&gt;

&lt;p&gt;The problem is not that these tools are unintelligent. The problem is architectural. Each AI session is stateless by design. There is no persistence layer. There is no memory. Your Claude Code session and your Cursor session are completely isolated. A fact stored in one never reaches the other.&lt;/p&gt;

&lt;p&gt;I wanted to fix this. Not by building yet another AI wrapper or a fancy prompt template, but by adding a proper memory layer that sits beneath every tool and persists across all of them. That project became &lt;a href="https://smara.io" rel="noopener noreferrer"&gt;Smara&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MCP Was the Right Protocol
&lt;/h2&gt;

&lt;p&gt;When I started building Smara, I had three options for integrating with AI coding tools: fork each tool and patch memory in, build custom plugins for each platform, or find a universal protocol.&lt;/p&gt;

&lt;p&gt;The Model Context Protocol (MCP) made the choice obvious. MCP is an open standard — originally created by Anthropic, now adopted by OpenAI, Google, and dozens of other tool vendors — that lets you extend any compatible AI tool without touching its source code. You write a server that exposes tools, and any MCP-compatible client can call them.&lt;/p&gt;

&lt;p&gt;The key insight is that MCP's tool-calling model maps naturally to memory operations. An AI assistant already knows how to call tools. It already reasons about when to use &lt;code&gt;grep&lt;/code&gt; versus &lt;code&gt;read_file&lt;/code&gt;. Adding &lt;code&gt;smara_store&lt;/code&gt; and &lt;code&gt;smara_search&lt;/code&gt; to its toolkit requires zero behavioral changes. The AI decides when to store a memory and when to recall one, the same way it decides when to run a shell command.&lt;/p&gt;

&lt;p&gt;Custom plugins would have locked me into a single platform. API wrappers would have required explicit integration code in every tool. MCP gave me write-once, run-everywhere. One server, one &lt;code&gt;npm install&lt;/code&gt;, and suddenly Claude Code, Cursor, Windsurf, and any future MCP-compatible tool all share the same memory pool.&lt;/p&gt;

&lt;p&gt;The ecosystem validated this bet. MCP SDK downloads have crossed 97 million per month. There are over 10,000 MCP servers in the wild. When OpenAI and Google both adopted the protocol within months of Anthropic publishing it, it was clear that MCP was not a niche experiment — it was becoming the standard interface between AI tools and the outside world.&lt;/p&gt;

&lt;p&gt;Building on MCP also meant I could focus entirely on what mattered: the memory engine itself. No platform-specific glue code. No maintaining five different plugin formats. Just one clean protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing the 7 Memory Tools
&lt;/h2&gt;

&lt;p&gt;Early prototypes of Smara had two tools: &lt;code&gt;store&lt;/code&gt; and &lt;code&gt;search&lt;/code&gt;. It worked, technically. But the AI made poor decisions about when to use them. A blunt interface produces blunt behavior.&lt;/p&gt;

&lt;p&gt;The production MCP server exposes seven tools, each with a specific semantic purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;smara_store&lt;/code&gt;&lt;/strong&gt; — Save a new fact to memory with importance scoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;smara_search&lt;/code&gt;&lt;/strong&gt; — Semantic search across stored memories&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;smara_recall&lt;/code&gt;&lt;/strong&gt; — Load context at conversation start (top memories by decay score)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;smara_forget&lt;/code&gt;&lt;/strong&gt; — Explicitly remove a memory that is outdated or wrong&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;smara_list&lt;/code&gt;&lt;/strong&gt; — Browse memories with filtering (by source, namespace, date)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;smara_tag&lt;/code&gt;&lt;/strong&gt; — Organize memories with labels for better retrieval&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;smara_relate&lt;/code&gt;&lt;/strong&gt; — Create explicit connections between related memories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why seven instead of two? Granularity improves AI decision-making. When the AI sees &lt;code&gt;smara_forget&lt;/code&gt;, it understands it can correct mistakes. When it sees &lt;code&gt;smara_relate&lt;/code&gt;, it can link a debugging session to an architectural decision. These are not just CRUD operations — they are cognitive primitives that map to how an intelligent agent should interact with memory.&lt;/p&gt;

&lt;p&gt;Adding Smara to your AI tool takes one config block. Here is the MCP configuration for Claude Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"smara"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@smara/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"SMARA_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"smara_your_key_here"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop that into &lt;code&gt;~/.claude/mcp_config.json&lt;/code&gt; (or &lt;code&gt;.cursor/mcp.json&lt;/code&gt; for Cursor), restart, and memory is live. Context loads automatically at conversation start. New facts are stored silently during normal work. The AI handles the memory management itself — you do not need to think about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ebbinghaus Decay Scoring
&lt;/h2&gt;

&lt;p&gt;Most memory systems rank results by recency or by vector similarity. Recency is naive — a two-week-old architectural decision matters more than this morning's typo fix. Pure similarity misses temporal context — it cannot distinguish between a current fact and an obsolete one.&lt;/p&gt;

&lt;p&gt;Smara uses Ebbinghaus forgetting curve decay, modeled after how human memory actually works. Every memory's relevance decays exponentially over time, modulated by its importance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ebbinghaus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;importance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;halfLife&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;importance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;days&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;halfLife&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;A high-importance memory (importance: 1.0) has a half-life of about 10 days. A low-importance memory (importance: 0.1) fades in roughly a day. This means "the production database uses PostgreSQL 15 on port 5432" stays strong for weeks, while "I renamed a variable in utils.ts" naturally fades away.&lt;/p&gt;

&lt;p&gt;The critical mechanism: memories strengthen on access. Every time the AI retrieves a memory, Smara bumps its &lt;code&gt;access_count&lt;/code&gt; and resets its &lt;code&gt;last_accessed_at&lt;/code&gt; timestamp. Frequently used facts stay fresh. Forgotten facts decay. This is exactly how human memory works — rehearsal strengthens neural pathways.&lt;/p&gt;

&lt;p&gt;Search results are ranked by a blend of semantic similarity and temporal decay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;blendScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decayScore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;similarity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;decayScore&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.3&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;The 70/30 blend means relevance still dominates — you get the fact that best matches your query — but recency and access patterns break ties. A moderately relevant memory that you accessed yesterday beats a slightly more relevant memory you have not touched in a month.&lt;/p&gt;

&lt;p&gt;No competitor in this space has Ebbinghaus decay scoring. Mem0, Zep, Supermemory — they all use flat recency or pure vector similarity. Smara's temporal scoring is, as far as I can tell, unique in the developer tools space. It is also what makes the memory feel natural rather than mechanical.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making It Work Across Teams
&lt;/h2&gt;

&lt;p&gt;Individual memory was the easy part. The hard problem — the one I underestimated by weeks — was shared team memory.&lt;/p&gt;

&lt;p&gt;The challenge is not technical complexity. It is semantic complexity. When developer A stores "the auth service uses JWT with RS256," should developer B's AI session see that? Probably yes. When developer A stores "I prefer tabs over spaces," should developer B's session see that? Absolutely not.&lt;/p&gt;

&lt;p&gt;Smara solves this with a namespace and visibility model. Every memory has a &lt;code&gt;namespace&lt;/code&gt; (like &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;project-api&lt;/code&gt;, &lt;code&gt;infra&lt;/code&gt;) and a &lt;code&gt;visibility&lt;/code&gt; setting (&lt;code&gt;private&lt;/code&gt; or &lt;code&gt;team&lt;/code&gt;). When a memory is stored with a &lt;code&gt;team_id&lt;/code&gt;, it is automatically visible to all team members in that namespace. Private memories stay private.&lt;/p&gt;

&lt;p&gt;The search engine performs a UNION query across both pools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;importance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;tenant_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;valid_until&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;team_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;team_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;visibility&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'team'&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;Your private memories and your team's shared memories are searched together, ranked by the same blended score. The AI does not need to know or care about the distinction — it just gets the most relevant facts.&lt;/p&gt;

&lt;p&gt;Here is the scenario that makes this powerful: your teammate debugs a gnarly API rate-limiting issue on Monday. Their Claude session stores the root cause and the fix as team-scoped memories. On Tuesday, you hit a related issue. Your Claude session automatically recalls your teammate's findings. No Slack thread to search. No knowledge base article to write. The team's AI tools build collective knowledge passively, as a byproduct of normal work.&lt;/p&gt;

&lt;p&gt;Team management is handled through a full REST API — create teams, invite members by email, assign roles (admin, member, read-only), and set per-team memory limits. Deduplication and contradiction detection are scoped per team namespace, so team memories stay clean even as multiple people contribute.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture and Self-Hosting
&lt;/h2&gt;

&lt;p&gt;Smara's architecture has three layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The MCP server&lt;/strong&gt; (&lt;code&gt;@smara/mcp-server&lt;/code&gt; on npm) is a lightweight TypeScript process that runs locally alongside your AI tool. It translates MCP tool calls into REST API calls. No state, no database, no dependencies beyond Node.js. Install with &lt;code&gt;npx -y @smara/mcp-server&lt;/code&gt; and point it at any Smara-compatible backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The hosted API&lt;/strong&gt; (&lt;code&gt;api.smara.io&lt;/code&gt;) is a Fastify application running on Railway. It handles authentication, rate limiting, billing, and the core memory operations. PostgreSQL with pgvector stores the memories and their embeddings. Voyage AI (&lt;code&gt;voyage-3&lt;/code&gt;, 1024 dimensions) generates the embeddings for semantic search. The API auto-migrates on startup — create tables, indexes, and extensions automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The storage layer&lt;/strong&gt; is PostgreSQL with pgvector. Memories are stored with their vector embeddings, importance scores, decay metadata, source tags, namespace labels, team associations, and soft-delete timestamps. Deduplication uses cosine similarity bands: &amp;gt;= 0.985 is a true duplicate (skip), 0.94-0.985 is a contradiction (soft-delete old, store new), below 0.94 is a genuinely new fact.&lt;/p&gt;

&lt;p&gt;Self-hosting takes five minutes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/smara-io/api.git
&lt;span class="nb"&gt;cd &lt;/span&gt;api
&lt;span class="nv"&gt;VOYAGE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-key docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you the full API on &lt;code&gt;localhost:3011&lt;/code&gt; with a local PostgreSQL instance. Point the MCP server at your self-hosted instance by setting &lt;code&gt;SMARA_API_URL&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"smara"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@smara/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"SMARA_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"smara_your_key_here"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"SMARA_API_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:3011"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything is MIT-licensed. The hosted service exists for convenience and for teams that do not want to manage infrastructure. The self-hosted path exists for developers who want full control over their data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing a Developer Tool as a Solo Founder
&lt;/h2&gt;

&lt;p&gt;Pricing a developer tool is an exercise in controlled anxiety. Price too high and nobody tries it. Price too low and you cannot sustain the infrastructure. Price with a free tier that is too generous and you fund everyone's usage out of pocket.&lt;/p&gt;

&lt;p&gt;I looked at the competitive landscape. Mem0 charges $249/month for their Pro tier. Zep starts at $25 and climbs to $475. Supermemory charges $399 for teams. These prices make sense for enterprise buyers with procurement budgets. They are prohibitive for indie developers and small teams — exactly the people who need memory the most, because they cannot afford to waste time on context re-establishment.&lt;/p&gt;

&lt;p&gt;Smara's tiers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Memories&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;td&gt;$0/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Developer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;200,000&lt;/td&gt;
&lt;td&gt;$19/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pro&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,000,000&lt;/td&gt;
&lt;td&gt;$99/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The free tier is genuinely usable. 10,000 memories covers months of individual use. The goal is not to frustrate free users into upgrading — it is to let them experience the product fully and upgrade when they need team features or higher volume.&lt;/p&gt;

&lt;p&gt;The $19 Developer tier hits the "expense it without approval" threshold at most companies. The $99 Pro tier is literally half of Mem0's comparable plan, with more memories included.&lt;/p&gt;

&lt;p&gt;The mental model behind this pricing: memory is infrastructure, not a luxury. It should cost about the same as a database or a monitoring tool — present in the budget, never the biggest line item. If a developer saves twenty minutes per session and runs four sessions per day, that is over thirteen hours saved per month. At any reasonable hourly rate, $19 pays for itself before lunch on day one.&lt;/p&gt;

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

&lt;p&gt;Smara v1.2 is in active development with three focus areas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Teams&lt;/strong&gt; is shipping first. The API already supports team creation, invitation flows, role-based access, and shared memory search (as shown in the code above). The MCP server update will add team-aware tools so that AI sessions can store and retrieve team knowledge seamlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI Agents&lt;/strong&gt; comes next. Agents are identities with their own memory namespace, system prompt, and composable skills. Think of a code-review agent that remembers your team's style guide, or an onboarding agent that accumulates institutional knowledge from every new hire's questions. Eight built-in skills are planned: code review, PR review, doc writing, test generation, deploy checklist, onboarding, architecture advising, and security audit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IDE-native memory panels&lt;/strong&gt; will give you visibility into what your AI tools remember — browse, search, edit, and delete memories from a visual interface instead of relying on the AI to manage everything silently.&lt;/p&gt;

&lt;p&gt;The longer-term vision is straightforward: every AI tool you use should share one brain. Not just coding assistants — any AI agent, any workflow, any platform. Smara is the memory layer that makes that possible.&lt;/p&gt;




&lt;p&gt;If you want to try it, the fastest path is three commands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get a free API key at &lt;a href="https://smara.io" rel="noopener noreferrer"&gt;smara.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Add the MCP config to your Claude Code or Cursor setup&lt;/li&gt;
&lt;li&gt;Start working — memory happens automatically&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://smara.io" rel="noopener noreferrer"&gt;smara.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/smara-io/smara" rel="noopener noreferrer"&gt;github.com/smara-io/smara&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;a href="https://www.npmjs.com/package/@smara/mcp-server" rel="noopener noreferrer"&gt;@smara/mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Docs&lt;/strong&gt;: &lt;a href="https://api.smara.io/docs" rel="noopener noreferrer"&gt;api.smara.io/docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am building Smara as a solo founder. If you have questions about the architecture, the MCP integration, or the Ebbinghaus scoring model, I am &lt;a href="https://twitter.com/parallelromb" rel="noopener noreferrer"&gt;@parallelromb&lt;/a&gt; — happy to talk.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>devtools</category>
      <category>memory</category>
    </item>
    <item>
      <title>I Built a Cross-Platform Memory Layer for AI Agents Using Ebbinghaus Forgetting Curves</title>
      <dc:creator>Sri</dc:creator>
      <pubDate>Wed, 01 Apr 2026 04:04:05 +0000</pubDate>
      <link>https://dev.to/smara/how-ebbinghaus-forgetting-curves-make-ai-agents-smarter-ef3</link>
      <guid>https://dev.to/smara/how-ebbinghaus-forgetting-curves-make-ai-agents-smarter-ef3</guid>
      <description>&lt;p&gt;I live with Claude Code. It's where I build everything — my API, my infrastructure, my marketing copy. But every new session starts the same way: Claude has no idea who I am.&lt;/p&gt;

&lt;p&gt;I'd tell it I prefer Python for backend work. Three sessions later, it suggests TypeScript. I'd explain my project architecture on Monday. By Wednesday, gone. I was re-explaining the same context every single day.&lt;/p&gt;

&lt;p&gt;And if you're using Cursor, Codex, or Windsurf, you have this problem too — except worse. Because even if one tool starts remembering, the moment you switch to another, you're back to zero. Each tool is an island.&lt;/p&gt;

&lt;p&gt;I tried the usual fixes. Dumped context into a vector store. Built a RAG pipeline. It worked — until the store had hundreds of entries and a two-month-old preference outranked something I said yesterday, just because the phrasing matched better. The retrieval had no sense of time.&lt;/p&gt;

&lt;p&gt;That's when I started reading about Hermann Ebbinghaus.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 140-year-old experiment that changes everything
&lt;/h2&gt;

&lt;p&gt;In 1885, a German psychologist named Hermann Ebbinghaus spent years memorizing nonsense syllables — things like "DAX," "BUP," "ZOL" — and testing how quickly he forgot them. His results produced one of the most replicated findings in all of psychology: the forgetting curve.&lt;/p&gt;

&lt;p&gt;The core insight: memory retention decays exponentially. You don't gradually forget things in a linear way — you lose most of the information quickly, then the remainder fades slowly. But here's the part that got me: &lt;strong&gt;every time you recall something, the decay rate slows down.&lt;/strong&gt; Memories you access frequently become durable. Memories you never revisit fade to nothing.&lt;/p&gt;

&lt;p&gt;This mapped perfectly to what I needed. A preference mentioned once three months ago should carry less weight than something reinforced yesterday. Frequently accessed context should be strong. Old, unreinforced trivia should quietly disappear.&lt;/p&gt;

&lt;h2&gt;
  
  
  The math behind it
&lt;/h2&gt;

&lt;p&gt;Ebbinghaus's forgetting curve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R = e^(-t / S)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;R&lt;/strong&gt; = retention (0 to 1)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;t&lt;/strong&gt; = time elapsed since the memory was formed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt; = memory strength (higher = slower decay)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the same math behind spaced repetition systems like Anki. I realized I could apply it to AI agent memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://smara.io" rel="noopener noreferrer"&gt;Smara&lt;/a&gt; — a memory API that combines semantic vector search with Ebbinghaus decay scoring. Every stored memory gets an importance score between 0 and 1. At query time, importance scales the memory strength, so high-importance memories decay slowly while trivial ones fade fast.&lt;/p&gt;

&lt;p&gt;The retrieval score blends semantic relevance with temporal decay. Semantic search stays dominant — you still get the most &lt;em&gt;relevant&lt;/em&gt; memories — but recency breaks ties. A moderately relevant memory from yesterday can outrank a highly relevant one from three months ago.&lt;/p&gt;

&lt;p&gt;I also track access patterns. Every time a memory is retrieved, it gets reinforced — frequently accessed memories stay strong. Memories nobody asks about quietly fade. The specific weights took a while to tune, but the principle is simple: relevance × recency × reinforcement.&lt;/p&gt;

&lt;p&gt;The entire API is three calls:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Store a memory:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.smara.io/v1/memories &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "user_id": "user_abc",
    "fact": "Prefers Python over TypeScript for backend work",
    "importance": 0.8
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Search with decay-aware ranking:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://api.smara.io/v1/memories/search?&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
user_id=user_abc&amp;amp;q=what+language+for+backend&amp;amp;limit=5"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response gives you &lt;code&gt;similarity&lt;/code&gt;, &lt;code&gt;decay_score&lt;/code&gt;, and the blended &lt;code&gt;score&lt;/code&gt; — you can see exactly why a memory was ranked where it was.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get full user context for your LLM prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://api.smara.io/v1/users/user_abc/context"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop the context string into your system prompt and your agent knows who it's talking to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cross-platform problem nobody's solving
&lt;/h2&gt;

&lt;p&gt;Building the API was the easy part. The real insight came from dogfooding it.&lt;/p&gt;

&lt;p&gt;I had Smara wired into Claude Code via MCP. It worked great — my sessions finally had persistent memory. Claude remembered my preferences, my project context, my architecture decisions. It felt like a different tool.&lt;/p&gt;

&lt;p&gt;Then I thought: what about developers using Cursor? Or Codex? Or switching between multiple tools throughout the day? Their memory is siloed in each tool, and none of it carries over. Even Claude Code's built-in memory doesn't follow you to Cursor.&lt;/p&gt;

&lt;p&gt;So I made Smara platform-agnostic. Every memory is tagged with its source — which tool stored it — but all memories live in one pool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Prefers Python over TypeScript for backend work"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"namespace"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"decay_score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.97&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A preference stored via Claude Code is instantly available in Cursor, Codex, or anything else connected to the same account.&lt;/p&gt;

&lt;p&gt;For MCP-compatible tools (Claude Code, Cursor, Windsurf), I built an MCP server that handles everything automatically. Add this to your MCP config and restart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"smara"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@smara/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"SMARA_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-key"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No manual tool calls. The MCP server instructs the LLM to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;At conversation start:&lt;/strong&gt; Automatically load stored context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;During conversation:&lt;/strong&gt; Silently store new facts as they come up&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On explicit request:&lt;/strong&gt; Handle "remember this" and "forget that"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You don't configure rules or triggers. The LLM decides what's worth remembering. The Ebbinghaus decay does the rest.&lt;/p&gt;

&lt;p&gt;For OpenAI-compatible tools (Codex, ChatGPT, custom GPTs), there's a proxy endpoint that accepts OpenAI function calls. Same memory pool, different protocol. So if you're a Cursor user, a Codex user, or you bounce between tools — your context travels with you.&lt;/p&gt;

&lt;p&gt;The result: I store my preferences in Claude Code. A Cursor user on the same Smara account sees that context instantly. Switch to Codex — same memories. One pool, every tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  How this compares to what's out there
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;RAG / vanilla vector search.&lt;/strong&gt; This is where most teams start. Embed everything, retrieve by cosine similarity. Works until your store grows and old entries outrank recent ones because the phrasing happened to match better. No sense of time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Graph memory (Mem0, etc).&lt;/strong&gt; Knowledge graphs capture entity relationships, which is powerful for certain use cases. But the setup cost is high — entity extraction, relationship mapping, graph traversal. For most agent memory needs (preferences, decisions, project context), it's over-engineered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key-value stores (Redis, DynamoDB).&lt;/strong&gt; Fast and simple, but no semantic search. You can only retrieve by exact key, which means your agent needs to know exactly what it's looking for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built:&lt;/strong&gt; Semantic search combined with Ebbinghaus decay. Fuzzy matching that respects time, plus automatic contradiction detection — if a preference changes, the old memory is replaced, not stacked. Three REST endpoints, no SDK to learn. Decay runs at query time, no batch jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;The biggest surprise was how much a simple decay term changes the feel of agent conversations. With flat retrieval, agents feel like they're reading from a database. With decay-aware retrieval, they feel like they actually &lt;em&gt;know&lt;/em&gt; you. Recent interactions carry more weight. Repeated topics build stronger memories. Old noise fades naturally.&lt;/p&gt;

&lt;p&gt;The second surprise was that the cross-platform piece matters more than the memory science. Developers don't just use one AI tool — they use three or four. The siloed memory problem is what actually hurts day to day.&lt;/p&gt;

&lt;p&gt;If you're building agents that talk to users more than once, or you're tired of Cursor, Codex, or Claude Code forgetting everything between sessions — &lt;a href="https://smara.io#signup" rel="noopener noreferrer"&gt;Smara has a free tier&lt;/a&gt; (10,000 memories, no credit card). MCP setup takes 30 seconds. REST API works with anything.&lt;/p&gt;

&lt;p&gt;I'm building this in public and would love feedback — especially from Cursor and Codex users. I built this for Claude Code, but the cross-platform piece is where it gets interesting. What memory solutions are you using? What's working, what's not?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
