Skip to main content
Glama
thomaskawas

agent-context-substrate

by thomaskawas

agent-context-substrate

The substrate is the asset; the model is an interchangeable client.

git clone https://github.com/thomaskawas/agent-context-substrate.git
cd agent-context-substrate
make setup && make demo

Requirements: Python 3.12+, Docker, make. make setup creates a venv and installs the dependencies, about 1.4 GB since the demo runs on CPU and skips the CUDA wheels; allow a few minutes on a slow connection. The database binds 127.0.0.1:5432, so stop anything already holding that port.

One query traced through the four retrieval stages, then the ablation table and the baseline gate

Why this exists

I build long-running projects with AI agents, and re-establishing context at the start of every session was the tax I paid most often. Uploading the same files, re-explaining the same decisions, watching the useful part of the window fill with material the model had already seen twice. A better model would ship and none of it moved across. The problem was never that the context was missing. It was that the context was not addressable: no way to ask a question and get back only what answers it, so you send everything and hope. The fix was to stop treating context as something you carry into a session and start treating it as something you query.

A reference implementation of a model-independent memory substrate for AI agents: project memory lives outside the model in a queryable, versioned store, exposed through one MCP gateway. Swap the model; keep everything. Claude today, Gemini or GPT tomorrow, same project memory underneath. Instead of pasting history back into every session, retrieval selects the small set of records the current task actually needs.

This repository is a clean-room reference implementation of that pattern, written from scratch against a synthetic corpus so every number on this page reproduces from a clean clone with the pinned dependencies. It is the pattern, not the system I run on my own work.

No API keys required: make demo runs entirely on local components. The pinned local models (name and revision) are the default adapter profile, local (make warmup, run automatically by make demo, pre-downloads ~180 MB once); the hermetic zero-download deterministic profile backs the tests and the always-on CI gate.

Related MCP server: AI Memory MCP Server

Layout

src/acs/adapters/base.py is the thesis in code: four small interfaces every external capability sits behind. src/acs/store/ treats memory as a system of record (versioned, auditable, genuinely deletable). src/acs/retrieval/ is the pipeline as small, separately testable stages. eval/ is the gate: changes ship by matching or beating baseline.lock.json, or they don't ship.

Design rationale lives in docs/adr/: nine decision records. Most are half a page; three run longer, where the argument needed the room.

Also in docs/: architecture.md for why each layer exists, threat-model.md for the adversarial boundaries and where each defence lives, principles.md for the rules the rest follows from, and build-your-own.md for the build sequence this repo followed.

What it demonstrates

  • Ingest writes both representations in one pass: embeddings for similarity, an entity/relation graph for structure. Every document is embedded; a document that states no relation contributes no edges.

  • Retrieval is a four-stage pipeline: hybrid vector + full-text search with a tunable blend, multi-query fusion (RRF), cross-encoder rerank, and an entity-anchored partition where the graph reorders the reranked list so a topical reranker stops confusing one component with its similarly-named sibling. Per-consumer retrieval profiles are data, not code.

  • Governance: retrieval changes ship by matching or beating a locked eval baseline. Memory is SCD2-versioned with time-travel reads, purge genuinely deletes (vectors included), and the audit log refuses mutation at the database level.

  • Access: one MCP gateway serves the substrate to any MCP client, scoped per caller. A quarantined research loop fills gaps with citation-mandatory write-back.

  • Portability: every provider sits behind an adapter; the embedder is pinned on purpose.

you want to see

run

a query traced through every retrieval stage

make query Q="..."

the ablation benchmark (recall@5, MRR per stage)

make bench

a retrieval change fail CI against the locked baseline

make check

memory identities, and one memory's full version chain

make history

memory superseded, the old version still readable

make supersede LINEAGE=<id> CONTENT="..."

that memory read as it stood at a past time

make asof LINEAGE=<id> TS=<timestamp>

a subject purged, embeddings included

make purge SUBJECT=contributor-03

supersession chains + entity neighbours from the graph

make graph ENTITY=CHG-4568

two scoped callers on one substrate, one call refused

make gateway-client

the research loop fill a gap, cited and quarantined

make research then make vet

The lineage id and the timestamps both come from make history: bare, it lists current memories with their ids; with LINEAGE=<id> it walks one memory's version chain and prints each version's validity window. Those windows are ISO timestamps so that a TS= you paste back resolves to the version you actually read, rather than one a second either side of it. Ids are generated per clone, so yours will not match any shown here.

make purge genuinely deletes (golden-set targets included, when they belong to the purged subject), so a benchmark against a purged corpus refuses to run as incomplete rather than quietly reporting lower recall. make demo resets to a clean corpus.

Every benchmark number on this page comes from an ablation over a seeded synthetic corpus (corpus/generate.py), reproducible from a clean clone and gated in CI (the deterministic profile on every push, the local profile on the bench-local label) against a locked baseline that also locks the corpus digest. Read the deltas, not the absolutes: recall@5 / mrr@5 on a synthetic corpus demonstrate what each stage contributes, never real-world quality. To see where a stage earns its delta, run .venv/bin/python eval/run_benchmark.py --by-family.

The ablation, local profile

stage

recall@5

mrr@5

what the stage earns

vector-only

0.6333

0.4340

the floor: similarity alone

+hybrid

0.9667

0.5742

recall. The lexical lane recovers what embeddings miss

+fusion

0.9750

0.6026

ranking, and almost no recall (recall +0.0083)

+rerank

0.9917

0.9072

ranking. mrr +0.3046 on a recall that barely moves

+graph

0.9917

0.9315

identity. An entity partition, not more retrieval

Each stage earns a different thing, which is the argument for a pipeline rather than for one better retriever. tests/test_readme_table.py fails if this table and eval/baseline.lock.json ever disagree, so the table cannot drift from the numbers the gate enforces. The gate is a floor, so a change that improves a metric passes it and the numbers here stand until the baseline is re-locked on purpose with make lock-baseline, which then fails this table until it is brought up to match. Local profile, 120 golden queries, k=5, stage-1 merge rank, corpus digest ad7bf7ca. Reproduce with make demo.

What these numbers do and do not support, including why the model-lane comparison is a bound rather than a curve, is set out in docs/limitations.md.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides persistent, searchable memory for MCP-compatible agents, enabling recall by meaning, automatic decay, trust scoring, and cross-agent handoffs.
    4
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Durable, inspectable memory for MCP agents. Preserves decisions, preferences, and project knowledge across sessions with full provenance and version history.
    2
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides persistent, scoped shared memory for collaborating AI agents, with tools for storing observations, semantic recall, and handoff workflows. Backed by PostgreSQL and exposed through MCP.
    1
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.

  • Your memory, everywhere AI goes. Build knowledge once, access it via MCP anywhere.

  • An MCP memory server. One memory your agents share — across models, devices and apps.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/thomaskawas/agent-context-substrate'

If you have feedback or need assistance with the MCP directory API, please join our Discord server