Skip to main content
AllMCPs
BrowseBestCategoriesStackCompareToolsGuidesBlog Log in Submit MCP

Stay in the loop

Get new MCP servers and top picks in your inbox.

AllMCPs

The open directory for discovering and installing Model Context Protocol servers.

Explore

  • Browse servers
  • Best MCP servers
  • Categories
  • MCP clients
  • Agent prompts
  • Stack Builder
  • Compare servers
  • Tags index
  • Submit a server
  • Pricing

Learn

  • Guides hub
  • What is MCP?
  • Install guide
  • Troubleshooting
  • Security
  • Blog
  • Blog RSS

Tools

  • All tools
  • Config generator
  • Config validator
  • MCP playground
  • OpenAPI β†’ MCP
  • Badge generator

For agents

  • API docs
  • Trust & traffic
  • llms.txt β†— (opens in a new tab)
  • Catalog JSON β†— (opens in a new tab)
  • Remote MCP β†— (opens in a new tab)

Company

  • About
  • Contact
  • X (@AllMCPs) β†— (opens in a new tab)
  • GitHub β†— (opens in a new tab)
  • Terms
  • Privacy
AllMCPs VerifiedAllMCPs VerifiedFeatured on Nick LaunchesFeatured on Nick LaunchesLaunch Llama NewsletterLaunch Llama NewsletterVerified DR - allmcps.comVerified DR - allmcps.comFeatured on SaaSGrowFeatured on SaaSGrowFeatured on Twelve ToolsFeatured on Twelve ToolsFeatured on Saaspa.geFeatured on Saaspa.geFeatured on Findly.toolsFeatured on Findly.toolsFeatured on Startup FameFeatured on Startup FameFeatured on LaunchKiwiFeatured on LaunchKiwiFeatured on ScrollLaunchFeatured on ScrollLaunchFeatured on DailyPingsFeatured on DailyPingsFazier badgeFazier badgeFeatured on NewTool.siteFeatured on NewTool.siteFeatured on saasfame.comFeatured on saasfame.comDR Checker - Domain RatingDR Checker - Domain RatingListed on Turbo0Listed on Turbo0Launched on LaunchBoard - Product Launch PlatformLaunched on LaunchBoard - Product Launch PlatformList on SimilarlabsList on Similarlabshttps://codetrendy.comhttps://codetrendy.comListed on DevTool.ioFeatured on BuildlistFeatured on BuildlistAllMCPs VerifiedAllMCPs VerifiedFeatured on Nick LaunchesFeatured on Nick LaunchesLaunch Llama NewsletterLaunch Llama NewsletterVerified DR - allmcps.comVerified DR - allmcps.comFeatured on SaaSGrowFeatured on SaaSGrowFeatured on Twelve ToolsFeatured on Twelve ToolsFeatured on Saaspa.geFeatured on Saaspa.geFeatured on Findly.toolsFeatured on Findly.toolsFeatured on Startup FameFeatured on Startup FameFeatured on LaunchKiwiFeatured on LaunchKiwiFeatured on ScrollLaunchFeatured on ScrollLaunchFeatured on DailyPingsFeatured on DailyPingsFazier badgeFazier badgeFeatured on NewTool.siteFeatured on NewTool.siteFeatured on saasfame.comFeatured on saasfame.comDR Checker - Domain RatingDR Checker - Domain RatingListed on Turbo0Listed on Turbo0Launched on LaunchBoard - Product Launch PlatformLaunched on LaunchBoard - Product Launch PlatformList on SimilarlabsList on Similarlabshttps://codetrendy.comhttps://codetrendy.comListed on DevTool.ioFeatured on BuildlistFeatured on Buildlist
Β© 2026 Jackalope Digital LLC. All rights reserved.
  1. Home
  2. 🧠 Knowledge & Memory
  3. Cuba Memorys
C
Health: Not checked yetWe have not completed a health check for this listing yet.Last checked 8/11/2026, 12:05:33 AM

Cuba Memorys

Enrichment pendingWe haven’t run our AI enrichment pass on this listing yet, so the overview, use cases, and FAQ below may be sparse or missing. We work through the catalog over time β€” check back soon.
View Repository

Persistent memory MCP server. 25 tools, BM25+MMR+OOD retrieval, CFR-21 audit, knowledge graph.

Quick Install

Automated & IDE Setup

Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β€” or use 1-click editor setup below.

Add to CursorAdd to VS Code
Manual Client & Custom JSON ConfigExpand JSON β–Ύ

Install Config Generator

Choose your client
claude_desktop_config.json
{
  "mcpServers": {
    "cuba-memorys": {
      "command": "npx",
      "args": [
        "-y",
        "cuba-memorys"
      ]
    }
  }
}

πŸ’‘ Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)

Install Directory Badge Claim listing Alternatives🧠 More in Knowledge & Memory

Documentation Overview

Cuba-Memorys

CI PyPI npm MCP Registry Rust PostgreSQL License: Apache 2.0

Long-term memory for AI coding agents. An MCP server that gives your agent a knowledge graph it can search, reason over, and be corrected by β€” so it stops forgetting your codebase between sessions.

Written in Rust. Backed by PostgreSQL + pgvector. 28 MCP tools (29 with CUBA_DOCS=1), 19 CLI commands, and every number below measured on a benchmark that β€” as of v0.12 β€” actually measures what it claims to. (The previous one did not. See Measured.)

cuba-memorys terminal demo β€” hybrid search, claim verification with an LLM judge, procedural memory, and the CLI


Install

Terminal
pip install cuba-memorys        # or: npm install -g cuba-memorys
claude mcp add cuba-memorys -- cuba-memorys

That is the whole setup. On first run it provisions a PostgreSQL 18 + pgvector container via Docker and initializes the schema. Docker must be running.

Cursor / Windsurf / VS Code / Zed
config.json
{
  "mcpServers": {
    "cuba-memorys": {
      "command": "cuba-memorys"
    }
  }
}

No DATABASE_URL needed. Or run cuba-memorys setup and it writes the config for every client it finds β€” then cuba-memorys setup check audits them for disagreement, which is the failure that actually bites (two configs, two embedding dimensions, one silently broken search).

Bring your own PostgreSQL
config.json
{
  "mcpServers": {
    "cuba-memorys": {
      "command": "cuba-memorys",
      "env": { "DATABASE_URL": "postgresql://user:pass@localhost:5432/brain" }
    }
  }
}

Needs the vector and pg_trgm extensions. cuba-memorys doctor will tell you if anything is missing.

One shared daemon instead of one process per client

stdio gives every client its own process, and every process loads its own copy of the models β€” embeddings, reranker and NLI together are several GB. Three editor windows meant three copies, and on a 16 GB laptop that is the whole machine.

serve loads them once and answers every client over loopback HTTP, which is also the shape the 2026-07-28 MCP specification settled on: no session handshake, every request self-describing.

bash
cuba-memorys serve                      # 127.0.0.1:8787 by default
cuba-memorys serve 127.0.0.1:9000       # or pick the address

Point every client at it, and give each one its own Mcp-Client-Id so their sessions stay separate β€” without it jornada start in one window becomes the active session of the next:

config.json
{
  "mcpServers": {
    "cuba-memorys": {
      "type": "http",
      "url": "http://127.0.0.1:8787/mcp",
      "headers": { "Mcp-Client-Id": "editor-window-1" }
    }
  }
}

GET /health reports uptime, database reachability and the clients seen so far. CUBA_HTTP_ADDR overrides the address; CUBA_HTTP_TOKEN requires Authorization: Bearer, and is mandatory if you bind anything other than loopback β€” the daemon serves the entire graph with no authentication by default.

Models load in the background after the port opens, so a client that connects during startup waits on its first search instead of timing out the connection. Under stdio that timeout was how you ended up with abandoned multi-GB processes: the client gives up at 30 s but never closes stdin, so the server sat there holding every model it had loaded. Stdio now exits if no handshake arrives within CUBA_HANDSHAKE_TIMEOUT_SECS (60 s, 0 disables).

Semantic embeddings & models (recommended)

Without a model, embeddings are hash-based: deterministic, and semantically meaningless. Search still works through the lexical and BM25 branches, but nothing understands meaning.

One command installs the models and the ONNX runtime, on any OS β€” no shell scripts, no manual ORT_DYLIB_PATH:

bash
cuba-memorys models all          # embeddings + NLI + reranker + runtime
cuba-memorys models embed        # just the embeddings model (~113 MB)
cuba-memorys models all --gpu    # GPU runtime, if you have one
cuba-memorys doctor              # confirms what loaded

Everything lands in ~/.cache/cuba-memorys/ and is found automatically. models downloads only when you run it β€” nothing is fetched behind your back.

bge-m3 (1024-d) is better than e5-small for Spanish, though the size of the gap is no longer claimed (the old +21 nDCG figure came from a broken benchmark). It needs a dimension migration (scripts/migrate-embedding-dim.sh 1024) and CUBA_EMBED_MODEL=bge-m3 CUBA_POOLING=cls.

Modes: local Β· red Β· completo

CUBA_MODE is a preset that sets the database, the models, and outbound network together, so you pick one name instead of lining up a dozen env vars:

CUBA_MODEDatabaseCapabilitiesNetwork out
local (default)Docker on this machineembeddings + NLI as installednone
redshared managed Postgres (set DATABASE_URL with sslmode=require)+ provenance per node, real-time sync between machinesnone
completowhatever DATABASE_URL implies+ reranker (GPU if present) + cuba_docscuba_docs

Two machines, one memory. Point both at the same managed Postgres (Neon or Supabase free tier both have pgvector and fit the 36 MB corpus many times over), give each a name with CUBA_NODE_NAME, and CUBA_MODE=red. What one writes, the other reads; every memory records which machine it came from (origin_node). Do not expose your own Postgres port to the internet β€” use a managed provider's TLS, or a private network like Tailscale.

Real isolation when you share. A shared database is where row-level security stops being decorative. Run cuba-memorys secure once (as the admin role) to create a non-superuser cuba_app with RLS and append-only audit actually enforced, then point the runtime at it with CUBA_SKIP_MIGRATIONS=1. cuba-memorys doctor reports whether the runtime role is a superuser (which bypasses all of it) or not.

Maximum capability. CUBA_MODE=completo turns on the cross-encoder reranker (+93% nDCG) and cuba_docs. On a GPU the reranker is instant; on CPU faro time-boxes it and falls back to the RRF ranking (CUBA_RERANK_TIMEOUT_SECS, default 20 s), so a slow machine still answers. GPU binaries ship with CUDA (NVIDIA) and, on Windows, DirectML (any GPU) β€” cuba-memorys models runtime --gpu fetches the accelerated runtime.

Fetching the GPU runtime is only half of it: the binary itself has to be built with --features cuda, or gpu::configure() registers no provider and the reranker runs on CPU. That is not a hypothetical β€” it is what a 50-candidate rerank costs on a 6-core laptop, measured with cargo run --release --example rerank_bench:

build50 candidates, mixed lengthsinside the 20 s budget?
CPU, with_intra_threads(2)106,9 sno β€” scores computed, then discarded
CPU, physical cores61,0 sno
--features cuda4,1 syes

Same ranking either way β€” CPU and GPU agree candidate for candidate, differing only in the fifth decimal of the score. Run rerank_bench on any machine to see whether the reranker fits its budget there or is silently throwing the work away, and cuba-memorys doctor reports whether this build has a GPU provider at all.

This section used to say "every model quietly runs on CPU", implying all three would run on the GPU once you built with --features cuda. Only the reranker ever did. The embedder ships dynamically quantised to INT8, which means 96 DynamicQuantizeLinear feeding 144 MatMulInteger β€” and the CUDA provider registers no kernel for either, so ONNX Runtime partitions them onto the CPU no matter what you build. Registering CUDA for that session bought nothing and cost a VRAM arena the model never computed in: 374 MiB held while all 544 MB of weights sat in host RAM. The NLI cross-encoder has the opposite problem β€” it is FP32 and stuck there, because mDeBERTa is documented upstream as not supporting FP16 and the INT8 build returns confident false entailments.

So placement is now decided per model rather than once per process, and only the reranker asks for the GPU. On the 6 GB card this was measured on, the daemon went from 5228 MiB of VRAM to 2950 MiB while searching, and 0 while idle β€” and down to 1460 MiB with the two opt-in steps in Footprint below.

Individual env vars (CUBA_DOCS, CUBA_RERANKER_PATH, …) always override the preset.


What it actually does

Most memory servers are a key-value store with an embedding bolted on. This one models four kinds of memory, because the psychology literature says they are four different things and they decay differently:

What it holdsHow it strengthens
SemanticFacts about entities β€” "all endpoints are async"Access (Hebbian/BCM, Oja 1982)
EpisodicEvents with actors and time β€” "we shipped v2 on Tuesday"Power-law decay (Tulving 1972, Wixted 2004)
ProceduralHow things are done here β€” recipes with a track recordSuccess, not access (ACT-R)
WorkingScratch notes bound to the current sessionCleared with the session

Procedural memory is a separate table rather than a ninth observation type for a specific reason: ACT-R separates declarative memory (reinforced by access) from procedural (reinforced by success). As an observation, a recipe consulted constantly because it keeps failing would climb in importance. It is ranked by Wilson lower bound, so 1/1 successes scores 0.21 and 47/50 scores 0.84 β€” a lucky first try does not outrank a track record.

Retrieval

Hybrid RRF fusion (k=60, Cormack 2009) over three signals β€” full-text, BM25 (ts_rank_cd), and pgvector HNSW β€” with entropy-routed weighting that shifts from keyword-heavy to semantic as the query's Shannon entropy rises.

Answers arrive in compact by default: abbreviated keys, content truncated at 1200 chars. 30% fewer tokens, and a slightly better nDCG β€” measured on the 221 id-scored questions, +0.0090 with a paired 95% interval of [+0.0024, +0.0166]. The format genuinely cannot change which documents rank; what it changes is how many of them survive the response token budget before they are scored. Verbose at the default 5000-token budget weighs 5286 tokens and loses its tail; compact weighs 3723 and keeps it. Pass "format": "verbose" for the full per-branch score breakdown.

Verification that actually verifies

cuba_faro mode=verify checks a claim against what is stored. It used to score claims by cosine similarity to the retrieved evidence, and that does not work β€” similarity measures what a text is about, not what it asserts. "cuba-memorys is written in Rust" and "…in Java" are nearly the same vector. Measured on the live corpus, the false claim scored 0.61 and the true one 0.59.

Entailment is a different question from similarity, and it needs something that reads. A local cross-encoder now judges each piece of evidence β€” supports / contradicts / unrelated β€” and confidence is derived from the verdicts, each weighted by that evidence's similarity. Same corpus, after:

ClaimBefore (cosine)Now
"written in Rust" (true)0.590.995 Β· verified
"written in Java" (false)0.610.00 Β· contradicted
"the best paella uses saffron" (unrelated)0.45, with 10 "evidence" items0.00 Β· unknown, no evidence

Being on-topic is not support, and unrelated counts for neither side.

The judge is mDeBERTa-v3-base-xnli running locally on ONNX: 100 languages, ~50 ms per verdict, no API key, no network, no cost. That matters here β€” about 75% of this corpus is Spanish, and the English-only NLI models everyone reaches for first would have silently failed on three memories out of four. Install it with cuba-memorys models nli; cuba-memorys doctor will tell you whether it loaded.

Without it, verification falls back to an LLM (your MCP client's own model via sampling, a local claude CLI, or the Anthropic API) β€” and with none of those, to an honest unknown rather than an invented verdict.

Two things it will not do. It will not confirm a claim on weak evidence: entailment must clear 0.80 while contradiction needs only 0.60, because confirming a false memory and doubting a true one are not errors of equal cost. And when it cannot tell, it says so instead of returning whichever number came out largest β€” an argmax over a 3-way head will happily publish supports for a claim that is flatly false, and did.

Calibrated abstention

The out-of-distribution gate rejects queries the corpus cannot answer. The threshold is not a magic constant: Ledoit-Wolf covariance shrinkage plus a conformal quantile, calibrated against your own corpus with cuba-memorys calibrate --apply and persisted. (The theoretical χ² threshold rejected 100% of answerable queries. Distribution-free calibration is not a nicety here.)

And it tells you when it is broken

Code
$ cuba-memorys doctor
[  ok  ] migrations           33 aplicadas, ninguna dirty
[  ok  ] embedding_dim        runtime 1024-d == columna vector(1024)
[  ok  ] runtime_role         'cuba_app' sin superuser β€” RLS y audit efectivos
[ warn ] binary_freshness     4 proceso(s) MCP corren un binario mΓ‘s viejo que el de disco

This exists because the failure mode of a hybrid search engine is not a crash β€” it is a vector branch dying and the search quietly becoming lexical, with no symptom. The server now refuses to start on an embedding-dimension mismatch, and search sets degraded: true in the response when a branch fails.


The CLI: your memory without an LLM in the middle

Nineteen commands. cuba-memorys --help lists them all.

serveOne shared HTTP daemon for every client, instead of one process (and one copy of the models) per editor window
search <query> Β· save Β· delete Β· exportRead and write the brain from a shell
dashboardA self-contained HTML view of what is in there
doctorHealth check: schema, dimensions, config coherence, stale processes
recallSession-start context injection β€” wire it with setup hook
reembedRe-encode what needs it (default: only stale rows, not all of them)
calibrateRecompute the abstention threshold from your corpus
linkAuto-link entities by NPMI co-occurrence
dedupeEntities that are the same thing under different names β€” see below
skills <dir>Export procedures as Claude Code Skills
evalRetrieval benchmark β€” nDCG@10 with confidence intervals, MRR, recall, token cost
setupWire this into your MCP clients; setup check audits them

dedupe β€” because a different string is a different entity

cuba_alma create inserts with ON CONFLICT (name). So one project fragments into Mapupita-Web, Mapupitta-Web (typo), Mapupita Web, mapupita… and searching one finds none of the others. On a real 266-entity graph, 158 of them (59%) had not a single relation β€” for PageRank and multi-hop retrieval, they did not exist.

What decides a merge is not the embedding centroid. That was the obvious idea and it is wrong: M-Codes Reference Guide and G-Codes Reference Guide sit at 0.811 cosine between centroids. On a corpus about one domain, centroid similarity measures the domain, not the entity β€” a 0.80 threshold would have merged two different CNC guides, irreversibly.

So --apply merges only what is provable (identical after normalizing case and separators). Typos and near-matches are shown, and judged one at a time with --judge. The old name is written to brain_entity_aliases, so nothing is lost: looking it up still resolves.


The 28 tools

Named after Cuban culture. cuba-memorys advertises all of them, or set CUBA_TOOL_PROFILE=lean to advertise only cuba_tools + cuba_call β€” 67% smaller tool catalogue, zero functions lost, schemas loaded on demand.

Knowledge graph β€” cuba_alma (entities) Β· cuba_cronica (observations, episodes, timeline) Β· cuba_puente (typed relations, traversal, link prediction) Β· cuba_ingesta (bulk import)

Search β€” cuba_faro (hybrid RRF, verification, MMR diversification, OOD abstention)

Error memory β€” cuba_alarma (report) Β· cuba_remedio (resolve) Β· cuba_expediente (search past errors; warns if an approach failed before)

Sessions & decisions β€” cuba_jornada (session lifecycle, diff) Β· cuba_decreto (architecture decisions) Β· cuba_proyecto (per-project isolation) Β· cuba_pre_compact (survive /compact)

Procedural β€” cuba_receta (recipes ranked by Wilson lower bound)

Cognition β€” cuba_reflexion (gap detection) Β· cuba_hipotesis (abductive inference) Β· cuba_contradiccion (semantic conflicts) Β· cuba_juez (LLM judge) Β· cuba_centinela (prospective triggers) Β· cuba_calibrar (Bayesian calibration, source credibility)

Maintenance β€” cuba_zafra (decay, prune, merge, PageRank, Leiden communities) Β· cuba_eco (RLHF feedback) Β· cuba_vigia (health, drift, centrality) Β· cuba_forget (GDPR erasure) Β· cuba_archivo (CFR-21 hash-chain audit log) Β· cuba_pizarra (working memory) Β· cuba_sync (git-friendly export/import)

Meta β€” cuba_tools (discover) Β· cuba_call (invoke)


Configuration

VariableDefaultWhat it does
CUBA_MODElocallocal / red (shared cloud DB) / completo (everything + GPU). A preset for the rest.
CUBA_NODE_NAMEhostnameNames this machine in origin_node β€” which computer wrote each memory
DATABASE_URLauto (Docker)PostgreSQL connection. Set it (external + TLS) for red mode.
ONNX_MODEL_PATH + ORT_DYLIB_PATHauto (~/.cache)Semantic embeddings. cuba-memorys models sets these up for you.
CUBA_EMBED_MODEL Β· CUBA_EMBEDDING_DIM Β· CUBA_POOLINGmultilingual-e5-small Β· 384 Β· meanSet to bge-m3 Β· 1024 Β· cls for the stronger Spanish model
CUBA_TOOL_PROFILEfulllean β†’ 2 tools, 67% smaller catalogue, nothing lost
CUBA_JUDGEautonli / mcp_sampling / claude_cli / anthropic_api / heuristic
CUBA_NLI_PATH~/.cache/cuba-memorys/models-nliLocal entailment model (cuba-memorys models nli)
CUBA_NLI_ESCALATEoffSend claims the NLI could not decide to an LLM. Buys recall, costs ~12 s each
CUBA_RERANKER_PATH Β· CUBA_RERANK_TIMEOUT_SECS~/.cache/…/reranker Β· 20Cross-encoder reranker (+93% nDCG); on CPU it falls back to RRF past the budget
CUBA_RERANK_INTRA_THREADSphysical cores (2 on GPU)ONNX threads per rerank inference. Past the physical core count it gets slower β€” measure with rerank_bench before raising it
CUBA_RERANK_LENGTH_BUCKETINGon (off under fixed shape)Batch similar-length candidates so padding does not become compute. Scores are unchanged
CUBA_RERANK_CHUNK16Candidates per forward pass. Under fixed shapes every batch pads to 512 tokens, making this the main lever on the GPU arena: 16 β†’ 2938 MiB, 4 β†’ 2364 MiB. Scores are unchanged β€” a verbose search at 16 and at 4 came back byte-identical
CUBA_EMBED_DEVICE Β· CUBA_RERANK_DEVICE Β· CUBA_NLI_DEVICEcpu Β· gpu Β· cpuPer-model placement. Only the reranker gains from a GPU; the INT8 embedder cannot use one and the FP32 NLI is not worth the VRAM. Set to gpu/cpu to A/B a placement without rebuilding
CUBA_GPU_MEM_LIMIT_MB2048Caps the CUDA arena and pins arena_extend_strategy to SameAsRequested. The default (NextPowerOfTwo) doubles its reservation on every growth, which is how 1,65 GB of weights became 5+ GB of VRAM. The cap is per session
CUBA_EMBED_INTRA_THREADShalf the logical cores, max 4ONNX threads per embedding. Measured on 12 threads: 1 β†’ 94,8 ms, 2 β†’ 52,3 ms, 4 β†’ 35,8 ms, 6 β†’ 68,1 ms, 12 β†’ 155,4 ms per query
CUBA_IDLE_SHUTDOWN_SECS0 (off)Exit after this long with no request from any client. Pairs with a systemd .socket unit so the next call brings the daemon back β€” see Footprint
CUBA_WARM_RERANKERoffLoad the cross-encoder at startup instead of on its first batch. Off, a cold start costs 0,027 s instead of 11 s and holds no VRAM until something actually reranks
CUBA_HTTP_ADDR Β· CUBA_HTTP_TOKEN127.0.0.1:8787 Β· unsetAddress for serve, and the bearer token it requires. A token is mandatory to bind anything but loopback
CUBA_HANDSHAKE_TIMEOUT_SECS60stdio exits if no MCP handshake arrives, instead of holding the models for a client that gave up. 0 disables
CUBA_DOCSoff1 enables cuba_docs, the only tool that leaves your machine. Unset, it is not even advertised.
CUBA_COMPACT_CHARS1200Compact truncation (measured knee)
CUBA_OOD_THRESHOLDcalibratedOverride the abstention threshold
CUBA_BITEMPORALonMirror observations into brain_facts

Footprint

A memory server is infrastructure: it is running when you are not using it. On the 6 GB laptop GPU this was measured on, it used to hold 5228 MiB of VRAM from boot β€” 93% of the card β€” and other GPU programs stopped being able to start. The NVIDIA driver was returning NV_ERR_NO_MEMORY on channel creation, which is what a game or a GPU-accelerated terminal fails on.

Two of the numbers below ship as defaults; two need a line of config, and this table keeps them apart rather than quoting the best one as if it came free.

before0.20.0 defaultsCUBA_RERANK_CHUNK=4+ fused artifact
VRAM while searching5228 MiB2950 MiB2364 MiB1460 MiB
VRAM idle5228 MiB0 β€” the process is gone00
Cold start to answering11,1 s0,027 s0,027 s0,027 s
Search, warm5,90 s5,25 s3,73 s1,70 s
Embedding one query52,3 ms35,8 ms35,8 ms35,8 ms

Everything in the defaults column is code that ships. CUBA_RERANK_CHUNK=4 is one env var. The last column additionally needs the rebuilt reranker described below. None of it removed a feature.

Four things got it there:

Placement per model, not per process. Only the reranker is accelerated by a GPU β€” the INT8 embedder cannot be, and the FP32 NLI is not worth a gigabyte of VRAM for a judge that runs occasionally and tolerates 150-400 ms. The arena cap is per session, so three sessions asking for CUDA on a 6 GB card is a 3Γ— overcommit waiting to fail.

A CUDA arena that stops doubling. ArenaExtendStrategy::NextPowerOfTwo is the ONNX Runtime default and it reserves in powers of two rather than what the session asked for.

The reranker loads on its first batch. Under socket activation the daemon starts far more often than it reranks, and plenty of those starts only ever answer a save.

A daemon that is not running when nobody is asking. CUBA_IDLE_SHUTDOWN_SECS plus a systemd .socket unit: the socket owns the port, the daemon starts on the first real connection and exits after the idle window. It shuts down through the normal path β€” serve returns, the background drain flushes in-flight embedding writes, sqlx closes its pool β€” because exiting the process directly loses those writes silently.

The systemd pair
ini
# ~/.config/systemd/user/cuba-memorys.socket
[Socket]
ListenStream=127.0.0.1:8787
Accept=no

[Install]
WantedBy=default.target
ini
# ~/.config/systemd/user/cuba-memorys.service β€” no [Install]; the socket starts it
[Unit]
Requires=cuba-memorys.socket

[Service]
Type=exec
ExecStart=%h/.local/bin/cuba-memorys serve 127.0.0.1:8787
# An idle shutdown exits 0 β€” Restart=always would bounce it straight back up.
Restart=on-failure
Environment=CUBA_IDLE_SHUTDOWN_SECS=1200
Environment=CUBA_EMBED_DEVICE=cpu
Environment=CUBA_RERANK_DEVICE=gpu
Environment=CUBA_NLI_DEVICE=cpu

serve adopts the socket systemd passes as fd 3 (LISTEN_FDS), so the port is held while the daemon is not running and no client sees a refused connection.

The reranker artifact

The published bge-reranker-v2-m3 ONNX is converted to FP16 before any graph fusion, which leaves 785 Cast nodes threaded through it. ONNX Runtime claws some of that back at load time (2023 β†’ 897 nodes, 49 SkipLayerNormalization), but it cannot fuse Gelu and it repeats the work on every cold start. Rebuilding from the FP32 export and fusing first:

bash
python -m onnxruntime.transformers.optimizer \
  --input model.onnx --output model.onnx \
  --model_type bert --num_heads 16 --hidden_size 1024 \
  --opt_level 1 --use_gpu --float16
VRAMsearch p50load + warm
shipped FP162364 MiB3,73 s22,8 s
fused, then FP161460 MiB1,70 s10,2 s

Identical top-10 order on a real search, fused_score differing by at most 0,0029; on synthetic logits at the real batch shapes, Pearson β‰₯ 0,9997 with the same ranking in every batch.

Attention does not fuse, and that is not fixable here. is_fully_optimized: Attention (or MultiHeadAttention) not fused, at opt_level 0, 1, 2 and 99, on both the FP16 artifact and the clean FP32 one. The export builds its Q/K/V reshapes from dynamic shape subgraphs (Shape β†’ Gather β†’ Unsqueeze β†’ Concat β†’ Reshape) and AttentionFusion needs a Reshape with a constant shape to read num_heads and head_size off it. So flash/efficient attention stays unavailable without a re-export using static shapes β€” worth knowing before anyone spends an afternoon on it.


Measured β€” and the benchmark that was lying

Until v0.12 this section carried a line reading "every number here is measured rather than assumed", and every number in it was wrong. The benchmark was broken in three ways, and finding out cost two published conclusions.

It had ten queries. A 95% interval of roughly Β±0.12; the smallest effect it could detect was ~0.25 nDCG. Any claim about a smaller difference was noise wearing a decimal point.

Relevance was judged by substring match. A result counted as correct if its text merely contained a marker word β€” so every observation mentioning "postgres" scored as a right answer to any question about postgres, whether it answered anything or not. That measures keyword presence, not retrieval, and it tilts the whole benchmark toward the lexical branch and against the vector one.

nDCG normalized against what was retrieved, not what exists. With 5 relevant documents in the corpus and 2 found, the "ideal" ranking was taken to be those 2 β€” so a system that missed 60% of the answer scored a perfect 1.0. (And R@10 = 3.125 shipped in this file. Recall is a proportion.)

The real number is not 0.894. On 221 id-scored queries it is nDCG@10 = 0.50 [95% CI 0.44–0.56]. The system did not get worse. It was never 0.894.

What that cost

  • "The cross-encoder reranker earns nothing" β€” it had never run. Three bugs in series: faro wrapped the call in if let Ok(..) and dropped the error; it fed token_type_ids to a model that is XLM-RoBERTa and has none; it read f16 logits as f32. The output was "bit for bit identical" to no reranking not because reranking changed nothing, but because it never happened. Fixed; being measured properly now.

  • Associative retrieval does degrade β€” but the old evidence (βˆ’0.03 at n=10) could not have shown it. On the new dataset with a paired bootstrap (the correct test: same queries in both arms), the interval is [βˆ’0.051, βˆ’0.018] and never touches zero. It improves 0 queries and hurts 23. The decision was right; the reasoning was not. The power was never in more data β€” it was in using the right test.

What survives, re-measured honestly

compact by defaultβˆ’30% tokens, nDCG +0.0090 (paired 95% CI [+0.0024, +0.0166], n=191). The earlier "exactly 0.0000" was measured with a harness that let the 5000-token response budget truncate the ranking before scoring it: verbose lost its tail, compact did not. The old "βˆ’40%" came from the broken benchmark.
Conformal abstention100% of out-of-distribution queries caught, 0% false abstentions.
lean tool profileβˆ’67% catalogue, zero functions lost.
bge-m3 over e5-smallDirection almost certainly right; the +21.2 nDCG figure is withdrawn β€” it came from the broken benchmark and re-establishing it would mean re-embedding the corpus twice.
The benchmark itself221 queries (was 10), relevance by document id, bootstrap confidence intervals, and the minimum detectable effect printed beside every result β€” so nobody reads a 3-point difference as a finding again.

Foundations

AlgorithmReference
RRF fusion (k=60)Cormack et al. (2009)
Hebbian + BCM metaplasticityOja (1982); Bienenstock, Cooper & Munro (1982)
Conformal predictionVovk (2005); Angelopoulos & Bates (2023)
Ledoit-Wolf covariance shrinkageLedoit & Wolf (2004)
Mahalanobis OOD detectionLee et al. (NeurIPS 2018)
Wilson score intervalWilson (1927)
Declarative vs procedural memoryAnderson & Lebiere (ACT-R)
Testing effectKarpicke & Roediger (Science 2008)
Power-law forgettingWixted (2004)
Episodic vs semantic memoryTulving (1972)
PageRank Β· Leiden Β· BrandesBrin & Page (1998); Traag et al. (2019); Brandes (2001)
NPMI co-occurrenceBouma (2009)
MMR diversificationCarbonell & Goldstein (1998)
Contextual RetrievalAnthropic (2024)
Prompt-injection spotlightingHines et al. (2024)

Development

bash
git clone https://github.com/LeandroPG19/cuba-memorys.git
cd cuba-memorys/rust && cargo build --release

# On an NVIDIA machine, build this way instead β€” without it the reranker spends
# its whole budget for a ranking that gets discarded. It accelerates the
# reranker only; see Footprint for why the other two models stay on the CPU.
cargo build --release --features docs,cuda

./scripts/demo.sh                  # runs on a throwaway Postgres it removes on exit
./scripts/merge-gate.sh            # fmt Β· clippy -D warnings Β· 316 tests Β· audit Β· integration
cargo run --release --example rerank_bench   # does the reranker fit its budget here?

Publishing is tag-driven: v* triggers GitHub Release binaries (5 platforms), PyPI wheels, npm, and the MCP Registry. A test pins all four files that hold a version number to the same value, because they used to drift and nothing caught it.

License

Apache-2.0 β€” use it, modify it, ship it, sell it, embed it in a closed product. No copyleft obligation. The licence also grants patent rights explicitly, which is the part legal departments care about.

Author

Leandro Perez G. β€” @LeandroPG19

Related MCP Servers

View all in Knowledge & Memory View all alternatives
  • Moxie Docs MCP logoMoxie Docs MCP
    β˜… Featured

    MCP & Agent Skills for Automated Documentation, and codebase conventions + context

    🧠 Knowledge & Memory17 views
    Compare vs Moxie Docs MCP β†’
  • Mcp logoMcp

    AI memory layer β€” one shared, persistent memory across every AI tool you connect.

    🧠 Knowledge & Memory0 views
    Compare vs Mcp β†’
  • C
    Collective Memory

    MCP server for persistent, semantic memory across AI sessions

    🧠 Knowledge & Memory0 views
    Compare vs Collective Memory β†’
  • Memora logoMemora

    Persistent memory with knowledge graph visualization, semantic/hybrid search, cloud sync (S3/R2), and cross-session context management.

    🧠 Knowledge & Memory2 views
    Compare vs Memora β†’

Frequently Asked Questions about Cuba Memorys

Add the following block to your claude_desktop_config.json under mcpServers: "mcpServers": { "cuba-memorys": { "command": "npx", "args": ["-y", "cuba-memorys"] } }

AllMCPs Directory Badge

Full Badge Customizer

Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.

Badge Style:
Live Dynamic SVG PreviewCuba Memorys AllMCPs Directory Badge
Markdown (GitHub README)
[![AllMCPs](https://allmcps.com/api/badge/cuba-memorys?style=directory)](https://allmcps.com/mcp/cuba-memorys)
HTML Embed
<a href="https://allmcps.com/mcp/cuba-memorys"><img src="https://allmcps.com/api/badge/cuba-memorys?style=directory" alt="Cuba Memorys on AllMCPs" /></a>

Technical Specs & Signals

Category🧠Knowledge & Memory
More technical detailsExpand β–Ύ
TransportSTDIO
RuntimeNode.js
Views0
Unique ViewsTotal visits recorded for this listing page on AllMCPs.
Installs0
Installs & Copy ActionsTotal times users copied install commands or configuration snippets for this server.
27Quality signal: Emerging Β· 27/100How this signal is calculated β–Ύ
Server availabilityNot measured

Not scored for repo-hosted servers β€” we can't reach the running server, only its GitHub page. Hosted MCP endpoints are health-checked live.

Verified ownership8/20
Documentation & tools11/30
Adoption & activity1/15
Community engagement0/10

A guidance signal from public completeness & health data β€” not a user rating. New listings start lower and rise as they add docs, get verified, and grow adoption. Signals we can't observe for a listing are skipped, not counted against it.

β˜… FeaturedMoxie Docs MCP logo

Moxie Docs MCP

MCP & Agent Skills for Automated Documentation, and codebase conventions + context

Explore Server β†’

Own this project?

This directory is pre-filled from public sources. Claim via GitHub README, site badge, or DNS TXT to get the verified badge and attach your website.

Free dofollow backlink: after claiming, verify your product site and place a dofollow AllMCPs badge β€” we recheck it stays live.

Claim & get free dofollow

Share & Embed

Add our SVG badge (dark/light directory styles) or embeddable widget to your site.

Explore more

More in 🧠 Knowledge & Memory β†’Best MCP servers for Memory & Knowledge β†’Alternatives to Cuba Memorys β†’Install in Claude DesktopInstall in CursorInstall in VS Code