# How do I use jevmem in Cursor?

Run `jevmem init --tool cursor` in your project: it adds jevmem's MCP server to `.cursor/mcp.json` and writes a rule, `.cursor/rules/jevmem.mdc`, that tells Cursor's agent to save a decision with `add_memory` when you state one and to call `search_memory` before a non-trivial task.

Last updated: 2026-10-04 · jevmem 0.6.4 · [Install](https://avinash-jetwani.github.io/jevmem/install/) · [Source on GitHub](https://github.com/Avinash-jetwani/jevmem)

In Cursor, jevmem saves only when the agent calls it; saving is automatic in Claude Code, and in Codex while `jevmem watch` runs. A line the agent adds goes through the same check as a Claude Code turn: on 66 held-out turns that check was right on save or skip for 98.5% (jevmem 0.6.0, one run on 2026-09-30, [results](https://github.com/Avinash-jetwani/jevmem/blob/main/results/eval-heldout-2026-09-30-v060.json)). Those turns were given to the decider directly; nothing has been measured inside Cursor.

## Set it up

1. Install the CLI:
   ```bash
   npm install -g jevmem
   ```
2. Save your [TypeSafe API key](https://console.typesafe.ai/keys) (paste it when asked; it isn't shown):
   ```bash
   jevmem key
   ```
3. In your project's folder:
   ```bash
   jevmem init --tool cursor
   ```
4. Reload the Cursor window, so that it picks up the MCP server.

`init` also creates `JEVMEM.md`, `jevmem.config.json` and a gitignored `.jevmem/` folder in the project. Every install path: [install](https://avinash-jetwani.github.io/jevmem/install/).

## The MCP config, if you write it yourself

`.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):

```json
{
  "mcpServers": {
    "jevmem": {
      "command": "npx",
      "args": ["-y", "jevmem", "mcp"],
      "env": { "TYPESAFE_API_KEY": "${env:TYPESAFE_API_KEY}" }
    }
  }
}
```

## What the agent can call

`jevmem mcp` starts a stdio MCP server with four tools:

| Tool | Args | Jev calls | Annotations (readOnly / destructive / idempotent / openWorld) |
|---|---|---|---|
| `search_memory` | `query`, `limit?` | 1 (choice over ids + noul per candidate, + a poisoning-gate noul per unverified, unchecked candidate) | true / false / true / true |
| `add_memory` | `text`, `kind` | 1, or 2 on a borderline line (the hook's decide: scrub, then refuse injection / small talk / duplicates; Jev may correct the kind; a contradiction supersedes the old line) | false / true / false / true |
| `list_memory` | `include_superseded?` | 0, or 1 when unverified lines have no cached gate verdict (the poisoning gate alone) | true / false / true / true |
| `audit_memory` | `apply?` | ⌈memories / 60⌉ | false / true / true / true |

In a project without `jevmem.config.json` (not opted in with `jevmem enable` or `jevmem init`) every tool returns only "jevmem isn't enabled in this project: run `jevmem enable`" and does nothing else: no Jev call, no file.

`search_memory` and `list_memory` never return a line the [poisoning gate](https://github.com/Avinash-jetwani/jevmem/blob/main/SECURITY.md#memory-poisoning) withholds (they list it under `withheld` with the reason instead), and `list_memory` without a key withholds unverified lines it cannot check. Both are marked open-world because they may ask Jev.

`add_memory` takes `kind` ∈ `decision | constraint | preference | bug | architecture | todo`, and, since 0.6.0, `dead-end`: an approach that was tried and failed or was dropped. A dead-end line must say what was tried and why, and Jev decides whether it does (the dead-end noul, in the request `add_memory` already makes, at `thresholds.deadEndMin`), or it is refused ("a dead end must say why it failed or was dropped, and Jev found no reason in this line"); a line Jev reads as a dead end with no reason keeps the kind you gave. A retry of a saved dead end that failed again for the reason that line gives is refused ("a retry that failed again adds nothing"); for a new reason, the saved line is the old line's reason followed by "retried:" and yours, and it replaces the old line ([Dead ends](https://github.com/Avinash-jetwani/jevmem/blob/main/docs/dead-ends.md#when-it-is-tried-again)). `search_memory` and `list_memory` return dead ends with `"kind": "dead-end"`; the Claude Code hook injects them as `Already tried: <line>` ([Dead ends](https://github.com/Avinash-jetwani/jevmem/blob/main/docs/dead-ends.md)).

Both writing tools are marked destructive because they can change existing lines, not only add new ones: `add_memory` re-tags a contradicted memory `[superseded]`, which takes it out of what is served (the line stays in the file), and `audit_memory` with `apply: true` sets or clears `[stale?]` flags on existing lines (flagged lines keep their text and stay live).

The `Dockerfile` at the repository root is for MCP directories that inspect a server in a sandbox (Glama builds it, starts the server and calls `tools/list`): it installs the jevmem CLI from npm and starts `jevmem mcp` on an empty folder, where the server lists its four tools and a call to one replies that jevmem isn't enabled there. It needs no key. It is not a way to run jevmem: the server works on the project it is started in.

## What is automatic in each tool

What is automatic and what depends on the agent:

| Tool | Setup | Capture | Recall |
|---|---|---|---|
| **Claude Code** | the plugin, or `jevmem init --tool claude` | **Automatic**, every turn, via the `Stop` hook | **Automatic**, every prompt, via `UserPromptSubmit` |
| **Codex** | `jevmem init --tool codex` | **Automatic while `jevmem watch` runs** (it tails Codex's session log for this project and runs the same decide → write path); otherwise agent-initiated via MCP `add_memory`, prompted by an `AGENTS.md` section | Agent-initiated: `search_memory` via MCP, prompted by `AGENTS.md` |
| **Cursor** | `jevmem init --tool cursor` | Agent-initiated: a `.cursor/rules/jevmem.mdc` rule tells the agent to call MCP `add_memory` when you state a decision. Nothing is captured if it doesn't | Agent-initiated: the rule tells it to call `search_memory` before non-trivial tasks |
| **Claude Desktop** | `jevmem init --tool claude-desktop` prints a config snippet to paste (one project per config, named with `--root`) | Manual: ask it to call `add_memory` (no hook, no rule file) | On request: `search_memory` |

MCP `add_memory` goes through the same gate as the hook. Client configs: [docs/mcp.md](https://github.com/Avinash-jetwani/jevmem/blob/main/docs/mcp.md).

## The limits, in short

- jevmem needs a TypeSafe API key ([where to get one, and the install steps](https://avinash-jetwani.github.io/jevmem/install/)).
- Message text is sent to TypeSafe to be scored, with common secrets scrubbed first ([what leaves your machine](https://avinash-jetwani.github.io/jevmem/privacy/)).
- It is automatic in Claude Code, automatic in Codex while `jevmem watch` runs, and in Cursor only when the agent calls it ([what each tool does](https://avinash-jetwani.github.io/jevmem/install/#works-with)).
- Rules every task must follow still belong in `CLAUDE.md` ([jevmem next to CLAUDE.md](https://avinash-jetwani.github.io/jevmem/compare/)).
- The guard is a backstop, not a sandbox ([what it misses](https://avinash-jetwani.github.io/jevmem/guard/#limits)).

Every limit, with the numbers: [the FAQ](https://avinash-jetwani.github.io/jevmem/faq/#what-are-jevmems-limits).
