Skip to main content
Glama
README.md
# sostenuto

*The pedal that sustains only the notes already held. A self-hosted memory system for AI companions where chosen memories persist across every reset.*

> **Not a developer?** Start with **[docs/getting-started.md](docs/getting-started.md)** — a plain-language, copy-paste walkthrough that takes you from zero to Claude-that-remembers-you on your phone, web, and desktop in about an hour. No code required.

---

## Why

Every major AI now ships memory — Claude, ChatGPT, Gemini, Grok. It's real, and for getting work done it's useful. But it's an *assistant's* memory: it remembers **facts about a user** — preferences, projects, settings — and it does so inside one vendor's walls, opaque and unportable.

It doesn't remember the **relationship**: the emotional weight of things, the shared shorthand built over weeks, the corrections that reshaped how it talks to you, the running threads. That texture isn't lost on reset — a preferences profile was never built to hold it.

Sostenuto is the missing layer. It **complements** platform memory rather than replacing it.

|  | Platform memory | Sostenuto |
|---|---|---|
| **What it holds** | Preferences, facts, projects | The relationship — valence, salience, shared concepts, rituals, the arc |
| **Who owns it** | The vendor; opaque, auto-managed | You; your database, fully readable / editable / deletable |
| **Portability** | Locked to one provider | Yours — one memory across desktop, web, phone, any MCP client |
| **Model of memory** | "Remember everything," or vendor heuristics | Selective by design — chosen memories sustain, the rest fades |
| **Discipline** | Always surfaced | Initiative ≠ access — sensitive memories stay reachable but never volunteered |

Keep the assistant's memory for the assistant things. Sostenuto adds the part that makes a long relationship with an AI feel continuous: being *known*, not just being on file.

Under the hood, that means:

- **Structured relational memory** — memory objects tagged with domain, emotional valence + arousal, salience, sensitivity, and a usage policy.
- **Initiative ≠ access** — `proactive_use` controls whether a memory surfaces *unprompted* (`yes` / `only_when_relevant` / `no`), separately from whether it's *retrievable*. Sensitive memories stay reachable when explicitly referenced, without ever being volunteered.
- **Two-tier guidance** — most memories are content-only. A curated few carry a short, positive `should_do` instruction that silently shapes behavior. Restriction lists are never auto-generated: lean, warm, action-oriented — not a wall of caution.
- **Time-decayed retrieval** — semantic search scored by `similarity × e^(−λ·age)`; recency matters, but the deep past stays findable.
- **Reinforce, don't duplicate** — new observations that match existing memories add evidence and confidence instead of creating copies; content upgrades preserve full version history.
- **Migration** — import months of existing conversations (a structured export prompt + import pipeline) so a relationship can move *into* Sostenuto without starting over.

## Sostenuto

**Sostenuto** *(It., "sustained")* — the middle pedal on a grand piano sustains only the notes already sounding when it's pressed; everything played afterward stays dry. This project applies the same principle to AI memory: the memories you choose to hold persist across every context window, every session, every surface — and the rest is allowed to fade.

Not "the AI remembers everything." **Selective persistence, by design** — pinned memories sustain, the rest decays. The mechanism, not a vibe.

## What ships here

```
db/schema.sql        Consolidated Postgres + pgvector schema (Supabase-ready)
src/memory/          Memory objects: dedup, reinforce, version history, scoring
src/retrieval/       Embeddings, time-decayed semantic search, prompt assembly
src/classify/        Session classification with a pluggable LLM executor
src/migrate/         Conversation-export prompt + structured importer
mcp/                 Thin MCP server (recall / remember / context) — try it
                     from your own Claude Desktop or Claude Code in minutes
templates/           Persona + classification calibration — your companion's
                     voice lives here, in files you edit, not in our code
docs/                Getting started (non-developer guide), memory model,
                     usage-policy semantics, deployment patterns, safety
```

## Model support

Sostenuto is **model-agnostic** with first-class Claude support. The classifier accepts transcripts with optional reasoning blocks — when your model exposes its thinking (Claude does), Sostenuto mines it for perception that never made it into rendered replies, producing the companion's private diary and thinking-highlights. Without reasoning access, everything else works unchanged.

The classification executor is pluggable: Anthropic API, any OpenAI-compatible endpoint (OpenAI, Gemini, DeepSeek, Ollama, vLLM, …), or your own. The Anthropic backend defaults to Claude Haiku 4.5 (`claude-haiku-4-5`) — classification is structured extraction, so a fast, cheap model is the right choice; save the frontier models (the Claude 5 family — Opus 5, Sonnet 5) for the conversation itself.

## The MCP server: try it in minutes

`sostenuto-mcp` exposes `recall` / `remember` / `context` to any MCP client, in two modes from one binary:

- **Local (Claude Desktop / Code)** — add it to your client config as a stdio command. Private by construction; no `PORT` needed.
- **Remote (Claude web / mobile)** — set `PORT` and it serves the MCP transport over HTTP so you can add it as a custom connector. **Fail-closed**: refuses to start without `SOSTENUTO_AUTH_TOKEN`, since a remote endpoint exposes your memory to the network. Token via `Authorization: Bearer` header or `?token=` query.

Both modes and the deploy story — persistent-process hosts and a ready **Vercel** adapter (`api/mcp.js` + `vercel.json`) — are in [docs/deployment-patterns.md](docs/deployment-patterns.md).

## Status

✅ **Core shipped.** Everything listed under "What ships here" is extracted and covered by the test suite (`npm test` — smoke, HTTP-transport, and Vercel-adapter checks). The private system it was extracted from has run in production daily since early 2026 (260+ memory objects across 70+ sessions and three surfaces as of the 0.2 releases). What remains is the roadmap below — watch the repo if you want it as it lands.

## Roadmap

- **Trajectory safety reference** — depth without the dependency trap: this project's design philosophy includes conversation-trajectory awareness (emotional volatility, dependency, recovery capacity) rather than engagement maximization. A reference design is planned; the memory schema already carries the hooks (valence, arousal, sensitivity).
- Decay engine (Ebbinghaus-style, arousal-modulated) over `memory_objects`
- Provider-agnostic chat-surface example

## License

[MIT](LICENSE)

Maintenance

ActivityMaintained
ResponsivenessNo issues