Skip to main content

Overview

Hindsight is an open-source memory server for AI agents. Agents retain conversations and documents, and an LLM extracts facts, entities and timestamps into a per-bank memory graph. Agents then recall (hybrid search, reranked) or reflect (the LLM reasons over the bank) through a REST API or a built-in MCP server. A bank is one isolated memory store, created on first use; give each agent or user its own. Unlike plain vector search, Hindsight does not store raw chunks and return the nearest ones. Retain turns text into structured facts linked to entities and timestamps, consolidation merges related facts over time, and recall combines semantic, keyword and graph signals with a reranker. This template deploys the API, a web UI (called Hindsight Control Plane upstream), optional dedicated workers, and PostgreSQL with pgvector (a single instance by default, or a highly available cluster).
This template deploys into an existing GVC that you already have. It does not create or manage a GVC. Install into a GVC with a single location: the database runs in one location.

What Gets Created

The template creates no secrets with credentials. The postgresHA option also creates its own identities, policies and startup secrets.

Prerequisites

Create these secrets before you install. Secret names are org-wide, so give each release its own. Secrets are org-level, so no GVC flag is involved.
1

Create the API key secret

The Bearer token for REST and MCP. It opens every bank:
Set auth.apiKeySecretName to this name.
2

Create the database credentials secret

A dictionary secret with exactly username, password and database. Use letters and digits only, because they go into a connection URL:
Set pgvector.config.credentialsSecretName to this name (and postgresHA.config.credentialsSecretName when you use the HA database). Read it back with cpln secret reveal DB_CREDENTIALS_SECRET_NAME -o yaml.
3

Create the web UI access key secret

Needed while ui.enabled is true. It is the key you type to log in to the web UI:
Set ui.accessKeySecretName to this name.
4

Create the LLM key secret

The API key of your LLM provider. Not needed for ollama, for a mock or none provider, or for a self-hosted server without authentication:
Set llm.apiKeySecretName to this name, or to "" when no key is needed. The model must support JSON-schema (structured) output. Hindsight asks for up to 65k output tokens per retain call; for a model with a smaller limit set HINDSIGHT_API_RETAIN_MAX_COMPLETION_TOKENS (above 3000) in hindsight.extraEnv.
Create every secret before installing, or the deployment wedges silently. A name that points at a secret which does not exist installs successfully and then never starts. The container never runs, so cpln logs returns zero lines. The one place the reason appears is status.versions[].message:
Create the missing secret, then run cpln workload force-redeployment RELEASE_NAME-hindsight --gvc GVC_NAME to skip the wait.
Database backups are optional and need a bucket and a Control Plane cloud account, set up as in the pgvector or PostgreSQL Highly Available template.

Installation

Install the chart from the marketplace registry, pointing it at the secrets you created:
The defaults use OpenAI with gpt-5-mini; for another provider add the llm.* values described under Configuration. Or follow the instructions for your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

API and Access

The API and the web UI are private by default. The two public switches are independent: you can expose the web UI while the API stays private, because the web UI calls the API inside the GVC.

LLM

The LLM does fact extraction, reflect and consolidation. Settings for other providers (the provider’s own key goes in llm.apiKeySecretName, empty for a server without authentication): vLLM and LiteLLM expose an OpenAI-compatible API, so they use provider openai with a /v1 base URL. A small model on CPU can need minutes for one reflect; raise hindsight.requestTimeoutSeconds (up to 3600) or give Ollama a GPU.

Embeddings and Reranker

Choose the embedding provider at install: stored vectors belong to the model that wrote them. To change it later, follow Changing the Embedding Model. The default full image (about 1 GB compressed) bundles both local models, so recall makes no external call. The -slim image is less than half the size and has no local models; use it with an OpenAI-compatible embeddings server and rank fusion:

Extra Settings

Any upstream HINDSIGHT_API_* setting goes in extraEnv; secret ones (a Cohere reranker key, per-operation LLM keys) go in a dictionary secret listed in extraSecrets. The template refuses the settings it owns, including every HINDSIGHT_API_TENANT_* setting.

Workers

Without dedicated workers each API replica also runs retain, consolidation and other background tasks. Each worker replica keeps a stable id, so a restarted worker picks up its own unfinished tasks.

Web UI

Database

Enable exactly one of pgvector and postgresHA. Every knob of the pgvector and PostgreSQL Highly Available templates is available under its key, including scheduled backups under backup.

Connecting

Read a canonical endpoint with cpln workload get RELEASE_NAME-hindsight --gvc GVC_NAME -o yaml, and the API key with cpln secret reveal API_KEY_SECRET_NAME -o yaml. From a workload in the same GVC:
A bank is created on first use. Without the key every /v1 and /mcp call returns 401.

MCP Clients

An MCP client connects to one bank at /mcp/BANK_ID/ (streamable HTTP); the tools include retain, recall and reflect. For Claude Code, with the public API enabled:
With --scope project, Claude Code lists the server as pending until you approve it the next time you start claude.

Web UI Access

Open the web UI and log in with the access key from your web UI secret. It lets you browse banks, entities and documents, and try recall and reflect. While it is private, forward the API or the web UI to your machine (then open http://localhost:9999):
For regular browser use, set publicAccess.ui: true and use the public web UI behind its access key; port-forward suits curl and short checks. Firewall changes take a short while to propagate.

Operations

Changing the Embedding Model

Stored vectors belong to the model that wrote them, so changing embeddings.* after data exists breaks recall until every memory is re-embedded. The install wizard refuses this change; make it with the CLI. With the release still on the old model, run the re-embed with the new model’s settings, then upgrade, then finish:
The upgrade uses a values.yaml file with the new embeddings.* values, in the chart’s nesting. Between the first and second command, retains to the old servers return 503; recall keeps working.

Scaling and Availability

The defaults are one API replica and one database instance. For near-zero-downtime upgrades and failover set hindsight.replicas: 2, worker.enabled: true and postgresHA.enabled: true (with pgvector.enabled: false). API replicas share PostgreSQL and are interchangeable. A single database instance restarts with a brief interruption; the HA cluster fails over instead. Keep (hindsight.replicas + worker.replicas) x hindsight.dbPoolMaxSize at or below 90. The template runs in one location. Uninstalling deletes the database volume and every memory bank with it.

Webhooks

Webhooks deliver only to public addresses by default. To reach a receiver inside Control Plane, list its exact hostname (comma-separated, no wildcards) in HINDSIGHT_API_WEBHOOK_ALLOWED_HOSTS through hindsight.extraEnv:

Mental Models

Mental models and pages are synthesized summaries of a bank: a mental model answers a standing question (for example, what is known about a person or project), and a page collects such content into a document. Create them in the web UI, or through the API or MCP. A refresh rewrites the content from the facts retained so far, so a refresh after new retains includes the new facts; a bank with no facts gives empty content. They are written by an agentic reflect loop that needs a capable LLM. A small model on CPU may not finish before HINDSIGHT_API_REFLECT_WALL_TIMEOUT (300 seconds): use a hosted or GPU-served model, or raise that timeout through hindsight.extraEnv.

Stuck Background Tasks

A task claimed by a process that was hard-killed (an out-of-memory kill, a lost node) stays claimed under that process’s id. List them and hand them back:

Troubleshooting

A prerequisite secret (API key, database, web UI key or LLM key) does not exist. Read the reason with cpln workload get-deployments RELEASE_NAME-hindsight --gvc GVC_NAME -o yaml (status.versions[].message), create the secret, then run cpln workload force-redeployment RELEASE_NAME-hindsight --gvc GVC_NAME.
The request has no Authorization: Bearer API_KEY header, or the key differs from the API key secret. /health needs no key.
The LLM key or base URL is wrong; a bad key does not stop startup. Read the API logs with cpln logs '{gvc="GVC_NAME", workload="RELEASE_NAME-hindsight"}' --limit 50 --since 10m.

Important Notes

  • One API key opens every bank: anyone holding it, or the web UI access key, can read and change all banks. Give each agent its own bank id to keep memories separate, not for security. Per-user keys are not available.
  • Updating a secret restarts nothing: after rotating one, run cpln workload force-redeployment on the API, the workers and the web UI.
  • The database password is read only when PostgreSQL first initializes; run ALTER ROLE before updating its secret.
  • Database credentials must be letters and digits only.
  • Choose the embedding provider at install; changing it later needs a re-embed.
  • Use the -slim image only with embeddings.provider: openai and reranker.provider: rrf.
  • Install into a GVC with one location; uninstalling deletes every memory bank.

External References