Compare commits

..
Author SHA1 Message Date
33d2bc495d fix(openclaw): clear security scanner exfiltration warning (#4678)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Saket Aryan <saketaryan2002@gmail.com>
2026-04-03 00:34:49 +05:30
c0cae68646 feat(plugin): add Codex plugin support and integration docs (#4665)
Co-authored-by: Gabriel Stein <gabrielstein416@gmail.com>
2026-04-03 00:18:02 +05:30
3b2f01796e feat(cli): comprehensive docs, version bump, and purple branding (#4680)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 22:52:00 +05:30
26 changed files with 1479 additions and 88 deletions
+20
View File
@@ -0,0 +1,20 @@
{
"name": "mem0-plugins",
"interface": {
"displayName": "Mem0 Plugins"
},
"plugins": [
{
"name": "mem0",
"source": {
"source": "local",
"path": "./mem0-plugin"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
+2 -2
View File
@@ -10,8 +10,8 @@
"logoMini": "\u25c6 mem0",
"tagline": "The Memory Layer for AI Agents",
"colors": {
"brand": "#F1C96C",
"accent": "#F5D78E",
"brand": "#8b5cf6",
"accent": "#a78bfa",
"success": "#22c55e",
"error": "#ef4444",
"warning": "#f59e0b",
+299 -37
View File
@@ -2,10 +2,12 @@
The official command-line interface for [mem0](https://mem0.ai) — the memory layer for AI agents. TypeScript implementation.
> **Built for AI agents.** Pass `--agent` (or `--json`) as a global flag on any command to get structured JSON output optimized for programmatic consumption — sanitized fields, no colors or spinners, and errors as JSON too.
## Prerequisites
- Node.js **18+**
- pnpm (`npm install -g pnpm`)
- pnpm (`npm install -g pnpm`) — for development only
## Installation
@@ -13,22 +15,307 @@ The official command-line interface for [mem0](https://mem0.ai) — the memory l
npm install -g @mem0/cli
```
Or from source:
## Quick start
```bash
cd node
pnpm install
pnpm build
pnpm link --global
# Interactive setup wizard
mem0 init
# Now use it like a normal CLI
mem0 --help
# Or login via email
mem0 init --email alice@company.com
# Or authenticate with an existing API key
mem0 init --api-key m0-xxx
# Add a memory
mem0 add "I prefer dark mode and use vim keybindings" --user-id alice
# Search memories
mem0 search "What are Alice's preferences?" --user-id alice
# List all memories for a user
mem0 list --user-id alice
# Get a specific memory
mem0 get <memory-id>
# Update a memory
mem0 update <memory-id> "I switched to light mode"
# Delete a memory
mem0 delete <memory-id>
```
## Running during development
## Commands
### `mem0 init`
Interactive setup wizard. Prompts for your API key and default user ID.
```bash
cd node
mem0 init
mem0 init --api-key m0-xxx --user-id alice
mem0 init --email alice@company.com
```
If an existing configuration is detected, the CLI asks for confirmation before overwriting. Use `--force` to skip the prompt (useful in CI/CD).
```bash
mem0 init --api-key m0-xxx --user-id alice --force
```
| Flag | Description |
|------|-------------|
| `--api-key` | API key (skip prompt) |
| `-u, --user-id` | Default user ID (skip prompt) |
| `--email` | Login via email verification code |
| `--code` | Verification code (use with `--email` for non-interactive login) |
| `--force` | Overwrite existing config without confirmation |
### `mem0 add`
Add a memory from text, a JSON messages array, a file, or stdin.
```bash
mem0 add "I prefer dark mode" --user-id alice
mem0 add --file conversation.json --user-id alice
echo "Loves hiking on weekends" | mem0 add --user-id alice
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Scope to a user |
| `--agent-id` | Scope to an agent |
| `--messages` | Conversation messages as JSON |
| `-f, --file` | Read messages from a JSON file |
| `-m, --metadata` | Custom metadata as JSON |
| `--categories` | Categories (JSON array or comma-separated) |
| `--graph / --no-graph` | Enable or disable graph memory extraction |
| `-o, --output` | Output format: `text`, `json`, `quiet` |
### `mem0 search`
Search memories using natural language.
```bash
mem0 search "dietary restrictions" --user-id alice
mem0 search "preferred tools" --user-id alice --output json --top-k 5
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Filter by user |
| `-k, --top-k` | Number of results (default: 10) |
| `--threshold` | Minimum similarity score (default: 0.3) |
| `--rerank` | Enable reranking |
| `--keyword` | Use keyword search instead of semantic |
| `--filter` | Advanced filter expression (JSON) |
| `--graph / --no-graph` | Enable or disable graph in search |
| `-o, --output` | Output format: `text`, `json`, `table` |
### `mem0 list`
List memories with optional filters and pagination.
```bash
mem0 list --user-id alice
mem0 list --user-id alice --category preferences --output json
mem0 list --user-id alice --after 2024-01-01 --page-size 50
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Filter by user |
| `--page` | Page number (default: 1) |
| `--page-size` | Results per page (default: 100) |
| `--category` | Filter by category |
| `--after` | Created after date (YYYY-MM-DD) |
| `--before` | Created before date (YYYY-MM-DD) |
| `-o, --output` | Output format: `text`, `json`, `table` |
### `mem0 get`
Retrieve a specific memory by ID.
```bash
mem0 get 7b3c1a2e-4d5f-6789-abcd-ef0123456789
mem0 get 7b3c1a2e-4d5f-6789-abcd-ef0123456789 --output json
```
### `mem0 update`
Update the text or metadata of an existing memory.
```bash
mem0 update <memory-id> "Updated preference text"
mem0 update <memory-id> --metadata '{"priority": "high"}'
echo "new text" | mem0 update <memory-id>
```
### `mem0 delete`
Delete a single memory, all memories for a scope, or an entire entity.
```bash
# Delete a single memory
mem0 delete <memory-id>
# Delete all memories for a user
mem0 delete --all --user-id alice --force
# Delete all memories project-wide
mem0 delete --all --project --force
# Preview what would be deleted
mem0 delete --all --user-id alice --dry-run
```
| Flag | Description |
|------|-------------|
| `--all` | Delete all memories matching scope filters |
| `--entity` | Delete the entity and all its memories |
| `--project` | With `--all`: delete all memories project-wide |
| `--dry-run` | Preview without deleting |
| `--force` | Skip confirmation prompt |
### `mem0 import`
Bulk import memories from a JSON file.
```bash
mem0 import data.json --user-id alice
```
The file should be a JSON array where each item has a `memory` (or `text` or `content`) field and optional `user_id`, `agent_id`, and `metadata` fields.
### `mem0 config`
View or modify the local CLI configuration.
```bash
mem0 config show # Display current config (secrets redacted)
mem0 config get api_key # Get a specific value
mem0 config set user_id bob # Set a value
```
### `mem0 entity`
List or delete entities (users, agents, apps, runs).
```bash
mem0 entity list users
mem0 entity list agents --output json
mem0 entity delete --user-id alice --force
```
### `mem0 event`
Inspect background processing events created by async operations (e.g. bulk deletes, large add jobs).
```bash
# List recent events
mem0 event list
# Check the status of a specific event
mem0 event status <event-id>
```
| Flag | Description |
|------|-------------|
| `-o, --output` | Output format: `text`, `json` |
### `mem0 status`
Verify your API connection and display the current project.
```bash
mem0 status
```
### `mem0 version`
Print the CLI version.
```bash
mem0 version
```
## Agent mode
Pass `--agent` (or its alias `--json`) as a **global flag** on any command to get output designed for AI agent tool loops:
```bash
mem0 --agent search "user preferences" --user-id alice
mem0 --agent add "User prefers dark mode" --user-id alice
mem0 --agent list --user-id alice
mem0 --agent delete --all --user-id alice --force
```
Every command returns the same envelope shape:
```json
{
"status": "success",
"command": "search",
"duration_ms": 134,
"scope": { "user_id": "alice" },
"count": 2,
"data": [
{ "id": "abc-123", "memory": "User prefers dark mode", "score": 0.97, "created_at": "2026-01-15", "categories": ["preferences"] }
]
}
```
What agent mode does differently from `--output json`:
- **Sanitized `data`**: only the fields an agent needs (id, memory, score, etc.) — no internal API noise
- **No human output**: spinners, colors, and banners are suppressed entirely
- **Errors as JSON**: errors go to stdout as `{"status": "error", "command": "...", "error": "..."}` with a non-zero exit code
Use `mem0 help --json` to get the full command tree as JSON — useful for agents that need to self-discover available commands.
## Output formats
Control how results are displayed with `--output`:
| Format | Description |
|--------|-------------|
| `text` | Human-readable with colors and formatting (default) |
| `json` | Structured JSON for piping to `jq` (raw API response) |
| `table` | Tabular format (default for `list`) |
| `quiet` | Minimal — just IDs or status codes |
| `agent` | Structured JSON envelope with sanitized fields (set by `--agent`/`--json`) |
## Global flags
These flags are available on all commands:
| Flag | Description |
|------|-------------|
| `--json` | Enable agent mode: structured JSON envelope output, no colors or spinners |
| `--agent` | Alias for `--json` |
| `--api-key` | Override the configured API key for this request |
| `--base-url` | Override the configured API base URL for this request |
| `-o, --output` | Set the output format |
## Environment variables
| Variable | Description |
|----------|-------------|
| `MEM0_API_KEY` | API key (overrides config file) |
| `MEM0_BASE_URL` | API base URL |
| `MEM0_USER_ID` | Default user ID |
| `MEM0_AGENT_ID` | Default agent ID |
| `MEM0_APP_ID` | Default app ID |
| `MEM0_RUN_ID` | Default run ID |
| `MEM0_ENABLE_GRAPH` | Enable graph memory (`true` / `false`) |
Environment variables take precedence over values in the config file, which take precedence over defaults.
## Development
```bash
cd cli/node
pnpm install
# Development mode (runs TypeScript directly, no build needed)
@@ -39,36 +326,11 @@ pnpm dev search "test" --user-id alice
# Or build first, then run the compiled JS
pnpm build
node dist/index.js --help
node dist/index.js add "test memory" --user-id alice
```
## Quick Start
## Documentation
```bash
# Set up your configuration
mem0 init
# Add a memory
mem0 add "I prefer dark mode and use vim keybindings" --user-id alice
# Search memories
mem0 search "What are Alice's preferences?" --user-id alice
# List all memories
mem0 list --user-id alice
```
## Environment Variables
| Variable | Description |
|----------|-------------|
| `MEM0_API_KEY` | API key (overrides config file) |
| `MEM0_BASE_URL` | API base URL |
| `MEM0_USER_ID` | Default user ID |
| `MEM0_AGENT_ID` | Default agent ID |
| `MEM0_APP_ID` | Default app ID |
| `MEM0_RUN_ID` | Default run ID |
| `MEM0_ENABLE_GRAPH` | Enable graph memory (true/false) |
Full documentation is available at [docs.mem0.ai/platform/cli](https://docs.mem0.ai/platform/cli).
## License
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@mem0/cli",
"version": "0.1.2",
"version": "0.2.1",
"description": "The official CLI for mem0 — the memory layer for AI agents",
"type": "module",
"bin": {
+2 -2
View File
@@ -19,8 +19,8 @@ export const LOGO = `
export const LOGO_MINI = "◆ mem0";
export const TAGLINE = "The Memory Layer for AI Agents";
export const BRAND_COLOR = "#F1C96C";
export const ACCENT_COLOR = "#F5D78E";
export const BRAND_COLOR = "#8b5cf6";
export const ACCENT_COLOR = "#a78bfa";
export const SUCCESS_COLOR = "#22c55e";
export const ERROR_COLOR = "#ef4444";
export const WARNING_COLOR = "#f59e0b";
+1 -1
View File
@@ -39,7 +39,7 @@ afterEach(() => {
describe("branding constants", () => {
it("has correct brand color", () => {
expect(BRAND_COLOR).toBe("#F1C96C");
expect(BRAND_COLOR).toBe("#8b5cf6");
});
it("has correct tagline", () => {
+310 -7
View File
@@ -1,6 +1,12 @@
# mem0 CLI
# mem0 CLI (Python)
The official command-line interface for [mem0](https://mem0.ai) — the memory layer for AI agents.
The official command-line interface for [mem0](https://mem0.ai) — the memory layer for AI agents. Python implementation.
> **Built for AI agents.** Pass `--agent` (or `--json`) as a global flag on any command to get structured JSON output optimized for programmatic consumption — sanitized fields, no colors or spinners, and errors as JSON too.
## Prerequisites
- Python **3.10+**
## Installation
@@ -18,28 +24,325 @@ pip install mem0-cli
> **Note:** On macOS with Homebrew Python, `pip install` outside a virtual environment will fail with an `externally-managed-environment` error ([PEP 668](https://peps.python.org/pep-0668/)). Use `pipx` instead, or install inside a virtual environment.
## Quick Start
## Quick start
```bash
# Set up your configuration
# Interactive setup wizard
mem0 init
# Or login via email
mem0 init --email alice@company.com
# Or authenticate with an existing API key
mem0 init --api-key m0-xxx
# Add a memory
mem0 add "I prefer dark mode and use vim keybindings" --user-id alice
# Search memories
mem0 search "What are Alice's preferences?" --user-id alice
# List all memories
# List all memories for a user
mem0 list --user-id alice
# Get a specific memory
mem0 get <memory-id>
# Update a memory
mem0 update <memory-id> "I switched to light mode"
# Delete a memory
mem0 delete <memory-id>
```
## Commands
### `mem0 init`
Interactive setup wizard. Prompts for your API key and default user ID.
```bash
mem0 init
mem0 init --api-key m0-xxx --user-id alice
mem0 init --email alice@company.com
```
If an existing configuration is detected, the CLI asks for confirmation before overwriting. Use `--force` to skip the prompt (useful in CI/CD).
```bash
mem0 init --api-key m0-xxx --user-id alice --force
```
| Flag | Description |
|------|-------------|
| `--api-key` | API key (skip prompt) |
| `-u, --user-id` | Default user ID (skip prompt) |
| `--email` | Login via email verification code |
| `--code` | Verification code (use with `--email` for non-interactive login) |
| `--force` | Overwrite existing config without confirmation |
### `mem0 add`
Add a memory from text, a JSON messages array, a file, or stdin.
```bash
mem0 add "I prefer dark mode" --user-id alice
mem0 add --file conversation.json --user-id alice
echo "Loves hiking on weekends" | mem0 add --user-id alice
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Scope to a user |
| `--agent-id` | Scope to an agent |
| `--messages` | Conversation messages as JSON |
| `-f, --file` | Read messages from a JSON file |
| `-m, --metadata` | Custom metadata as JSON |
| `--categories` | Categories (JSON array or comma-separated) |
| `--graph / --no-graph` | Enable or disable graph memory extraction |
| `-o, --output` | Output format: `text`, `json`, `quiet` |
### `mem0 search`
Search memories using natural language.
```bash
mem0 search "dietary restrictions" --user-id alice
mem0 search "preferred tools" --user-id alice --output json --top-k 5
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Filter by user |
| `-k, --top-k` | Number of results (default: 10) |
| `--threshold` | Minimum similarity score (default: 0.3) |
| `--rerank` | Enable reranking |
| `--keyword` | Use keyword search instead of semantic |
| `--filter` | Advanced filter expression (JSON) |
| `--graph / --no-graph` | Enable or disable graph in search |
| `-o, --output` | Output format: `text`, `json`, `table` |
### `mem0 list`
List memories with optional filters and pagination.
```bash
mem0 list --user-id alice
mem0 list --user-id alice --category preferences --output json
mem0 list --user-id alice --after 2024-01-01 --page-size 50
```
| Flag | Description |
|------|-------------|
| `-u, --user-id` | Filter by user |
| `--page` | Page number (default: 1) |
| `--page-size` | Results per page (default: 100) |
| `--category` | Filter by category |
| `--after` | Created after date (YYYY-MM-DD) |
| `--before` | Created before date (YYYY-MM-DD) |
| `-o, --output` | Output format: `text`, `json`, `table` |
### `mem0 get`
Retrieve a specific memory by ID.
```bash
mem0 get 7b3c1a2e-4d5f-6789-abcd-ef0123456789
mem0 get 7b3c1a2e-4d5f-6789-abcd-ef0123456789 --output json
```
### `mem0 update`
Update the text or metadata of an existing memory.
```bash
mem0 update <memory-id> "Updated preference text"
mem0 update <memory-id> --metadata '{"priority": "high"}'
echo "new text" | mem0 update <memory-id>
```
### `mem0 delete`
Delete a single memory, all memories for a scope, or an entire entity.
```bash
# Delete a single memory
mem0 delete <memory-id>
# Delete all memories for a user
mem0 delete --all --user-id alice --force
# Delete all memories project-wide
mem0 delete --all --project --force
# Preview what would be deleted
mem0 delete --all --user-id alice --dry-run
```
| Flag | Description |
|------|-------------|
| `--all` | Delete all memories matching scope filters |
| `--entity` | Delete the entity and all its memories |
| `--project` | With `--all`: delete all memories project-wide |
| `--dry-run` | Preview without deleting |
| `--force` | Skip confirmation prompt |
### `mem0 import`
Bulk import memories from a JSON file.
```bash
mem0 import data.json --user-id alice
```
The file should be a JSON array where each item has a `memory` (or `text` or `content`) field and optional `user_id`, `agent_id`, and `metadata` fields.
### `mem0 config`
View or modify the local CLI configuration.
```bash
mem0 config show # Display current config (secrets redacted)
mem0 config get api_key # Get a specific value
mem0 config set user_id bob # Set a value
```
### `mem0 entity`
List or delete entities (users, agents, apps, runs).
```bash
mem0 entity list users
mem0 entity list agents --output json
mem0 entity delete --user-id alice --force
```
### `mem0 event`
Inspect background processing events created by async operations (e.g. bulk deletes, large add jobs).
```bash
# List recent events
mem0 event list
# Check the status of a specific event
mem0 event status <event-id>
```
| Flag | Description |
|------|-------------|
| `-o, --output` | Output format: `text`, `json` |
### `mem0 status`
Verify your API connection and display the current project.
```bash
mem0 status
```
### `mem0 version`
Print the CLI version.
```bash
mem0 version
```
## Agent mode
Pass `--agent` (or its alias `--json`) as a **global flag** on any command to get output designed for AI agent tool loops:
```bash
mem0 --agent search "user preferences" --user-id alice
mem0 --agent add "User prefers dark mode" --user-id alice
mem0 --agent list --user-id alice
mem0 --agent delete --all --user-id alice --force
```
Every command returns the same envelope shape:
```json
{
"status": "success",
"command": "search",
"duration_ms": 134,
"scope": { "user_id": "alice" },
"count": 2,
"data": [
{ "id": "abc-123", "memory": "User prefers dark mode", "score": 0.97, "created_at": "2026-01-15", "categories": ["preferences"] }
]
}
```
What agent mode does differently from `--output json`:
- **Sanitized `data`**: only the fields an agent needs (id, memory, score, etc.) — no internal API noise
- **No human output**: spinners, colors, and banners are suppressed entirely
- **Errors as JSON**: errors go to stdout as `{"status": "error", "command": "...", "error": "..."}` with a non-zero exit code
Use `mem0 help --json` to get the full command tree as JSON — useful for agents that need to self-discover available commands.
## Output formats
Control how results are displayed with `--output`:
| Format | Description |
|--------|-------------|
| `text` | Human-readable with colors and formatting (default) |
| `json` | Structured JSON for piping to `jq` (raw API response) |
| `table` | Tabular format (default for `list`) |
| `quiet` | Minimal — just IDs or status codes |
| `agent` | Structured JSON envelope with sanitized fields (set by `--agent`/`--json`) |
## Global flags
These flags are available on all commands:
| Flag | Description |
|------|-------------|
| `--json` | Enable agent mode: structured JSON envelope output, no colors or spinners |
| `--agent` | Alias for `--json` |
| `--api-key` | Override the configured API key for this request |
| `--base-url` | Override the configured API base URL for this request |
| `-o, --output` | Set the output format |
## Environment variables
| Variable | Description |
|----------|-------------|
| `MEM0_API_KEY` | API key (overrides config file) |
| `MEM0_BASE_URL` | API base URL |
| `MEM0_USER_ID` | Default user ID |
| `MEM0_AGENT_ID` | Default agent ID |
| `MEM0_APP_ID` | Default app ID |
| `MEM0_RUN_ID` | Default run ID |
| `MEM0_ENABLE_GRAPH` | Enable graph memory (`true` / `false`) |
Environment variables take precedence over values in the config file, which take precedence over defaults.
## Development
```bash
cd cli/python
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# Run during development
python -m mem0_cli --help
mem0 add "test memory" --user-id alice
```
## Releasing
1. Update `version` in `pyproject.toml`
2. Create a GitHub Release with tag `cli-v<version>` (e.g. `cli-v0.2.0`)
2. Create a GitHub Release with tag `cli-v<version>` (e.g. `cli-v0.2.1`)
For a pre-release, use a beta version like `0.2.0b1` and check the **pre-release** checkbox.
For a pre-release, use a beta version like `0.2.1b1` and check the **pre-release** checkbox.
## Documentation
Full documentation is available at [docs.mem0.ai/platform/cli](https://docs.mem0.ai/platform/cli).
## License
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "mem0-cli"
version = "0.2.0"
version = "0.2.1"
description = "The official CLI for mem0 — the memory layer for AI agents"
readme = "README.md"
license = "Apache-2.0"
+1 -1
View File
@@ -1,3 +1,3 @@
"""mem0 CLI — the command-line interface for the mem0 memory layer."""
__version__ = "0.1.0"
__version__ = "0.2.1"
+2 -2
View File
@@ -26,8 +26,8 @@ LOGO_MINI = "◆ mem0"
TAGLINE = "The Memory Layer for AI Agents"
BRAND_COLOR = "#F1C96C" # Golden
ACCENT_COLOR = "#F5D78E"
BRAND_COLOR = "#8b5cf6" # Purple
ACCENT_COLOR = "#a78bfa"
SUCCESS_COLOR = "#22c55e"
ERROR_COLOR = "#ef4444"
WARNING_COLOR = "#f59e0b"
-5
View File
@@ -83,11 +83,6 @@ class TestCLIIntegration:
assert "add" in result.stdout
assert "search" in result.stdout
def test_version_flag(self):
result = _run(["--version"])
assert result.returncode == 0
assert "0.1.0" in result.stdout
def test_add_help(self):
result = _run(["add", "--help"])
assert result.returncode == 0
-10
View File
@@ -30,7 +30,6 @@ from mem0_cli.commands.memory import (
from mem0_cli.commands.utils import (
cmd_import,
cmd_status,
cmd_version,
)
@@ -742,15 +741,6 @@ class TestStatusCommand:
assert '"status"' in output
class TestVersionCommand:
def test_version(self):
console, buf = _make_console()
with patch("mem0_cli.commands.utils.console", console):
cmd_version()
output = buf.getvalue()
assert "0.1.0" in output
class TestImportCommand:
def test_import_json(self, mock_backend, tmp_path):
file_path = tmp_path / "import.json"
+14
View File
@@ -430,6 +430,20 @@
}
]
},
{
"tab": "Agent Plugins",
"groups": [
{
"group": "Coding Agents",
"icon": "terminal",
"pages": [
"integrations/claude-code",
"integrations/cursor",
"integrations/codex"
]
}
]
},
{
"tab": "API Reference",
"groups": [
+21
View File
@@ -381,4 +381,25 @@ Here are the available integrations for Mem0:
>
Build AI agents with persistent memory using Mastra's framework and tools.
</Card>
<Card
title="Claude Code"
icon="terminal"
href="/integrations/claude-code"
>
Add persistent memory to Claude Code and Cowork with MCP server, lifecycle hooks, and SDK skill.
</Card>
<Card
title="Cursor"
icon="i-cursor"
href="/integrations/cursor"
>
Add persistent memory to Cursor with MCP server, lifecycle hooks, and context-aware coding.
</Card>
<Card
title="Codex"
icon="robot"
href="/integrations/codex"
>
Add persistent memory to OpenAI Codex with MCP server and skill-based memory protocol.
</Card>
</CardGroup>
+156
View File
@@ -0,0 +1,156 @@
---
title: Claude Code
description: "Add persistent memory to Claude Code and Claude Cowork with the Mem0 plugin — MCP server, lifecycle hooks, and SDK skill."
---
Add persistent memory to [**Claude Code**](https://docs.anthropic.com/en/docs/claude-code) (CLI) and **Claude Cowork** (desktop app) with the Mem0 plugin. Your agent forgets everything between sessions — this plugin fixes that by connecting to Mem0's cloud memory layer via MCP, automatically capturing learnings at key lifecycle points, and retrieving relevant context before every response.
## Overview
1. **MCP Server** — Connect to Mem0's remote MCP server for memory tools (add, search, update, delete)
2. **Lifecycle Hooks** — Automatic memory capture at session start, context compaction, task completion, and session end
3. **SDK Skill** — Teaches the agent how to integrate the Mem0 SDK into your applications
4. **Zero local dependencies** — Cloud-hosted MCP server, no local setup required
## Prerequisites
Before setting up Mem0 with Claude Code, ensure you have:
1. A Mem0 Platform account and API key:
- [Sign up at app.mem0.ai](https://app.mem0.ai)
- [Get your API key](https://app.mem0.ai/dashboard/api-keys) (starts with `m0-`)
2. Claude Code CLI or Claude Cowork desktop app installed
3. Your API key exported in your shell:
```bash
export MEM0_API_KEY="m0-your-api-key"
```
## Installation
### Option A — Plugin Marketplace (Recommended)
Install the full plugin including MCP server, lifecycle hooks, and SDK skill:
```
/plugin marketplace add mem0ai/mem0
/plugin install mem0@mem0-plugins
```
**Claude Cowork desktop app:** Open the Cowork tab, click **Customize** in the sidebar, click **Browse plugins**, and install Mem0.
### Option B — MCP Only
Add the Mem0 MCP server directly with a single command:
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "claude code"
```
This gives you the MCP tools but not the lifecycle hooks or SDK skill.
### Option C — Manual MCP Configuration
Add to your Claude Code MCP config (`.mcp.json`):
```json
{
"mcpServers": {
"mem0": {
"type": "http",
"url": "https://mcp.mem0.ai/mcp/",
"headers": {
"Authorization": "Token ${MEM0_API_KEY}"
}
}
}
}
```
<Info icon="check">
Start a new session and ask: *"List my mem0 entities"* or *"Search my memories for hello"*. If the `mem0` tools appear and respond, you're all set.
</Info>
## What's Included
| Component | Plugin Install | MCP Only |
|-----------|:--------------:|:--------:|
| MCP Server (9 memory tools) | Yes | Yes |
| Lifecycle Hooks | Yes | No |
| Mem0 SDK Skill | Yes | No |
## Available MCP Tools
Once installed, the following tools are available in every Claude Code session:
| Tool | Description |
|------|-------------|
| `add_memory` | Save text or conversation history for a user/agent |
| `search_memories` | Semantic search across memories with filters |
| `get_memories` | List memories with filters and pagination |
| `get_memory` | Retrieve a specific memory by ID |
| `update_memory` | Overwrite a memory's text by ID |
| `delete_memory` | Delete a single memory by ID |
| `delete_all_memories` | Bulk delete all memories in scope |
| `delete_entities` | Delete a user/agent/app/run entity and its memories |
| `list_entities` | List users/agents/apps/runs stored in Mem0 |
## Lifecycle Hooks
When installed via the plugin marketplace, Mem0 hooks into Claude Code's lifecycle to automatically manage memory:
### Session Start
On every new session, the plugin prompts Claude to call `search_memories` to load relevant context from prior sessions. On resumed or post-compaction sessions, it adjusts the prompt accordingly.
### User Prompt
Before processing each user message, the plugin searches Mem0 for memories relevant to the current prompt and injects them into context. Short prompts (< 20 characters) are skipped to minimize latency.
### Pre-Compaction
Before context compaction, the plugin prompts Claude to store a comprehensive session summary — including goals, accomplishments, decisions, modified files, and current state — so nothing is lost.
### Task Completed
After each task completion, the plugin prompts Claude to extract and store key learnings: successful strategies, failed approaches, architectural decisions, and new conventions.
### Session End
When Claude finishes responding, the plugin prompts for any unstored learnings and captures transcript state via the Mem0 REST API as a background safety net.
## Example Workflow
```text
# Session 1: Working on a feature
You: Let's refactor the auth module to use JWT tokens instead of sessions.
# Claude searches memories, finds nothing relevant, proceeds with the work.
# After completing the task, Mem0 stores:
# - Decision: "Migrated auth from sessions to JWT tokens"
# - Files modified: auth/middleware.ts, auth/token.ts
# - User preference: "Prefers TypeScript, uses ESLint"
# Session 2 (days later): Related work
You: Add refresh token rotation to the auth system.
# Claude searches memories, retrieves the JWT migration context.
# Knows the file structure, decisions made, and user preferences.
# Continues seamlessly without re-explaining the codebase.
```
## Troubleshooting
- **"Connection failed"** — Verify `MEM0_API_KEY` is set in your shell: `echo $MEM0_API_KEY`
- **No tools appearing** — Restart your Claude Code session after installation
- **Memories not being captured** — Ensure you installed via the plugin marketplace (Option A) for lifecycle hooks. MCP-only installs require manual memory operations.
<CardGroup cols={2}>
<Card title="Mem0 MCP Setup" icon="puzzle-piece" href="/platform/mem0-mcp">
Detailed MCP configuration for all clients
</Card>
<Card title="Codex Integration" icon="robot" href="/integrations/codex">
Add Mem0 memory to OpenAI Codex workflows
</Card>
</CardGroup>
+212
View File
@@ -0,0 +1,212 @@
---
title: Codex
description: "Add persistent memory to OpenAI Codex with the Mem0 plugin — MCP server, memory protocol skill, and plugin marketplace support."
---
Add persistent memory to [**OpenAI Codex**](https://openai.com/index/codex/) with the Mem0 plugin. Codex forgets everything between tasks — this plugin fixes that by connecting to Mem0's cloud memory layer via MCP and using a skill-based memory protocol to automatically retrieve context and store learnings.
## Overview
1. **MCP Server** — Connect to Mem0's remote MCP server for memory tools (add, search, update, delete)
2. **Memory Protocol Skill** — Instructs the agent to retrieve memories at task start, store learnings on completion, and capture session state before context loss
3. **Plugin Marketplace** — Install via Codex's repo-level or personal plugin marketplace
4. **Zero local dependencies** — Cloud-hosted MCP server, no local setup required
## Prerequisites
Before setting up Mem0 with Codex, ensure you have:
1. A Mem0 Platform account and API key:
- [Sign up at app.mem0.ai](https://app.mem0.ai)
- [Get your API key](https://app.mem0.ai/dashboard/api-keys) (starts with `m0-`)
2. OpenAI Codex access
3. Your API key exported in your shell:
```bash
export MEM0_API_KEY="m0-your-api-key"
```
## Installation
### Option A — Repo Marketplace (Recommended for Teams)
Add a `.agents/plugins/marketplace.json` to your repository root:
```json
{
"name": "mem0-plugins",
"interface": {
"displayName": "Mem0 Plugins"
},
"plugins": [
{
"name": "mem0",
"source": {
"source": "local",
"path": "./plugins/mem0"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
```
Then in Codex, browse the repo's plugin directory and install Mem0.
### Option B — Personal Marketplace
Add to `~/.agents/plugins/marketplace.json`:
```json
{
"name": "mem0-plugins",
"interface": {
"displayName": "Mem0 Plugins"
},
"plugins": [
{
"name": "mem0",
"source": {
"source": "local",
"path": "/path/to/mem0-plugin"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
```
### Option C — Manual MCP Configuration
Add to your Codex MCP config:
```json
{
"mcpServers": {
"mem0": {
"type": "http",
"url": "https://mcp.mem0.ai/mcp/",
"headers": {
"Authorization": "Token ${MEM0_API_KEY}"
}
}
}
}
```
<Info icon="check">
Start a new Codex task and ask: *"List my mem0 entities"* or *"Search my memories for hello"*. If the `mem0` tools appear and respond, you're all set.
</Info>
## What's Included
| Component | Plugin Install | MCP Only |
|-----------|:--------------:|:--------:|
| MCP Server (9 memory tools) | Yes | Yes |
| Memory Protocol Skill | Yes | No |
| Mem0 SDK Skill | Yes | No |
## Available MCP Tools
Once installed, the following tools are available in every Codex session:
| Tool | Description |
|------|-------------|
| `add_memory` | Save text or conversation history for a user/agent |
| `search_memories` | Semantic search across memories with filters |
| `get_memories` | List memories with filters and pagination |
| `get_memory` | Retrieve a specific memory by ID |
| `update_memory` | Overwrite a memory's text by ID |
| `delete_memory` | Delete a single memory by ID |
| `delete_all_memories` | Bulk delete all memories in scope |
| `delete_entities` | Delete a user/agent/app/run entity and its memories |
| `list_entities` | List users/agents/apps/runs stored in Mem0 |
## Memory Protocol Skill
Codex uses a skill-based approach instead of lifecycle hooks. When installed via the plugin marketplace, the memory protocol skill instructs the agent to:
### On Every New Task
1. Call `search_memories` with a query related to the current task to load relevant context
2. Review returned memories to understand what was learned in prior sessions
3. Optionally call `get_memories` to browse all stored memories
### After Completing Significant Work
Store key learnings using `add_memory` with structured metadata:
| What to store | Metadata type |
|--------------|---------------|
| Architectural decisions | `{"type": "decision"}` |
| Strategies that worked | `{"type": "task_learning"}` |
| Failed approaches | `{"type": "anti_pattern"}` |
| User preferences observed | `{"type": "user_preference"}` |
| Environment discoveries | `{"type": "environmental"}` |
| Conventions established | `{"type": "convention"}` |
### Before Losing Context
Store a comprehensive session summary including goals, accomplishments, decisions, files modified, and current state with metadata `{"type": "session_state"}`.
## Plugin Manifest
The Codex plugin manifest (`.codex-plugin/plugin.json`) follows the Codex plugin specification:
```json
{
"name": "mem0",
"version": "0.1.0",
"description": "Mem0 memory layer for AI applications.",
"skills": "./skills/",
"mcpServers": "./.codex-mcp.json",
"interface": {
"displayName": "Mem0",
"shortDescription": "Persistent memory layer for AI coding workflows",
"category": "Productivity",
"capabilities": ["Read", "Write"]
}
}
```
## Example Workflow
```text
# Task 1: Setting up a new service
You: Create a REST API for the notifications service using Express and TypeScript.
# Codex searches memories, finds user preferences from prior tasks.
# After completing the task, Mem0 stores:
# - Decision: "Notifications service uses Express + TypeScript + Zod validation"
# - Convention: "All API routes follow /api/v1/{resource} pattern"
# - Preference: "User prefers explicit error types over generic catch-all"
# Task 2 (days later): Extending the service
You: Add WebSocket support for real-time notification delivery.
# Codex searches memories, retrieves the architecture decisions and conventions.
# Follows the same patterns established in the first task.
```
## Troubleshooting
- **"Connection failed"** — Verify `MEM0_API_KEY` is set in your shell: `echo $MEM0_API_KEY`
- **No tools appearing** — Restart your Codex session after plugin installation
- **Plugin not found** — Ensure `.agents/plugins/marketplace.json` is at the repository root and `source.path` points to the correct plugin directory
- **Skills not loading** — Verify the `skills` field in `plugin.json` points to a valid directory containing `SKILL.md` files
<CardGroup cols={2}>
<Card title="Mem0 MCP Setup" icon="puzzle-piece" href="/platform/mem0-mcp">
Detailed MCP configuration for all clients
</Card>
<Card title="Claude Code Integration" icon="terminal" href="/integrations/claude-code">
Add Mem0 memory to Claude Code workflows
</Card>
</CardGroup>
+148
View File
@@ -0,0 +1,148 @@
---
title: Cursor
description: "Add persistent memory to Cursor with the Mem0 plugin — MCP server, lifecycle hooks, and SDK skill for context-aware coding."
---
Add persistent memory to [**Cursor**](https://cursor.com) with the Mem0 plugin. Your AI assistant forgets everything between sessions — this plugin fixes that by connecting to Mem0's cloud memory layer via MCP, automatically capturing learnings at key lifecycle points, and retrieving relevant context before every response.
## Overview
1. **MCP Server** — Connect to Mem0's remote MCP server for memory tools (add, search, update, delete)
2. **Lifecycle Hooks** — Automatic memory capture at session start, compaction, and user prompts (Marketplace install)
3. **SDK Skill** — Teaches the agent how to integrate the Mem0 SDK into your applications
4. **Zero local dependencies** — Cloud-hosted MCP server, no local setup required
## Prerequisites
Before setting up Mem0 with Cursor, ensure you have:
1. A Mem0 Platform account and API key:
- [Sign up at app.mem0.ai](https://app.mem0.ai)
- [Get your API key](https://app.mem0.ai/dashboard/api-keys) (starts with `m0-`)
2. Cursor installed ([cursor.com](https://cursor.com))
3. Your API key exported in your shell:
```bash
export MEM0_API_KEY="m0-your-api-key"
```
<Warning>
Already have `mem0` configured as an MCP server in Cursor? Remove the existing entry from your Cursor MCP settings before installing to avoid duplicate tools.
</Warning>
## Installation
### Option A — One-Click Deeplink (MCP Only)
The fastest way to get started. Click the link below to install the Mem0 MCP server directly in Cursor:
[Install Mem0 MCP in Cursor](cursor://anysphere.cursor-deeplink/mcp/install?name=mem0&config=eyJtY3BTZXJ2ZXJzIjp7Im1lbTAiOnsidXJsIjoiaHR0cHM6Ly9tY3AubWVtMC5haS9tY3AvIiwiaGVhZGVycyI6eyJBdXRob3JpemF0aW9uIjoiVG9rZW4gJHtlbnY6TUVNMF9BUElfS0VZfSJ9fX19)
### Option B — npx (MCP Only)
```bash
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "cursor"
```
### Option C — Manual Configuration (MCP Only)
Add the following to your `.cursor/mcp.json`:
```json
{
"mcpServers": {
"mem0": {
"url": "https://mcp.mem0.ai/mcp/",
"headers": {
"Authorization": "Token ${env:MEM0_API_KEY}"
}
}
}
}
```
### Option D — Cursor Marketplace (Full Plugin)
Install from the [Cursor Marketplace](https://cursor.com/marketplace) for the complete experience including lifecycle hooks, the Mem0 SDK skill, and automatic memory capture.
<Info icon="check">
Start a new Cursor session and ask: *"List my mem0 entities"* or *"Search my memories for hello"*. If the `mem0` tools appear and respond, you're all set.
</Info>
## What's Included
| Component | Marketplace Install | Deeplink / Manual / npx |
|-----------|:-------------------:|:-----------------------:|
| MCP Server (9 memory tools) | Yes | Yes |
| Lifecycle Hooks | Yes | No |
| Mem0 SDK Skill | Yes | No |
## Available MCP Tools
Once installed, the following tools are available in every Cursor session:
| Tool | Description |
|------|-------------|
| `add_memory` | Save text or conversation history for a user/agent |
| `search_memories` | Semantic search across memories with filters |
| `get_memories` | List memories with filters and pagination |
| `get_memory` | Retrieve a specific memory by ID |
| `update_memory` | Overwrite a memory's text by ID |
| `delete_memory` | Delete a single memory by ID |
| `delete_all_memories` | Bulk delete all memories in scope |
| `delete_entities` | Delete a user/agent/app/run entity and its memories |
| `list_entities` | List users/agents/apps/runs stored in Mem0 |
## Lifecycle Hooks (Marketplace Install)
When installed via the Cursor Marketplace, Mem0 hooks into Cursor's lifecycle:
### Session Start
On every new session, the plugin prompts the agent to call `search_memories` to load relevant context from prior sessions.
### User Prompt
Before processing each user message, the plugin searches Mem0 for relevant memories and injects them into context. Short prompts are skipped to minimize latency.
### Pre-Compaction
Before context compaction, the plugin captures a comprehensive session summary so nothing is lost when the context window resets.
## Example Workflow
```text
# Session 1: Debugging a performance issue
You: The API endpoint /users is taking 3 seconds. Help me optimize it.
# Cursor agent searches memories, proceeds with investigation.
# After completing the task, Mem0 stores:
# - Learning: "N+1 query in UserService.getAll() — fixed with eager loading"
# - Decision: "Added database index on users.email column"
# - Preference: "User prefers query-level fixes over caching"
# Session 2 (next week): Similar issue
You: The /orders endpoint is also slow, same pattern as before.
# Agent searches memories, retrieves the optimization learnings.
# Immediately checks for N+1 queries and missing indexes.
```
## Troubleshooting
- **"Connection failed"** — Verify `MEM0_API_KEY` is set: `echo $MEM0_API_KEY`
- **Duplicate tools** — If you had a previous MCP config for `mem0`, remove it before installing the plugin
- **No tools appearing** — Go to Cursor Settings > MCP and verify the `mem0` server shows as connected
- **Hooks not running** — Hooks require the Marketplace install (Option D). Deeplink/manual installs only provide MCP tools.
<CardGroup cols={2}>
<Card title="Mem0 MCP Setup" icon="puzzle-piece" href="/platform/mem0-mcp">
Detailed MCP configuration for all clients
</Card>
<Card title="Claude Code Integration" icon="terminal" href="/integrations/claude-code">
Add Mem0 memory to Claude Code workflows
</Card>
</CardGroup>
+8
View File
@@ -0,0 +1,8 @@
{
"mcpServers": {
"mem0": {
"url": "https://mcp.mem0.ai/mcp/",
"bearer_token_env_var": "MEM0_API_KEY"
}
}
}
+35
View File
@@ -0,0 +1,35 @@
{
"name": "mem0",
"version": "0.1.0",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search to Codex workflows using the Mem0 Platform MCP server.",
"author": {
"name": "Mem0",
"email": "support@mem0.ai"
},
"homepage": "https://mem0.ai",
"repository": "https://github.com/mem0ai/mem0",
"license": "Apache-2.0",
"skills": "./skills/",
"mcpServers": "./.codex-mcp.json",
"interface": {
"displayName": "Mem0",
"shortDescription": "Persistent memory layer for AI coding workflows",
"longDescription": "Mem0 adds long-term memory to Codex. Store decisions, user preferences, project context, and session state across conversations. Memories are automatically retrieved via semantic search so Codex always has the right context.",
"developerName": "Mem0",
"category": "Productivity",
"capabilities": [
"Read",
"Write"
],
"websiteURL": "https://mem0.ai",
"privacyPolicyURL": "https://mem0.ai/privacy",
"termsOfServiceURL": "https://mem0.ai/terms",
"defaultPrompt": [
"Search my memories for recent project decisions",
"Remember that I prefer TypeScript over JavaScript",
"What do you know about my coding preferences?"
],
"brandColor": "#FBBF24",
"logo": "./logo.svg"
}
}
+69 -8
View File
@@ -1,6 +1,6 @@
# Mem0 Plugin for Claude Code, Claude Cowork & Cursor
# Mem0 Plugin for Claude Code, Claude Cowork, Cursor & Codex
Add persistent memory to your AI workflows. Store, retrieve, and manage memories across sessions using the Mem0 Platform. Works with **Claude Code** (CLI), **Claude Cowork** (desktop app), and **Cursor**.
Add persistent memory to your AI workflows. Store, retrieve, and manage memories across sessions using the Mem0 Platform. Works with **Claude Code** (CLI), **Claude Cowork** (desktop app), **Cursor**, and **Codex**.
## Step 1: Set your API key
@@ -47,6 +47,65 @@ Claude Code and Claude Cowork share the same plugin system.
This installs the full plugin including the MCP server, lifecycle hooks (automatic memory capture), and the Mem0 SDK skill.
### Codex
**Option A — Repo marketplace** (recommended for teams):
Add the plugin marketplace to your repo root (already included in this repository):
```
.agents/plugins/marketplace.json
```
Then in Codex, browse the repo's plugin directory and install Mem0.
**Option B — Personal marketplace**:
Add to `~/.agents/plugins/marketplace.json`:
```json
{
"name": "mem0-plugins",
"interface": {
"displayName": "Mem0 Plugins"
},
"plugins": [
{
"name": "mem0",
"source": {
"source": "local",
"path": "/path/to/mem0/mem0-plugin"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
```
**Option C — Manual MCP configuration**:
Add to your Codex MCP config:
```json
{
"mcpServers": {
"mem0": {
"type": "http",
"url": "https://mcp.mem0.ai/mcp/",
"headers": {
"Authorization": "Token ${MEM0_API_KEY}"
}
}
}
}
```
This installs the MCP server and the Mem0 SDK skill. Codex uses the skill-based memory protocol instead of lifecycle hooks.
### Cursor
> **Already have `mem0` configured as an MCP server?** Remove the existing entry from your Cursor MCP settings before installing to avoid duplicate tools.
@@ -86,15 +145,17 @@ After installing, confirm the MCP server is connected:
## What's included
| Component | Claude Code / Cowork | Cursor (Marketplace) | Cursor (Deeplink/Manual) |
|-----------|:--------------------:|:--------------------:|:------------------------:|
| MCP Server | Yes | Yes | Yes |
| Lifecycle Hooks | Yes | Yes | No |
| Mem0 SDK Skill | Yes | Yes | No |
| Component | Claude Code / Cowork | Cursor (Marketplace) | Cursor (Deeplink/Manual) | Codex |
|-----------|:--------------------:|:--------------------:|:------------------------:|:-----:|
| MCP Server | Yes | Yes | Yes | Yes |
| Lifecycle Hooks | Yes | Yes | No | No |
| Mem0 SDK Skill | Yes | Yes | No | Yes |
| Memory Protocol Skill | No | No | No | Yes |
- **MCP Server** — Connects to the Mem0 remote MCP server (`mcp.mem0.ai`), providing tools to add, search, update, and delete memories. No local dependencies required.
- **Lifecycle Hooks** — Automatic memory capture at key points: session start, context compaction, task completion, and session end.
- **Lifecycle Hooks** — Automatic memory capture at key points: session start, context compaction, task completion, and session end. (Claude Code/Cursor only)
- **Mem0 SDK Skill** — Guides the AI on how to integrate the Mem0 SDK (Python & TypeScript) into your applications.
- **Memory Protocol Skill** — Codex-specific skill that instructs the agent to retrieve relevant memories at task start, store learnings on completion, and capture session state before context loss. Replaces lifecycle hooks on platforms that don't support them.
## MCP Tools
+62
View File
@@ -0,0 +1,62 @@
---
name: mem0-codex
description: >
Mem0 persistent memory integration for Codex. Automatically retrieve relevant
memories at the start of each task, store key learnings when tasks complete,
and capture session state before context is lost. Use the mem0 MCP tools
(add_memory, search_memories, get_memories, etc.) for all memory operations.
---
# Mem0 Memory Protocol for Codex
You have access to persistent memory via the mem0 MCP tools. Follow this protocol to maintain context across sessions.
## On every new task
1. Call `search_memories` with a query related to the current task or project to load relevant context.
2. Review returned memories to understand what has been learned in prior sessions.
3. If appropriate, call `get_memories` to browse all stored memories for this user.
## After completing significant work
Extract key learnings and store them using the `add_memory` tool:
- **Decisions made** -> Include metadata `{"type": "decision"}`
- **Strategies that worked** -> Include metadata `{"type": "task_learning"}`
- **Failed approaches** -> Include metadata `{"type": "anti_pattern"}`
- **User preferences observed** -> Include metadata `{"type": "user_preference"}`
- **Environment/setup discoveries** -> Include metadata `{"type": "environmental"}`
- **Conventions established** -> Include metadata `{"type": "convention"}`
Memories can be as detailed as needed -- include full context, reasoning, code snippets, file paths, and examples. Longer, searchable memories are more valuable than vague one-liners.
## Before losing context
If context is about to be compacted or the session is ending, store a comprehensive session summary:
```
## Session Summary
### User's Goal
[What the user originally asked for]
### What Was Accomplished
[Numbered list of tasks completed]
### Key Decisions Made
[Architectural choices, trade-offs discussed]
### Files Created or Modified
[Important file paths with what changed]
### Current State
[What is in progress, pending items, next steps]
```
Include metadata: `{"type": "session_state"}`
## Memory hygiene
- Do NOT write to MEMORY.md or any file-based memory. Use mem0 MCP tools exclusively.
- Only store genuinely useful learnings. Skip trivial interactions.
- Use specific, searchable language in memory content.
+18
View File
@@ -2,6 +2,24 @@
All notable changes to the `@mem0/openclaw-mem0` plugin will be documented in this file.
## [1.0.3] - 2026-04-03
### Fixed
- **Path traversal vulnerability**: Added `safePath()` containment helper to `readSkillFile` and `readDomainOverlay` in `skill-loader.ts` — prevents directory traversal via `config.domain` or the exported `loadSkill` API
- **Noise filter regression**: Reverted incorrect `After-Compaction` regex rename back to `Post-Compaction` so the filter correctly matches real upstream compaction audit messages
- **Cosmetic revert**: Restored `// Over-fetch for ranking` comment in `recall.ts` (was changed to work around a false-positive scanner match on the substring `fetch`)
### Changed
- **Supply-chain hardening**: Pinned `mem0ai` dependency to exact `2.3.0` (was `^2.3.0`)
### Added
- **Path traversal tests**: 12 new tests covering `safePath`, `readSkillFile`, `readDomainOverlay`, and `loadSkill` with traversal inputs
## [1.0.2] - 2026-04-02
### Fixed
- **Security scanner warning**: Removed `resolveEnvVars()` and `resolveEnvVarsDeep()` from `config.ts` — OpenClaw already resolves `${VAR}` in `openclaw.json` before passing config to the plugin, so plugin-side env resolution was redundant and triggered the "credential harvesting" static analysis warning ([#4676](https://github.com/mem0ai/mem0/pull/4676))
## [1.0.1] - 2026-04-02
### Added
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@mem0/openclaw-mem0",
"version": "1.0.2",
"version": "1.0.3",
"type": "module",
"description": "Mem0 memory backend for OpenClaw — platform or self-hosted open-source",
"license": "Apache-2.0",
@@ -35,7 +35,7 @@
},
"dependencies": {
"@sinclair/typebox": "0.34.47",
"mem0ai": "^2.3.0"
"mem0ai": "2.3.0"
},
"openclaw": {
"extensions": [
+5 -5
View File
@@ -12,8 +12,8 @@ importers:
specifier: 0.34.47
version: 0.34.47
mem0ai:
specifier: ^2.3.0
version: 2.4.0(@anthropic-ai/sdk@0.40.1)(@azure/identity@4.13.0)(@azure/search-documents@12.2.0)(@cloudflare/workers-types@4.20260313.1)(@google/genai@1.45.0)(@langchain/core@0.3.80(openai@4.104.0(ws@8.19.0)(zod@3.25.76)))(@mistralai/mistralai@1.15.1)(@qdrant/js-client-rest@1.13.0(typescript@5.9.3))(@supabase/supabase-js@2.99.1)(@types/jest@29.5.14)(@types/pg@8.11.0)(better-sqlite3@12.8.0)(cloudflare@4.5.0)(groq-sdk@0.3.0)(neo4j-driver@5.28.3)(ollama@0.5.18)(pg@8.11.3)(redis@4.7.1)(ws@8.19.0)
specifier: 2.3.0
version: 2.3.0(@anthropic-ai/sdk@0.40.1)(@azure/identity@4.13.0)(@azure/search-documents@12.2.0)(@cloudflare/workers-types@4.20260313.1)(@google/genai@1.45.0)(@langchain/core@0.3.80(openai@4.104.0(ws@8.19.0)(zod@3.25.76)))(@mistralai/mistralai@1.15.1)(@qdrant/js-client-rest@1.13.0(typescript@5.9.3))(@supabase/supabase-js@2.99.1)(@types/jest@29.5.14)(@types/pg@8.11.0)(better-sqlite3@12.8.0)(cloudflare@4.5.0)(groq-sdk@0.3.0)(neo4j-driver@5.28.3)(ollama@0.5.18)(pg@8.11.3)(redis@4.7.1)(ws@8.19.0)
devDependencies:
'@types/node':
specifier: ^22.15.0
@@ -1466,8 +1466,8 @@ packages:
md5@2.3.0:
resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==}
mem0ai@2.4.0:
resolution: {integrity: sha512-b1V8KXUse8ySvio8D0bRHOvgxa9BlmP4g4bjtEnA3uILcu+2PAtcAiHDPdBxUIeoxTxAeJM+0wBGaMIps4bIaw==}
mem0ai@2.3.0:
resolution: {integrity: sha512-9e0B9hgM7nxnKDD6zmSRkfkrQ2sa9tGdpZE3CPsp7eIu18soYbXvm9YT08mllCYuiW+EdEW7L/+DNCphOfvkKQ==}
engines: {node: '>=18'}
peerDependencies:
'@anthropic-ai/sdk': ^0.40.1
@@ -3543,7 +3543,7 @@ snapshots:
crypt: 0.0.2
is-buffer: 1.1.6
mem0ai@2.4.0(@anthropic-ai/sdk@0.40.1)(@azure/identity@4.13.0)(@azure/search-documents@12.2.0)(@cloudflare/workers-types@4.20260313.1)(@google/genai@1.45.0)(@langchain/core@0.3.80(openai@4.104.0(ws@8.19.0)(zod@3.25.76)))(@mistralai/mistralai@1.15.1)(@qdrant/js-client-rest@1.13.0(typescript@5.9.3))(@supabase/supabase-js@2.99.1)(@types/jest@29.5.14)(@types/pg@8.11.0)(better-sqlite3@12.8.0)(cloudflare@4.5.0)(groq-sdk@0.3.0)(neo4j-driver@5.28.3)(ollama@0.5.18)(pg@8.11.3)(redis@4.7.1)(ws@8.19.0):
mem0ai@2.3.0(@anthropic-ai/sdk@0.40.1)(@azure/identity@4.13.0)(@azure/search-documents@12.2.0)(@cloudflare/workers-types@4.20260313.1)(@google/genai@1.45.0)(@langchain/core@0.3.80(openai@4.104.0(ws@8.19.0)(zod@3.25.76)))(@mistralai/mistralai@1.15.1)(@qdrant/js-client-rest@1.13.0(typescript@5.9.3))(@supabase/supabase-js@2.99.1)(@types/jest@29.5.14)(@types/pg@8.11.0)(better-sqlite3@12.8.0)(cloudflare@4.5.0)(groq-sdk@0.3.0)(neo4j-driver@5.28.3)(ollama@0.5.18)(pg@8.11.3)(redis@4.7.1)(ws@8.19.0):
dependencies:
'@anthropic-ai/sdk': 0.40.1
'@azure/identity': 4.13.0
+70
View File
@@ -0,0 +1,70 @@
/**
* Tests for path traversal prevention in skill-loader.
*/
import { describe, it, expect } from "vitest";
import { safePath, loadSkill } from "./skill-loader.ts";
// ---------------------------------------------------------------------------
// safePath — path containment
// ---------------------------------------------------------------------------
describe("safePath", () => {
it("rejects parent directory traversal", () => {
expect(safePath("../../etc/passwd")).toBeNull();
});
it("rejects deep traversal", () => {
expect(safePath("../../../etc/shadow")).toBeNull();
});
it("rejects traversal in nested segment", () => {
expect(safePath("valid", "../../etc")).toBeNull();
});
it("rejects bare '..' as segment", () => {
expect(safePath("..")).toBeNull();
});
it("accepts valid skill paths", () => {
expect(safePath("memory-triage", "SKILL.md")).not.toBeNull();
});
it("accepts valid domain overlay paths", () => {
expect(safePath("memory-triage", "domains", "companion.md")).not.toBeNull();
});
it("returns null for empty segments that resolve to skills root with subpath escape", () => {
// path.resolve("skills", "", "../../etc") still escapes
expect(safePath("", "../../etc")).toBeNull();
});
it("rejects traversal disguised with valid prefix", () => {
expect(safePath("memory-triage/../../etc/passwd")).toBeNull();
});
});
// ---------------------------------------------------------------------------
// loadSkill — integration tests for traversal prevention
// ---------------------------------------------------------------------------
describe("loadSkill path traversal", () => {
it("returns null for traversal skillName", () => {
expect(loadSkill("../../etc/passwd")).toBeNull();
});
it("returns null for deep traversal skillName", () => {
expect(loadSkill("../../../..")).toBeNull();
});
it("loads a valid skill", () => {
const result = loadSkill("memory-triage");
expect(result).not.toBeNull();
expect(result?.prompt).toBeTruthy();
});
it("blocks domain traversal while loading valid skill", () => {
// Valid skill name, malicious domain — should load skill but skip the overlay
const result = loadSkill("memory-triage", { domain: "../../etc/passwd" });
// Should still succeed (skill itself is valid), domain overlay is just skipped
expect(result).not.toBeNull();
expect(result?.prompt).toBeTruthy();
});
});
+20 -4
View File
@@ -110,10 +110,26 @@ function resolveSkillsDir(): string {
}
const SKILLS_DIR = resolveSkillsDir();
const RESOLVED_SKILLS_DIR = path.resolve(SKILLS_DIR);
/**
* Resolve path segments under SKILLS_DIR and verify the result doesn't escape.
* Returns null if the resolved path is outside the skills directory (path traversal).
* Note: path.resolve follows symlinks lexically; the skills directory is
* package-owned so symlink escape is not a practical concern.
*/
export function safePath(...segments: string[]): string | null {
const resolved = path.resolve(SKILLS_DIR, ...segments);
if (resolved !== RESOLVED_SKILLS_DIR &&
!resolved.startsWith(RESOLVED_SKILLS_DIR + path.sep)) {
return null;
}
return resolved;
}
function readSkillFile(skillName: string): string | null {
// Skills use OpenClaw directory format: <skill-name>/SKILL.md
const filePath = path.join(SKILLS_DIR, skillName, "SKILL.md");
const filePath = safePath(skillName, "SKILL.md");
if (!filePath) return null;
try {
return fs.readFileSync(filePath, "utf-8");
} catch {
@@ -127,8 +143,8 @@ function readSkillFile(skillName: string): string | null {
* The `applies_to` frontmatter field is checked for backward compatibility.
*/
function readDomainOverlay(domain: string, targetSkill: string): string | null {
// Domain overlays are stored inside the target skill's directory
const filePath = path.join(SKILLS_DIR, targetSkill, "domains", `${domain}.md`);
const filePath = safePath(targetSkill, "domains", `${domain}.md`);
if (!filePath) return null;
try {
const content = fs.readFileSync(filePath, "utf-8");
const parsed = parseSkillFile(content);