Model or dataset
rtk-ai/icm avatar
rtk-ai/icm

ICM: A Single-Binary Memory Layer for AI Coding Agents

Permanent memory for AI agents. Single binary, zero dependencies, MCP native.

579 stars60 forksRustApache-2.0

At a glance

What is it?
ICM (Infinite Context Memory) stores agent memories in one SQLite database that Claude Code, Cursor, Gemini CLI and other MCP tools read and write. It is pre-1.0, experimental, and the README says so.
Who is it for?
Adopt ICM if you already switch between several MCP-capable coding agents and want one shared memory corpus instead of per-tool context; start with a global icm init and a throwaway topic before pointing it at real project decisions. Do not adopt it if you need a stable API or cannot tolerate breaking changes in minor releases, which the README states explicitly.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem ICM targets: context that dies when you switch tools

Every MCP-capable coding agent keeps its own conversation state. Close the session, change tools, and the reasoning is gone. The README frames the target user narrowly: someone who moves between Claude Code, Codex, Gemini CLI, Cursor, Roo, Amp and Aider in the same week, and who is tired of restating the same project decisions each time.

ICM's answer is a shared store rather than a per-tool feature. The README describes two memory models. Memories are episodic entries with temporal decay, filtered by topic or keyword. Memoirs are permanent knowledge graphs where concepts are linked by typed relations such as depends_on, contradicts, refines, part_of and superseded_by. A third mechanism, feedback, records corrections when an agent prediction was wrong so past mistakes can be searched before a new prediction is made.

The decay rule is the part worth pausing on. According to the README, critical memories never fade while low-importance ones decay naturally unless they are accessed. That is a deliberate bet: not everything an agent writes down deserves to survive. It also means importance assignment, not storage, is where the useful signal lives.

How the storage layer works: SQLite, FTS5 and sqlite-vec

The architecture diagram in the README puts SQLite with FTS5 and sqlite-vec under both memory models, with hybrid search weighted as BM25 at 30 percent and cosine similarity at 70 percent. The workspace Cargo.toml confirms the pieces: rusqlite 0.34 with the bundled, modern_sqlite and backup features, sqlite-vec 0.1, and fastembed 6 with default features off so each crate selects its own ONNX backend.

The crate split is four members: icm-core, icm-store, icm-mcp and icm-cli. The release profile sets opt-level 3, LTO on, one codegen unit, panic set to abort and symbols stripped. That is a deliberate binary-size and startup trade-off, and panic=abort means a panic terminates the process rather than unwinding, which matters if you are embedding the MCP server somewhere that expects to recover.

Because storage is a single SQLite file at an OS-standard location, the cross-tool story is mechanical rather than clever. A write from one agent is visible to another because they open the same file. The README lists the default paths as ~/.local/share/icm/memories.db on Linux, ~/Library/Application Support/icm/memories.db on macOS and %APPDATA%\icm\icm\data\memories.db on Windows. Topics are global, so there is no per-tool partition unless you create one.

Installing ICM and storing your first memory

The README offers several install paths. Homebrew is the shortest on macOS and Linux, and the quick install script verifies a SHA256 against release checksums.

bash
brew tap rtk-ai/tap && brew install icm

For source builds, cargo installs the CLI crate directly. The workspace member list confirms crates/icm-cli exists.

bash
cargo install --path crates/icm-cli

After the binary is on your PATH, icm init auto-detects supported tools and configures them against a global database. The README states this configures 18 tools.

bash
icm init

One caveat before you run it. The Homebrew build ships without the ONNX Runtime because it builds in a network-less sandbox, so semantic search is keyword-only until you fetch the runtime. The README gives these commands and notes the download is roughly 7 MB on macOS and Linux, and about 65 MB on Windows.

bash
icm embeddings download
icm embeddings status

With that done, storing and recalling is a single command each. The README's own example writes to a topic named decisions-myapp, and any other configured tool reading the same database can retrieve it.

bash
icm store -t decisions-myapp -c "..."
icm recall "query"

Isolation, and the cost of one shared database

Shared memory is the selling point and also the sharpest edge. If every configured tool writes to the same corpus, a bad entry from an experimental session pollutes recall for every other agent. The README acknowledges this by offering escapes: pass --db <path>, set the ICM_DB environment variable, or run icm init --per-project, which creates .icm/config.toml at the git root and stores memories in .icm/memories.db.

The important detail is that these are independent corpora, not views over one store. A per-project database and the global one do not see each other. The README notes you can combine the two: global settings such as tools and hooks are unaffected, only the database is scoped. So the practical question is not which mode is better but which memories you want to be portable across projects and which should stay local.

The README also states that ICM is pre-1.0 and that breaking changes can land in any minor release, with hooks and MCP configuration formats subject to shifting. The maintainer writes that ICM is used daily as a primary memory layer, but that focus is currently on a different project, rtk, and ICM updates are merged on a best-effort cadence. That is an honest statement of maintenance posture, and it should shape how much of your workflow you build on top of it.

Where ICM is the wrong tool

If you use one agent in one repository, ICM's central mechanism does nothing for you. The shared-corpus benefit only appears when a second MCP-capable tool reads the same file. A single-tool user is paying setup cost for a feature they will not exercise.

If you need API stability, the README's own status block rules it out. Configuration formats for hooks and MCP may change between minor versions, so anything scripted against those formats is a maintenance liability. Teams that pin dependencies for compliance reasons will find pre-1.0 versioning awkward, and the release history shows rapid patch iteration: v0.10.65 and v0.10.64 both landed on 2026-09-08, sixteen days apart from v0.10.63.

There is also an operational risk the README itself flags. It advises running the read-only equivalent before any destructive operation, naming icm uninstall --dry-run and icm uninstall --check. The presence of a --scan-dir flag in the workspace dependencies, via walkdir, suggests uninstall scans the filesystem for artifacts it previously wrote. That is exactly the kind of command you want to dry-run first, particularly if you have configured many of the 18 supported tools.

Finally, semantic search is optional and environment-dependent. In a non-interactive context such as an MCP server, hook or CI job, a declined or impossible runtime download leaves ICM keyword-only. If your recall quality depends on vector similarity, that degradation is silent unless you check icm embeddings status.

How ICM differs from agent memory built into a single tool

The obvious alternative is whatever memory your agent already ships with. Claude Code, Cursor and similar tools have their own project context mechanisms, and those require no second binary, no database path to reason about and no MCP configuration. The difference in approach is scope: built-in memory belongs to one vendor's client, while ICM is a separate process that any MCP-capable client can attach to.

That trade is real in both directions. A built-in memory system is maintained by the same team that maintains the agent, so it moves when the agent moves. ICM is maintained separately, currently on a best-effort cadence per the README, and its value depends on the MCP ecosystem staying stable enough for one server to serve many clients.

A second alternative is simply keeping notes in files the agent reads, such as a CLAUDE.md or AGENTS.md at the repository root. Both files exist in this repository's top level. That approach is transparent, versionable and requires no runtime. It also has no decay, no typed relations and no cross-tool retrieval beyond whatever the client chooses to read. ICM's memoirs, with relations like superseded_by and contradicts, are aimed at exactly the case where a flat notes file stops being enough: when you need to know that one decision replaced another, not just that both were written down.

Licence, upgrade path and what maintenance actually costs

ICM is Apache-2.0. The README points to LICENSE and states the software ships as-is, without warranty of any kind. Apache-2.0 includes an express patent grant and requires attribution and notice retention, which is generally friendlier for commercial embedding than a copyleft licence, but this is not legal advice and the DISCLAIMER.md file at the repository root is worth reading before you redistribute anything.

Upgrades are handled by re-running the install command, per the README. Version pinning is available by passing --version icm-vX.Y.Z, and for the shell installer that means sh -s -- --version followed by the tag. The release tags follow the icm-v prefix, matching the release list.

Ongoing cost is mostly configuration drift. Because icm init configures 18 tools, a version that changes hook or MCP formats can require re-running init across every tool you use. The README's warning that these formats may shift is the practical budget line: assume periodic reconfiguration, not a set-and-forget install. If you use the Homebrew build, add the one-time ONNX Runtime download to your setup notes, since semantic search stays off until it completes.

Editorial conclusion

Adopt ICM if you already switch between several MCP-capable coding agents and want one shared memory corpus instead of per-tool context; start with a global icm init and a throwaway topic before pointing it at real project decisions. Do not adopt it if you need a stable API or cannot tolerate breaking changes in minor releases, which the README states explicitly. Verify three things first: that icm embeddings status reports the ONNX runtime you expect, that icm uninstall --dry-run lists only files you recognise, and which database path your tool is actually writing to, since --per-project and the global default are separate corpora.

Frequently asked questions

What is ICM and who is it for?

ICM (Infinite Context Memory) is a permanent memory layer for AI agents, distributed as a single binary with MCP support. The README targets people who switch between multiple MCP-capable coding agents and want them to share one memory corpus instead of re-explaining context each time.

How do I install ICM?

The README lists Homebrew via brew tap rtk-ai/tap && brew install icm, a quick install script that verifies SHA256 against release checksums, a PowerShell installer for Windows, cargo install --path crates/icm-cli from source, and a Nix flake. After installing, run icm init to configure your tools.

Why is semantic search not working after installing ICM with Homebrew?

The README states the Homebrew build ships without the ONNX Runtime because it builds in a network-less sandbox, so ICM stays keyword-only. Run icm embeddings download to fetch it, and icm embeddings status to check the runtime state. In non-interactive contexts such as MCP servers, hooks or CI, ICM remains keyword-only until that download happens.

Can ICM keep memories separate per project instead of sharing one database?

Yes. The README documents icm init --per-project, which creates a project-local .icm/config.toml at the git root and stores memories in .icm/memories.db. You can also pass --db <path> or set the ICM_DB environment variable. These are independent corpora, so a per-project database and the global one do not see each other's entries.

Is ICM stable enough for production use?

The README marks the project as experimental and pre-1.0, stating that breaking changes can land in any minor release and that hooks and MCP configuration formats may shift. It also says the maintainer's focus is currently on rtk, with ICM updates merged on a best-effort cadence.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. Releases
  5. rtk-ai/icm on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rtk-ai-icm.svg)](https://hysenlabs.com/projects/rtk-ai-icm)