ctxshard
Enables deterministic, token-budgeted context compilation for local models served by Ollama, injecting stored tenant memory, entities, assertions, directives, and live resource state into prompts.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
ctxshard — Deterministic SQLite Memory & Pre-Turn Context Compiler for Local LLMs (4B–14B)
ctxshardis a zero-dependency, physically sharded multi-tenant memory engine, state graph, andstdioMCP server built on Node.js nativenode:sqlite(FTS5+WAL). Instead of running vector databases or hoping a4B–9Bsmall language model remembers to callsearch_memory,ctxsharddeterministically compiles matching entities, aliases, relational assertions, directives, and live resource state from isolated<tenant>.sqlitefiles into a<800-token prompt frame in~1ms.
Works out of the box with llama.cpp (llama-server), Ollama, LM Studio, vLLM, Claude Desktop, Cursor, OpenCode, Goose, and custom local agent loops.
Why Small Local Models (4B–9B) Break on Standard AI Memory
Most agent memory frameworks (Letta, Mem0, Zep / Graphiti, vector RAG) assume frontier reasoning budgets or external embedding infrastructure. When paired with local SLMs (Qwen3.5-4B, Qwen2.5-7B, Llama-3.2-3B/8B, Gemma-3-4B, Phi-4, Ministral-8B), four failure modes appear immediately:
Skipped Memory Tool Calls:
4B–9Bmodels frequently answer directly without callingrecall()orsearch_nodes()first, hallucinating missing context.Vector RAG Pollution in
8k–16kWindows: Cosine-similarity chunks inject noisy, low-precision text into narrow local KV caches while burning extra RAM/VRAM on embedding models (sqlite-vec,Chroma,sentence-transformers).Cross-Tenant Context Bleed: Storing personal, employer, and client projects inside one shared vector index or JSONL file risks leaking facts across workspaces via fuzzy similarity.
Restart Amnesia &
node-gypFriction: Live agent state maps vanish on process restart, and C++ SQLite addons (better-sqlite3) frequently fail to compile across Node upgrades.
ctxshard fixes all four in deterministic CPU code using Node's built-in node:sqlite—zero runtime npm dependencies, zero embeddings, and hard file-per-tenant isolation.
Related MCP server: nuzo-memory
How ctxshard Compares to Existing Agent Memory Tools
Capability |
|
|
|
|
|
Works if | Yes (Pre-turn CPU compiler) | No (Requires self-paging tool loops) | Partial | Partial | No (Passive pull-only) |
Vector DB / Embedding VRAM needed | No ( | Yes | Yes | Yes + Graph DB | No (Flat JSONL file) |
Hard multi-tenant isolation | 1 | Shared DB | Logical namespace | Logical namespace | Single shared JSONL |
Live resource state + metric merge | Built-in ( | No | No | Temporal edges | No |
Runtime npm / C++ dependencies | Zero ( | Python server + DB | Vector store + SDK | Neo4j / FalkorDB | Node (JSONL lock risk) |
| High | Low ( | Medium | Medium | Medium |
Architecture
User Prompt: "Why is ACME slow right now?"
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Pre-Turn Context Compiler (compileContext — ~1.0ms CPU, 0 LLM tokens) │
│ 1. Boundary-safe entity + alias linker ("ACME" -> client:acme-core) │
│ 2. SQLite FTS5 keyword fallback across entities_fts & assertions_fts │
│ 3. 1-hop graph walk (parent, children, linked live resource telemetry) │
│ 4. Priority packer with hard token ceiling (default <= 800 tokens) │
└───────────────┬─────────────────────────────────────────┬───────────────┘
│ │
▼ ▼
┌───────────────────────────────┐ ┌───────────────────────────────┐
│ principal.sqlite (Global) │ │ shards/acme.sqlite (Isolated) │
│ • Principal identity & role │ │ • entities + entities_fts │
│ • Tenant shard registry │ │ • assertions + assertions_fts │
│ • Append-only audit_log │ │ • resources (live state+meta) │
└───────────────────────────────┘ │ • directives (standing KV) │
└───────────────────────────────┘
│
▼
Injected System Frame (~245 tokens) ──► Local 4B–9B Model (llama.cpp / Ollama)flowchart LR
Prompt["User Prompt"] --> Compiler["Deterministic Context Compiler\n(~1ms CPU · Hard Token Budget)"]
Principal[("principal.sqlite\nIdentity + Audit Log")] --> Compiler
ShardA[("shards/acme.sqlite\nEntities · FTS5 · State")] --> Compiler
ShardB[("shards/personal.sqlite\nPhysically Sealed")] -. "Air-gapped when\nacme is active" .- Compiler
Compiler --> Frame["Compact Context Frame\n(<= 800 tokens)"]
Frame --> SLM["Local 4B–14B LLM\n(llama.cpp / Ollama / vLLM)"]Quick Start
1. Drop-In stdio MCP Server (Claude Desktop, Cursor, OpenCode, Goose)
Add ctxshard to your .mcp.json or claude_desktop_config.json:
{
"mcpServers": {
"ctxshard": {
"command": "npx",
"args": ["-y", "ctxshard", "mcp"]
}
}
}Optional flags: --dir /custom/path/to/data and --tenant my-workspace.
2. Pre-Turn Context Compilation in TypeScript (llama.cpp / Ollama / OpenAI-Compatible)
Install into any Node.js >=22.5.0 project:
npm install ctxshardCompile deterministic tenant memory before calling your local model—so even a 4B model that never calls a memory tool still answers with exact facts and live state:
import { CtxShardEngine } from 'ctxshard';
const memory = new CtxShardEngine({
defaultTenant: 'acme',
principal: {
name: 'Jordan Lee',
role: 'Staff Infrastructure Engineer',
directives: ['Never cross-pollinate client data', 'Cite live resource status first'],
},
});
// 1. Teach durable entities + plain-sentence assertions (scoped to shards/acme.sqlite)
memory.upsertEntity({
id: 'client:acme',
kind: 'client',
name: 'Acme Logistics',
aliases: ['ACME'],
about: 'Primary freight routing platform',
resourceId: 'site:api.acme.internal',
fact: 'Runs PostgreSQL 17 on us-west-2; maintenance window is Tuesdays 02:00 UTC.',
});
// 2. Persist live resource state (telemetry polls merge metrics without wiping learned tags)
memory.upsertResources([
{
id: 'site:api.acme.internal',
kind: 'site',
name: 'api.acme.internal',
status: 'warn',
metrics: { tier: 'enterprise', latencyMs: 940, sslDays: 62 },
},
]);
// 3. Compile a token-bounded frame in ~1ms before calling llama-server / Ollama
const userPrompt = 'Why is ACME degraded right now, and when can we fail over Postgres?';
const frame = memory.compileContext(userPrompt, { maxTokens: 600 });
const res = await fetch('http://127.0.0.1:8080/v1/chat/completions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'qwen-local',
messages: [
{ role: 'system', content: `Use this verified workspace context:\n\n${frame.text}` },
{ role: 'user', content: userPrompt },
],
}),
});3. Human CLI Inspector (Zero Black-Box Embeddings)
Every shard is plain relational SQLite. Inspect, teach, export, or physically purge any tenant from your terminal:
# Seed an entity + fact from CLI
npx ctxshard entity add client "Acme Logistics" --tenant acme --about "Freight platform" --fact "Bills quarterly"
# Preview the exact compiled prompt frame and token count
npx ctxshard compile "When does Acme Logistics bill?" --tenant acme --max-tokens 600
# Atomic single-file backup or complete physical deletion (GDPR / client offboarding)
npx ctxshard tenant export acme ./backups/acme-2026.sqlite
npx ctxshard tenant purge acmeBenchmarks (npm run bench)
Measured locally on Node.js (node:sqlite WAL + PRAGMA data_version write-invalidated cache) across 1,000 seeded entities + 1,000 assertions + 1,000 live resources:
Metric | Result |
Seed 1,000 entities + FTS5 + resources |
|
|
|
|
|
Compiled prompt size (2 matched entities + principal + tail) |
|
Extra embedding / vector DB VRAM required |
|
Runtime npm dependencies |
|
Run npm run bench on your own hardware to reproduce.
MCP Tools & Resources Exposed
When running ctxshard mcp, the following small-model-safe tools and resources are exposed:
compile_context— Deterministically compile a token-budgeted context frame for a prompt.tenant_switch/tenant_list— Switch active<tenant>.sqliteshard or inspect shard counts.entity_upsert/entity_lookup— Upsert typed graph nodes (person,company,brand,client,project,service,place,other) or search via SQLiteFTS5.assertion_add— Attach deduplicated plain-sentence facts with provenance (human | agent | ingest).resource_upsert/resource_list— Persist tracked infrastructure/business resources (client,site,service,machine,agent,lead,ticket) across restarts while merging live telemetry metrics cleanly.directive_set/directive_recall— Store and search per-tenant standing rules and preferences.Resource
ctxshard://context/active— Live text snapshot of the active tenant shard.
Pairing with local-llm-relay
Building full autonomous workflows on 4B–9B local models? Pair ctxshard (long-term sharded memory & pre-turn context compilation) with local-llm-relay (out-of-context SQLite dataset handles ds-* for 200+ row tool outputs, persistent multi-turn checklists, and max_tokens batch-shrinking recovery).
FAQ
How do I give an Ollama or llama.cpp 4B model long-term memory without a vector database?
Install ctxshard, record entities/assertions via entity_upsert (or the stdio MCP server), and call engine.compileContext(userMessage, { maxTokens: 600 }) before sending your chat completion request. Relevant entities, aliases, facts, and live resource statuses are matched in <2ms via word-boundary linking and SQLite FTS5—requiring zero vector embeddings.
How does multi-tenant isolation work for agencies, consultants, or work-vs-personal setups?
Each tenant ID maps to a separate SQLite database file on disk (~/.local/share/ctxshard/shards/<tenant_id>.sqlite). Queries against tenant client-a never open or scan client-b.sqlite or personal.sqlite. Syncing a single workspace to a work laptop or permanently wiping an offboarded client is a single file copy (tenant export) or file delete (tenant purge).
Why use SQLite FTS5 + an entity graph instead of vector embeddings for SLMs?
Exact identifiers—hostnames, error codes, account slugs, ports, SKU names, and policy constraints—degrade under dense vector compression and return fuzzy near-misses that confuse small 4B–9B models. Relational entity/alias matching + FTS5 prefix search is exact, deterministic, auditable in plain SQL, and uses 0 MB of GPU memory.
License
MIT © Cynthia Schomp
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Shared memory for your AI tools: tasks, notes and context every tool can read and write over MCP.
Cross-tool persistent memory and context for AI assistants over MCP.
Persistent memory, knowledge graph, task management and more for AI agents via MCP.
Related MCP Servers
AlicenseNot gradedqualityCmaintenanceEnables AI agents to capture, search, and manage structured memory from agent sessions with append-only events and provenance tracking, providing eight local MCP stdio tools.1Apache 2.0- AlicenseNot gradedqualityFmaintenanceLocal-first, auditable memory for AI agents. Provides durable context for MCP hosts with SQLite storage, CLI, and MCP tools for memory management.2Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables AI agents and developers to dynamically tokenize session context windows and compact dialogue history into structured outputs via MCP, CLI, or Python client. Runs on pure standard library Python with no external dependencies for deterministic, low-latency execution.8-
- AlicenseBqualityCmaintenanceGives MCP clients a local, single-tenant SQLite-backed store for saving, searching, bootstrapping and recalling memory records, plus saving and loading session handoffs, using text search by default with optional embeddings. It runs over stdio or an authenticated loopback HTTP gateway with explicit-confirmation pruning, scoped policies, and admin-driven backup, restore-copy and restart-drill verification.16MIT