fortytwo-guide
Uses local Ollama models for generating text embeddings to enable semantic search over stored memories.
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.
@justfortytwo/memory
A standalone semantic-memory MCP server. It stores text "memories" with
free-form provenance and recalls them by meaning (vector search), by keyword
(FTS5), or by structured filter. Backed by SQLite + sqlite-vec, embeddings
from a local Ollama model (or an opt-in remote provider).
It is persona-agnostic: no journal/persona/approval coupling, just a generic
memory store and tool surface. Use it on its own, or through
@justfortytwo/installer, which registers it in your project's .mcp.json.
What it stores
A memory is content plus provenance:
field | meaning |
| the text (embedded for recall) |
| where it came from — free-form ( |
| how it was observed — free-form ( |
| ISO date the memory pertains to (defaults to today, UTC) |
| free-form tags for filtering |
| id of a prior memory this one replaces (history is kept) |
Recall is hybrid: recall (semantic), lexical (FTS5 keyword), and query
(structured). reindex + recall_docs index/search a directory of markdown
documents separately from the memory store.
Related MCP server: Cognio
MCP tools
The server registers under the id fortytwo-memory, so a consumer calls the
tools as mcp__fortytwo-memory__<tool>:
tool | description |
| store a memory (+ provenance); set |
| structured query (source/observed/tag/time; live rows by default) |
| semantic top-k recall by meaning |
| semantic recall over reindexed markdown |
| full-text keyword search (FTS5) |
| self-heal the doc index from a markdown directory |
| render a date range of memories to markdown |
On connect, the server also sends usage instructions in the MCP initialize
result: when to search vs. store, which search tool fits, how to correct a
memory with supersedes, and reindex caveats. Hosts such as Claude Code add
them to the model's context. The text lives in src/server.ts; update it when
the tool surface changes.
Contract version
Consumers depend on the tool surface, not the internals. The contract is versioned:
import { MEMORY_TOOL_CONTRACT_VERSION, memoryToolContract } from '@justfortytwo/memory/contract';A major change to a tool name, its required inputs, or its result shape is a contract break → bump
MEMORY_TOOL_CONTRACT_VERSION. Siblings pin a caret range on@justfortytwo/memory, so a major bump forces an explicit opt-in.Additive changes (new optional inputs, new tools) do not bump it.
memoryToolContract is the authoritative human-readable list of tools and their
guarantees, kept in sync with the wire schema in src/tools.ts.
Embedder
The default embedder is OllamaEmbedder, which calls a local Ollama
/api/embeddings endpoint.
OLLAMA_BASE_URL=http://localhost:11434 # default
EMBED_MODEL=qwen3-embedding:0.6b # default model (1024-dim)Pull the model once:
ollama pull qwen3-embedding:0.6bIf EMBED_MODEL is unset, the server falls back to a deterministic,
dependency-free FakeEmbedder — useful for tests, CI, and first-run smoke
checks with zero infra. (The vector tables are fixed at 1024-dim; a model with a
different dimensionality requires a schema change.)
Other remote providers (opt-in)
Ollama stays the default. To use a remote OpenAI-compatible provider instead, set
EMBED_PROVIDER=openai:
EMBED_PROVIDER=openai
EMBED_MODEL=text-embedding-3-small # must be in the allowlist below
EMBED_API_KEY=sk-... # optional for self-hosted servers
EMBED_BASE_URL=https://api.openai.com/v1 # default for OpenAI/Voyage models; required otherwiseOnly models that emit (or can be truncated to) 1024 dims are accepted, because
the vector tables are fixed at that size. Any other EMBED_MODEL fails at startup
with the accepted list:
| Default | Notes |
|
| truncated to 1024 via |
|
| truncated to 1024 via |
|
| 1024 by default |
| none — set | self-hosted, e.g. vLLM; 1024 native |
| none — set | self-hosted, e.g. vLLM; no query instruction prefix is applied |
For self-hosted servers the model must be served under exactly the name above
(vLLM: --served-model-name).
Switching models on an existing database: two models with the same dimension do not share a vector space. Vectors already stored by another model are not comparable with new query vectors, and
recallwill not error — it will return plausible but wrong neighbours. Re-embed existing memories with the library'sreembed(h, embedder, id)(one id at a time; no bulk command or MCP tool is provided) and re-run thereindextool for docs after switching. New databases are unaffected.
Standalone usage
npm install @justfortytwo/memoryPrerequisites. Requires Node.js >= 20. The package depends on
better-sqlite3 ^12, a native module that ships prebuilt binaries for LTS
Node releases — on an unsupported Node version or platform, npm install will
compile it from source (needs a C/C++ toolchain). It also needs an embedding
source for real embeddings — a local (or remote) Ollama, or an opt-in remote
provider; without EMBED_MODEL set it falls back to a deterministic
FakeEmbedder (see Embedder). sqlite-vec ships as
a bundled npm dependency — no manual SQLite-extension install is needed.
# build (once); the server runs the built JS, not TS
npm run build
# apply migrations to the DB (DB_PATH or ./memory.db)
DB_PATH=./memory.db npm run migrate
# run the MCP server over stdio
DB_PATH=./memory.db EMBED_MODEL=qwen3-embedding:0.6b fortytwo-memoryThe bin is fortytwo-memory → dist/index.js. You can also run it with
npx -y @justfortytwo/memory (it is published to npm).
Register in your own .mcp.json
To use the server in any MCP host, drop this into
your project's .mcp.json with a real DB path:
{
"mcpServers": {
"fortytwo-memory": {
"command": "npx",
"args": ["-y", "@justfortytwo/memory"],
"env": {
"DB_PATH": "./memory.db",
"EMBED_MODEL": "qwen3-embedding:0.6b",
"OLLAMA_BASE_URL": "http://localhost:11434"
}
}
}
}OLLAMA_BASE_URL may point at a remote host. The embedder strips a trailing
slash, so either form works — but prefer no trailing slash.
As a library
import { openDb, runMigrations, OllamaEmbedder, embedderFromEnv, store, recall, deleteByIds } from '@justfortytwo/memory';
const h = openDb('memory.db');
await runMigrations(h.k);
const embedder = new OllamaEmbedder();
// or choose from env exactly like the server does (EMBED_PROVIDER / EMBED_MODEL / ...):
// const embedder = embedderFromEnv();
await store(h, embedder, { content: 'the deploy script lives in scripts/deploy.sh', source: 'owner', observed: 'stated' });
const hits = await recall(h, embedder, 'how do I deploy?', 5);
deleteByIds(h, [hits[0].id]); // hard-delete (row + vector + FTS); returns the count removedDeleting memories
deleteByIds(h, ids) hard-deletes memories — the row, its vector, and its FTS
entry — so nothing resurfaces in recall/lexical/query. It is intentionally
a library API and NOT an MCP tool: deletion is an owner-privileged operation,
and exposing it to the assistant's turn loop would let prompt-injected content
trick it into erasing memories. Selecting which ids to remove (by query, tag,
date range, …) is the caller's job — see @justfortytwo/installer's forget.
Continuous enrichment
enrich(h, embedder, candidates) folds a batch of candidate memories into the
store: it drops low-salience candidates, dedupes near-duplicates by meaning,
and writes the survivors with provenance — honoring an explicit supersedes to
replace a stale belief (history is kept, never a silent overwrite).
enrichFromTurn(h, embedder, turn, extractor) runs an injected SalienceExtractor
and feeds its candidates to enrich.
The salience extractor itself is model-driven and lives in the sibling
@justfortytwo/salience engine (a SalienceExtractor with an injected
LlmClient) — memory owns only the dedupe + write, never the model call.
Peer seams
memory depends on two sibling packages one-directionally (declared as optional peers, no cycle):
@justfortytwo/gate— memory shipsGateApprovalStore(src/gate-approval-store.ts), a durable SQLite-backed implementation of gate'sApprovalStore+AuditLoggerinterfaces. Pass it to gate'sdecide(..., { store, audit })to back the safety gate's one-shot approvals with memory's db instead of the gate's standalone JSONL store.@justfortytwo/salience— the model-driven salience extractor injected intoenrichFromTurn(see above).
Development
npm run build # tsc
npm test # vitest run
npm run test:watch # vitestSet RUN_OLLAMA_TESTS=1 to run the opt-in live-Ollama embedder test.
License
MIT © 2026 Enrico Deleo
Created and maintained by Enrico Deleo.
Incremental library reads
memoryHead(h) returns { database, position }, using a persistent database
identity and SQLite's AUTOINCREMENT high watermark (not timestamps or MAX(id)).
memoryDelta(h, cursor, limit = 50) returns ascending insertion pages and the
last reviewed position; it includes superseded rows as evidence and never skips
unreturned rows. Deleted ID gaps remain safe. Invalid/foreign/backwards cursors
fail closed. These are library APIs only; the MCP tool contract is unchanged.
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
Cross-vendor AI memory over MCP. One semantic store, readable and writeable from every MCP client.
Shared cross-LLM long-term memory over MCP: semantic recall, sessions, and media (pgvector).
An MCP memory server. One memory your agents share — across models, devices and apps.
Hosted agent memory: store, search, and recall facts across sessions from any MCP client.
Related MCP Servers
- AlicenseAqualityCmaintenanceA local, fully-offline MCP memory server that enables persistent storage and retrieval of information using SQLite with both keyword and semantic vector search capabilities.1013 npm13MIT
- AlicenseNot gradedqualityDmaintenancePersistent semantic memory server for AI assistants via MCP, enabling long-term context retention and semantic search across conversations.12MIT
- AlicenseNot gradedqualityDmaintenanceSemantic memory server for AI agent teams. Stores, searches, and retrieves knowledge across sessions using pluggable vector backends with local ONNX embeddings, exposed as an MCP server.MIT
- AlicenseBqualityDmaintenanceAn MCP server for storing and retrieving memories using Qdrant vector search, acting as a semantic memory layer.2Apache 2.0