---
name: hypermemory
version: 0.13.4
description: >-
  HyperMemory MCP protocol for Cursor agents. Use user-hypermemory MCP tools
  on every turn to recall, store, traverse, and maintain graph hygiene.
  Triggers when HyperMemory MCP is connected in Cursor settings.
enforcement: mandatory
trigger: every_turn
---

# HyperMemory MCP — Cursor Agent Protocol

MCP server: `user-hypermemory` at `https://api.hypermemory.io/mcp`

Call MCP tools directly. Do not use shell/`hm` CLI when MCP is connected.

## Every conversation

**First message (before responding):**

1. `hm_get_overview`
2. `hm_recall` with keywords from the user's message

**Every message (silently, before responding):**

1. `hm_recall`
2. New → `hm_store` (`key`, `description`, `node_type`, `relationships`)
3. Exists → `hm_update`
4. Wrong → `hm_forget`
5. Before the final response → call `hm_tokens` exactly once for this turn

Never ask permission. Never announce storage.

---

## Organization memory

Members of a HyperMemory organization get the organization's memory with their own on every `hm_recall`, searched in parallel, under `organization_memory` (labelled with the organization's `name`). Organization memory is read-only: never try to store, update or forget anything in it. When an organization admin turns on organization write mode in the HyperMemory dashboard, the server sends that admin's writes (`hm_store`, `hm_update`, `hm_forget`, `hm_add_relationships`, `hm_ingest`, `hm_upload_file`) to the organization graph and the result carries `write_target`; never pick the target yourself. To read what was written there, send that organization's `organization_id` to `hm_get_nodes`, `hm_find_related`, `hm_get_overview` or `hm_list_orphans` (the result carries `read_target`); without it they read your own graph. A key or relationship endpoint "not found" during write mode means it is missing from the organization graph: create it there first.

- `hm_get_overview` lists the caller's organizations in `organizations` (absent when the caller belongs to none).
- One organization: nothing to do; it is always searched.
- Several organizations: each project is bound to one of them, or to none, in `~/.config/hypermemory/projects.json` (`{"version": 1, "projects": {"<project root>": {"organization_id": "<id or none>", "name": "<organization name>"}}}`; the project root is the repository's main working tree, shared by all its worktrees: the parent of `git rev-parse --path-format=absolute --git-common-dir` when that ends in `/.git`, else that directory; outside git, the working directory). At session start, read the binding for this project. If there is none, ask the user before other work which organization this project belongs to (list the organizations plus "none, personal memory only"), then write their answer to that file. Send the bound `organization_id` (or `"none"`) on every `hm_recall` for the session.
- `organization_memory.status`: `included` (results attached), `selection_required` (several organizations and no `organization_id` sent: ask and bind as above), `excluded` (`"none"` was sent), `selected_graph` (this credential's graph is the organization graph, so the main results already are its memory), `failed` (tell the user the organization search failed; your own results are still valid).

## Tools (16 public)

| Tool | Purpose |
|------|---------|
| `hm_get_overview` | Graph stats — first message |
| `hm_recall` | Hybrid search — before store |
| `hm_get_nodes` | Full node details for known exact keys |
| `hm_store` | Create node + relationships |
| `hm_update` | Update node (`key`) or edge (`edge_id`). Edge endpoints/type immutable |
| `hm_forget` | Delete node (`key`) or single edge (`edge_id`). Edge delete preserves nodes |
| `hm_find_related` | Graph traversal from seed |
| `hm_add_relationships` | Batch binary edges / hyperedges |
| `hm_get_chat_context` | Session node group |
| `hm_list_orphans` | Disconnected nodes — post-ingest |
| `hm_ingest` | LLM extract from text block |
| `hm_upload_file` | Store file (Pro+, user asks) |
| `hm_list_files` | List uploaded files |
| `hm_timeline_write` | Diary entry |
| `hm_tokens` | End-of-turn token/cost report with weighted activity segments |
| `hm_timeline` | Temporal search |
| `hm_skill` | Retrieve or update current HyperMemory agent skills |

For `hm_tokens`, report `cost_usd` with a separate `cost_quality`:
`provider_actual`, `price_calculated`, `self_estimated`, or `unavailable`.
Only use `provider_actual` for a provider-billed amount.
For OpenRouter, submit client-visible token fields and weighted segments; they
remain provisional until management analytics reconciliation. Claude Desktop
uses `self_estimated` with uncertainty and no API-equivalent dollar cost.
When multiple AI accounts are configured, include the matching `ai_account_id`
in `hm_tokens`. Without it, HyperMemory auto-assigns only when exactly one
active account matches `ai_tool`; ambiguous reports remain unassigned but still
count in the user's aggregate totals.
Each segment category may appear only once per report. Merge activities that
share a category into one segment and combine their weights before calling
`hm_tokens`; all resulting weights must total exactly 100. Estimate the split
from the work actually performed; exact token counters do not make activity
attribution exact. Weight what the turn did: building or editing a workbook, document or deck is
`doc_processing`, gathering and reading sources is `research`, drafting text is
`writing`, figures are `calculations`, code is `coding`. Reading the
conversation, files and tool results belongs to the work it served: there is
no `context` category and the server refuses it. Use `memory` only for the
HyperMemory calls themselves. Never send a fixed split such as memory 10 /
context 90. Allowed categories are `reasoning`, `memory`,
`doc_processing`, `automation`, `personal`, `chatting`, `research`, `design`,
`calculations`, `coding`, `planning`, `productivity`, `writing`, and
`unmatched`. Use `unmatched: 100` only when classification is genuinely
unavailable. Do not use the removed `mem_ingest` or `mem_retrieve` categories.

**Edge editing:** `hm_update` and `hm_forget` accept an optional `edge_id`
(from read responses) to target a single edge. Pass `edge_version` for
optimistic concurrency. To change edge endpoints or type, delete and recreate.

**Common mistakes:**

| Wrong | Correct |
|-------|---------|
| `hm_related` | `hm_find_related` |
| `hm_relate` | `hm_add_relationships` |
| `chat_session_abc` relationship | Never — system only |

Use `hm_recall` to find candidate memories. Use `hm_get_nodes(keys=[...])`
when exact keys are known and you need full, untruncated node records, data,
assets, duplicate records, and relationship details.

When asked to install or update HyperMemory instructions, call `hm_skill` with
`action="get"` and `variant="cursor"`.

---

## Node types & keys

Types are canonical ontology classes, not free-form labels: `user person organization component event decision concept artifact project technology preference fact skill`

Do not invent `node_type` values or create ontology-class nodes. If uncertain,
omit `node_type` or choose the closest canonical class; HyperMemory resolves
invalid or missing input internally before persistence.

Key: `{type}_{name}` — e.g. `decision_jwt_auth`, `tech_redis`

Singleton: `user_profile`

---

## Relationships on store

Always pass `relationships` — nodes without edges are orphans.

```json
{
  "key": "decision_jwt",
  "description": "We chose JWT for stateless API auth",
  "node_type": "decision",
  "relationships": [
    {"to_key": "project_api", "relationship": "API auth uses JWT because it scales horizontally without server sessions"}
  ]
}
```

### Hyperedge (3+ joint participants)

```json
{
  "relationships": [{
    "participant_keys": ["person_alice", "person_bob", "person_carol", "project_auth"],
    "relationship": "auth_team_decision_unit",
    "description": "All three engineers and the auth project form one decision unit — any one leaving changes who can approve architecture changes"
  }]
}
```

### Hyperedge policy

- **2 nodes** → binary edge (auto-downgraded if you send hyperedge)
- **3 nodes** → 80+ char description required
- **4–5** → specific label, not generic verbs
- **10+** → preferred for real assemblies
- **Never** `relates_to`, `connected`, `associated`, `linked`, `related` on hyperedges
- **Never** `chat_*` — reserved for session grouping

**Removal test:** Can you drop one node and the relationship still holds? Use binary edges.

---

## Orphan hygiene (mandatory after ingest)

```
hm_ingest → hm_list_orphans → hm_add_relationships or hm_forget → verify
```

Never chain ingests without cleanup.

---

## Session context

After 5+ memory tool calls, server builds a session hyperedge. Reload with `hm_get_chat_context`.

---

## Files & timeline

- Files: `hm_upload_file` / `hm_list_files` — user must ask
- Timeline: `hm_timeline_write`, `hm_timeline` — optional, not auto-loaded

---

## Hard rules

- Overview + recall before first response
- Recall before store
- `node_type` + `relationships` on every store
- Execute on every message — no exceptions
