Metadata-Version: 2.5
Name: hypermemory-cli
Version: 2.2.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]` | Search memory by natural language, keywords, or regex |
| `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 |

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

### 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 software-development --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
```

Built-in variants: `general`, `openai`, `software-development`, `marketing`, `legal`, `cursor`, `cli`, `project`, `audit`, and `memorize-full-chat`.

### 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.

## 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
