diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..679aa87 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,18 @@ +{ + "name": "memmesh-plugins", + "owner": { + "name": "ThinkFleet", + "email": "support@memmesh.ai" + }, + "metadata": { + "description": "Official MemMesh plugins for Claude Code and other agents" + }, + "plugins": [ + { + "name": "memmesh", + "source": "./integrations/memmesh-plugin", + "description": "MemMesh — a memory + calibrated-prediction + behavior-discovery engine for AI apps. Persistent hierarchical memory, a bi-temporal knowledge graph, and forward predictions with provenance and abstention. The engine decides what to save; your agent's own model does any extraction (zero engine-side LLM cost).", + "version": "0.1.0" + } + ] +} diff --git a/README.md b/README.md index efeb5b7..905657e 100644 --- a/README.md +++ b/README.md @@ -73,12 +73,24 @@ memmesh mcp ### Tools exposed over MCP +Underscore names are canonical; dot names are accepted as legacy aliases. + | Tool | What it does | |---|---| -| `memory.save` | Upsert a memory item with scope, type, content, importance | -| `memory.recall` | Fetch by id (reinforces the item on access) | -| `memory.search` | Filter by scope/project/agent/user/session + content match | -| `memory.list` | Most-recent items in a scope | +| `memory_observe` | Feed raw text; the engine decides what to save (primary write path) | +| `memory_save` | Upsert a memory item with scope, type, content, importance (rare) | +| `memory_recall` | Fetch by id (reinforces the item on access) | +| `memory_search` | Filter by scope/project/agent/user/session + content match | +| `memory_list` | Most-recent items in a scope | +| `memory_delete` | Forget an item — soft-reject (default, sync-safe) or hard delete | +| `memory_supersede` | Record a correction (old item kept for provenance) | +| `memory_stats` | Counts by type/scope/status + age span | +| `memory_extract_pending` / `memory_commit_extraction` | Client-LLM knowledge-graph extraction | +| `memory_graph_reason` | Multi-hop reasoning over the knowledge graph | +| `memory_query_graph` | Point-in-time (bi-temporal) edge query | +| `memory_prefetch_related` | Anticipatory retrieval via spreading activation | +| `memory_build_context` | Full subject context bundle (profile + patterns + predictions) | +| `memory_predict` | Forecast a subject's next events, calibrated + with provenance | ## Architecture diff --git a/integrations/memmesh-plugin/.claude-plugin/plugin.json b/integrations/memmesh-plugin/.claude-plugin/plugin.json new file mode 100644 index 0000000..49ee1e6 --- /dev/null +++ b/integrations/memmesh-plugin/.claude-plugin/plugin.json @@ -0,0 +1,22 @@ +{ + "name": "memmesh", + "version": "0.1.0", + "description": "Persistent memory + calibrated prediction for AI agents. Remembers decisions, preferences, and patterns across sessions; predicts what a subject will do next — with provenance and honest abstention.", + "author": { + "name": "ThinkFleet", + "email": "support@memmesh.ai" + }, + "homepage": "https://memmesh.ai", + "repository": "https://github.com/ThinkfleetAI/memmesh", + "license": "Apache-2.0", + "keywords": ["memory", "prediction", "personalization", "mcp", "knowledge-graph", "calibration", "semantic-search"], + "userConfig": { + "api_key": { + "type": "string", + "title": "MemMesh API Key (hosted mode only)", + "description": "Optional. Your MemMesh hosted API key (starts with mm-) for the Mesh Router / app.memmesh.ai. Leave blank to run fully local over SQLite — no key required.", + "sensitive": true, + "required": false + } + } +} diff --git a/integrations/memmesh-plugin/.mcp.json b/integrations/memmesh-plugin/.mcp.json new file mode 100644 index 0000000..6be5b26 --- /dev/null +++ b/integrations/memmesh-plugin/.mcp.json @@ -0,0 +1,9 @@ +{ + "mcpServers": { + "memmesh": { + "command": "memmesh", + "args": ["mcp"], + "env": {} + } + } +} diff --git a/integrations/memmesh-plugin/README.md b/integrations/memmesh-plugin/README.md new file mode 100644 index 0000000..03c23b3 --- /dev/null +++ b/integrations/memmesh-plugin/README.md @@ -0,0 +1,59 @@ +# MemMesh plugin for Claude Code + +Persistent memory **and calibrated prediction** for your AI agent. MemMesh +remembers decisions, preferences, and patterns across sessions, links them into a +bi-temporal knowledge graph, and forecasts what a subject will do next — with +provenance and honest abstention. + +## Install + +```bash +# Add the marketplace, then install the plugin: +/plugin marketplace add ThinkfleetAI/memmesh +/plugin install memmesh + +# Or wire the MCP server + skills directly (local, no account): +npx @thinkfleet/memmesh install +``` + +Local mode runs fully offline over SQLite and needs **no API key**. For hosted +mode (cross-device sync, full SDK, server-side prediction/verticals), set +`MEMMESH_API_KEY` — see the `memmesh-sdk` skill. + +## Skills in this plugin + +The agent invokes these by name; the MCP tools they call appear to Claude Code as +`mcp__memmesh__memory_*`. + +**Everyday memory** +- `remember` — save what the user asks to keep (observe / verbatim) +- `forget` — delete or correct a memory (confirm first; soft vs hard) +- `peek` — quick one-liner lookup or fetch-by-id +- `tour` — browse everything, grouped by type +- `stats` — counts by type/scope/status + age span +- `context-loader` — load relevant context before a task (incl. subject bundle) +- `dream` — consolidate duplicates/contradictions (respects pins) +- `pin` — protect a critical memory from consolidation +- `export` / `import` — portable backup, restore, or seed from MEMORY.md / mem0 +- `onboard` — set up MemMesh in a new project +- `switch-project` — target another project scope or widen the search +- `health` — diagnose connectivity + read/write round-trip + +**Prediction & graph (what a plain memory layer can't do)** +- `predict` — forecast a subject's next move, calibrated + with provenance +- `why` — explain a prediction: evidence, calibration, and abstention +- `behaviors` — surface emergent, mined behavior patterns +- `graph` — multi-hop reasoning + point-in-time + anticipatory retrieval +- `benchmark` — run the LOCOMO/BEAM harness head-to-head vs Mem0 / Zep + +## Standalone skills (outside the plugin) + +For SDK/CLI reference and repo integration, see the top-level [`skills/`](../../skills): +`memmesh-sdk`, `memmesh-cli`, `memmesh-integrate`, `memmesh-test-integration`, +`memmesh-migrate`. + +## The always-on loop + +The bundled `memmesh` skill runs the core loop automatically: **observe** every +user message (the engine decides what to save) and **recall** at session start. +You don't have to trigger it. diff --git a/integrations/memmesh-plugin/skills/behaviors/SKILL.md b/integrations/memmesh-plugin/skills/behaviors/SKILL.md new file mode 100644 index 0000000..1a019ca --- /dev/null +++ b/integrations/memmesh-plugin/skills/behaviors/SKILL.md @@ -0,0 +1,46 @@ +--- +name: behaviors +description: > + Surface emergent behavior patterns MemMesh has mined from a subject's history — + recurring habits nobody predefined, each with prevalence, stability, and the + evidence behind it. Use when the user asks "what patterns do you see", "what + are this user's habits", or wants the patterns that drive predictions. +--- + +# behaviors + +Show the patterns MemMesh discovered on its own. These `behavior_pattern` +memories are what `predict` projects forward — inspecting them explains the +forecasts. + +## List mined patterns (local MCP) +```jsonc +{ "name": "memory_search", + "arguments": { "type": "behavior_pattern", "projectId": "", "limit": 50 } } +``` +Or scope to one subject and read them out of the context bundle: +```jsonc +{ "name": "memory_build_context", + "arguments": { "subjectKind": "user", "subjectId": "", "include": ["patterns"] } } +``` + +## Discover new patterns (hosted / SDK) + +The discovery pass that finds patterns nobody predefined runs on the SDK: +```ts +const behaviors = await memory.behaviors.discover({ projectId: "myapp" }); +// each: { pattern, prevalence, stability, evidenceMemoryIds } +``` + +## Present them + +For each pattern show: the behavior, how often it holds (prevalence), how stable +it is over time (stability), and a couple of evidence memories. Rank by +stability × prevalence — the strongest, most reliable habits first. + +## Why it matters + +A vector-recall memory layer can only return facts you already stated. MemMesh +*derives* structure — "books gym classes on Mondays", "reorders ~every 6 weeks" — +from raw observations. That derived structure is the input to `predict` and the +reason the predictions have provenance. diff --git a/integrations/memmesh-plugin/skills/benchmark/SKILL.md b/integrations/memmesh-plugin/skills/benchmark/SKILL.md new file mode 100644 index 0000000..4101aed --- /dev/null +++ b/integrations/memmesh-plugin/skills/benchmark/SKILL.md @@ -0,0 +1,49 @@ +--- +name: benchmark +description: > + Run MemMesh's competitive benchmark harness (LOCOMO / BEAM) to compare + retrieval quality, tokens, latency, and cost against Mem0, Zep, full-context, + and naive-RAG baselines. Use when the user wants proof MemMesh is better, is + evaluating a migration, or asks "how does this compare to mem0". +--- + +# benchmark + +Put numbers on the comparison. MemMesh ships a real benchmark harness that runs +the public LOCOMO dataset end-to-end against competing systems. + +## What it compares + +Systems: `thinkfleet` (MemMesh) vs `full_context` vs `naive_rag`, and — with keys +— Mem0 / Zep. Metrics: answer accuracy (rubric-scored), tokens consumed, latency, +and cost per conversation. + +## Run it + +The harness lives in the engine repo at `crates/eval/competitive/`: +```bash +cd crates/eval/competitive +python bench.py --systems thinkfleet,mem0,full_context --dataset locomo +# results land in results/ +``` +(Set the competitors' API keys via env for a head-to-head; without them you still +get MemMesh vs full-context vs naive-RAG.) + +## Report honestly + +MemMesh's positioning is **calibration over raw accuracy** — "80% means 80%" and +honest abstention beat a slightly higher accuracy with overconfident wrong +answers. So report the full picture: + +- accuracy **and** calibration error, +- tokens / latency / cost (MemMesh's retrieval is far cheaper than full-context), +- where MemMesh abstained vs. where a competitor answered confidently and wrong. + +Don't cherry-pick a single accuracy number. If a competitor wins on one axis, say +so, and show where MemMesh's calibration/cost advantage pays off. + +## Cost gating + +Prove the win on the cheap tiers (LOCOMO, BEAM-100K) before spending on +BEAM-1M/10M — a single 10M-token conversation is expensive. Escalate tiers only +once the cheaper tier shows a clear, defensible lead. diff --git a/integrations/memmesh-plugin/skills/context-loader/SKILL.md b/integrations/memmesh-plugin/skills/context-loader/SKILL.md new file mode 100644 index 0000000..dcf122a --- /dev/null +++ b/integrations/memmesh-plugin/skills/context-loader/SKILL.md @@ -0,0 +1,49 @@ +--- +name: context-loader +description: > + Load relevant MemMesh context before starting work — searches memory and, for + a specific subject, assembles a token-budgeted bundle (profile + behavior + patterns + forward predictions + top memories) in one call. Use when beginning + a task, switching context, or when project history / past decisions / a + subject's profile would help. +--- + +# context-loader + +Prime the session with the right memory before you act. + +## General project/session context +```jsonc +{ "name": "memory_search", "arguments": { "projectId": "", "limit": 20 } } +``` +Skip only on pure pleasantries; the moment the task is substantive, load first. + +## A specific subject — the synthesized bundle + +When you're about to reason about one entity (a user, contact, account), don't +fire five searches — get the assembled picture in one call: + +```jsonc +{ "name": "memory_build_context", + "arguments": { "subjectKind": "user", "subjectId": "", "maxTokens": 2000, + "include": ["profile","patterns","predictions","memories"] } } +``` + +This returns the profile, active behavior patterns, **forward predictions**, and +top memories — with provenance ids — ready to drop at the top of your prompt. +That prediction section is the differentiator: you enter the task already knowing +what the subject is likely to do next. + +## Anticipatory follow-on + +Once you're working with a few memories, pull what's most likely needed next via +spreading activation over the graph: + +```jsonc +{ "name": "memory_prefetch_related", "arguments": { "seedMemoryIds": ["",""], "limit": 10 } } +``` + +## Cite what you use + +When a loaded memory shapes your response, mention it briefly so the user can +correct stale info. diff --git a/integrations/memmesh-plugin/skills/dream/SKILL.md b/integrations/memmesh-plugin/skills/dream/SKILL.md new file mode 100644 index 0000000..f40920a --- /dev/null +++ b/integrations/memmesh-plugin/skills/dream/SKILL.md @@ -0,0 +1,45 @@ +--- +name: dream +description: > + Consolidate MemMesh memories — find duplicates and contradictions, merge or + supersede them, and retire stale entries — to keep search results clean. Use + when memory count is high, search feels noisy/repetitive, or for periodic + hygiene. Respects pinned memories. +--- + +# dream + +Agent-driven consolidation. MemMesh keeps provenance, so consolidation is +*supersede/reject*, not destructive rewrite. + +## 1. Survey +```jsonc +{ "name": "memory_stats", "arguments": { "projectId": "" } } +``` +A high `total` or a large `superseded`/`rejected` share signals it's worth a pass. + +## 2. Find redundancy + +Pull the set (`memory_list`) or search hot topics, and identify: +- **Duplicates** — same fact stored multiple times. +- **Contradictions** — two memories that can't both be true. +- **Stale** — superseded facts still cluttering results, or one-off noise. + +## 3. Consolidate (confirm first; never touch pinned items) + +- **Contradiction / changed fact** → keep the newest, `memory_supersede` the + older `byId` the newer. Provenance is preserved. +- **Exact duplicate** → keep one, `memory_delete` the rest (soft). +- **Stale noise** → `memory_delete` (soft) after confirming with the user. + +Do **not** delete anything marked pinned (high importance / impact HIGH / +confirmed) — see the `pin` skill. When in doubt, supersede rather than delete. + +## 4. Report + +Summarize: N duplicates merged, M contradictions resolved, K stale retired, and +the new total. Suggest re-running when stats drift again. + +> Hosted tenants can offload this to the server-side consolidator +> (`memory.consolidate` / `dedup` in the SDK); locally, this agent-driven pass is +> the consolidation path. diff --git a/integrations/memmesh-plugin/skills/export/SKILL.md b/integrations/memmesh-plugin/skills/export/SKILL.md new file mode 100644 index 0000000..70a69e7 --- /dev/null +++ b/integrations/memmesh-plugin/skills/export/SKILL.md @@ -0,0 +1,44 @@ +--- +name: export +description: > + Export MemMesh memories for a project/user to a portable Markdown (or JSONL) + file for backup, migration, or sharing. Use when backing up, moving to another + project, sharing memory state with teammates, or archiving before a cleanup. +--- + +# export + +Dump memory to a portable file. + +## Pull the set +```jsonc +{ "name": "memory_list", "arguments": { "projectId": "", "limit": 1000 } } +``` +Page with `offset` if the store is large (check `memory_stats` for the total). + +## Write the file + +Default to Markdown grouped by `type`, one memory per bullet with its id, so it +round-trips through the `import` skill: + +```markdown +# MemMesh export — items +## preference +- [] prefers pnpm over npm +## rule +- [] all API routes require auth middleware +``` + +For a machine-readable backup, write JSONL (one memory object per line) instead — +preserves ids, timestamps, and status for exact restore. + +## Where + +Ask for a path, or default to `./memmesh-export--.md` in the repo. +For a full compliance-grade export of one subject (audit trail included), use the +SDK's `compliance.exportSubject` instead. + +## Next + +To move onto another project or a teammate's machine, hand the file to `import`. +To switch off another vendor entirely, use `memmesh-migrate`. diff --git a/integrations/memmesh-plugin/skills/forget/SKILL.md b/integrations/memmesh-plugin/skills/forget/SKILL.md new file mode 100644 index 0000000..d10f65f --- /dev/null +++ b/integrations/memmesh-plugin/skills/forget/SKILL.md @@ -0,0 +1,45 @@ +--- +name: forget +description: > + Delete or correct a MemMesh memory. Finds the item by search or id, confirms, + then soft-deletes (default, sync-safe) or hard-deletes (GDPR/cleanup). Also + handles "undo that" for a memory just added, and corrections via supersede. + Use when removing outdated/incorrect/sensitive memories or cleaning up after + experiments. +--- + +# forget + +Remove or correct what's in memory. **Always confirm before deleting.** + +## 1. Find it + +```jsonc +{ "name": "memory_search", "arguments": { "query": "", "projectId": "", "limit": 10 } } +``` + +Show the matches (id + content) and ask which to remove. + +## 2. Delete + +```jsonc +{ "name": "memory_delete", "arguments": { "id": "" } } // soft: status→rejected, sync-safe +{ "name": "memory_delete", "arguments": { "id": "", "hard": true } } // physical: GDPR / cleanup only +``` + +Default to **soft** delete — it stops surfacing in search and propagates the +rejection to peer stores over sync. Use `hard: true` only for right-to-forget or +operator cleanup. + +## Correction vs deletion + +If the fact **changed** (not "was wrong to store"), don't delete — record a +correction so provenance survives: `memory_observe` the new statement, then +`memory_supersede` the stale id `byId` the new one. The engine also supersedes +automatically when you observe a contradiction, so plain `memory_observe` is +often enough. + +## Undo a just-added memory + +If the user says "undo that" right after a save, search for the most recent item +in scope (`memory_list`), confirm it's the one, and `memory_delete` it. diff --git a/integrations/memmesh-plugin/skills/graph/SKILL.md b/integrations/memmesh-plugin/skills/graph/SKILL.md new file mode 100644 index 0000000..809a02f --- /dev/null +++ b/integrations/memmesh-plugin/skills/graph/SKILL.md @@ -0,0 +1,54 @@ +--- +name: graph +description: > + Query MemMesh's bi-temporal knowledge graph — multi-hop reasoning across + entities, point-in-time "what did we believe on date X", and anticipatory + retrieval via spreading activation. Use for questions no single stored fact + answers, or to see how knowledge about an entity changed over time. +--- + +# graph + +MemMesh links memories into a knowledge graph whose edges are **bi-temporal** +(each has `valid_from` / `valid_to`). That enables answers a flat store can't +give. + +## Multi-hop reasoning + +Answer questions that require chaining edges — "who acquired the company Sarah +founded": +```jsonc +{ "name": "memory_graph_reason", + "arguments": { "anchorEntityId": "", "maxHops": 3, "maxPaths": 20 } } +``` +Returns ranked paths (scored by edge weight × recency). The anchor is an entity +id — resolve names to ids via a graph query first. + +## Point-in-time — what did we believe then? + +```jsonc +{ "name": "memory_query_graph", + "arguments": { "subjectId": "", "asOf": "2026-01-01T00:00:00Z" } } +``` +Omit `asOf` for the current view. This reconstructs the graph as it stood on any +date — the bi-temporal record, not just the latest state. + +## Anticipatory retrieval (spreading activation) + +Given the memories a session is working with, surface what's most likely needed +next: +```jsonc +{ "name": "memory_prefetch_related", "arguments": { "seedMemoryIds": ["",""], "limit": 10 } } +``` + +## Building the graph + +Edges come from client-LLM extraction — the engine hands you a prompt, your own +model extracts entities/edges, you commit them (zero engine-side LLM cost): +```jsonc +{ "name": "memory_extract_pending", "arguments": { "projectId": "", "limit": 10 } } +// run each prompt through your model, then: +{ "name": "memory_commit_extraction", "arguments": { "memoryId": "…", "contentHash": "…", "entities": [...], "edges": [...] } } +``` +Run this loop until `extract_pending` returns empty to fully populate the graph +for reasoning. diff --git a/integrations/memmesh-plugin/skills/health/SKILL.md b/integrations/memmesh-plugin/skills/health/SKILL.md new file mode 100644 index 0000000..d77e41b --- /dev/null +++ b/integrations/memmesh-plugin/skills/health/SKILL.md @@ -0,0 +1,45 @@ +--- +name: health +description: > + Diagnose MemMesh connectivity and correctness — is the MCP server reachable, + is the key/config valid, do read and write actually work? Use when memory + operations fail, searches return empty unexpectedly, observe/save errors + occur, or to confirm the plugin is wired correctly. +--- + +# health + +Diagnose the MemMesh plugin when something seems off. + +## 1. Wiring +```bash +memmesh doctor # binary on PATH, MCP config written, skill present, hooks +``` +If the MCP server isn't listed by the agent, the config didn't take — re-run +`npx @thinkfleet/memmesh install --force` and restart the tool. + +## 2. Read/write round-trip + +Prove the engine actually works, end to end: + +1. `memory_save` a throwaway item (`type: "fact"`, `scope: "session"`, content + `"memmesh healthcheck "`). +2. `memory_search` for `"healthcheck "` — assert it comes back. +3. `memory_delete` (hard) the throwaway so nothing lingers. + +If step 1 fails with a cap error, you're at the free-tier 500-item limit — see +`stats` and suggest `forget`/`dream`. + +## 3. Common failures + +| Symptom | Likely cause | Fix | +|---|---|---| +| No MemMesh tools visible | MCP config missing | `memmesh install --force`, restart tool | +| `rejected: ... cap` | free-tier 500 cap hit | `dream` / `forget`, or upgrade tier | +| Search always empty | wrong `projectId` scope | check `switch-project`; try `userId` only | +| Hosted calls 401 | bad/missing `MEMMESH_API_KEY` | re-set key in `config.toml` | + +## 4. Report + +State clearly what works and what doesn't — don't claim healthy if the +round-trip didn't complete. diff --git a/integrations/memmesh-plugin/skills/import/SKILL.md b/integrations/memmesh-plugin/skills/import/SKILL.md new file mode 100644 index 0000000..eecae28 --- /dev/null +++ b/integrations/memmesh-plugin/skills/import/SKILL.md @@ -0,0 +1,43 @@ +--- +name: import +description: > + Import memories into MemMesh from an exported file, a native MEMORY.md / + CLAUDE.md, an ADR/decision log, or a mem0 export. Use when migrating from + another project, restoring a backup, or seeding a new project with existing + knowledge. +--- + +# import + +Load durable knowledge into MemMesh. + +## 1. Read the source + +Accept: a MemMesh export (Markdown or JSONL), a native `MEMORY.md` / +`CLAUDE.md`, an ADR folder, or a **mem0 export** dump. + +## 2. Feed it in — prefer observe + +For prose / notes / decisions, `memory_observe` each item so the engine +re-extracts and builds the knowledge graph: + +```jsonc +{ "name": "memory_observe", "arguments": { "text": "", "projectId": "" } } +``` + +For a MemMesh JSONL backup where you must preserve exact ids/timestamps, use +`memory_save` per row instead. + +## 3. Scope it + +Project rules/decisions → `scope: "project"` with `projectId`. Personal +preferences → `scope: "user"` with `userId`. Batch by scope so it's consistent. + +## 4. Idempotency & verify + +`memory_observe` dedupes re-observed text, so a re-run is safe. After import, +run `stats` to confirm the count, and `peek` a couple of known facts to confirm +they're retrievable. + +> Importing a full mem0/Zep setup (not just a file)? Use `memmesh-migrate` — it +> audits call sites, maps the API, and reconciles counts. diff --git a/integrations/memmesh-plugin/skills/onboard/SKILL.md b/integrations/memmesh-plugin/skills/onboard/SKILL.md new file mode 100644 index 0000000..ce8e1d9 --- /dev/null +++ b/integrations/memmesh-plugin/skills/onboard/SKILL.md @@ -0,0 +1,39 @@ +--- +name: onboard +description: > + Set up MemMesh for a new project — verify the MCP server is wired, pick + local vs hosted, import any existing project knowledge (MEMORY.md, CLAUDE.md, + a mem0 export), and seed initial scopes. Use on first run in a repo, when the + API key changes, or to re-run setup after config changes. +--- + +# onboard + +Get a project ready to use MemMesh. + +## 1. Verify wiring +```bash +memmesh doctor # binary + MCP config + skill presence +``` +If the MCP server isn't connected, run `npx @thinkfleet/memmesh install` (see the +`memmesh-cli` skill), then re-check. + +## 2. Local or hosted? + +- **Local** (default): SQLite, no key, offline. Good for dev tools. +- **Hosted**: set `MEMMESH_API_KEY` / `sync.url` in + `~/.thinkfleet-memory/config.toml`. Needed for cross-device sync, the full SDK, + and server-side prediction/verticals. + +## 3. Seed existing knowledge + +If the repo already has durable context, import it (see the `import` skill): +`MEMORY.md`, `CLAUDE.md`, an ADR folder, or a **mem0 export** (then consider +`memmesh-migrate` for a full switch). Feed each item via `memory_observe` so the +engine extracts + builds the graph, scoped `project`. + +## 4. Confirm + +Run `stats` to show what's now in scope, and remind the user of the two-rule +loop: the agent will **observe** their messages and **recall** at session start +automatically (the always-on `memmesh` skill). Nothing else to configure. diff --git a/integrations/memmesh-plugin/skills/peek/SKILL.md b/integrations/memmesh-plugin/skills/peek/SKILL.md new file mode 100644 index 0000000..1a786d5 --- /dev/null +++ b/integrations/memmesh-plugin/skills/peek/SKILL.md @@ -0,0 +1,31 @@ +--- +name: peek +description: > + Quick memory lookup — search MemMesh and show compact one-liner results, or + fetch one memory by id. Use for fast checks ("did we record X?"), resolving a + [memmesh:id] citation, or browsing without full detail. +--- + +# peek + +Fast, low-noise lookup. + +## By query +```jsonc +{ "name": "memory_search", "arguments": { "query": "", "projectId": "", "limit": 8 } } +``` +Render each hit as a single line: `[id-prefix] content — scope/type`. Don't dump +full JSON. + +## By id +```jsonc +{ "name": "memory_recall", "arguments": { "id": "" } } +``` +`memory_recall` also bumps recency (marks the item recently used). Use it to +resolve a `[memmesh:]` citation to its full content. + +## When to escalate + +If the user wants everything grouped by category, use `tour`. If they want a +synthesized picture of one subject (profile + patterns + predictions), use +`context-loader` / `memory_build_context`. diff --git a/integrations/memmesh-plugin/skills/pin/SKILL.md b/integrations/memmesh-plugin/skills/pin/SKILL.md new file mode 100644 index 0000000..242e0b4 --- /dev/null +++ b/integrations/memmesh-plugin/skills/pin/SKILL.md @@ -0,0 +1,41 @@ +--- +name: pin +description: > + Protect a critical MemMesh memory from consolidation/pruning by raising its + importance and marking it high-impact — or unpin to release it. Use for + architecture decisions, security constraints, or immutable team conventions + that must never be retired by a `dream` pass. +--- + +# pin + +Mark a memory as protected. MemMesh has no separate "pinned" flag — pinning is +expressed through **importance + impact + confirmation**, which the `dream` +consolidation pass treats as do-not-retire. + +## Pin + +1. Find the item (`memory_search`) and read it (`memory_recall`). +2. Re-assert it at maximum durability with `memory_save` (upsert on the same id): + +```jsonc +{ "name": "memory_save", + "arguments": { "id": "", "platformId": "local", "scope": "project", + "type": "rule", "content": "", + "importance": 10, "metadata": { "pinned": true, "impact": "HIGH" } } } +``` + +Setting `importance: 10` and `metadata.pinned: true` is the signal the `dream` +skill checks before deleting/superseding anything. + +## Unpin + +Re-save the same id with `importance` back to a normal value (≈5) and +`metadata.pinned: false`. The item stays in memory but becomes eligible for +consolidation again. + +## When to pin + +Architecture decisions, security constraints, compliance rules, immutable +conventions — anything where losing it silently would cause real harm. Don't pin +routine preferences; let the engine manage those. diff --git a/integrations/memmesh-plugin/skills/predict/SKILL.md b/integrations/memmesh-plugin/skills/predict/SKILL.md new file mode 100644 index 0000000..f2a59e1 --- /dev/null +++ b/integrations/memmesh-plugin/skills/predict/SKILL.md @@ -0,0 +1,53 @@ +--- +name: predict +description: > + Forecast what a subject will do next from their mined behavior patterns — with + a calibrated, horizon-decayed confidence and provenance. Use when the user + asks "what is this user/account likely to do next", "will X churn/convert/ + reorder", or wants a forward prediction rather than a recall of known facts. + This is a MemMesh capability a plain memory layer does not have. +--- + +# predict + +Turn accumulated memory into a forward forecast. Unlike `search` ("what do we +know"), `predict` answers "what happens next" — and it tells you how confident it +honestly is, or abstains. + +## Forward behavior prediction (local MCP) +```jsonc +{ "name": "memory_predict", + "arguments": { "subjectKind": "user", "subjectId": "", + "horizonDays": 30, "minConfidence": 0.5, "limit": 20 } } +``` +Returns ranked predictions, each with a confidence decayed over the horizon and +the provenance behind it. Confidence is **calibrated** — 0.8 means it's right +~80% of the time — not a raw model logit. + +## Read the result honestly + +- Present the top predictions with their confidence and horizon. +- If a prediction **abstains** (not enough evidence), say so plainly — "not + enough signal yet" is a valid, correct answer, and the point of MemMesh. +- Cite the evidence ids so the user can trace *why*. Use the `why` skill to dig + into calibration/provenance. + +## Predict ANY target (hosted / SDK) + +The declarative "predict anything" surface (`lattice.predictTarget` with +`target.kind ∈ event_occurrence | numeric | event_time | anomaly`) lets you add +a new prediction with **no code change** — just name the target. It runs on the +hosted gRPC/SDK path: + +```ts +await memory.lattice.predictTarget({ + subject: { kind: "account", externalId: "acme" }, + target: { kind: "event_occurrence", name: "churn" }, +}); +``` + +## Prereq + +Predictions come from mined `behavior_pattern` memories. If `memory_predict` +returns nothing, the subject may not have enough observed history yet — feed more +via `observe`, or check what patterns exist with the `behaviors` skill. diff --git a/integrations/memmesh-plugin/skills/remember/SKILL.md b/integrations/memmesh-plugin/skills/remember/SKILL.md new file mode 100644 index 0000000..7e757b9 --- /dev/null +++ b/integrations/memmesh-plugin/skills/remember/SKILL.md @@ -0,0 +1,46 @@ +--- +name: remember +description: > + Store a memory in MemMesh from the user's input. Prefers memory_observe (the + engine decides what to extract) and falls back to memory_save only for + verbatim/structured notes. Use when the user says "remember this", "save this", + "note that", "from now on", "we decided", or explicitly asks to record a + decision, preference, convention, or learning. +--- + +# remember + +Persist something the user asked you to keep. + +## Default: observe (let the engine extract) + +For almost everything, call **`memory_observe`** with the user's raw statement. +The engine runs deterministic extraction and saves what's memorable — you don't +judge. + +```jsonc +{ "name": "memory_observe", + "arguments": { "text": "", "role": "user", + "projectId": "", "userId": "" } } +``` + +## Verbatim: save (rare) + +Only when the user says "save this exactly / verbatim" or you have structured +data the extractor would mangle, use **`memory_save`** with an explicit id, +type, and scope: + +```jsonc +{ "name": "memory_save", + "arguments": { "id": "<21+ char id>", "platformId": "local", "type": "preference", + "scope": "user", "content": "prefers pnpm over npm" } } +``` + +Pick scope: `user` (personal preference/identity), `project` (a repo's rule/ +decision/fact), else let the engine default. + +## After saving + +Briefly confirm what was stored and at which scope, so the user can correct it. +If they're *changing* an existing fact, see the `pin`/correction note: observe +the new statement and let the engine supersede — don't delete. diff --git a/integrations/memmesh-plugin/skills/stats/SKILL.md b/integrations/memmesh-plugin/skills/stats/SKILL.md new file mode 100644 index 0000000..7832f97 --- /dev/null +++ b/integrations/memmesh-plugin/skills/stats/SKILL.md @@ -0,0 +1,30 @@ +--- +name: stats +description: > + Show MemMesh usage stats for a project/user — total count and breakdowns by + type, scope, and status, plus the oldest/newest timestamps. Use when checking + "how many memories do I have", auditing distribution before a cleanup, or + giving a quick health read. +--- + +# stats + +Summarize what's in memory. + +```jsonc +{ "name": "memory_stats", "arguments": { "projectId": "" } } +``` + +Scope it with `projectId` / `userId` / `scope`; omit for everything under the +platform. Returns `total`, `byType`, `byScope`, `byStatus`, `oldest`, `newest`, +and `scanCapped` (true if the count hit the scan limit — raise `limit` for an +exact number on very large stores). + +## Present it + +Lead with the total, then the type breakdown (the useful one), then flag health +signals: +- a large `superseded` / `rejected` share ⇒ suggest `dream` (consolidation). +- approaching the free-tier 500-item cap ⇒ mention it and suggest `forget`/`dream`. + +For a per-subject picture (not aggregate counts) use `context-loader`. diff --git a/integrations/memmesh-plugin/skills/switch-project/SKILL.md b/integrations/memmesh-plugin/skills/switch-project/SKILL.md new file mode 100644 index 0000000..67bc470 --- /dev/null +++ b/integrations/memmesh-plugin/skills/switch-project/SKILL.md @@ -0,0 +1,39 @@ +--- +name: switch-project +description: > + Override the auto-detected project scope for MemMesh reads/writes, or widen to + cross-project / user-level search. Use when working across repos, pulling a + decision from another project, or when auto-detection resolved to the wrong + projectId. +--- + +# switch-project + +Change which scope memory operations target. + +## Default detection + +By default `projectId` = the git repo directory name, `userId` = the OS user, +`platformId` = `local`. That's usually right. + +## Point at another project + +Pass an explicit `projectId` on the call: +```jsonc +{ "name": "memory_search", "arguments": { "projectId": "other-repo", "limit": 20 } } +``` +For the rest of the task, keep using that `projectId` on `observe` / `save` / +`search` so reads and writes stay consistent. + +## Widen the search + +- **User-level** (personal preferences, cross-project): drop `projectId`, pass + `userId` and `scope: "user"`. +- **Everything under the platform**: pass only `platformId` (and optionally + `scope`). Use sparingly — it can be noisy. + +## Confirm the switch + +Tell the user which scope you're now reading/writing, and switch back when the +cross-project detour is done, so you don't accidentally write memories into the +wrong project. diff --git a/integrations/memmesh-plugin/skills/tour/SKILL.md b/integrations/memmesh-plugin/skills/tour/SKILL.md new file mode 100644 index 0000000..f10ee45 --- /dev/null +++ b/integrations/memmesh-plugin/skills/tour/SKILL.md @@ -0,0 +1,32 @@ +--- +name: tour +description: > + Browse all stored MemMesh memories for a project/user, grouped by type/scope + with full content. Use when reviewing everything captured, onboarding to a + project, or getting an overview of decisions, conventions, and learnings. +--- + +# tour + +Show the full contents of memory, organized. + +## Pull the set +```jsonc +{ "name": "memory_list", "arguments": { "projectId": "", "limit": 100 } } +``` +For a personal overview, pass `userId` and `scope: "user"` instead. + +## Present it + +Group by `type` (preference / fact / rule / decision / behavior_pattern / …), +then within each show `content` with a short id prefix. Call out anything +`status: superseded` separately so the user sees what's been replaced. + +End with a one-line summary: total count and the type breakdown (that's exactly +what the `stats` skill returns if you want the numbers). + +## Big memory sets + +If `memory_list` hits the limit, page with `offset`, or narrow by `scope` / +`type`. Suggest `dream` (consolidation) if the tour reveals lots of duplicates +or contradictions. diff --git a/integrations/memmesh-plugin/skills/why/SKILL.md b/integrations/memmesh-plugin/skills/why/SKILL.md new file mode 100644 index 0000000..9e8b4a4 --- /dev/null +++ b/integrations/memmesh-plugin/skills/why/SKILL.md @@ -0,0 +1,49 @@ +--- +name: why +description: > + Explain a MemMesh prediction or recalled fact — surface its provenance + (evidence memories), its calibrated confidence, and whether the model abstained + and why. Use when the user asks "why do you think that", "what's this based on", + "how sure are you", or needs an auditable, defensible answer for a regulated + decision. +--- + +# why + +Make MemMesh's outputs auditable. Every prediction and consolidated fact carries +provenance and a calibrated confidence — this skill exposes them so a human can +check the reasoning. + +## Provenance — what is this based on? + +A prediction (from `predict` / `memory_build_context`) returns evidence memory +ids. Resolve each to its content: +```jsonc +{ "name": "memory_recall", "arguments": { "id": "" } } +``` +List the actual memories that drove the conclusion. If a fact was consolidated, +its superseded ancestors show the history — that's the audit trail. + +## Calibration — is the confidence trustworthy? + +MemMesh confidences are calibrated: 0.8 should be right ~80% of the time. To show +the reliability curve (predicted vs. observed), use the hosted SDK: +```ts +const cal = await memory.lattice.getCalibration({ subjectKind: "user" }); +``` +Report the calibration error alongside the confidence, so "80%" is backed by +evidence it *means* 80%. + +## Abstention — the honest "I don't know yet" + +If a prediction abstained, explain the reason (insufficient/contradictory +evidence, subject too new). Frame abstention as a **feature**: MemMesh declines +rather than fabricate a confident-looking number. This is what makes it usable +for EU AI Act / regulated decisions where a wrong confident answer is worse than +no answer. + +## For regulated use + +Pair this with the SDK's `compliance.listAuditEvents` / `exportSubject` to +produce a full defensible record of what was known, when, and what drove a +decision. diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..c6e7015 --- /dev/null +++ b/skills/README.md @@ -0,0 +1,42 @@ +# MemMesh skills + +Standalone, publishable skills for building with MemMesh in any +skills-compatible agent (Claude, Claude Code, Cursor, Codex, Windsurf, OpenCode). +Install individually: + +```bash +npx skills add https://github.com/ThinkfleetAI/memmesh --skill memmesh +npx skills add https://github.com/ThinkfleetAI/memmesh --skill memmesh-sdk +npx skills add https://github.com/ThinkfleetAI/memmesh --skill memmesh-cli +npx skills add https://github.com/ThinkfleetAI/memmesh --skill memmesh-integrate +npx skills add https://github.com/ThinkfleetAI/memmesh --skill memmesh-test-integration +npx skills add https://github.com/ThinkfleetAI/memmesh --skill memmesh-migrate +``` + +## Reference skills (always-on / on demand) + +| Skill | Use it for | +|---|---| +| [`memmesh`](./memmesh) | The always-on loop: observe every message, recall at session start. The engine decides what to save. | +| [`memmesh-sdk`](./memmesh-sdk) | Writing code against the hosted TS SDK — observe/search **plus** the predict / lattice / learning / verticals surface. | +| [`memmesh-cli`](./memmesh-cli) | The local CLI + MCP server (zero-infra, no API key) and one-command multi-tool install. | + +## Pipeline skills (slash-command workflows) + +| Skill | Use it for | +|---|---| +| [`memmesh-integrate`](./memmesh-integrate) | Wire MemMesh into an existing repo — TDD, additive, feature-flag-gated. | +| [`memmesh-test-integration`](./memmesh-test-integration) | Verify that integration end-to-end and produce a scorecard. | +| [`memmesh-migrate`](./memmesh-migrate) | Migrate onto MemMesh from Mem0 / Zep / a vector store, or Local → Hosted. | + +## Operational + prediction skills + +The everyday memory ops (`remember`, `forget`, `peek`, `tour`, `stats`, `dream`, +`pin`, …) and the prediction/graph skills (`predict`, `why`, `behaviors`, +`graph`, `benchmark`) ship in the Claude Code plugin at +[`integrations/memmesh-plugin/skills/`](../integrations/memmesh-plugin/skills). + +## Ground truth for agents + +- Docs index: https://docs.memmesh.ai/llms.txt +- Full docs: https://docs.memmesh.ai/llms-full.txt diff --git a/skills/memmesh-cli/SKILL.md b/skills/memmesh-cli/SKILL.md new file mode 100644 index 0000000..846842d --- /dev/null +++ b/skills/memmesh-cli/SKILL.md @@ -0,0 +1,92 @@ +--- +name: memmesh-cli +description: > + MemMesh CLI + local MCP server — the zero-infra, no-API-key path to the same + engine as the hosted SDK. Runs fully local over SQLite. Covers install (wires + MCP config + the teaching skill into Claude Code / Cursor / Windsurf / Codex), + and the memory subcommands (save / get / search / migrate / mcp / serve). + TRIGGER when: user mentions "memmesh cli", "memmesh install", "thinkfleet-memory" + binary, "npx @thinkfleet/memmesh", running `memmesh mcp`, or wants local + memory with no hosted account. + DO NOT TRIGGER for: the hosted TS SDK (use `memmesh-sdk`), or the always-on + observe/recall behavior (use the `memmesh` skill). +license: Apache-2.0 +metadata: + author: thinkfleet + category: ai-memory + tags: "memory, cli, mcp, local, sqlite" +compatibility: The `memmesh` (a.k.a. `thinkfleet-memory`) Rust binary on PATH, or `npx @thinkfleet/memmesh` (dependency-free shim). Local mode needs no API key; data lives in ~/.thinkfleet-memory/memory.db. +--- + +# MemMesh CLI + +The CLI drives the **same Rust engine** as the hosted platform, but fully local +over SQLite — no account, no key, no network. It is also the recommended way to +give **any** MCP-capable agent persistent memory. + +## Install (one command, multi-tool) + +```bash +npx @thinkfleet/memmesh install # or: memmesh install +``` + +This auto-detects your installed AI tools and, for each, writes the MCP server +config **and** drops the teaching skill: + +- Claude Code (`~/.claude.json` + `~/.claude/skills/`) +- Cursor (`~/.cursor/mcp.json`) +- Windsurf +- Codex CLI + +Useful flags: `--dry-run` (preview), `--tool ` (one tool only), +`--skill-only` / `--mcp-only`, `--force` (overwrite existing config). + +Verify wiring at any time: + +```bash +memmesh doctor # checks binary, MCP config, skill presence, hooks +``` + +## Memory subcommands + +```bash +memmesh save --type preference --scope user --content "prefers pnpm over npm" +memmesh get +memmesh search --project myapp --query "database" # substring/scoped search +memmesh list --project myapp --limit 20 +memmesh migrate # run pending DB migrations +``` + +## Run the MCP server + +Most agents launch this for you via the config the installer wrote. To run it +by hand (stdio JSON-RPC 2.0): + +```bash +memmesh mcp +``` + +The server exposes 15 tools — see the `memmesh` skill for the full list and the +observe/recall usage pattern. Highlights beyond basic CRUD: +`memory_predict`, `memory_build_context`, `memory_graph_reason`, +`memory_query_graph`, `memory_prefetch_related`, plus the client-LLM graph +extraction pair (`memory_extract_pending` / `memory_commit_extraction`) — the +engine never makes LLM calls; your agent's own model does the extraction. + +## Local vs hosted + +| | Local (CLI + MCP) | Hosted (SDK / Mesh Router) | +|---|---|---| +| Storage | SQLite (`~/.thinkfleet-memory/memory.db`) | Postgres, multi-tenant | +| API key | not required | `mm-…` key or Cognito JWT | +| Surface | 15 MCP tools + CLI | full TS SDK (`memmesh-sdk`) | +| Sync | CRDT-style bi-temporal push to server (optional) | authoritative | + +Free tier caps local storage at 500 items (`free_tier.entry_cap` in +`~/.thinkfleet-memory/config.toml`). + +## Config + +`~/.thinkfleet-memory/config.toml` holds the sync URL, JWT token, and tier caps. +Point `sync.url` at your hosted mesh to push local memory up; leave it unset to +stay fully offline. diff --git a/skills/memmesh-integrate/SKILL.md b/skills/memmesh-integrate/SKILL.md new file mode 100644 index 0000000..63d76e5 --- /dev/null +++ b/skills/memmesh-integrate/SKILL.md @@ -0,0 +1,86 @@ +--- +name: memmesh-integrate +description: > + Integrate MemMesh into an existing repository using a goal-driven, test-first + (TDD) pipeline. Detects the repo's language/stack, asks whether to use MemMesh + Hosted (SDK, managed) or Local (CLI + MCP over SQLite), writes failing tests + before any implementation, and lands additive, feature-flag-gated code that a + maintainer can accept without argument. Produces `.memmesh-integration/` + artifacts for the paired verification skill. + TRIGGER when: user says "integrate memmesh", "add memmesh to this repo", "wire + memmesh into ", "add memory to this app", or "add prediction to this app". + DO NOT TRIGGER for: general SDK usage (use `memmesh-sdk`), CLI usage + (use `memmesh-cli`), or migrating off another vendor (use `memmesh-migrate`). + After success, invoke `memmesh-test-integration` in the same workspace. +license: Apache-2.0 +metadata: + author: thinkfleet + category: ai-memory + tags: "memory, prediction, integration, tdd" +--- + +# memmesh-integrate + +Wire MemMesh into an existing repo with a goal-driven, test-first pipeline. +Pairs with `memmesh-test-integration` for verification. + +## Canonical sources (fetch BEFORE deciding anything) + +`WebFetch` these and cite them in `plan.md`. They are ground truth — do not +rely on ambient knowledge of the API. + +- Docs index (agent-ready): https://docs.memmesh.ai/llms.txt +- Full docs (deep dives): https://docs.memmesh.ai/llms-full.txt +- Platform vs Local: https://docs.memmesh.ai/platform-vs-local +- Published skills to DELEGATE to (don't reimplement call-site patterns): + - SDK: `memmesh-sdk` · CLI + MCP: `memmesh-cli` · MCP loop: `memmesh` + +## Integration principles (non-negotiable) + +The goal is a **PR the maintainers accept without argument.** + +1. **Additive, not replacing.** If the repo already has a memory / session / + user-context layer, MemMesh sits *alongside* it. The existing system keeps + working unchanged. +2. **Opt-in by default.** Gate all new code behind a flag (`MEMMESH_ENABLED=1`, + a config key, or a strategy selector). Flag unset ⇒ original behavior, + byte-for-byte. +3. **No breakage.** No removed/renamed exports, no changed signatures, no + modified existing tests. All pre-existing tests pass unchanged with the flag + both set and unset. +4. **Minimal dependency surface.** Add `@thinkfleet/memory-sdk` (hosted) or the + `memmesh` binary (local) and nothing else. +5. **Separable commits.** Code, tests, config/docs in separate commits. +6. **The null hypothesis wins.** If no additive, gated fit exists, exit with a + rationale. A bad PR is worse than no PR. +7. **Backend only.** Integration lives in server-side code. Keys never ship to + the client. + +## Pipeline + +1. **Detect** the stack (language, test runner, where user/session context is + handled). Record in `.memmesh-integration/detect.md`. +2. **Choose surface** — ask the user: **Hosted** (managed, `mm-` key, best for + prediction/calibration/verticals) or **Local** (CLI + MCP over SQLite, no + key, best for dev tools / offline). Default to Local for CLIs and dev + tooling, Hosted for user-facing apps. +3. **Pick the seam.** The highest-value seam is usually the request/response + loop around the LLM: `observe` the user turn, `search`/`buildContext` before + generating, and — where it adds value — `predict` the next action. Write the + goal in `plan.md` and cite the canonical sources. +4. **Write failing tests first** into `.memmesh-integration/` and the repo's + test dir: (a) flag-off ⇒ behavior unchanged; (b) flag-on ⇒ observe is called + with the user turn; (c) flag-on ⇒ retrieved context reaches the prompt. +5. **Implement** the smallest gated wiring that makes the tests pass. Delegate + call-site patterns to `memmesh-sdk` / `memmesh-cli`. +6. **Consider the moat.** If the app makes a decision about a user/account + (offer, routing, retention), add an *optional* `predict` / `predictTarget` + call and surface the calibrated confidence + abstention. Never let an + abstention crash the flow — treat "I don't know yet" as a first-class branch. +7. **Emit artifacts** in `.memmesh-integration/` (`detect.md`, `plan.md`, + `changes.md`, seed test data) and stop. Then run `memmesh-test-integration`. + +## Definition of done + +Feature branch + `.memmesh-integration/` artifacts, all pre-existing tests green +with the flag both set and unset, and the new tests green with it set. diff --git a/skills/memmesh-migrate/SKILL.md b/skills/memmesh-migrate/SKILL.md new file mode 100644 index 0000000..174d54e --- /dev/null +++ b/skills/memmesh-migrate/SKILL.md @@ -0,0 +1,83 @@ +--- +name: memmesh-migrate +description: > + Migrate an existing memory setup ONTO MemMesh — either from another vendor + (Mem0, Zep, Letta/MemGPT, a raw vector store) or from MemMesh Local (SQLite) + up to MemMesh Hosted. Audits the current usage, produces a reviewable + migration plan (API mapping + data export/import), and executes it on + approval. Maps add→observe, search→search, and shows what MemMesh adds that + the source lacked (prediction, calibration, bi-temporal graph). + TRIGGER when: user says "migrate from mem0", "switch from zep to memmesh", + "move my memory to memmesh", "replace mem0 with memmesh", or "move local + memmesh to the hosted platform". + DO NOT TRIGGER for: a fresh integration with no incumbent (use + memmesh-integrate) or general SDK questions (use memmesh-sdk). +license: Apache-2.0 +metadata: + author: thinkfleet + category: ai-memory + tags: "memory, migration, mem0, zep, platform" +--- + +# memmesh-migrate + +Move an existing memory setup onto MemMesh with a reviewable, reversible plan. + +## Canonical sources (fetch first) + +- Docs / API mapping: https://docs.memmesh.ai/llms.txt +- Delegate call-site code to: `memmesh-sdk` (hosted) / `memmesh-cli` (local) + +## Step 1 — audit the incumbent + +Detect what's in use and record `.memmesh-migration/audit.md`: + +- **Vendor & SDK** (Mem0 `MemoryClient` / `Memory`, Zep, Letta, LangChain memory, + bare Qdrant/pgvector, …). +- **Call sites** — every `add` / `search` / `get_all` / `update` / `delete`. +- **Scoping** — how `user_id` / `agent_id` / `run_id` / `session` map today. +- **Data volume** — roughly how many memories, and where they live. + +## Step 2 — API mapping (cite in the plan) + +| Incumbent (e.g. Mem0) | MemMesh equivalent | Notes | +|---|---|---| +| `client.add(text, user_id=…)` | `memory.observe({ text, userId })` | MemMesh's engine decides what to save — you can stop pre-filtering. | +| `client.search(q, user_id=…)` | `memory.search({ query, userId })` | Same shape; MemMesh adds scope hierarchy + status lifecycle. | +| `client.get_all(user_id=…)` | `memory.list({ userId })` | | +| `client.update(id, text)` | `memory.observe(new)` + `memory.supersede(oldId, newId)` | Correction keeps provenance instead of destructive overwrite. | +| `client.delete(id)` | `memory.delete({ id })` (soft) / `hard:true` (GDPR) | | +| user / agent / run scoping | `userId` / `agentId` / `sessionId` (+ `projectId`, `platformId`) | 6-level hierarchy. | +| *(no equivalent)* | `lattice.predict` / `predictTarget`, `behaviors.discover`, `context.queryGraph` | **This is why you're migrating** — calibrated prediction the source can't do. | + +## Step 3 — data migration + +1. **Export** from the incumbent (its export API or a `get_all` dump to JSONL). +2. **Transform** each record to a MemMesh `observe` (preferred — lets the engine + re-extract and build the graph) OR a `memory.save` with an explicit id when + you must preserve exact rows. +3. **Import** in batches; keep a checkpoint file so a re-run is idempotent. +4. **Reconcile** — count source vs destination, sample-search for known facts, + write `.memmesh-migration/reconcile.md`. + +For **Local → Hosted**: set `sync.url` in `~/.thinkfleet-memory/config.toml` and +let the CRDT-style bi-temporal sync push; or export the SQLite items and `observe` +them into the hosted tenant. Reconcile the same way. + +## Step 4 — cutover (gated) + +Keep the incumbent behind the old flag; bring MemMesh up behind `MEMMESH_ENABLED`. +Run both in shadow (dual-write) for a window, compare retrieval quality, then flip +the default. Never hard-delete the source until reconciliation passes. + +## Step 5 — show the upgrade + +After parity, add one prediction call at a real decision point so the user *sees* +what they gained: a calibrated confidence + provenance + honest abstention that +their previous vendor could not produce. Consider running the `benchmark` skill to +put numbers on the retrieval-quality / cost delta. + +## Definition of done + +Reconciled counts match, known facts retrievable on MemMesh, dual-write window +clean, and a rollback note (how to fall back to the incumbent) in the plan. diff --git a/skills/memmesh-sdk/SKILL.md b/skills/memmesh-sdk/SKILL.md new file mode 100644 index 0000000..80996a4 --- /dev/null +++ b/skills/memmesh-sdk/SKILL.md @@ -0,0 +1,166 @@ +--- +name: memmesh-sdk +description: > + MemMesh TypeScript SDK reference (@thinkfleet/memory-sdk) for the hosted + platform at app.memmesh.ai. Covers the ThinkFleetMemory client — observe / + search / list, the predict + lattice prediction surface, closed-loop + learning (recordDecision / recordOutcome), emergent behavior discovery, and + the health / financial vertical packs. + TRIGGER when: user is writing code that calls the MemMesh SDK, mentions + "@thinkfleet/memory-sdk", "ThinkFleetMemory", "memmesh sdk", "lattice.predict", + "predictTarget", or wants to add memory OR prediction to a TS/JS app. + DO NOT TRIGGER for: the local MCP observe/recall loop (that's the always-on + `memmesh` skill), CLI usage (use `memmesh-cli`), or wiring into an existing + repo (use `memmesh-integrate`). +license: Apache-2.0 +metadata: + author: thinkfleet + category: ai-memory + tags: "memory, prediction, calibration, typescript, knowledge-graph" +compatibility: Requires Node.js 18+. npm install @thinkfleet/memory-sdk. A MEMMESH_API_KEY (hosted) or a Cognito JWT. For a no-key local setup use the memmesh CLI + MCP instead. +--- + +# MemMesh TypeScript SDK + +MemMesh is not just a store-and-recall memory layer. It is a **memory + +calibrated-prediction + behavior-discovery engine** over a bi-temporal +knowledge graph. The SDK talks to the hosted platform (`app.memmesh.ai`) over +REST; for a zero-infra local setup, drive the same engine through the CLI + +MCP server instead (see `memmesh-cli`). + +> **Mental model:** `observe` (feed raw text — the engine decides what to save) +> → `search` / `buildContext` (retrieve) → `predict` (forecast the subject's +> next move, with a calibrated confidence and provenance). + +## Step 1 — install and authenticate + +```bash +npm install @thinkfleet/memory-sdk +export MEMMESH_API_KEY="mm-your-api-key" # from app.memmesh.ai +``` + +## Step 2 — initialize + +```ts +import { ThinkFleetMemory } from "@thinkfleet/memory-sdk"; + +const memory = new ThinkFleetMemory({ + apiKey: process.env.MEMMESH_API_KEY, // or a Cognito JWT via `token` + // baseUrl defaults to https://app.memmesh.ai +}); +``` + +## Step 3 — the core loop: observe → retrieve → (predict) + +### Observe — the engine decides what to save +Unlike layers where *you* judge "is this worth saving?", you feed MemMesh raw +text and its extractor (regex + structural rules + optional LLM refinement) +decides. Cheap, idempotent, silent on filler. + +```ts +await memory.memory.observe({ + text: "Alice is vegetarian and allergic to nuts. She books gym classes on Mondays.", + userId: "alice", + projectId: "myapp", +}); +``` + +There are also typed intake helpers: `observeImage`, `observeVoice`, +`observeDocument`, `ingestMedia`. + +### Retrieve — search or a full context bundle +```ts +const hits = await memory.memory.search({ query: "dietary restrictions", userId: "alice" }); + +// Or the synthesized, token-budgeted bundle (profile + patterns + predictions + top memories): +const ctx = await memory.context.build({ subjectKind: "user", subjectId: "alice", maxTokens: 2000 }); +``` + +## The moat — predict anything, with calibration + abstention + +This is what a vector-recall layer cannot do. Predictions carry a **calibrated** +confidence ("80% means 80%"), **provenance** (`evidenceMemoryIds`), and a +first-class **abstention** ("I don't know yet" is a valid, honest answer). + +```ts +// Forward behavior prediction — what will this subject do next? +const preds = await memory.lattice.predict({ subjectKind: "user", subjectId: "alice", horizonDays: 30 }); + +// Declarative "predict ANY target" — no code change to add a new prediction: +const p = await memory.lattice.predictTarget({ + subject: { kind: "user", externalId: "alice" }, + target: { kind: "event_occurrence", name: "churn" }, // or numeric | event_time | anomaly +}); +if (p.abstained) { + console.log("abstained:", p.abstentionReason); // honest "not enough evidence" +} else { + console.log(p.probability, "±", p.calibration, "because", p.evidenceMemoryIds); +} + +// Is the model actually calibrated? Check the reliability curve: +const cal = await memory.lattice.getCalibration({ subjectKind: "user" }); +``` + +## Closed-loop learning — make predictions get better + +Record the decision you made and the outcome that followed; the engine feeds +that back into calibration and effectiveness reporting. + +```ts +const d = await memory.learning.recordDecision({ subjectId: "alice", decision: "sent_winback_offer" }); +await memory.learning.recordOutcome({ decisionId: d.id, outcome: "converted", value: 49.0 }); +const eff = await memory.learning.getEffectiveness({ subjectKind: "user" }); +``` + +## Emergent behavior discovery — patterns nobody predefined + +```ts +const behaviors = await memory.behaviors.discover({ projectId: "myapp" }); +// each carries prevalence, stability, and the evidence memories behind it +``` + +## Knowledge graph (bi-temporal) + +```ts +const g = await memory.context.queryGraph({ subjectId: "alice", asOf: "2026-01-01T00:00:00Z" }); +// "what did we believe about Alice on Jan 1" — every edge has valid_from / valid_to +``` + +## Vertical packs + +```ts +// Health +await memory.health.recordBiomarker({ subjectId: "alice", marker: "hba1c", value: 5.4 }); +const risk = await memory.health.getCohortRisk({ condition: "prediabetes" }); + +// Financial +await memory.financial.ingestPrices({ symbol: "AAPL", bars: [...] }); +const f = await memory.financial.predict({ symbol: "AAPL", target: { kind: "numeric", name: "close_5d" } }); +``` + +## Compliance & consent (regulated use) + +```ts +await memory.consent.optOut({ subjectId: "alice" }); +await memory.compliance.hardDeleteSubject({ subjectId: "alice" }); // GDPR right-to-forget +const audit = await memory.compliance.listAuditEvents({ subjectId: "alice" }); +``` + +## Scoping model + +Six-level hierarchy: `platform` › `project` › `location` › `agent` › `user` › +`session`. Pass `projectId` / `userId` / `agentId` / `sessionId` to scope any +call. Lifecycle: `pending → confirmed → superseded → rejected` (the engine +supersedes on contradiction — you don't hand-manage it). + +## Language support + +TypeScript/JavaScript is the shipping distributed SDK today. For non-TS stacks, +use the **MCP server** (any MCP-capable agent) or the REST API directly +(`llms.txt` / OpenAPI at docs.memmesh.ai). A Python SDK is on the roadmap. + +## Ground truth (fetch before relying on ambient knowledge) + +- Docs index (agent-ready): https://docs.memmesh.ai/llms.txt +- SDK examples: `predict-anything.ts`, `financial-demo.ts`, `next-best-offer.ts` +- Related skills: `memmesh` (MCP loop), `memmesh-cli`, `memmesh-integrate` diff --git a/skills/memmesh-test-integration/SKILL.md b/skills/memmesh-test-integration/SKILL.md new file mode 100644 index 0000000..e34410a --- /dev/null +++ b/skills/memmesh-test-integration/SKILL.md @@ -0,0 +1,60 @@ +--- +name: memmesh-test-integration +description: > + Verify a MemMesh integration produced by memmesh-integrate. Runs in the same + workspace: executes the repo's native test suite, then exercises a real + end-to-end smoke flow (observe → search → optionally predict) against the + user's live key or local engine, and produces a pass/fail scorecard. + TRIGGER when: the user has just run memmesh-integrate and says "verify", + "test the integration", or when a `.memmesh-integration/` directory exists and + tests have not been run yet. + DO NOT TRIGGER for: first-time wiring (use memmesh-integrate) or vendor + migration (use memmesh-migrate). +license: Apache-2.0 +metadata: + author: thinkfleet + category: ai-memory + tags: "memory, integration, testing, verification" +--- + +# memmesh-test-integration + +Prove the integration actually works — not just that it typechecks. + +## Preconditions + +- A `.memmesh-integration/` directory exists (else tell the user to run + `memmesh-integrate` first). +- Credentials: Hosted ⇒ `MEMMESH_API_KEY` set; Local ⇒ `memmesh doctor` passes. + +## Steps + +1. **Static gate.** Typecheck / lint / build. Any failure ⇒ stop, report. +2. **Native suite.** Run the repo's own tests **twice** — once with + `MEMMESH_ENABLED` unset (must be byte-for-byte the original behavior) and + once set. Both must pass. +3. **Real E2E smoke** against the live engine (not a mock): + - `observe` a known fact for a throwaway `userId` (e.g. `smoke-`). + - `search` for it; assert the fact comes back. + - `buildContext` for the subject; assert the fact appears in the bundle. + - If prediction was wired: call `predict` / `predictTarget` and assert you get + *either* a calibrated probability *or* an honest abstention — both are a + pass; a crash or an uncalibrated 1.0/0.0 with no evidence is a fail. + - Clean up: `memory_delete` (or `compliance.hardDeleteSubject`) the throwaway + subject so the smoke run leaves no residue. +4. **Scorecard.** Write `.memmesh-integration/scorecard.md`: + + | Check | Result | + |---|---| + | Typecheck / build | ✅ / ❌ | + | Native tests (flag off) | ✅ / ❌ | + | Native tests (flag on) | ✅ / ❌ | + | E2E observe→search | ✅ / ❌ | + | E2E buildContext | ✅ / ❌ | + | E2E predict (calibrated OR abstained) | ✅ / ❌ / n/a | + | Smoke cleanup | ✅ / ❌ | + +## Definition of done + +Every applicable row green, throwaway data removed, and a one-paragraph verdict: +ship / needs-work, with the failing checks called out.