Metadata-Version: 2.5
Name: hypermemory-cli
Version: 2.3.2
Summary: Persistent memory graph for AI agents — store, recall, and connect knowledge across conversations.
Project-URL: Homepage, https://app.hypermemory.io
Project-URL: Documentation, https://app.hypermemory.io/integration
Project-URL: Repository, https://github.com/hypermemory-ai/hypergraph_memory
Project-URL: Bug Tracker, https://github.com/hypermemory-ai/hypergraph_memory/issues
Author-email: RunStack <hello@runstack.ai>
License-Expression: MIT
Keywords: agents,ai,claude,cursor,hypergraph,knowledge-graph,llm,mcp,memory,persistent-memory
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: keyring>=24
Requires-Dist: rich>=13.0
Requires-Dist: tomli>=2.0; python_version < '3.11'
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# HyperMemory CLI

**Persistent memory graph for AI agents** — store, recall, and connect knowledge across conversations.

HyperMemory gives AI assistants (Claude, Cursor, ChatGPT, custom agents) a long-term memory layer. The `hm` CLI is the primary interface for reading and writing to that memory, both for humans and for AI agents running shell commands.

## Installation

```bash
pip install hypermemory-cli
```

Requires Python 3.10+ (tested on 3.10–3.14).

## Quick Start

```bash
# Authenticate (opens your browser) — or: hm login --api-key
hm login

# Store a fact
hm store person_alice "Alice, senior backend engineer at Acme" --type person

# Store a decision
hm store decision_jwt "We chose JWT over session cookies for auth" --type decision

# Connect them — describe WHY
hm relate --from person_alice --to decision_jwt --rel "Alice drove the JWT decision based on her scaling experience"

# Search by natural language
hm recall "authentication decisions"

# Traverse the graph
hm find person_alice --depth 2

# Check what you have
hm overview
```

## Authentication

**Browser login (recommended):**

```bash
hm login
```

Opens your browser for OAuth 2.1 + PKCE login. A temporary server on `127.0.0.1` receives the callback; tokens refresh automatically. If the page you land on after signing in fails to load, paste its full URL into the terminal: `hm login` accepts it while it waits for the callback (up to `--timeout`, default 600 seconds).

**Sign in from another device** (SSH sessions, remote and headless machines):

```bash
hm login --no-browser
```

Prints the sign-in URL. Open it in a browser on any device and sign in. The browser is then sent to `http://127.0.0.1:<port>/?code=...`, a page that fails to load because it points at that device, not at this machine; that is expected. Copy the full URL from the address bar and paste it into the terminal (the bare `code` value works too). The CLI checks the `state` value, exchanges the code with its PKCE verifier and stores the tokens like a normal login. A code is valid for 5 minutes and works once. `hm login` picks this mode by itself when no browser can be opened here (an SSH session or no display).

**API key** (CI, agents, or where no one can sign in interactively):

```bash
hm login --api-key hm_YOUR_API_KEY      # or
echo "$HM_KEY" | hm login --api-key     # read from stdin, keeps the key out of shell history
hm login --api-key                      # hidden prompt
```

The key is checked with an authenticated request before it is saved; a rejected key is never stored. Generate API keys at [app.hypermemory.io/api-keys](https://app.hypermemory.io/api-keys).

**Environment variables** (override anything stored):

```bash
export HYPERMEMORY_API_KEY=hm_YOUR_KEY
export HYPERMEMORY_API_URL=https://api.hypermemory.io   # optional
hm recall "recent decisions"
```

**Where credentials are stored:** in the OS keyring (macOS Keychain, Windows Credential Locker, Secret Service on Linux) when one is available. Otherwise — or with `HYPERMEMORY_NO_KEYRING=1` — they go to `~/.config/hypermemory/config.json` with mode `0600`. Config files written by earlier releases keep working; their secrets move to the keyring the next time the CLI saves credentials (login or token refresh). `hm config` shows which store is in use.

## Commands

### Memory Operations

| Command | Description |
|---------|-------------|
| `hm store KEY "desc" [--type T] [--data JSON] [--rels JSON] [--asset ID]... [--search-text T] [--session-id S]` | Create a new memory node |
| `hm recall "query" [--max-results N] [--force-regex] [--session-id S] [--org ID\|none]` | Search memory by natural language, keywords, or regex (plus your organization's memory) |
| `hm nodes KEY... [--no-relationships] [--no-duplicates] [--relationship-detail summary\|full] [--participant-limit N] [--enrichment-history] [--session-relationships]` | Fetch full details for known exact node keys |
| `hm update KEY [--desc] [--type] [--data JSON] [--asset ID]... [--search-text T]` | Update an existing node |
| `hm update --edge-id ID [--edge-version N] [--desc ...]` | Update one edge or hyperedge |
| `hm forget KEY` | Delete a node and all its edges |
| `hm forget --edge-id ID [--edge-version N]` | Delete one edge or hyperedge |
| `hm relate --from A --to B --rel R` | Create a binary relationship |
| `hm relate --rels JSON` | Create several relationships, including hyperedges |
| `hm find KEY [--depth N] [--query Q] [--max N] [--relationship-pattern P] [--lens L] [--session-id S]` | Traverse the graph from a starting node |
| `hm relationships KEY` | List every edge and hyperedge of a node |
| `hm ingest "text" [--context "label"]` | Auto-extract nodes from free-form text |
| `hm orphans [--limit N] [--cursor C]` | List nodes with no edges |
| `hm timeline [--period 24h] [--query Q] [--node KEY] [--start] [--end] [--limit N]` | Search the activity timeline |
| `hm timeline-write "summary" [--meta JSON]` | Write a timeline entry |
| `hm upload FILE [--desc D] [--key K]` | Upload a file (Pro+) |
| `hm files [--type T] [--search S] [--limit N]` | List uploaded files |
| `hm tabular outline\|range\|search\|trace FILE_ID ...` | Query uploaded spreadsheets and CSV files |
| `hm hm_tokens JSON\|@file.json` | Submit a canonical token-usage report |
| `hm overview` | Show graph stats and top nodes |
| `hm export [-o FILE] [--no-wait] [--export-id ID] [--timeout S]` | Export the full graph as JSON (asynchronous server job) |
| `hm skill list [--name N] [--content]` | List built-in skills and your published agent skills |
| `hm skill get [--variant V \| --name N \| --skill-id ID] [--raw] [-o FILE]` | Retrieve skill instructions |
| `hm skill check --current-version X [--variant V \| --skill-id ID]` | Check whether a skill update is available |
| `hm skill install (--skill-id ID \| --name N) --dir DIR [--force]` | Write a published agent skill (SKILL.md plus its supporting files) to `DIR/<name>/` |

Options that take JSON (`--data`, `--rels`, `--meta`, the `hm_tokens` report) also accept `@path/to/file.json`.

### Organization memory (`hm org`)

If you belong to a HyperMemory organization, every recall (`hm recall` and the recall the agent hooks run) also returns the organization's matching memory, in the answer's `organization_memory` object after your own `results`. With one organization this is always on. With several, bind each project to the organization it works for, or to none:

```bash
hm org list                  # your organizations; * marks the one this project is bound to
hm org use ORGANIZATION_ID   # bind this project; hm org use none = personal memory only
hm org show                  # this project's binding
hm org clear                 # remove it
hm recall "pricing" --org none   # override the binding for one recall
```

A project is the git repository around the current directory (keyed by its main working tree, so every worktree of the repository shares one binding), or the directory itself outside git. Bindings are per user, in `~/.config/hypermemory/projects.json`. Until a project is bound, recall reports `organization_memory.status` `selection_required` and includes no organization memory, and the SessionStart hook asks the agent to have you choose. `hm org use` checks the id against your organizations; an id you do not belong to is rejected (exit 6), by the CLI and by the server.

`organization_memory.status` is `included` (results attached), `selection_required`, `excluded` (`none` was sent), `selected_graph` (your credential's graph is the organization's graph, so `results` already are its memory) or `failed` (the organization search failed; your own results are still valid). On a terminal `hm recall` shows the organization's results under a heading with its name; piped, it prints the server JSON and writes the `selection_required` and `failed` notices to stderr.

### Spreadsheets and CSV (`hm tabular`)

```bash
hm tabular outline FILE_ID [--no-regions] [--max-sheets N]            # workbook → sheets → regions
hm tabular range FILE_ID --sheet S --range A1:D20 [--max-cells N]     # cells of an exact range
hm tabular search FILE_ID "revenue" [--sheet S] [--limit N]           # regions, headers, labels, values
hm tabular trace FILE_ID --sheet S --cell F12 [--direction precedents|dependents] [--max-depth N] [--max-nodes N]
```

`FILE_ID` is the `file_id` reported by `hm upload` / `hm files`.

### Export

The server builds exports in the background. `hm export` starts one, polls it until it is published, downloads the document, and verifies its size and SHA-256:

```bash
hm export -o memory-backup.json          # summary JSON on stdout, document in the file
hm export | jq '.nodes | length'         # document on stdout
hm export --no-wait                      # print {export_id, status, status_url} and exit
hm export --export-id EXPORT_ID -o b.json  # resume / download an export started earlier
```

A failed or expired export, or one still running after `--timeout` seconds (default 600), exits with code 10.

### Auth & Config

| Command | Description |
|---------|-------------|
| `hm login` | Authenticate via browser (OAuth 2.1 + PKCE) |
| `hm login --no-browser` | Sign in on any device and paste the resulting URL back (SSH, remote machines) |
| `hm login --api-key [KEY]` | Validate and save an API key (KEY, stdin, or prompt) |
| `hm logout` | Clear saved OAuth tokens (keeps an API key) |
| `hm config` | Show auth method, masked credential, API URL, credential store |
| `hm config --set-key KEY` | Save an API key without validating it |
| `hm config --clear-key` | Remove the saved API key |
| `hm config --set-url URL` | Override the API endpoint |
| `hm health` | Server health with your credentials: `{status: ok\|degraded, checks}` |
| `hm ready` | Server readiness (`{status: ready}`; exits 8 when not ready) |
| `hm version` | Print CLI version |

## Node Types

Every node requires a `--type`:

| Type | Use for |
|------|---------|
| `user` | The primary user (singleton `user_profile` node) |
| `person` | People — teammates, contacts, users |
| `organization` | Companies, teams, departments |
| `component` | Software components, services, libraries |
| `event` | Meetings, launches, incidents |
| `decision` | Architecture choices, policy decisions |
| `concept` | Ideas, patterns, abstract topics |
| `artifact` | Documents, repos, configs, files |
| `project` | Projects, initiatives, products |
| `technology` | Languages, frameworks, tools, platforms |
| `preference` | User preferences and settings |
| `fact` | Verified facts, data points, measurements |
| `skill` | Skills, expertise, capabilities |

## Relationships

Describe connections in plain language with `--rel`. Be specific about **why** the connection exists:

```bash
# BAD — bare verb, no context
hm relate --from component_api --to tech_redis --rel depends_on

# GOOD — explains why the connection exists
hm relate --from component_api --to tech_redis --rel "API depends on Redis for session caching and rate limiting"
hm relate --from person_alice --to decision_jwt --rel "Alice chose JWT because it supports stateless scaling"
hm relate --from project_app --to tech_sveltekit --rel "frontend built with SvelteKit for SSR and progressive enhancement"
```

The server automatically summarizes long labels into shorter searchable versions.

## Key Format

Use descriptive, namespaced keys: `{type}_{name}`

```
person_alice          decision_jwt_auth       component_redis
pref_dark_mode        event_2025_launch       org_acme
```

## AI Agent Integration

HyperMemory is designed to be used by AI agents as a persistent memory layer. The typical agent workflow:

1. **Start of conversation:** `hm overview` + `hm recall "relevant keywords"` to load context
2. **When meaningful info appears:** `hm recall` first to check for duplicates, then `hm store` new facts, decisions, or preferences
3. **As needed:** `hm update` to correct information, `hm forget` to remove outdated info
4. **Always:** run with `--json` and branch on the exit code (see below)

The server automatically enriches stored nodes with structured data, edges, and hyperedges — agents just provide the key, description, and type.

Agents can retrieve current skill instructions directly:

```bash
hm skill list
hm skill get --variant general --raw
hm skill get --variant project --output hypermemory-skill.md
hm skill get --name my-team-skill --raw          # one of your published agent skills
hm skill check --variant general --current-version 0.7.1
hm skill install --name my-team-skill --dir ~/.claude/skills   # SKILL.md + supporting files
```

Published agent skills can carry supporting files (for example `references/api.md`) next to
`SKILL.md`. `hm skill install` writes the whole skill directory to `DIR/<name>/`: it checks every
file path (relative, no `..`, no second `SKILL.md`, no duplicates) and every file's sha256 before
writing anything, builds the tree in a temporary directory inside `DIR` and moves it into place,
so a failed install leaves nothing behind. An existing `DIR/<name>/` is replaced only with
`--force`. `hm skill get --output` refuses a skill that has supporting files, since it would
write `SKILL.md` alone.

Built-in variants: `general` (also `openai`, `chatgpt`, `gpt`, `codex`, `claude-code`), `project`, `cursor`, `cli`, and `memorize-full-chat`. System agent skills managed by the platform administrator, such as `hyper-cleanup`, are fetched with `--name`.

### Agent setup (`hm setup`)

`hm setup` wires HyperMemory into Claude Code, Codex, Hermes Agent, Kimi Code and OpenClaw with the
`hm` CLI as the only memory interface (no MCP server). Name one or more agents, or `all`:

```bash
hm setup all                       # every supported agent detected on this machine
hm setup claude hermes kimi        # exactly these agents
hm setup codex --scope project     # this git repository: .codex/, .agents/skills/, AGENTS.md
hm setup all --dry-run             # show the planned changes, write nothing
hm doctor                          # verify auth, the API, the skill and every install (--json for machines)
hm uninstall claude kimi           # remove exactly what setup wrote for these agents
hm uninstall all                   # remove everything the setup manifest records
```

`hm setup all` sets up each agent it detects, by its command on PATH or its home directory, and
prints a skip line for the others:

| Agent | Command | Home directory | Scopes |
|---|---|---|---|
| `claude` (Claude Code) | `claude` | `$CLAUDE_CONFIG_DIR` or `~/.claude` | user, project |
| `codex` (Codex) | `codex` | `$CODEX_HOME` or `~/.codex` | user, project |
| `hermes` (Hermes Agent) | `hermes` | `$HERMES_HOME` or `~/.hermes` | user |
| `kimi` (Kimi Code) | `kimi` | `$KIMI_CODE_HOME` or `~/.kimi-code` | user, project |
| `openclaw` (OpenClaw) | `openclaw` | `$OPENCLAW_STATE_DIR` or `~/.openclaw` | user, project |

Agents are set up one after another and one failing agent does not stop the rest. An agent that
cannot take the given options (Hermes with `--scope project` or `--no-hooks`) gets its own message:
under `all` it is skipped, when named it counts as failed. A run with several agents ends with a
summary table, and the exit code is 1 if any agent failed (or, for `hm setup all`, if no agent was
detected). `hm uninstall all` removes every install recorded in
`~/.config/hypermemory/setup-manifest.json`, limited to one scope with `--scope`.

The skill ships inside this package and matches the commands of this release. When the server
publishes a newer `cli` skill version, `hm setup` and `hm doctor` cache and install that instead.

#### Claude Code and Codex

`hm setup claude` and `hm setup codex` install SessionStart, UserPromptSubmit and Stop hooks
(through a small shell shim), the `hypermemory-cli` skill, a marked block in CLAUDE.md / AGENTS.md
and, for Claude Code, a `hypermemory-memory-writer` agent. The prompt hook runs a recall with your
prompt and injects the results; the Stop hook asks Claude Code to dispatch the memory writer and
Codex to run `hm timeline-write` and `hm hm_tokens`, blocking a turn at most twice. With an OAuth
login the hooks refresh an expired access token once, like every other command. Every write is
recorded in `~/.config/hypermemory/setup-manifest.json`; other hooks and settings are never touched.

#### Kimi Code

`hm setup kimi` does the same for Kimi Code CLI (`kimi`): `[[hooks]]` tables in
`$KIMI_CODE_HOME/config.toml` (default `~/.kimi-code`), the skill in `$KIMI_CODE_HOME/skills/` and a
block in `$KIMI_CODE_HOME/AGENTS.md`. The agent persists with `hm` commands itself, and Kimi lets the
Stop hook send one reminder per turn. Kimi reads hooks only from that user file, so `--scope project`
puts the skill and block under `.kimi-code/` in the repository and registers hooks that act only
inside it. Details and limits: [docs/agents/kimi.md](docs/agents/kimi.md).

#### OpenClaw

`hm setup openclaw` installs a small native OpenClaw plugin instead of hooks (OpenClaw changes a
turn only through plugin hooks): `before_prompt_build` runs `hm --json recall` on every message and
injects the results before the model answers, and `agent_end` runs `hm --json timeline-write` and
`hm --json hm_tokens` after every turn. It enables the plugin in `~/.openclaw/openclaw.json`
(`plugins.entries.hypermemory-cli` with `hooks.allowConversationAccess`), installs the skill in
`~/.openclaw/skills`, and adds the block to the workspace AGENTS.md. Setup edits strict JSON only and
stops with a message when `openclaw.json` uses JSON5 syntax; `hm doctor`'s plugin self-test needs
`node` and only warns without it. Details: [docs/agents/openclaw.md](docs/agents/openclaw.md).

#### Hermes Agent

```bash
hm setup hermes                    # $HERMES_HOME (default ~/.hermes); needs `hermes` on PATH and `hm login`
hm uninstall hermes                # remove the plugin and skill, restore the previous memory.provider
```

Hermes calls its active memory provider on every turn, so instead of hooks setup installs a
provider plugin in `$HERMES_HOME/plugins/hypermemory/` and the `hypermemory-cli` skill,
and runs `hermes config set memory.provider hypermemory` (user scope only). Before the model answers, the provider
runs `hm recall` on the message and Hermes adds the results to it; after every turn it writes a
timeline entry and a token report (exact counts from Hermes's session counters) with
`hm timeline-write` and `hm hm_tokens`, without the model having to call anything. It also mirrors
Hermes's built-in memory writes and gives the model `hypermemory_*` tools that run `hm` commands.
Every call has a timeout and fails open. `hm doctor` checks the files, the activation, the `hm`
path, and runs `hermes hypermemory selftest` (a live, read-only recall from inside Hermes).
Research and source references: [docs/agents/hermes.md](docs/agents/hermes.md).

## Output, `--json`, and Exit Codes

By default, data commands print the server's JSON answer pretty-printed on stdout (syntax-highlighted on a terminal, indented when piped) and write errors and progress as readable text on stderr.

For agents and scripts, add `--json` anywhere on the command line (`hm --json recall q` or `hm recall q --json`):

- stdout: the server's JSON answer, unchanged, as one line;
- stderr: errors as one JSON object, e.g. `{"error":"not_found","detail":"node not found: k","exit_code":5,"status":404,"retryable":false,"request_id":"..."}`;
- no progress messages or spinners.

```bash
hm --json overview | jq '.nodes'
hm --json recall "decisions" | jq '.results[].key'
hm --json nodes fact_a fact_b | jq '.nodes.fact_a.node'
hm --json relationships component_redis | jq '.binary_edges[].relationship'
hm export > memory-backup-$(date +%F).json
```

Exit codes are stable:

| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | Other failure (local I/O, malformed server answer, export integrity check) |
| 2 | Invalid command-line usage (missing/invalid arguments, invalid JSON option) |
| 3 | Not authenticated: no credentials, or the server rejected them (401) |
| 4 | Forbidden or plan limit (402, 403) |
| 5 | Not found or gone (404, 410) |
| 6 | Request rejected as invalid (400, 409, 413, 415, 422) |
| 7 | Rate limited (429) |
| 8 | Server or dependency error (5xx, including `hm ready` when not ready) |
| 9 | Network error: server unreachable or request timed out |
| 10 | Long-running operation incomplete: export failed, expired, or outlived `--timeout` |

## Configuration

Settings live in `~/.config/hypermemory/config.json` (mode `0600`); secrets live in the OS keyring when one is available (see Authentication). Priority:

1. `$HYPERMEMORY_API_KEY` / `$HYPERMEMORY_API_URL` environment variables
2. Stored API key, then stored OAuth tokens
3. Defaults (API URL `https://api.hypermemory.io`)

`HYPERMEMORY_NO_KEYRING=1` stores secrets in the config file instead of the keyring.

Per-project organization bindings (`hm org use`) live in `~/.config/hypermemory/projects.json`. The file is checked on every read; if it is malformed, `hm recall` and `hm org` fail with an error naming it, and the prompt hook skips recall rather than recall without the binding.

## Links

- **Web app:** [app.hypermemory.io](https://app.hypermemory.io)
- **Integration guide and agent skills:** [app.hypermemory.io/integration](https://app.hypermemory.io/integration)
- **API endpoint:** `https://api.hypermemory.io`
- **Claude Connector:** Add `https://api.hypermemory.io/mcp` as an MCP server in Claude Desktop

## License

MIT
