Retrieved article excerpt
Open article Β· Retrieved 2026-09-17T14:22:20.744499+00:00
[a8888b2b-d683-44b9-a4d9-ab08585cd393](https://private-user-images.githubusercontent.com/299753491/650933295-b7f6ecd4-31d7-4d14-aff1-6707c0e8653f.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODk2NTUyNDAsIm5iZiI6MTc4OTY1NDk0MCwicGF0aCI6Ii8yOTk3NTM0OTEvNjUwOTMzMjk1LWI3ZjZlY2Q0LTMxZDctNGQxNC1hZmYxLTY3MDdjMGU4NjUzZi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwOTE3JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDkxN1QxNDIyMjBaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0yMWMxZmIyNmE3MmYxYjNmYjIwYWJjZDIwZjc2Y2YyNjNkNmZmYWY1YWFjY2Q2Y2Q5MTVmMzA1ZWNmNDY4MWM1JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.T-9A5aaR-BS8GEKj3Jei-Bh8D2ruVstRvdfjUx875B4)
# m8m
[npm version](https://www.npmjs.com/package/@th0t3p/m8m)
[license](https://github.com/th0t3p/m8m/blob/main/LICENSE)
[tests](https://github.com/th0t3p/m8m/actions/workflows/test.yml)
AI memory observability, provenance & security. Eight eyes. Nothing gets past.
m8m monitors what your AI agents remember about you β where each memory came
from, what changed, and whether anything looks suspicious. The core pieces
share one local SQLite database:
- **MCP server** β live memory operations as your agent works
- **File watcher** β tracks local memory files (`MEMORY.md`, `CLAUDE.md`, β¦);
it runs automatically inside the MCP server (and can also run standalone via
`m8m watch`)
- **Security analysis** β pattern-based scanning of every memory for
credentials, instructions, URLs/emails, and hidden characters
- **Snapshots & rollback** β point-in-time baselines to diff drift and roll back
- **CLI** β query and audit memory state from the terminal
- **Local dashboard** β a dark, browser-based visualization
Phase 1 is entirely local: SQLite storage, pattern-based analysis, and **zero**
LLM or network calls in the analyzer itself.
## Why m8m?
Your AI remembers everything about you β preferences, habits, work patterns,
relationships. But do you know what it remembers? Can you tell if those
memories have been tampered with?
- Microsoft Security identified **50 memory poisoning attempts** across 31
companies in just 60 days (Feb 2026)
- A single email can silently rewrite your AI agent's memory
([MemGhost, Jul 2026](https://arxiv.org))
- More capable models are **more vulnerable**, not less β GPT-5.4 showed
87.5% injection success rate
m8m gives you visibility and control. Think of it as `git log` for your
AI's memory.
## Install
### From npm (published) β one command
```
npm install -g @th0t3p/m8m
```
### From source (this repo) β one command
```
./scripts/install.sh
```
That installs dependencies, builds, and runs `npm link` so `m8m` is on your
`PATH`. (Equivalent manual steps: `npm install` then `npm install -g .`.)
### Run without installing
```
node dist/cli/index.js --help
npx tsx src/cli/index.ts --help
```
The first command requires `npm run build` first; the second runs TypeScript
directly with no build.
> **Data location:** everything lives in `~/.m8m/` by default. If `~` is
> read-only (e.g. some sandboxes), set `M8M_HOME` to a writable directory:
> `export M8M_HOME=/path/to/m8m-data`.
## Quick start
```
m8m init
m8m import ./MEMORY.md --platform local_file
m8m status
m8m list --flagged
m8m audit
```
## CLI
| Command | Description |
| --- | --- |
| `m8m init` | Initialize config + database |
| `m8m status` | Overview of agent + file memories, flags, security events |
| `m8m list [--platform <p>] [--status <s>] [--source-type <t>] [--flagged]` | List memories with filters |
| `m8m show <id>` | Full detail + changelog history |
| `m8m search <query> [--limit <n>]` | Keyword search |
| `m8m flag <id> --reason <reason>` | Manually flag a memory |
| `m8m unflag <id>` | Remove flags |
| `m8m quarantine <id>` | Quarantine a suspicious memory |
| `m8m restore <id>` | Restore from quarantine |
| `m8m dismiss <id>` | Clear flags + dismiss |
| `m8m purge <id> [--force]` | Permanently delete a memory (removes row + history) |
| `m8m clear [-f]` | Clear all stored memories (soft-delete) |
| `m8m import <file> [--source claude|chatgpt|local] [--platform <p>]` | Import Claude/ChatGPT/local file |
| `m8m files` | List imported memory files |
| `m8m files show <id>` | Show a memory file tree |
| `m8m files raw <id>` | Print a memory file's raw content |
| `m8m files export <id> [--output <path>]` | Export a memory file's raw content (recovery) |
| `m8m files diff <id>` | Show a memory file's change history |
| `m8m files rollback <id> [--yes]` | Roll a memory file back to its previous version |
| `m8m scan [--dry-run] [--yes]` | Discover + import memory files from all AI providers |
| `m8m providers` | List scan providers (vendor memory paths) |
| `m8m providers add <name> <path> [--platform <p>] [--dir] [--ext <e>] [--desc <d>]` | Add a vendor scan target |
| `m8m providers rm <name>` | Remove a vendor |
| `m8m snapshot [--platform <p>]` | Manual snapshot for diffing |
| `m8m rollback <snapshot-id> [--yes]` | Restore memories to a snapshot (preview + confirm) |
| `m8m diff [--since "2 hours ago"] [--snapshot <id1> <id2>]` | Show changes since a snapshot or time |
| `m8m audit [--severity critical] [--resolved]` | List security events |
| `m8m watch` | Start the file watcher standalone (foreground β optional; the MCP server already runs it) |
| `m8m dashboard [--port <p>]` | Start the web dashboard (default 8808) |
| `m8m mcp` | Start the MCP server (stdio) |
| `m8m mcp add <client> [--data-dir <path>]` | Add m8m to an MCP client (codex | claude | cursor | dsh) |
| `m8m config` | Show config |
| `m8m config set <key> <value>` | Update a config value |
| `m8m config add-watch <path>` | Add a watch path |
### Example
```
$ m8m status
m8m β Memory Observatory
βββββββββββββββββββββββββ
Agent memories
Total: 138
Active: 136
Quarantined: 2
Flagged: 4
File memories
Files: 3
Nodes: 120
Flagged: 9
By platform:
claude_code 89
claude_web 41
chatgpt_web 12
Security events: 3 unresolved
```
## Memory lifecycle
m8m never silently overwrites history β every change is appended to a
changelog. Statuses:
| State | How | Reversible? | What's kept |
| --- | --- | --- | --- |
| **active** | default | β | row + full changelog |
| **quarantined** | `m8m quarantine <id>` (or dashboard) | yes β `m8m restore <id>` | row + full changelog |
| **dismissed** | `m8m dismiss <id>` | yes | row, flags cleared |
| **deleted** (soft) | `m8m_delete` MCP tool / `m8m clear` | yes (status only) | row + content + changelog |
| **purged** (hard) | `m8m purge <id> --force` | **no** | removed: row, changelog, security events |
Soft-delete keeps the content so it can be restored or audited. Purge
physically removes the row and its history (earlier snapshots may still hold a
copy).
## Snapshots & rollback
Snapshots are point-in-time dumps of **both kinds of memory** β agent memories
and file memories β so you can diff drift and roll back the whole store
atomically.
- **Auto-snapshots** run inside the MCP server every
`auto_snapshot_interval_minutes` (default 60), so a recent baseline is always
available while a client is connected.
- `m8m snapshot` takes one manually.
- `m8m diff` compares the current store against the latest snapshot (or two
snapshots, or a time window).
**Rollback always previews first, then asks to confirm:**
```
m8m rollback <snapshot-id> # shows restore/revert/remove preview, then [y/N]
m8m files rollback <id> # shows a line diff, then restores the previous version
```
Rollback is traceable β it writes normal changelog/version entries, so you can
roll forward again. Snapshot rollback re-adds deleted agent memories, reverts
modified ones, soft-deletes memories added after the snapshot, restores file
memories to their snapshot content, and purges file memories added since.
`m8m files rollback <id>` rolls a single file back one version instead.
## MCP server
m8m exposes `m8m_store`, `m8m_search`, `m8m_recent`, `m8m_status`,
`m8m_flag`, and `m8m_delete` over stdio. (`m8m_delete` is a reversible
soft-delete; hard deletion is `m8m purge` in the CLI.)
> **The MCP server also runs the file watcher.** While any client is connected,
> it watches your memory files (`watch_paths`, scan-provider targets, and every
> file already imported) and re-imports changes as a new version with a stored
> diff β so you don't need to run `m8m watch` separately. `m8m watch` remains
> available for standalone/foreground use.
### Easiest: auto-configure
```
m8m mcp add codex
```
Replace `codex` with `claude`, `cursor`, or `dsh`.
This writes the right config entry into the client's config file for you
(Codex `~/.codex/config.toml`, Claude `~/.claude.json`, Cursor
`~/.cursor/mcp.json`, DSH `$DSH_HOME/cordis.patch.yml`). Add
`--data-dir /path` to bake in a `M8M_HOME` override.
Or use your client's native command:
```
codex mcp add m8m -- npx -y @th0t3p/m8m mcp
claude mcp add m8m -- npx -y @th0t3p/m8m mcp
```
### Manual (equivalent config)
The server is fetched from npm on demand via `npx`, so no clone or build is
needed.
**OpenAI Codex** β `~/.codex/config.toml`:
```
[mcp_servers.m8m]
command = "npx"
args = ["-y", "@th0t3p/m8m", "mcp"]
startup_timeout_sec = 30
```
Tools appear as `m8m_store`, etc.
**Claude Code** β project scope `.mcp.json`, or user scope `~/.claude.json`:
```
{
"mcpServers": {
"m8m": { "command": "npx", "args": ["-y", "@th0t3p/m8m", "mcp"] }
}
}
```
Tools appear as `m8m_store`, etc.
**Cursor** β `~/.cursor/mcp.json`:
```
{
"mcpServers": {
"m8m": { "command": "npx", "args": ["-y", "@th0t3p/m8m", "mcp"] }
}
}
```
**DeepSeek Harness (DSH)** β `$DSH_HOME/cordis.patch.yml`:
```
- insert:
- id: mcp-m8m
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: m8m
transport: stdio
command: npx
args: ['-y', '@th0t3p/m8m', 'mcp']
```
Tools appear as `mcp__m8m__m8m_store`, etc.
## Dashboard
```
m8m dashboard
```
Then open <http://localhost:8808>.
Four views: **Timeline**, **Memories**, **Security**, and **Diff**. The Memories
view shows both kinds of memory together β **agent memories** (facts stored via
the MCP server) and **file memories** (imported markdown/json files).
## Configuration
Config lives at `~/.m8m/config.json` (override the directory with `$M8M_HOME`).
It has two lists that control where m8m looks for vendor memory files:
- **`providers`** β the agent harnesses `m8m scan` discovers. Each entry names
a vendor and lists the files/directories that hold its memories.
- **`watch_paths`** β the paths the file watcher (inside the MCP server, or
`m8m watch`) monitors for changes in real time.
```
{
"db_path": "~/.m8m/m8m.db",
"watch_paths": [
"~/.claude/memories",
"./.claude/MEMORY.md",
"./.cursor/memory",
"./AGENTS.md",
"./MEMORY.md",
"~/.codex/memories",
"~/.hindsight",
"~/.basic-memory"
],
"providers": [
{
"name": "Claude Code",
"platform": "claude_code",
"targets": [
{ "path": "~/.claude/CLAUDE.md", "description": "User-level instructions" },
{ "path": "~/.claude/memories", "description": "User memories directory", "isDir": true, "extensions": [".md", ".json", ".txt"] },
{ "path": "./CLAUDE.md", "description": "Project-level instructions" }
]
},
{
"name": "Codex",
"platform": "local_file",
"targets": [
{ "path": "~/.codex/memories", "description": "Native memory directory", "isDir": true, "extensions": [".md", ".json", ".txt"] },
{ "path": "~/.codex/AGENTS.md", "description": "Global agent rules" }
]
}
],
"dashboard_port": 8808,
"auto_