hippo is a command-line client for a running Hippocampus service. It exposes the full RPC surface
as noun-verb subcommands and can talk to the service over either transport:
- gRPC (the default) — dials the service's gRPC port (
port, default50051). - HTTP (
--transport http) — calls the JSON/HTTP/v1grpc-gateway (gateway.port, default8080).
Both transports share one client interface, so every command behaves identically whichever is
selected — including the error codes and messages, which are surfaced as gRPC status codes on both.
hippo holds no state; it dials the service named by --address and turns each command into one
RPC. What a token is actually allowed to do is enforced by the service's auth
tiers, not by this tool.
It lives in its own Go module under integrations/cli/ (its client dependency tree stays out of the
root build), and ships as a cross-compiled binary on each GitHub release.
On macOS or Linux, install it from the tap:
brew install fastbean-au/tap/hippocampus-cliOtherwise take a pre-built binary from the
releases page — each release attaches hippo
archives for Linux, macOS, and Windows on amd64/arm64 — or build from source:
cd integrations/cli
go build -o hippo .
# gRPC (default)
./hippo --address localhost:50051 whoami
# HTTP /v1 gateway
./hippo --transport http --address localhost:8080 whoamiIf --address is omitted it defaults to localhost:50051 for gRPC and localhost:8080 for HTTP.
For HTTP, a bare host:port gains an http:// (or https:// under --tls) scheme automatically.
These apply to every command and may appear on either side of the subcommand:
| Flag | Default | Description |
|---|---|---|
-t, --transport |
grpc |
transport to the service: grpc or http |
-a, --address |
(per transport) | service address |
--token |
bearer token sent on every request | |
--tls |
false |
connect over TLS |
--tls-ca-cert |
PEM CA bundle to verify the service certificate against | |
--tls-cert / --tls-key |
client certificate/key for mutual TLS | |
--tls-insecure-skip-verify |
false |
skip certificate verification (dev only) |
--timeout-seconds |
30 |
per-request timeout (0 disables) |
-o, --output |
text |
output format: text or json |
--log-level |
warn |
logging level written to stderr |
Every global flag can also be set via a HIPPOCAMPUS_<FLAG> environment variable, so a secret need
not appear in the argv:
export HIPPOCAMPUS_TOKEN="$(hippocampus --mint-token --client-id ci --role writer --ttl 24h -c config.json)"
hippo memory store --body "authenticated write"Whether a token is needed depends on the service's auth.method
(authentication):
-
none(the default) — no token; omit--tokenentirely. -
hmac— mint one with the service's own CLI, signed by the configured secret:hippo_token=$(hippocampus --mint-token --client-id ci --role writer --ttl 24h -c config.json) hippo --token "$hippo_token" memory store --body "authenticated write"
--rolestamps the tier the token carries; give it the tier the commands you run require (readerfor the read-only ones,writerto store/update,adminforpurge/sleep/data movement).--mint-tokenis HMAC-only. -
idp— the service verifies tokens issued by your identity provider, so obtain the bearer token from the IdP (the OAuth2/OIDC flow your organisation uses); the service cannot mint it.
Pass the token with --token, or as HIPPOCAMPUS_TOKEN to keep the secret out of the argv (shown
above). The TLS trust options mirror the service's own Transfer client and the MCP
bridge: a private-CA bundle, an optional client certificate for mutual TLS, and an
insecureSkipVerify escape hatch. --tls is required for https/TLS endpoints; without it the
client connects in plaintext.
-
--output text(default) — a compact human-readable rendering, one field per line. Binary memory bodies are shown as a<binary, N bytes>placeholder rather than dumped. -
--output json— indented protojson using the wire field names. This is the stable, machine-parseable form for scripting:hippo -o json memory list --group svc-a | jq '.memories[].id'
Errors are written to stderr as hippo: <message> and the process exits non-zero.
hippo completion <shell> prints a completion script for bash, zsh, or fish. The script wires
the shell to hippo itself at completion time, so subcommands (memory store, event list, ...),
flags, and the closed-set flag values (--transport grpc|http, --output text|json,
--place-mode, --extremum, --order-by, --log-level) always match the installed binary.
# bash — for the current shell, or add to ~/.bashrc
source <(hippo completion bash)
# zsh — requires compinit (usually already run by your setup)
source <(hippo completion zsh)
# fish
hippo completion fish | sourceTo install permanently, write the script into your shell's completions directory (e.g.
hippo completion bash | sudo tee /etc/bash_completion.d/hippo).
Run hippo --help for the list and hippo <command> --help for a single command's flags.
| Command | Purpose |
|---|---|
memory store |
store a new memory (--body/--body-file, --significance, --event-id, --group, --metadata k=v, --timestamp, --binary) |
memory update |
partial update of an existing memory (--id plus any content fields) |
memory delete |
delete memories by id (--id repeatable, or positional ids) |
memory list |
list memories with filters (--group, --metadata k=v, --recalled, --summary, --binary, --recall-count-min/-max, --recalled-after/-before, --significance-min/-max, --timestamp-min/-max, --order-by, --order-dir, --limit, --offset, --extremum) |
memory recall |
recall memories by id (reinforces them; --include-linked also returns their neighbours, unreinforced) |
memory link |
link a memory to others (--id, --link memoryID:sig repeatable) |
memory unlink |
remove links between a memory and others (--id, --target repeatable or positional) |
memory links |
list a memory's links (--id, --direction both|outbound|inbound) |
memory search |
content-search the index (--query, --mode keyword|semantic|hybrid, --limit, --event-id, --group, --metadata k=v, --reinforce, --include-linked) |
memory explain |
where memories stand against consolidation (--id repeatable or positional, --curve-significance, --curve-days, --curve-points) |
memory explain reports each memory's computed value, the threshold it is measured against, and how
long it has before it is forgotten; with --curve-significance it also returns the decay curve of
the current configuration. Both halves stand alone — a curve with no ids asks only what the
configuration does. See Where a memory stands.
| Command | Purpose |
|---|---|
event link |
link an event to others (--id, --link eventID:sig repeatable) |
event unlink |
remove links between an event and others (--id, --target repeatable or positional) |
event links |
list an event's links (--id, --direction both|outbound|inbound) |
event create |
create an event (--name, --description, --significance, --group, --metadata k=v, --time-start, --time-end, --link eventID:sig) |
event end |
set an event's end time (--id, --time-end) |
event significance |
change an event's significance (--id, --significance or placement) |
event merge |
re-point one event's memories onto another (--from, --to) |
event delete |
delete an event, optionally its memories (--id, --memories) |
event get |
fetch a single event (--id, --memories, --memory-counts) |
event list |
list events with filters (same shape as memory list, plus --time-start-min/-max, --time-end-min/-max, --memories, --memory-counts) |
| Command | Purpose |
|---|---|
summary candidates |
list events the last sleep cycle flagged as worth condensing |
summary replace |
replace an event's memories with a caller-supplied summary (--event-id plus content fields) |
summary summarise |
generate and store a summary with the embedded LLM (--event-id, --significance) |
| Command | Purpose |
|---|---|
whoami |
report the caller's identity, effective tier and group scope, plus what the instance can serve |
topology |
report the deployment this instance is part of, and each component's health (--all) |
sleep |
trigger a consolidation cycle now, or preview one (--dry-run) |
status |
when the next cycle is due, and what the last one forgot |
forgotten list |
list memories a cycle forgot, and why (--memory-id, --group, --rule, --since) |
forgotten clear |
delete records from the forgotten log (--before or --all) |
callbacks queue |
show the outbound callback queue: depth, ages, attempt counts (--kind, --limit) |
callbacks clear |
discard pending callbacks (--before or --all) |
purge |
delete every event and memory (requires --yes) |
sleep --dry-run reports what a cycle would forget and deletes nothing — see
Previewing what would be forgotten. It calls a
separate read-only RPC (PreviewConsolidation), so it cannot trigger a cycle by accident;
--limit bounds how many individual memories are detailed (default 100, max 1000) without
affecting the counts, which are always complete.
topology is the terminal form of the console's Deployment tab, and the more useful of the two
when the console is exactly what is unreachable. It reports this instance, the components it dials,
the peer instances sharing its database, and the last known health of each — with when each was
last checked, since the statuses come from a background prober rather than from the request. Any
deployment-wide warning (no instance is consolidating, or more than one is) is printed first and is
never filtered out, because it describes a fault with no component to be listed under. By default it
lists only what is configured;
--all adds the components that are switched off, each naming the config key that would enable
them. Addresses are redacted server-side, so no DSN password or cluster credential is ever printed.
See Deployment topology for what an instance can and cannot
know about its own deployment.
forgotten list reads the optional forgotten log
— what the cycle actually deleted, as against the dry run's account of what it would delete next.
It is the only way to ask about a memory that no longer exists (--memory-id), and it never
returns a body. forgotten clear requires --before or --all: it destroys the record of what
was destroyed, so it must never be something a bare command does. Neither is affected by the log's
configured caps, which trim but never empty it, and which stop being applied at all once recording
is turned off.
callbacks queue shows what the outbound callback queue is
holding — the depth, how old the oldest waiting delivery is, and a page of pending ones with their
attempt counts and next-attempt deadlines. That pair is what separates a queue that is draining from
one that is stuck: rising attempts against a receding deadline is a receiver that is refusing, while
a deep queue with zero attempts is one the dispatcher has not reached yet. It never prints a
delivery's payload, which may carry memory bodies. --kind narrows it to memory-forgotten,
event-forgotten or sleep-completed.
callbacks clear requires --before or --all, and is a harder discard than forgotten clear:
what it destroys is not the record of a notification but the notification itself, and nothing else
will ever send it. It exists because the queue's caps stop applying the moment callbacks are turned
off, so disabling the feature leaves whatever was queued in place rather than destroying it.
Both are admin, and both are refused to a group-scoped token — a queued delivery batches memories
across groups, so there is nothing to scope it by.
whoami reports the token's group scope on its own line —
groups: unscoped (whole store) when the token carries none, which is the state to check first when
a listing comes back shorter than expected:
client_id: agent-a
role: writer
auth_enabled: true
groups: alpha
consolidating: true
forgotten log: false
summariser: false
search modes: keyword
The four lines below the scope describe the instance answering, not the caller, and are the same
for everyone who calls it. consolidating is the one to reach for when two addresses front one
shared database: it says which of them holds the single-consolidator lock and therefore which one
sleep, sleep --dry-run and memory explain will work against — a replica refuses all three. The
others say whether the forgotten log is being
recorded, whether an embedded LLM can author a summary, and which memory search --mode values this
deployment can serve.
All three of sleep, sleep --dry-run and purge act on the whole store, so all three are
refused to a group-scoped token whatever its tier — an operator runs them with an unscoped one. The
same applies to the MergeEvents dangling-reference heal. Everything else narrows to the scope
rather than failing, export and clear included, so a scoped export is a per-group snapshot.
| Command | Purpose |
|---|---|
export |
snapshot the store into an S3 archive object (--clear) |
import |
import an archive object from S3 (--object-key) |
import-batch |
upsert full-state rows from a JSON ImportBatchRequest file (--file, - for stdin) |
transfer |
stream the whole store into a centralised instance (--clear) |
clear |
delete exactly the records captured by an export/transfer run (--manifest-id) |
- Time flags (
--timestamp,--time-start,--time-end, and the*-min/*-maxfilters) take RFC3339 (e.g.2026-08-03T09:30:00Z); an empty value means "unset" (the server defaults to now on create, or applies no bound on a filter). - Significance can be set relative to existing values instead of absolutely, via the shared
placement flags:
--place-mode above|below|between,--place-anchor/--place-anchor-id, and (forbetween)--place-upper/--place-upper-id. See SignificancePlacement.
# Store an event and a memory under it, over gRPC.
EV=$(hippo -o json event create --name "release 1.4" --significance 8 --group deploy | jq -r .id)
hippo memory store --body "canary healthy" --significance 6 --event-id "$EV" --group deploy
# The same over the HTTP gateway, with the token from the environment.
export HIPPOCAMPUS_TOKEN=... HIPPOCAMPUS_TRANSPORT=http HIPPOCAMPUS_ADDRESS=localhost:8080
hippo memory list --group deploy --significance-min 5 --limit 50
# Multi-dimensional labels, and the filters over them. --metadata is repeatable and every pair must
# match; the value may itself contain '=' since the split is on the first one.
hippo memory store --body "deploy failed" --significance 6 \
--metadata source=slack --metadata project=apollo
hippo memory list --metadata source=slack --metadata project=apollo
# What have I never recalled? --recall-count-max cannot ask this: 0 means "no bound" everywhere in
# this API, so the tri-state --recalled is what carries it. Also --summary and --binary.
hippo memory list --recalled false --order-by significance
# Sorting. --order-by names the column, --order-dir reverses it; omitting the direction uses that
# column's natural one (most-significant/most-recent first, but alphabetical for id/group/name).
# The two listings sort on different columns - completion offers each command's own set.
hippo memory list --order-by time_recalled --limit 20
hippo event list --order-by name --order-dir desc
# Metadata replaces wholesale on update, so removing labels needs an explicit instruction.
hippo memory update --id "$ID" --clear-metadata
# Ingest full-state rows exported elsewhere.
hippo import-batch --file batch.json
# Destructive operations are gated.
hippo purge --yes