AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified Apache-2.0 Self-run

AIngram

mcp-bozbuilds-aingram · by bozbuilds

Local-first agent memory in one SQLite file: sqlite-vec/QJL two-pass vector + FTS5 search, knowledge graph (optional auto capture,) Ed25519-signed entries, and MCP server. No cloud dependencies.

No reviews yet
0 installs
38 views
0.0% view→install

Install

$ agentstack add mcp-bozbuilds-aingram

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-bozbuilds-aingram)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of AIngram? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Aingram (Lite)

Agent memory that finds the right context. Every time. Locally.

pip install aingram

[](https://pypi.org/project/aingram/) [](LICENSE) [](https://python.org) [](https://discord.gg/zSJCFZnXxf)


Most AI memory systems are filing cabinets with a search bar. Store everything, search later, hope the right thing comes back.

Aingram is different. It runs three retrieval signals simultaneously — full-text search, semantic vector search, and knowledge graph traversal — and fuses them into a single ranked result using Reciprocal Rank Fusion. Everything lives in one SQLite file on your machine. No cloud. No API key. No vendor to trust with your agents' memory.

On LongMemEval — the most rigorous public benchmark for AI memory — Aingram's retrieval pipeline finds the correct context in the top 3 results for every single query when the evidence is present. On the real benchmark with full noisy conversation histories, it surfaces the right sessions in the top 10 for 95.5% of queries. End-to-end answer accuracy (retrieval → gpt-4o-mini) reaches 72.8% across all question types.

from aingram import MemoryStore

with MemoryStore('./agent_memory.db') as mem:
    mem.remember('The API rate limit is 100 req/min. Exceeding it causes silent drops.')
    mem.remember('Deployment takes ~3 min. Always run migrations before the container swap.')

    results = mem.recall('what do I need to know before deploying?', limit=5)
    for r in results:
        print(r.score, r.entry.content)

Numbers

Benchmarked on LongMemEval (Wu et al., ICLR 2025) — 500 hand-curated questions across multi-session conversation histories averaging 115,000 tokens. All runs on RTX 4060 8GB. No reranking model. No LLM in the retrieval loop.

| Benchmark | Metric | Score | |-----------|--------|-------| | LongMemEval (oracle split) | recallany@3 | 1.000 | | LongMemEval (oracle split) | ndcg@10 | 0.994 | | LongMemEval-S (real retrieval) | recallany@10 | 0.955 | | LongMemEval-S (real retrieval) | recall_any@3 | 0.902 | | LongMemEval-S (real retrieval) | ndcg@10 | 0.836 | | BEIR SciFact | nDCG@10 | 0.703 |

What these numbers mean:

  • recall_any@3 = 1.000 (oracle): When the evidence exists, Aingram puts the right session in the top 3 results for every query across 500 instances. The correct context is always available to your agent.
  • recall_any@10 = 0.955 (real): On real noisy conversation histories — ~40 sessions of noise per query — the right sessions appear in the top 10 for 95.5% of queries. This sets the ceiling for any downstream LLM accuracy.
  • 22ms median retrieval latency — pure local pipeline, no network round-trip.

End-to-end answer accuracy (LongMemEval-S)

Full pipeline accuracy: AIngram retrieval → gpt-4o-mini answering 500 questions across multi-session conversation histories. All categories use gpt-4o-mini for clean comparability to published baselines.

| Question Type | Correct | Total | Accuracy | |---|---|---|---| | single-session-user | 66 | 70 | 94.3% | | knowledge-update | 65 | 78 | 83.3% | | multi-session | 102 | 133 | 76.7% | | temporal-reasoning | 80 | 133 | 60.2% | | single-session-preference | 18 | 30 | 60.0% | | single-session-assistant | 33 | 56 | 58.9% | | Overall | 364 | 500 | 72.8% |

> ⚠️ Temporal-reasoning note: The 60.2% figure uses gpt-4o-mini throughout — this is the clean comparable to published baselines. Running that category with gpt-4o yields 98/133 (73.7%), a +13.5pp improvement, and pushes overall accuracy to 76.4% (382/500). That score is not directly comparable to published gpt-4o-mini baselines.

Retrieval speed scales with corpus size. Vector search is the dominant cost at scale — Aingram's QJL two-pass compression keeps it manageable:

| Entries | Full recall | Embedding | Vector search | |---------|-------------|-----------|---------------| | 1K | ~16ms | ~8ms | ~3ms | | 10K | ~47ms | ~9ms | ~34ms | | 50K | ~222ms | ~11ms | ~160ms | | 100K | ~347ms | ~11ms | ~320ms |

QJL's two-pass approach (compressed candidates → float32 rerank) breaks even against brute-force at ~30K entries and delivers meaningful speedup above that threshold.


Why not just use a vector database?

Single-signal retrieval misses. Semantic similarity is powerful but breaks on:

  • Exact terminology — a query about "the 100 req/min rate limit" might not semantically match a memory that says "hard cap: 100/min" without FTS
  • Entity relationships — "what did Alice decide about auth?" needs graph traversal, not cosine similarity
  • Keyword-first queries — agents often search with specific technical terms where BM25 outperforms dense retrieval

Aingram runs all three signals and fuses them. The hybrid consistently outperforms any single signal, especially on the kinds of precise, domain-specific queries agents actually make.


How It Works

Agent query
    │
    ├──▶ FTS5 (keyword)                        ─┐
    ├──▶ sqlite-vec + QJL two-pass (semantic)  ─┤──▶ RRF fusion ──▶ ranked results
    └──▶ Knowledge graph (entity)              ─┘

FTS5 full-text search — SQLite's native full-text index. Fast, no embedding required, excellent for exact terminology and technical strings.

sqlite-vec vector search — Dense semantic retrieval using nomic-embed-text-v1.5 running locally via ONNX. 768-dimensional embeddings, CPU or GPU. No external API.

QJL two-pass vector search — At larger corpus sizes, vector search dominates retrieval latency. Aingram uses a Quantized Johnson-Lindenstrauss (QJL) two-pass approach: a fast first pass over compressed quantized vectors narrows the candidate pool, then a precise second pass over full float32 vectors reranks the survivors. This trades a small fraction of recall for significantly lower latency at scale — the break-even point is around 30K entries, above which QJL is faster than brute-force float32 search with no meaningful quality loss.

Knowledge graph traversal — Entities and relationships extracted from memory entries. Multi-hop queries resolved via CTE. "What did Alice decide about auth?" finds the entity, traverses relationships, returns relevant entries — even if the query didn't match the entry verbatim.

Reciprocal Rank Fusion — Results from all three signals are combined and re-ranked. Each signal's rank position, not raw score, contributes to the final order. This makes the fusion robust to scale differences between signals.


Everything in One File

Your entire agent memory — entries, embeddings, entity graph, signing chain — lives in a single SQLite file. No separate vector database to manage. No graph database. No external embedding service. No Docker containers.

agent_memory.db     ← that's it

Copy it. Back it up with cp. Inspect it with any SQLite client. Share it between agents. Export it to JSON. Import it somewhere else.

This is a deliberate design choice. Memory that requires infrastructure to operate is fragile. Memory that's a file is durable.


Cryptographic Integrity

Every memory entry is Ed25519-signed and linked in a tamper-evident hash chain. You can verify that a memory hasn't been modified since it was written — useful when memory is shared between agents or stored across trust boundaries.

result = mem.verify()
# VerificationResult(valid=True, session_id='...', entries_checked=1247, errors=[])

Entity Extraction and Knowledge Graph

Install aingram[extraction] to enable GLiNER-based entity extraction. Aingram uses the GLiNER multitask-large model — a 205M-parameter multitask model that handles person, organization, location, project, and technology extraction in a single pass. Entities and relationships are automatically extracted from memory entries and stored in the knowledge graph as you write.

# After 'User Alice approved the migration to Clerk on Jan 15.'
# is stored, the graph contains:
#   Alice ─[approved]─▶ migration (valid_from: 2026-01-15)
#   migration ─[uses]─▶ Clerk

results = mem.recall('what did Alice decide?')
# Returns entries linked to Alice via graph traversal,
# not just entries that mention "Alice" by text

Query the graph directly:

aingram --db ./agent_memory.db graph "Alice"
aingram --db ./agent_memory.db entities

Memory Consolidation

Run aingram consolidate (or mem.consolidate()) to clean up accumulated memory over time. Consolidation runs four steps:

  1. Decay — reduces the importance score of memories that haven't been accessed recently (always active, no configuration needed)
  2. Contradiction detection — finds pairs of memories about the same entity that say conflicting things and marks the older one as superseded
  3. Merge — clusters near-duplicate memories and synthesizes a single canonical entry (requires Ollama)
  4. Knowledge synthesis — summarizes chains of related observations into higher-level conclusions (requires Ollama)

Contradiction detection is powered by a local DeBERTa-v3 NLI model running via ONNX Runtime — no LLM or network call required at inference time. Enable it in ~/.aingram/config.toml:

contradiction_backend = "deberta"   # or "llm" to use Ollama instead
contradiction_threshold = 0.7       # confidence cutoff (0.0–1.0)

The DeBERTa model (~740MB) downloads from HuggingFace on first use and caches locally. For contradiction detection to work, entity extraction must have been run on your memories (aingram[extraction] required) so entries can be grouped by the entities they mention.

aingram consolidate        # run all steps, print JSON summary

Capture daemon auto-consolidation: if the capture daemon is running, it can trigger consolidation automatically every N ingested memories. Set consolidation_interval_records in the [capture] section of your config (default: 50, set to 0 to disable).


MCP Server

Install aingram[mcp] and connect any MCP-compatible agent (Claude, Cursor, Windsurf, Cline) to your memory store.

aingram --db ./agent_memory.db mcp

Tools exposed: remember, recall, reference, verify, get_experiment_context, and more. Optional bearer-token auth middleware included.

Add to your MCP config:

{
  "mcpServers": {
    "aingram": {
      "command": "aingram",
      "args": ["--db", "/path/to/agent_memory.db", "mcp"]
    }
  }
}

Quick Start

pip install aingram

Python API:

from aingram import MemoryStore

with MemoryStore('./agent_memory.db') as mem:
    # Store a memory
    mem.remember('Deploy always requires a migration run first.')

    # Recall with hybrid search
    results = mem.recall('deployment checklist', limit=5)
    for r in results:
        print(f'{r.score:.3f}  {r.entry.content}')

CLI:

aingram --db ./agent_memory.db status
aingram --db ./agent_memory.db add "API rate limit is 100 req/min"
aingram --db ./agent_memory.db search "rate limiting"
aingram --db ./agent_memory.db entities
aingram --db ./agent_memory.db graph "Alice"
aingram --db ./agent_memory.db export ./backup.json
aingram --db ./agent_memory.db import ./backup.json

GPU embeddings (optional):

pip uninstall -y onnxruntime
pip install onnxruntime-gpu
pip install "aingram[gpu]"
export AINGRAM_ONNX_PROVIDER=cuda

Multi-agent patterns

AIngram supports concurrent multi-agent setups where multiple logical agents share one SQLite memory file. Two shapes work out of the box:

  • Intra-process (simplest): multiple async tasks share a single MemoryStore instance. The engine's internal threading.Lock serializes writes.
  • Cross-process (or when you want per-agent attribution): each agent constructs its own MemoryStore(db_path, agent_name='agent-N') pointing at the same .db file. SQLite's WAL mode handles multi-writer safety.

See [examples/05_multi_agent_shared_memory.py](examples/05multiagentsharedmemory.py) for a self-contained ~100-line demonstration of the intra-process shape: three async agents share one MemoryStore to solve a toy hyperparameter search task, with each agent's recall() surfacing sibling findings for piggyback exploration.

For a production-grade multi-agent research integration — including three concurrency modes (mock / solo / swarm), subprocess orchestration with CUDA pinning, workspace isolation, and the full Karpathy autoresearch loop wired into AIngram's memory layer — see the companion repo bozbuilds/aingram-AR.


Install

pip install aingram                   # core — CPU embeddings
pip install "aingram[extraction]"     # + GLiNER entity extraction
pip install "aingram[mcp]"            # + MCP server
pip install "aingram[llm]"            # + Ollama/local LLM client
pip install "aingram[api]"            # + Anthropic API extractor
pip install "aingram[gpu]"            # + CUDA ONNX Runtime wheels
pip install "aingram[capture]"        # + capture daemon (starlette, uvicorn, watchdog)
pip install "aingram[all]"            # everything (except capture and gpu)

Capture Daemon

Install aingram[capture] to enable automatic prompt/response capture from AI coding tools. The daemon runs locally on localhost:7749 and supports Claude Code, Cursor, Gemini CLI, Aider, Copilot, Cline, and ChatGPT (manual export).

aingram capture start                 # foreground mode
aingram capture start --daemon        # background mode
aingram capture stop                  # stop the daemon
aingram capture status                # show tool status and queue depth
aingram capture install claude_code   # print hook setup instructions
aingram capture on                    # enable all tools
aingram capture off cursor            # disable a specific tool

Captured interactions flow through a filter pipeline (@nocapture opt-out, secret redaction) into a separate SQLite queue, then drain into your main memory database via MemoryStore.remember(). Configure via [capture] in ~/.aingram/config.toml or AINGRAM_CAPTURE_ENABLED / AINGRAM_CAPTURE_PORT env vars. Disabled by default.


Claude Code Hook

AIngram can inject relevant memories directly into Claude Code's context window — before every prompt you type and before every file edit. This lets Claude Code see what you've learned across sessions without you having to ask.

aingram hook install        # patches ~/.claude/settings.json
aingram hook uninstall      # removes the hook entries

Under the hood, hook install registers aingram_cc_hook.py as a non-blocking UserPromptSubmit and PreToolUse hook. On each trigger, AIngram queries the recall daemon for relevant memories and writes them as an `` XML block for Claude Code to consume. No token budget is consumed unless a relevant memory is found.

Recall daemon — the hook communicates with a local HTTP server (localhost:7750) that keeps the ONNX embedding model warm so hook responses stay under the 2-second timeout:

aingram recall-daemon start    # foreground (the hook auto-spawns this if needed)
aingram recall-daemon stop
aingram recall-daemon status

The daemon shuts itself down after 30 minutes of inactivity.

Hook config (~/.aingram/hook.toml):

[scoring]
project_boost = 0.003        # extra weight for memories from the current directory
seen_demote = 0.004          # penalty for memories already surfaced this session
prompt_limit = 8             # max memories injected on UserPromptSubmit
edit_limit = 3               # max memories injected on PreToolUse (Edit/Wri

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [bozbuilds](https://github.com/bozbuilds)
- **Source:** [bozbuilds/AIngram](https://github.com/bozbuilds/AIngram)
- **License:** Apache-2.0
- **Homepage:** https://aingram.dev

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.