Governed, time-aware memory for Attio records, backed by Perseus Vault — the open-source durable-memory system for AI agents (MIT, local-first, encrypted).
This repo contains two components:
| Path | What it is |
|---|---|
bridge/ |
perseus-vault-bridge: a small dependency-free Python REST gateway over the official perseus_vault_client (vendored, MIT). Runs next to a perseus-vault binary. |
app/ |
The Attio App SDK application: a record widget, two record actions, workspace settings, and server functions that talk to the bridge. |
Attio apps run in a sandboxed JS runtime that cannot spawn local binaries, but can make HTTP requests. The bridge exposes a curated REST surface over the Vault's MCP stdio server, so Attio server functions can read and write governed memory without giving up Vault's semantics:
- Per-record scope — every entry lives in category
attio:{object}:{record_id}; memory for one record can never leak into another. - Supersession, not overwrite — corrections create a new fact and archive the old one with a reason; the old version stays queryable.
- As-of time travel — "what did we believe about this record last Tuesday" is a query, not a guess.
- Audit trail — every write, supersession, and forget is recorded with actor, reason, and timestamp.
- Fail-closed writes — without an authority manifest, writes land as
requires_reviewrather than silently becoming trusted state.
Attio record page
├── record widget "Memory by Perseus Vault"
├── record action "Remember this…"
└── record action "Recall memory"
│ (server functions — Attio sandbox, HTTPS)
▼
perseus-vault-bridge (HTTP :8973, Bearer token)
│ (MCP JSON-RPC over stdio)
▼
perseus-vault binary (SQLite + FTS5, AES-256-GCM at rest)
cd bridge
PERSEUS_VAULT_BIN=/path/to/perseus-vault \
PERSEUS_VAULT_DB=/path/to/vault.db \
PERSEUS_VAULT_ENCRYPTION_KEY=/path/to/vault.key \
BRIDGE_TOKEN=<long-random-token> \
python3 server.pyBRIDGE_HOST (default 0.0.0.0) and BRIDGE_PORT (default 8973) are also
configurable. If BRIDGE_TOKEN is unset the bridge runs unauthenticated —
development only.
| Method | Path | Purpose |
|---|---|---|
| GET | /health |
liveness |
| GET | /v1/stats |
vault statistics |
| POST | /v1/records/{object}/{record_id}/memory |
write {kind, text} |
| GET | /v1/records/{object}/{record_id}/memory?query=&limit=&as_of_unix_ms= |
scoped recall |
| GET | /v1/records/{object}/{record_id}/memory/{key}/history |
version trail |
| GET | /v1/records/{object}/{record_id}/memory/{key}/as-of?as_of_unix_ms= |
transaction-time view |
| GET | /v1/records/{object}/{record_id}/memory/{key}/valid-at?valid_at_unix_ms= |
valid-time view |
| POST | /v1/records/{object}/{record_id}/memory/{key}/supersede |
replace with reason |
| POST | /v1/records/{object}/{record_id}/memory/{key}/forget |
archive with reason |
cd bridge
python3 test_bridge_e2e.py # 16/16 checks: auth, scope isolation, supersede, as-of, forget, statsThe test boots the bridge against a real perseus-vault binary in a temp dir.
cd app
npm install
npm run typecheck # tsc --noEmit against the real attio SDK typesTo run inside Attio: create an app in the
Attio developer console, then either scaffold with
npm create attio@latest <your-slug> and drop this repo's src/ in, or use
this folder directly and point the CLI at your app. Install the app in a dev
workspace, configure the bridge URL/token in workspace settings, then add the
widget via Configure page → Add Widget.
| Id | Type | What it does |
|---|---|---|
perseus-vault-memory |
record widget | latest memory + count for the open record; click for the full list |
perseus-vault-remember |
record action | write a governed memory (fact, decision, correction, preference) |
perseus-vault-recall |
record action | search, browse, and forget this record's memories |
bridge_url and bridge_token (workspace-level). The token is only used by
server functions; it never reaches the browser.
See LISTING.md for the prepared listing copy. Submission is done by the app
owner in the developer console (build.attio.com → app → Publish).
- Bridge traffic must be HTTPS in production (terminate at a reverse proxy).
- The Vault DB is AES-256-GCM encrypted at rest; keep the key file out of the DB directory.
- Writes without an authority manifest are stored as
requires_review— review them via the Vault's own tooling. - Nothing leaves your infrastructure: the bridge, vault binary, and DB all run in your environment.
MIT. The vendored perseus_vault_client is the official MIT-licensed client
from Perseus-Computing-LLC/perseus-vault (integrations/client), copied for
dependency-free deployment.