gimem
A GitHub Issues-backed memory system for AI agents. Each memory is a GitHub Issue. Retrieval uses GitHub's hybrid search API. No external database, no vector store, no infrastructure to run.
Install
# CLI binary
cargo install --git https://github.com/9oelM/gimem --branch main memory-store --bin gimem
# Claude Code plugin
claude plugin marketplace add 9oelM/gimem
claude plugin install gimem@gimem
Why GitHub Issues
- Semantic search -- GitHub's hybrid search surfaces memories by meaning, not just keywords.
- Free and permanent -- Issues are free, have no storage limits, and never expire.
- Portable -- Memory lives in a repository you own. Transfer it, share it, fork it.
- Generous rate limits -- Standard GitHub API: 5,000 requests/hour. Semantic search: 10 requests/minute.
Memory types
| Type | Purpose | Search tier |
|---|
episodic | A specific event or interaction ("User asked about deployment at 3pm") | Warm (hybrid) |
semantic | A general fact or preference ("User prefers Python over Java") | Cold (hybrid) |
procedural | A learned skill or procedure ("To deploy: run make prod") | Cold (hybrid) |
working | Active context for the current task; always loaded every turn | Hot (lexical, 5-min TTL) |
Repository structure
memory-store/ Rust library crate
src/
manager.rs MemoryManager -- the main public API
store.rs GitHub Issues read/write (create, get, archive, delete)
search.rs GitHub hybrid/semantic search with rate limiting
consolidation.rs Episodic consolidation pipeline and eviction
models.rs MemoryEntry, MemoryType, MemoryTier, builders
labels.rs Label definitions and bootstrap
schema.rs Issue body serialization (TOML front-matter)
error.rs MemoryError, Result
bin/
gimem.rs CLI binary
tests/
integration.rs Library integration tests (real GitHub API)
cli.rs CLI subprocess tests (real GitHub API + no-API exit code tests)
examples/
basic.rs Full lifecycle walkthrough
Quickstart: Rust library
[dependencies]
memory-store = { git = "https://github.com/9oelM/gimem", branch = "main" }
tokio = { version = "1", features = ["full"] }
use memory_store::{MemoryManager, MemoryType};
#[tokio::main]
async fn main() {
let mem = MemoryManager::new("owner/agent-memory", "ghp_...", None);
// Run once per repository to create required labels.
mem.bootstrap().await.unwrap();
// Store a memory.
mem.remember(
"User prefers Rust for systems programming",
MemoryType::Semantic,
"alice",
0.9, // importance [0.0, 1.0]
vec!["Rust".into()],
vec!["preferences".into()],
).await.unwrap();
// Retrieve relevant memories within a token budget.
let context = mem.recall("programming language preferences", "alice", 2000).await.unwrap();
println!("{context}");
}
Full API
let mem = MemoryManager::new(repo, token, summarize_fn);
mem.bootstrap().await?;
mem.remember(content, type, user, importance, entities, tags).await?;
mem.recall(query, user, token_budget).await?; // returns a formatted context string
mem.forget(issue_number).await?; // hard delete
mem.set_working(content, user).await?; // replace working memory
mem.clear_working(user).await?; // archive working memory
mem.start_session(user, description).await?; // returns session_id
mem.end_session(user, session_id).await?; // consolidate + close session
mem.consolidate(user).await?; // batch episodic consolidation
mem.evict(user, dry_run).await?; // archive low-retention entries
Custom summarisation
MemoryManager::new accepts an optional SummarizeFn called when consolidating episodic memories into semantic ones. Pass None for the built-in stub, or inject an LLM call:
use memory_store::SummarizeFn;
use std::sync::Arc;
let summarize: SummarizeFn = Arc::new(|contents| Box::pin(async move {
my_llm_summarize(contents).await
}));
let mem = MemoryManager::new("owner/repo", "ghp_...", Some(summarize));
Quickstart: Claude Code Plugin
Install gimem as a Claude Code plugin to get the gimem skill loaded automatically in every session.
claude plugin marketplace add 9oelM/gimem
claude plugin install gimem@gimem
This copies skills/gimem/SKILL.md into your ~/.claude/skills/gimem/ directory. Claude Code loads it at session start, so you can invoke it with /gimem and Claude will follow the workflow automatically.
Quickstart: CLI
Install
cargo install --git https://github.com/9oelM/gimem --branch main memory-store --bin gimem
Or clone and build locally: