McpEngramMemory.Synthesis.Onnx
2.0.0
dotnet add package McpEngramMemory.Synthesis.Onnx --version 2.0.0
NuGet\Install-Package McpEngramMemory.Synthesis.Onnx -Version 2.0.0
<PackageReference Include="McpEngramMemory.Synthesis.Onnx" Version="2.0.0" />
<PackageVersion Include="McpEngramMemory.Synthesis.Onnx" Version="2.0.0" />
<PackageReference Include="McpEngramMemory.Synthesis.Onnx" />
paket add McpEngramMemory.Synthesis.Onnx --version 2.0.0
#r "nuget: McpEngramMemory.Synthesis.Onnx, 2.0.0"
#:package McpEngramMemory.Synthesis.Onnx@2.0.0
#addin nuget:?package=McpEngramMemory.Synthesis.Onnx&version=2.0.0
#tool nuget:?package=McpEngramMemory.Synthesis.Onnx&version=2.0.0
<p align="center"> <img src="images/banner.svg?v=2.0.0" alt="MCP Engram Memory" width="900"/> </p>
<p align="center"> <a href="https://dotnet.microsoft.com/"><img src="https://img.shields.io/badge/.NET-8%20%7C%209%20%7C%2010-512BD4" alt=".NET"/></a> <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"/></a> <a href="https://www.nuget.org/packages/McpEngramMemory.Core"><img src="https://img.shields.io/nuget/v/McpEngramMemory.Core" alt="NuGet"/></a> <img src="https://img.shields.io/badge/tests-multi--target-brightgreen" alt="Tests: .NET 8, 9, and 10"/> <img src="https://img.shields.io/badge/release-2.0-blueviolet" alt="Release: 2.0"/> </p>
The governed, local-first cognitive memory kernel for AI agents
Memory physics, not just storage. Most agent memory systems store context. Engram evolves context — topology-driven decay, consolidation, and contradiction detection, all running locally with zero external API.
2.0 makes the boundary explicit. Tenant scope stops being a defaulted argument: 55 Core retrieval and scoping APIs now require tenantId with no default, positioned so that pre-2.0 positional calls fail to compile rather than silently rebinding. The compiler makes you state the scope — it does not choose one for you, and tenantId: "" still selects the legacy partition.
- Tenant-Partitioned Throughout — partitioning runs through storage, graph, clusters, lifecycle, diffusion, synthesis, and visualization. Edges never cross tenants; cross-namespace association within a tenant is preserved.
- Context Control — graph-Laplacian diffusion decays trivial chats so your context window doesn't choke on noise. Important, well-connected knowledge stays sharp; transient chatter fades.
- Contradiction Detection —
find_contradictionssurfaces conflicting goals or architecture decisions on demand, so you can review and retire logic you've already reversed instead of letting the agent keep acting on it. - Governed Core — a deterministic Root Constitution, versioned knowledge and provenance, Teacher/Verifier promotion, authorization-first retrieval planning, and citation-aware context manifests are available to embedding hosts.
- 100% Privacy-First — local ONNX embeddings + local SQLite. Your memory never leaves your machine. No telemetry, no analytics, no phone-home: the server makes no outbound network call at all in its default configuration. (The optional synthesis backend talks to a local Ollama daemon, and
OLLAMA_URLcan be pointed elsewhere if you choose to.)
→ See the cold-start scorecard · Get started in 5 minutes · What's new in 2.0
What's New in 2.0
2.0 is a breaking release for hosts embedding McpEngramMemory.Core. MCP clients and stdio
deployments are unaffected — tool names, arguments, and on-disk data are unchanged, and legacy
empty-tenant deployments still behave byte-for-byte as before.
| Change | What it means |
|---|---|
tenantId is required on 55 Core retrieval/scoping APIs |
The old tenantId = "" default wasn't a sentinel — "" is the legacy partition, a real readable dataset, so a forgotten argument compiled clean and silently degraded to cross-tenant scope. It did, twice. The compiler now finds every omission. |
| Parameter placement is anti-rebinding | tenantId only moved into slots previously held by an int/float/bool, so pre-2.0 positional calls fail to compile rather than binding a relation or query string into the tenant slot. |
| Topology reads are revision-consistent | Graph and cluster projections publish only if the tenant's attribution revision held through the whole projection; continuous churn fails closed. |
| Auto-link accounting is exact | Pair walks report completed comparison slots once per anchor, so cancellation no longer over- or under-states progress. |
AutoLinkResult reshaped |
Four new trailing members; PairsExamined is now long and reports completed comparison slots. Use PairSlotsPlanned for the window budget, PairsAboveThreshold for the find count. |
2.0 supersedes 1.6.0, which is where the underlying features landed: full multi-tenant graph,
clusters, lifecycle, diffusion, intelligence, synthesis and snapshots (with no storage migration —
tenant travels inside the existing JSON blobs), and the governed cognitive constitution
(deterministic Root Constitution, audited pre/post MCP filter, versioned Knowledge, append-only
Provenance, promote_knowledge on the full profile). 2.0 is what makes that boundary mandatory
instead of optional.
Upgrading: recompile, and at each error pass the tenant the call site already holds —
tenantId: myTenant, or tenantId: "" where legacy scope is the deliberate meaning. Treat every
tenantId: "" you add as a claim, not a fix. Full detail in the
2.0.0 release notes and
Tenant Isolation Design.
How It Works
Engram sits between your AI assistant and a local store. Every memory is embedded, indexed for hybrid search, woven into a knowledge graph, and then left to evolve on its own — background workers decay noise, consolidate what matters, and densify the graph while you're away.
<p align="center"> <img src="images/how-it-works.svg?v=1.2.0" alt="How It Works — store, search, link, route, with automatic diffusion subsystem and lifecycle transitions" width="900"/> </p>
The loop, end to end:
- Store —
rememberembeds text with a local ONNX model (bge-micro-v2, 384-dim), detects near-duplicates, and auto-links the new memory to related ones in the graph. - Search —
recallruns hybrid retrieval (BM25 keyword + vector similarity, fused with RRF), expands synonyms, and re-ranks through the graph's spectral structure. (Opt-in MMR diversity reranking is available onsearch_memoryandcross_search.) - Route — with the namespace omitted,
recallauto-routes across expert namespaces to find knowledge you didn't know where to look for. - Evolve — background services run the physics: spectral decay fades weakly-connected memories (archiving the weakest), sleep consolidation promotes well-connected STM to LTM, and auto-link densifies the graph.
Retrieval itself is a nine-stage pipeline — candidate generation, keyword rescue, fusion, diversity, and spectral re-ranking:
<p align="center"> <img src="images/retrieval-pipeline.svg?v=2.0.0" alt="9-stage retrieval pipeline including v0.9.0 spectral re-ranking" width="900"/> </p>
See It in Action
<p align="center">
<img src="images/memory-graph.gif" alt="Engram memory graph clustering during a consolidation cycle: STM (amber) nodes migrating into LTM (blue) clusters, with pulse-highlight on retrieval" width="900"/> </p>
<p align="center"><em>The memory graph consolidating in real time — short-term (amber) memories cluster and promote to long-term (blue) during a sleep cycle.</em></p>
The built-in D3.js graph viewer lets you explore your own memory graph interactively. Generate a snapshot from any AI assistant, then open the viewer:
get_graph_snapshot → save the JSON → open visualization/memory-graph.html
<p align="center"> <img src="images/graph-overview.png" alt="Memory graph overview — 1,207 nodes, 375 edges, 178 clusters" width="860"/> </p>
<p align="center"> <img src="images/graph-detail.png" alt="Memory graph connected-only detail view" width="860"/> </p>
Viewer features:
- Force-directed layout — related memories cluster together, typed edges (elaborates, contradicts, depends_on, …) shown in distinct neon colors
- Lifecycle colors — STM nodes amber, LTM nodes blue; cluster summaries marked with a dashed ring
- Convex-hull cluster overlays — cluster membership visible at a glance
- Search & highlight — type in the search bar to instantly dim non-matching nodes and pulse-highlight matches in gold;
‹ ›buttons orEnter / Shift+Enterto cycle through results - Zoom / pan / rotate —
+/−/⊡buttons; scroll to zoom; right-click drag to rotate the whole graph - Fractal density overlay — zooms out reveal a quadtree density map color-coded by lifecycle state
- Connected-only filter — hide isolated nodes to focus on the linked knowledge graph
- Drag-and-drop JSON loading — drop a snapshot file directly onto the viewer
The snapshot file is not committed (it's personal memory data). Generate a fresh one any time with get_graph_snapshot.
Quickstart
# Windows — clones, builds, and wires up your AI assistant automatically
irm https://raw.githubusercontent.com/wyckit/mcp-engram-memory/main/setup.ps1 | iex
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/wyckit/mcp-engram-memory/main/setup.sh | bash
The embedding model (bge-micro-v2) ships inside the package — it is fetched from Hugging Face at build time, checksum-verified, and bundled, so installing the tool needs no model download and the server makes no network call to start.
<details> <summary>Other install options (manual clone · Docker · NuGet)</summary>
Manual clone
git clone https://github.com/wyckit/mcp-engram-memory.git
cd mcp-engram-memory && dotnet restore
Add to your MCP client config:
{
"mcpServers": {
"engram-memory": {
"command": "dotnet",
"args": ["run", "--project", "/path/to/mcp-engram-memory/src/McpEngramMemory"],
"env": { "MEMORY_TOOL_PROFILE": "minimal" }
}
}
}
Docker
docker build -t mcp-engram-memory .
docker run -i -v memory-data:/app/data mcp-engram-memory
NuGet library (embed the engine in your own .NET app)
dotnet add package McpEngramMemory.Core --version 2.0.0
See examples/ for ready-to-use config files.
</details>
At a Glance
| Metric | Value |
|---|---|
| Version | 2.0.0 (breaking for Core library hosts; MCP surface unchanged) |
| MCP tools | 63 (profiles: 17 / 39 / 63) |
| Isolation | Tenant-partitioned across storage, graph, clusters, lifecycle, diffusion, synthesis, and snapshots |
| Retrieval | Hybrid BM25 + vector with synonym expansion, cascade retrieval, MMR diversity, auto-PRF |
| Embedding | bge-micro-v2 (384-dim, ONNX, MIT license, runs locally, concurrent inference) |
| Best recall | 0.792 realworld dataset, 0.771 scale dataset (hybrid mode) |
| Search latency | ~2.7 ms production, ~0.04 ms benchmark |
| Storage | JSON (default) or SQLite (WAL mode) |
| Frameworks | net8.0, net9.0, net10.0 |
| Tests | Multi-target xUnit suite across net8.0, net9.0, and net10.0 |
| CI/CD | GitHub Actions: build + test on push, nightly MSA benchmarks |
Tool Profiles
Engram exposes a tunable tool surface. Start on minimal — three headline verbs (remember, recall, reflect) plus admin and multi-agent — and widen only if you need the advanced subsystems. Control it with MEMORY_TOOL_PROFILE:
| Profile | Tools | What's included |
|---|---|---|
minimal |
17 | Core CRUD + composite + admin + multi-agent — recommended starting point (default) |
standard |
39 | Adds graph (+auto-link), lifecycle (+consolidation), clustering, intelligence, memory-diffusion kernel, spectral retrieval |
full |
63 | Everything including governed knowledge promotion, expert routing, debate, synthesis, benchmarks |
MCP Tools (63)
| Group | Tools | Description |
|---|---|---|
| Core Memory | store_memory, store_batch, search_memory, delete_memory |
Vector CRUD with namespace isolation, batch import, and lifecycle-aware search |
| Composite | remember, recall (with spectralMode), reflect, get_context_block |
High-level wrappers with auto-dedup, auto-linking, expert routing, context assembly, and graph-aware spectral re-ranking on recall (default auto) |
| Knowledge Graph | link_memories, unlink_memories, get_neighbors, traverse_graph |
Directed graph with 7 relation types and multi-hop BFS; similarity-based auto-link densification runs as a 6-hour background sweep |
| Clustering | create_cluster, update_cluster, store_cluster_summary, get_cluster, list_clusters |
Semantic grouping with auto-computed centroids |
| Lifecycle | promote_memory, memory_feedback, deep_recall, configure_decay |
State transitions (STM/LTM/archived) and per-namespace decay configuration; spectral decay diffusion and sleep consolidation run automatically as background services |
| Memory Diffusion | compute_diffusion_basis, diffusion_stats, invalidate_diffusion, spectral_recall |
Graph-Laplacian eigenbasis primitive shared by decay, consolidation, and retrieval; standalone graph-aware retrieval |
| Intelligence | detect_duplicates, find_contradictions, merge_memories, uncollapse_cluster, list_collapse_history |
Dedup, contradiction detection, merge, collapse reversal |
| Expert Routing | dispatch_task, create_expert, get_domain_tree, link_to_parent |
HMoE semantic routing with 3-level domain tree |
| Multi-Agent | cross_search, share_namespace, unshare_namespace, list_shared, whoami |
Namespace sharing, permissions, cross-namespace RRF search |
| Debate | consult_expert_panel, map_debate_graph, resolve_debate |
Multi-perspective analysis with debate tracking |
| Synthesis | synthesize_memories |
Map-reduce synthesis via a local SLM served by Ollama. For fully in-process generation, embed McpEngramMemory.Core and add the optional McpEngramMemory.Synthesis.Onnx package |
| Accretion | get_pending_collapses, collapse_cluster, dismiss_collapse |
DBSCAN cluster detection and two-phase summarization (the density scan runs as a 30-min background sweep) |
| Governed Learning | promote_knowledge |
Full-profile adapter for the Teacher → deterministic Verifier → Constitution receipt → atomic governed-store promotion path |
| Admin | get_memory, cognitive_stats, engram_status, purge_debates |
Inspection, system-wide statistics, background-worker health, and stale debate-namespace cleanup |
| Maintenance | rebuild_embeddings, compression_stats |
Re-embed entries and storage diagnostics |
| Benchmarks | run_benchmark, run_agent_outcome_benchmark, run_live_agent_outcome_benchmark, compare_live_agent_outcome_artifacts, check_for_regression, get_metrics, reset_metrics, run_mrcr_benchmark, compare_mrcr_artifacts |
IR quality validation, proxy and live memory-condition benchmarking, artifact diffing, CI regression gating, latency/throughput metrics, and MRCR v2 long-context A/B |
| Visualization | get_graph_snapshot |
Memory-graph JSON snapshot (nodes, typed edges, clusters) for the built-in D3 viewer (visualization/memory-graph.html) |
Full tool documentation: MCP Tools Reference
The server uses the ModelContextProtocol 2.2.0 SDK with negotiated protocol handling, a global
request-filter pipeline, and explicit read-only/destructive/idempotent/open-world tool metadata.
SDK package version and negotiated MCP protocol revision are not the same thing.
Architecture
| Layer | Stability | Components |
|---|---|---|
| Core | Stable | Storage, Embeddings, Retrieval, Lifecycle, Graph |
| Advanced | Stable | Clustering, Multi-Agent Sharing, Intelligence |
| Governed Core | Maturing | Constitution, Knowledge, Provenance, Learning, Planning, Semantic Assets |
| Orchestration | Maturing | Expert Routing (HMoE), Debate, Benchmarks |
Governed Core vs. MCP tools
The governed substrate lives in McpEngramMemory.Core: immutable Root/overlay Constitutions,
versioned Knowledge and append-only Provenance, quarantined Teacher proposals, deterministic-first
verification, atomic reference promotion, authorization-first retrieval planning, context manifests,
profiles/loadouts, and Skill/Documentation/CodeGraph/Curriculum contracts.
The 63 MCP tools include the full-profile promote_knowledge adapter, which executes the
Teacher → deterministic Verifier → Constitution receipt → atomic governed-store path. Context and
other asset-management tools remain Core APIs for embedded hosts. Every tool call also passes through
the global Constitution pre/post filter. Skill execution is
delegated to a host-provided ISkillSandbox; Engram does not run arbitrary Skill code.
Identity is also host-owned. IPrincipalContext carries tenant and principal claims. The stdio
server bootstraps it from MEMORY_TENANT_ID and AGENT_ID, which are process configuration rather
than authentication. Empty tenant + default agent is explicit legacy-unisolated mode.
Multi-tenancy is complete and, as of 2.0, mandatory at the API boundary. Memory CRUD and search,
the cognitive graph, clusters, lifecycle, collapse history, diffusion/spectral retrieval,
intelligence, maintenance, synthesis, and visualization are all tenant-partitioned: a tenant sees
and mutates only its own data, and graph edges never cross tenants (cross-namespace association
within a tenant is preserved). Core's retrieval and scoping APIs take tenantId as a required
argument, so scope is a decision the compiler makes you state rather than a default you can forget —
"" remains a valid answer, and the legacy partition it names is a real dataset, so state it
deliberately. Legacy empty-tenant deployments are byte-for-byte unchanged. See
Cognitive Constitution and Governed Core and Security.
AI Assistant Setup
Model execution belongs to the host harness, not the Engram server: expert profiles route to persona-backed memory namespaces, while the host model reasons over the retrieved evidence. See Model and Reasoning Routing for canonical task tiers, the current Codex model mapping, reasoning escalation rules, and ready-to-use profiles.
Copy the reference harness for your tool — each includes recall/store/routing patterns:
| Tool | Harness File | MCP Config |
|---|---|---|
| Claude Code | examples/CLAUDE.md → ~/.claude/CLAUDE.md |
examples/claude-code.json |
| GitHub Copilot | examples/copilot-instructions.md → .github/ |
examples/vscode-copilot.json |
| Google Gemini | GEMINI.md → workspace root |
Gemini CLI config |
| OpenAI Codex | examples/AGENTS.md → project root |
Codex config |
Claude Code users: Route memory sub-agents to Sonnet (
model: "sonnet") and utility sub-agents to Haiku (model: "haiku") to maximize your subscription. See the harness for details.
For step-by-step setup prompts, see AI Assistant Setup.
Cost-Optimized Usage (Claude Code)
| Tier | Model | What runs here |
|---|---|---|
| Main thread | Opus | Coding, architecture, reasoning, decisions |
| Memory sub-agents | Sonnet (model: "sonnet") |
All engram MCP tool calls: search, store, dispatch, link, merge |
| Utility sub-agents | Haiku (model: "haiku") |
Codebase exploration, file searches, grep research, simple lookups |
Opus thinks, Sonnet remembers, Haiku explores.
Environment Variables
| Variable | Default | Description |
|---|---|---|
MEMORY_TOOL_PROFILE |
minimal |
Tool profile: minimal (17), standard (39), full (63) |
AGENT_ID |
default |
Host-supplied agent identity for namespace sharing. The default is explicit legacy-unisolated compatibility mode, not authentication. |
MEMORY_TENANT_ID |
empty | Host-supplied tenant partition. Do not accept this value from model/tool arguments. Empty selects the legacy partition. |
MEMORY_STORAGE |
json |
Storage backend: json, sqlite, or sqlserver |
MEMORY_SQLITE_PATH |
data/memory.db |
SQLite database path (when MEMORY_STORAGE=sqlite) |
MEMORY_SQLSERVER_CONNECTION |
required | SQL Server connection string (when MEMORY_STORAGE=sqlserver) |
MEMORY_SQLSERVER_SCHEMA |
dbo |
SQL Server schema name (when MEMORY_STORAGE=sqlserver) |
MEMORY_MAX_NAMESPACE_SIZE |
unlimited | Max entries per namespace |
MEMORY_MAX_TOTAL_COUNT |
unlimited | Max total entries across all namespaces |
NuGet / GitHub Packages
The server ships as a dotnet global tool, and the core engine as a library you can embed in your
own .NET applications.
Server (global tool)
dotnet tool install --global McpEngramMemory --version 2.0.0
engram-memory
Core engine (library)
# nuget.org
dotnet add package McpEngramMemory.Core --version 2.0.0
# GitHub Packages
dotnet add package McpEngramMemory.Core --version 2.0.0 \
--source https://nuget.pkg.github.com/wyckit/index.json
Optional: in-process synthesis
synthesize_memories generates through an ITextGenerator. The server ships one implementation —
OllamaClient, talking to a local Ollama daemon. If you want generation fully in-process with no
daemon, add the optional ONNX backend when embedding the library:
dotnet add package McpEngramMemory.Synthesis.Onnx --version 2.0.0
using McpEngramMemory.Core.Services.Synthesis;
ITextGenerator generator = new OnnxGenAiTextGenerator(modelDir); // stage a model first
It lives in its own package because ONNX Runtime GenAI ships native binaries for every platform it
supports — roughly 500 MB. Keeping it separate means neither the McpEngramMemory tool nor a plain
McpEngramMemory.Core install pays that cost. Stage a model with
scripts/fetch-synthesis-model.ps1.
The
McpEngramMemoryserver does not supportSYNTHESIS_BACKEND=onnx; it fails at startup with a pointer to this package. In-process synthesis is for hosts embedding the Core library.
using McpEngramMemory.Core.Models;
using McpEngramMemory.Core.Services;
using McpEngramMemory.Core.Services.Storage;
var persistence = new PersistenceManager();
var embedding = new OnnxEmbeddingService();
var index = new CognitiveIndex(persistence);
// "" is the legacy (single-tenant) partition. Pass a real tenant id to isolate.
const string tenant = "";
// Store
var vector = embedding.Embed("The capital of France is Paris");
var entry = new CognitiveEntry(
"fact-1", vector, "default", "The capital of France is Paris", "facts", tenantId: tenant);
index.Upsert(entry);
// Search — tenantId is required as of 2.0
var results = index.Search(embedding.Embed("French capital"), "default", tenant, k: 5);
Documentation
| Doc | Description |
|---|---|
| First 5 Minutes | Store, close, recall — the whole loop |
| Cheat Sheet | One-page quick reference |
| MCP Tools Reference | Full documentation for all 63 tools |
| Architecture | System design, retrieval pipeline, data flow |
| Cognitive Constitution | Governed Core boundary, knowledge/provenance, learning, planning, assets, persistence, and current tenant limits |
| Services | All services with descriptions |
| Internals | Retrieval, quantization, persistence deep dive |
| Project Structure | File tree and module organization |
| AI Assistant Setup | Step-by-step setup prompts for each tool |
| Sample Prompts | Power prompts and usage patterns |
| Benchmarks | IR quality results and mode selection guide |
| MRCR v2 Benchmark | Long-context A/B (full context vs. hybrid retrieval) via Claude CLI subscription |
| Testing | Test coverage breakdown and current CI coverage |
| 2.0.0 Release Notes | What changed in 2.0, why it is major, and how to migrate an embedding host |
| Tenant Isolation Design | Partitioning model, guarantees, and the 2.0 required-tenantId boundary |
| Changelog | Full release history |
Build & Test
cd mcp-engram-memory
dotnet build
dotnet test # full suite, including slower MSA benchmark cases
Tech Stack
- .NET 8/9/10, C#
- ModelContextProtocol 2.2.0
- FastBertTokenizer 1.0.28
- Microsoft.ML.OnnxRuntime 1.29.0
- bge-micro-v2 ONNX (384-dim, MIT license)
- Microsoft.Data.Sqlite 10.0.11
- xUnit v3 (tests)
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- McpEngramMemory.Core (>= 2.0.0)
- Microsoft.ML.OnnxRuntime (>= 1.29.0)
- Microsoft.ML.OnnxRuntimeGenAI (>= 0.15.2)
-
net8.0
- McpEngramMemory.Core (>= 2.0.0)
- Microsoft.ML.OnnxRuntime (>= 1.29.0)
- Microsoft.ML.OnnxRuntimeGenAI (>= 0.15.2)
-
net9.0
- McpEngramMemory.Core (>= 2.0.0)
- Microsoft.ML.OnnxRuntime (>= 1.29.0)
- Microsoft.ML.OnnxRuntimeGenAI (>= 0.15.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
2.0.0 is a breaking release for hosts embedding McpEngramMemory.Core: tenantId is now a required argument on 55 Core retrieval and scoping APIs. The MCP tool surface and on-disk data are unchanged. Release notes: https://github.com/wyckit/mcp-engram-memory/blob/main/docs/release-notes-2.0.0.md