Skip to content

Commit 7e45720

Browse files
authored
Merge pull request #1632 from undeadindustries/feat/cursor-hooks-support
feat: add Cursor IDE support (hooks, plugin, skill, docs, tests)
2 parents 2ec4bae + 8e19e81 commit 7e45720

36 files changed

Lines changed: 4592 additions & 5 deletions
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
name: mempalace-recall
3+
description: Recall protocol for MemPalace — search the palace before answering about past work, prior decisions, people, or projects. Use when the user asks what was decided, what happened before, who someone is, what was discussed last time, or anything that may already be filed in their memory palace.
4+
allowed-tools: Bash
5+
---
6+
7+
# MemPalace Recall
8+
9+
Search-before-answer protocol for MemPalace. Read the user's memory
10+
palace before answering anything that may already be filed there,
11+
instead of guessing from model memory. This complements the `mempalace`
12+
skill (install / mine / status); this one covers recall only.
13+
14+
## Step 0 — Verify MemPalace is available
15+
16+
```bash
17+
mempalace --version
18+
```
19+
20+
If the `mempalace_*` MCP tools are not available, tell the user the
21+
server is not connected and point them at the `mempalace` skill or
22+
`/init`. Do not silently fall back to answering from model memory.
23+
24+
## When to recall
25+
26+
Search the palace **before answering** whenever the user asks about
27+
something that may be filed:
28+
29+
- Past work or prior decisions — "what did we decide / try / do?"
30+
- A person, project, or entity — "who is …", "what is …"
31+
- An earlier session — "remember when …", "last time …"
32+
- A preference, fact, or relationship that could have changed over time
33+
34+
Skip recall for pure greenfield work with no memory relevance (renaming
35+
a variable, fixing a typo). Recall is question-driven, not reflexive.
36+
37+
## Protocol
38+
39+
1. Before responding about people / projects / past events / prior
40+
decisions: call `mempalace_search` first. Use `mempalace_kg_query`
41+
for relational or time-bound facts.
42+
2. If unsure about a fact: say "let me check the palace" and query.
43+
3. Return the drawer's **verbatim** text — never summarize or paraphrase
44+
stored content.
45+
4. After a substantive session, record continuity with
46+
`mempalace_diary_write` (skip if a background hook already saved).
47+
5. When a fact changes: `mempalace_kg_invalidate` the old fact, then
48+
`mempalace_kg_add` the new one.
49+
50+
## Unhappy paths
51+
52+
- **Empty results** — say the palace has nothing on this; do not invent
53+
an answer. Offer to widen the search or file the new information.
54+
- **MCP error / server down** — surface the error, suggest `mempalace
55+
status` or re-running `/init`; never fall back to guessing.
56+
- **Conflicting facts** — trust the knowledge graph's time-valid answer;
57+
invalidate-then-add rather than overwriting silently.
58+
59+
The canonical protocol, shared across all MemPalace integrations, lives
60+
in `integrations/shared/recall-protocol.md`.

.cursor-plugin/README.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# MemPalace Cursor Plugin
2+
3+
A Cursor IDE plugin that gives your agent a persistent memory system. Auto-registers the `mempalace-mcp` server (19 MCP tools), ships 5 slash commands, two model-invocable skills (setup/mining/search and a recall protocol), and an optional recall rule.
4+
5+
> Hooks (auto-save + session-start memory recall) are shipped separately under `hooks/cursor/` so the plugin is safe to install in any Cursor workspace without touching the agent loop. See [Hooks](#hooks-optional) below.
6+
7+
## Prerequisites
8+
9+
- Python 3.9+
10+
- Cursor 1.7+ (plugin manifest schema requires it)
11+
12+
## Installation
13+
14+
### Local clone (recommended while not in the marketplace yet)
15+
16+
Symlink (or copy) this repository into Cursor's local plugins folder:
17+
18+
```bash
19+
ln -s /path/to/mempalace ~/.cursor/plugins/local/mempalace
20+
```
21+
22+
Then in Cursor: <kbd>Cmd</kbd>-<kbd>Shift</kbd>-<kbd>P</kbd> → **Developer: Reload Window**.
23+
24+
### Marketplace
25+
26+
Once published, install via the Cursor marketplace panel and select `mempalace`. Required-plugin distribution from a team marketplace is also supported.
27+
28+
## Post-Install Setup
29+
30+
After installing the plugin, run the `init` command in a Cursor chat:
31+
32+
```
33+
/mempalace-init
34+
```
35+
36+
(Or just say "use the mempalace skill" — Cursor will model-invoke the bundled skill.)
37+
38+
This installs the `mempalace` package via `uv tool` or `pip`, initializes a palace under `~/.mempalace/`, and verifies the MCP server is reachable.
39+
40+
## Available Slash Commands
41+
42+
| Command | Description |
43+
|---------------------|-----------------------------------------------------------------------------------|
44+
| `/mempalace-help` | Show available tools, skills, CLI commands, hooks, and architecture |
45+
| `/mempalace-init` | Set up MemPalace — install, configure, onboard |
46+
| `/mempalace-search` | Search your memories across the palace using semantic search |
47+
| `/mempalace-mine` | Mine projects and conversations into the palace |
48+
| `/mempalace-status` | Show palace overview — wings, rooms, drawer counts |
49+
50+
> Cursor commands are global, not plugin-namespaced — that's why each slug is prefixed with `mempalace-` rather than appearing as `/help`, `/init`, etc. This keeps them collision-free with built-in or other-plugin commands.
51+
52+
## Skills
53+
54+
Two model-invocable skills ship at the plugin root under `skills/`:
55+
56+
| Skill | What it does |
57+
|-------|--------------|
58+
| `mempalace` | Setup, mining, status, and the dynamic `mempalace instructions` CLI. |
59+
| `mempalace-recall` | Search-before-answer protocol — makes the agent read the palace before answering about past work, people, projects, or prior decisions instead of guessing. |
60+
61+
Cursor surfaces these automatically when a request matches their description, or you can attach them explicitly.
62+
63+
## Recall rule (optional)
64+
65+
The plugin also ships a Cursor rule at the plugin root under `rules/mempalace-recall.mdc`:
66+
67+
```yaml
68+
description: When the user asks about past work, prior decisions, people, ... call mempalace_search before answering ...
69+
alwaysApply: false
70+
```
71+
72+
It is `alwaysApply: false` on purpose — Cursor loads it only when its matcher judges the turn recall-relevant, so it never fires on unrelated coding work and never adds MCP latency to greenfield tasks. The rule, the `mempalace-recall` skill, and the `sessionStart` hook all reference the same canonical protocol in [`integrations/shared/recall-protocol.md`](../integrations/shared/recall-protocol.md).
73+
74+
Want recall forced into **every** conversation regardless of context? Copy the aggressive `alwaysApply: true` variant from [`examples/cursor/rules/`](../examples/cursor/rules/README.md) into `~/.cursor/rules/`. That is a deliberate, heavier opt-in, not a default.
75+
76+
## MCP Server
77+
78+
This plugin ships `mcp.json` at the plugin root, so Cursor auto-loads the `mempalace-mcp` server on plugin install:
79+
80+
```json
81+
{
82+
"mempalace": {
83+
"command": "mempalace-mcp"
84+
}
85+
}
86+
```
87+
88+
All 19 MemPalace MCP tools (`mempalace_search`, `mempalace_add_drawer`, `mempalace_diary_write`, `mempalace_check_duplicate`, `mempalace_diary_read`, …) become available to the agent immediately. No manual `~/.cursor/mcp.json` edit required.
89+
90+
If the server doesn't appear, confirm `mempalace-mcp` is on the user `$PATH`:
91+
92+
```bash
93+
command -v mempalace-mcp
94+
```
95+
96+
If it isn't, run `/init` (or `mempalace install` from a terminal) — `mempalace-mcp` is installed alongside the `mempalace` package.
97+
98+
## Hooks (optional)
99+
100+
Cursor's hooks system is configured separately from plugins (in `~/.cursor/hooks.json` or `.cursor/hooks.json`), so this plugin does **not** wire hooks itself. The MemPalace repository ships three Cursor-native hooks under [`hooks/cursor/`](../hooks/cursor/) that you install with one command.
101+
102+
User scope — writes `~/.cursor/hooks.json`, applies to every Cursor workspace (recommended):
103+
104+
```bash
105+
hooks/cursor/install.sh --scope user --variant full
106+
```
107+
108+
Project scope — writes `.cursor/hooks.json` under the current project only:
109+
110+
```bash
111+
hooks/cursor/install.sh --scope project --variant full
112+
```
113+
114+
What you get:
115+
116+
| Hook event | What it does |
117+
|----------------|-------------------------------------------------------------------------------------------------------|
118+
| `sessionStart` | Injects an `additional_context` recap of relevant memories scoped to the workspace wing |
119+
| `stop` | Counts agent turns; every N turns, emits a `followup_message` instructing a memory checkpoint |
120+
| `preCompact` | Synchronously mines the transcript before compaction, drops a marker so the next `stop` saves a diary |
121+
122+
Full details: [`website/guide/cursor-hooks.md`](../website/guide/cursor-hooks.md) and [`hooks/cursor/README.md`](../hooks/cursor/README.md).
123+
124+
## Uninstall
125+
126+
Remove the local plugin symlink:
127+
128+
```bash
129+
rm ~/.cursor/plugins/local/mempalace
130+
```
131+
132+
Then in Cursor: <kbd>Cmd</kbd>-<kbd>Shift</kbd>-<kbd>P</kbd> → **Developer: Reload Window**.
133+
134+
If you also installed the hooks, remove them (leaves any unrelated hooks in `hooks.json` untouched):
135+
136+
```bash
137+
hooks/cursor/install.sh --scope user --uninstall
138+
```
139+
140+
## Full Documentation
141+
142+
See the main [README](../README.md) for complete documentation, architecture details, and advanced usage.

.cursor-plugin/marketplace.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "mempalace",
3+
"owner": {
4+
"name": "milla-jovovich",
5+
"url": "https://github.com/MemPalace"
6+
},
7+
"plugins": [
8+
{
9+
"name": "mempalace",
10+
"source": ".",
11+
"description": "AI memory system — mine projects and conversations into a searchable palace. 19 MCP tools, slash commands, and a guided skill for Cursor.",
12+
"author": {
13+
"name": "milla-jovovich"
14+
}
15+
}
16+
]
17+
}

.cursor-plugin/mcp.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"mcpServers": {
3+
"mempalace": {
4+
"command": "mempalace-mcp"
5+
}
6+
}
7+
}

.cursor-plugin/plugin.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "mempalace",
3+
"description": "Give your AI a memory — mine projects and conversations into a searchable palace. 19 MCP tools, slash commands, and a guided skill for Cursor.",
4+
"author": {
5+
"name": "milla-jovovich"
6+
},
7+
"homepage": "https://github.com/MemPalace/mempalace",
8+
"repository": "https://github.com/MemPalace/mempalace",
9+
"license": "MIT",
10+
"keywords": [
11+
"memory",
12+
"ai",
13+
"rag",
14+
"mcp",
15+
"chromadb",
16+
"palace",
17+
"search"
18+
]
19+
}

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
1010

1111
### Features
1212

13+
- **Cursor IDE plugin (`.cursor-plugin/`).** Drops into `~/.cursor/plugins/local/mempalace` (or installs from the Cursor marketplace once published) and auto-registers the `mempalace-mcp` server, five slash commands (`/mempalace-help`, `/mempalace-init`, `/mempalace-mine`, `/mempalace-search`, `/mempalace-status`), and the model-invocable [`mempalace` skill](.cursor-plugin/skills/mempalace/SKILL.md) — no manual `~/.cursor/mcp.json` edit required. The plugin manifest deliberately omits a hardcoded `version` field — `mempalace/version.py` is the single source of truth, so there is nothing to drift on the next release (a contract test enforces the field stays absent). The canonical plugin components (`commands/`, `skills/`, `mcp.json`) are real files at the plugin root; no symlinks are committed (committed symlinks materialise as broken text files on Windows clones with `core.symlinks=false`). Mirrors the surface of [`.claude-plugin/`](.claude-plugin/) and [`.codex-plugin/`](.codex-plugin/) without duplicating their hook scripts: the Cursor hook scripts under [`hooks/cursor/`](hooks/cursor/) (shipped in the same release) remain the canonical install path for `stop` / `preCompact` / `sessionStart`, wired separately by [`hooks/cursor/install.sh`](hooks/cursor/install.sh). Contract tests in [`tests/test_cursor_plugin_manifest.py`](tests/test_cursor_plugin_manifest.py) cover manifest JSON validity, kebab-case naming, `..`-free relative paths, on-disk path resolution, marketplace alignment, MCP config shape (`mcpServers` wrapper required by Cursor, unlike Claude's flat `.mcp.json`), the version-field-absent guard, the no-symlink guard, and every skill/command frontmatter — all pure file inspection so they run on any CI platform without Cursor itself.
14+
15+
- **Cursor IDE hook support (`stop` / `preCompact` / `sessionStart`).** Three new bash hooks live under [`hooks/cursor/`](hooks/cursor/) and share a `lib/common.sh` helpers module. The save hook counts `stop` invocations per Cursor `conversation_id` and emits a `followup_message` every `MEMPAL_SAVE_INTERVAL` (default 15) so the agent files the session into MemPalace and writes a diary entry. Unlike the silent-by-default Claude Code hook, the Cursor followup fires **on by default**: Cursor's transcript format is undocumented and `normalize.py` has no Cursor parser yet, so the background `mempalace mine --mode convos` is best-effort only and the `followup_message` is the load-bearing verbatim-capture path. Users who want the Claude-style "zero tokens in the chat window" behaviour can suppress it with `MEMPAL_CURSOR_SILENT=1` (or `MEMPAL_VERBOSE=false`); the default flips to silent once a Cursor transcript parser lands. The precompact hook synchronously mines the transcript before Cursor's compaction summarises it and drops a marker so the next `stop` forces a save nudge (Cursor's `preCompact` is observational-only — it cannot block or emit a `followup_message`, unlike Claude Code's `PreCompact`); the synchronous mine is bounded by Cursor's per-hook timeout, and because `mempalace mine` is incremental/append-only a killed mine resumes cleanly on the next run rather than corrupting the palace. The wake hook is Cursor-only: `sessionStart` returns `additional_context` telling the agent to recall scoped to the wing inferred from the workspace root. Honours the same `MEMPALACE_HOOKS_AUTO_SAVE=false` kill switch as the Claude Code hooks, plus a new `MEMPAL_DISABLE_HOOK=1` alias and a `MEMPAL_STATE_DIR` env override. Per-conversation state files are garbage-collected by a daily-throttled, Cursor-namespaced TTL sweep (`MEMPAL_STATE_TTL_DAYS`, default 30) so `cursor_*.count` / `cursor_*.pending` cannot grow unbounded — shared logs and other editors' state are never touched. Includes an opt-in installer at [`hooks/cursor/install.sh`](hooks/cursor/install.sh) with `--scope user|project`, `--variant full|minimal`, `--dry-run`, and `--uninstall` (idempotent, preserves unrelated hooks via `python3`-based JSON merge — no `jq` dependency). Example wirings live at [`examples/cursor/hooks.json`](examples/cursor/hooks.json) and [`examples/cursor/hooks.minimal.json`](examples/cursor/hooks.minimal.json); they are intentionally not placed at the repo root because Cursor auto-loads project hooks from any trusted workspace and we do not arm hooks on contributor checkout. Per-event stdin/stdout schema documented at [`hooks/cursor/STDIN_SHAPE.md`](hooks/cursor/STDIN_SHAPE.md). Walkthrough at [`website/guide/cursor-hooks.md`](website/guide/cursor-hooks.md). Coverage added in [`tests/test_cursor_hooks_shell.py`](tests/test_cursor_hooks_shell.py) and [`tests/test_cursor_hooks_install.py`](tests/test_cursor_hooks_install.py).
16+
1317
- **First-class Antigravity IDE support.** New `.antigravity-plugin/` package + idempotent installer at `hooks/antigravity/install.sh` that registers MemPalace as a Google Antigravity plugin (MCP server, skill, two lifecycle hooks) at `~/.gemini/config/plugins/mempalace/`. The Stop hook background-mines the active conversation transcript every Nth fire (default 15, configurable via `MEMPAL_SAVE_INTERVAL`); the PreInvocation hook injects verbatim memory on the first model call only via Antigravity's `injectSteps[].ephemeralMessage` output, gated by `invocationNum == 1`. Both hooks are bash 3.2.57 compatible (macOS default), use the same `~/.mempalace/hook_state/` directory as the Claude Code / Codex / Cursor hooks (`antigravity_*`-namespaced state files), and respect every existing kill switch (`MEMPAL_DISABLE_HOOK`, `MEMPALACE_HOOKS_AUTO_SAVE`, `~/.mempalace/config.json` `hooks.auto_save`). Installer is `cmp`-gated (re-run produces a byte-identical install), uninstall is basename-guarded (refuses to wipe a directory whose basename isn't `mempalace`), and `--dry-run` is side-effect free. Full audit of which Antigravity surfaces we ship and which we deliberately don't is in [`hooks/antigravity/INVESTIGATION.md`](hooks/antigravity/INVESTIGATION.md). User-facing guide: [`website/guide/antigravity.md`](website/guide/antigravity.md). Standalone examples in [`examples/antigravity/`](examples/antigravity/).
1418
- **Zero-config interpreter resolution.** `mempal_resolve_python` now derives the Python interpreter from the `mempalace-mcp` / `mempalace` console-script shebang on `$PATH` before falling back to `python3`. The common `uv tool install mempalace` / `pipx install` layout installs the console scripts into an isolated environment whose interpreter is **not** system `python3`, so the previous `command -v python3` resolution landed on a Python that couldn't import `mempalace`, the `-m mempalace` probe failed, and mining silently never fired. Resolution is pure shebang parsing + `stat` (no Python subprocess at source time, preserving the hook performance budget). `MEMPAL_PYTHON` remains the explicit override. Documented under *How the hooks find your `mempalace` install* in the guide.
1519

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,14 @@ system prompt:
239239

240240
## Auto-save hooks
241241

242-
Two Claude Code hooks save periodically and before context compression:
243-
[mempalaceofficial.com/guide/hooks](https://mempalaceofficial.com/guide/hooks.html).
242+
Auto-save hooks for **Claude Code, Codex CLI, and Cursor IDE** save
243+
periodically and before context compression:
244+
245+
- Claude Code + Codex →
246+
[mempalaceofficial.com/guide/hooks](https://mempalaceofficial.com/guide/hooks.html)
247+
- Cursor IDE (adds session-start recall and a transcript snapshot before
248+
compaction) →
249+
[mempalaceofficial.com/guide/cursor-hooks](https://mempalaceofficial.com/guide/cursor-hooks.html)
244250

245251
If you are installing under time pressure, start with the
246252
[Claude Code retention setup checklist](https://mempalaceofficial.com/guide/claude-code-retention.html):

commands/mempalace-help.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
description: Show comprehensive MemPalace help — available skills, MCP tools, CLI commands, hooks, and architecture.
3+
---
4+
5+
Invoke the `mempalace` skill from this plugin and run the `help` instructions, then follow them.
6+
7+
Concretely: run `mempalace instructions help` in a terminal, then carry out the steps it prints.

commands/mempalace-init.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
description: Set up MemPalace — install the package, initialize a palace, register the MCP server with Cursor, and verify everything works.
3+
---
4+
5+
Invoke the `mempalace` skill from this plugin and run the `init` instructions, then follow them.
6+
7+
Concretely: run `mempalace instructions init` in a terminal, then carry out the steps it prints.
8+
9+
Cursor-specific extras after init:
10+
11+
1. The `mempalace-mcp` server is already auto-registered by this plugin — no manual `mcp.json` edit needed.
12+
2. For automatic background saves and session-start memory recall, also run `hooks/cursor/install.sh --scope user` from a cloned MemPalace repo. See `website/guide/cursor-hooks.md` for the walkthrough.

commands/mempalace-mine.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
description: Mine projects and conversations into the MemPalace. Supports project files, conversation exports, and auto-classification.
3+
---
4+
5+
Invoke the `mempalace` skill from this plugin and run the `mine` instructions, then follow them.
6+
7+
Concretely: run `mempalace instructions mine` in a terminal, then carry out the steps it prints.

0 commit comments

Comments
 (0)