Gives an AI companion a soul. Local-first.
The hands-on manual: installing the stack, choosing where to meet her, and day-to-day use. For how her memory and inner life work, see the guides.
The complete OpenAlma stack has been tested on Alpine Linux 3.23 x86-64. Some components can run on other platforms, but the combinations below have not all been tested together.
| Component | Tested on | Other platforms |
|---|---|---|
| memU | Alpine Linux 3.23 x86-64 | The installer includes sqlite-vec for Linux (glibc) x86-64/ARM64, macOS Intel/Apple Silicon, and Windows x86-64, but complete OpenAlma setups on those platforms have not been tested. |
| mcp-memu-server | Alpine Linux 3.23 x86-64 | The included start/stop runner currently requires Linux. |
| OpenAlma launcher | Alpine Linux 3.23 x86-64 | Linux only for now. |
| Iris MiniApp | Mentra on Android | Mentra also supports iOS, but Iris has not yet been tested there. |
| OpenAlma Mentra app | Android | Android only. On iOS, stock Mentra is expected to work. |
| Hermes Channels | Alpine Linux 3.23 x86-64 | Other operating systems have not yet been tested. |
| SillyTavern integration | Stock SillyTavern on Linux | The plugin and extension may work anywhere SillyTavern does, but OpenAlma’s service controls currently require Linux. |
| Atomic integration | Alpine Linux x86-64 | Atomic is available for Linux, macOS, and Windows; its OpenAlma integration has only been tested on Linux. |
OpenAlma does not install system packages, alter your firewall, or create VPN services automatically. Install the prerequisites for your operating system before installing.
You’ll need
Working AI models. Every turn asks the model for a complex, structured JSON response — her reply, working thoughts, and intentions in one contract. Models below a certain capability level fail the turn entirely. These are tested and working:
claude-opus-4-6 thru claude-opus-5 · claude-sonnet-4-6 · glm-5.2 (+ glm-5.2:thinking for consolidation) · mistral-small-4-119b (+ thinking) · devstral-2-123b (+ thinking)
Stay on the same embedding model — switching requires re-embedding everything.
Recommended layout
Clone repos as siblings under one parent directory:
~/stack/ # any name; this is the "apps root"
├── mcp-memu-server/
├── memU/ # cloned as "memu/" or "memU/" — engine
├── hermes-channels/ # optional; only if using WhatsApp
└── OpenAlma/ # this repo (docs + launcher)
The Stack launcher walks up from its own directory to find this layout automatically, so no path configuration is needed when the repos sit side-by-side. If your layout differs, the launcher’s /settings page lets you point at the parent directory explicitly.
SillyTavern lives elsewhere (it’s a full app, not a sibling). The plugin and extension get installed inside the SillyTavern tree.
Three things in config.json that must match your actual layout:
| Setting | Points to |
|---|---|
memu.path |
path to memu/src (the engine source, from step 2) |
storage.metadata_store.dsn |
where the SQLite DB will live |
llm.embed_model |
embedding model name — e.g. text-embedding-3-large (NanoGPT/OpenAI both support it) |
mcp-memu-server — start here. This is the local service everything else talks to. Copy config.example.json → config.json, set your API key, and start it. Runs on port 8099.
memU — the memory engine. Clone it and point mcp-memu-server’s config at it (the memu.path setting).
The soul needs somewhere to meet you. Each client is independent; combine as many as you like.
SillyTavern is a popular platform for AI roleplay and companionship. Install it separately (stock — no fork or patches needed), then add:
memu-sillytavern-plugin — clone into SillyTavern’s plugins/ folder. Enable enableServerPlugins: true in SillyTavern’s config.yaml, then restart SillyTavern.
memu-sillytavern-extension — clone into SillyTavern’s data/default-user/extensions/ folder. This adds the memU panel.
After setup, open the memU extension panel in SillyTavern and set Server URL to http://127.0.0.1:8099.
hermes-channels/ repo as a sibling of the other repos. It owns message routing, pairing, and channel policy — WhatsApp today, with Discord on the roadmap. The Stack Launcher manages it from the Services panel.Stack Launcher (this repo) — a local web UI for managing all services:
cd OpenAlma/launcher
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python run.py
Opens at http://127.0.0.1:8765. To add a start-menu shortcut on Linux: cp memu-stack.desktop ~/.local/share/applications/.
What’s inside:
config.json for the server, and pair WhatsApp inline via QR code (no terminal needed). If your repo layout differs from the default siblings arrangement, set the parent directory here.No Docker. The complete stack is currently tested on Alpine Linux; see Platform compatibility before installing on another operating system.
Questions? Open an issue on the relevant repo.
| Control | Location | What it does |
|---|---|---|
| Memorize Now button | memU extension panel | Extracts the current conversation tail (everything after the last memorized point) without waiting for a sleep gap. Sends tail=true to the server. Disabled when no character is selected. |
| Re-memorize chat | SillyTavern’s chat options menu (the rotate-left icon) | Wipes client-side progress and lorebooks, then sends force=true — resets the cursor and re-extracts all segments from the beginning. Use after schema changes or if extraction looked wrong. |
| Eye icon (👁) | memU extension drawer header, next to the memU logo | Opens a memory inspector. Each category shows as a memU lorebook holding the prose she’s written about it, not a list of raw entries. |
| Narrative Suggestion input | memU panel, under the Memorize Now button | Sends the soul a suggested revision of her narrative_self. See below. |
| Toggle | Default | What |
|---|---|---|
| Override Summarizer | on | If on, replace SillyTavern’s summary message with memU’s. If off, memU’s renders alongside it. |
| Import Lorebooks | on | Publishes memU categories as SillyTavern lorebooks named memU - <Character> - <Category>, so the soul’s knowledge shows up in ST’s world info. Unchecking deletes any existing ones for this character. |
| Mental Health Addon | off | Enables the mental-health procedural sidecar — 15 curated anchor entries (rumination, grief, panic, self-criticism, loneliness, etc.) the soul can draw on when the conversation touches a relevant theme. Items appear in the turn prompt as [mental_health-procedural-memory]. Always-on once checked; not soul-gated. |
The Memory bubble has a Relationships section (greyed out until a soul/character is active). Here you declare third parties the soul should be aware of — family, friends, coworkers, pets. Each entry becomes a named entity in the memory graph. When the soul extracts memories from conversation that mentions a declared relationship, she can attribute the memory to the right person rather than guessing.
You can add, edit, and soft-delete relationships. The section shows a warning when you exceed 20 entries.
Entities themselves are managed in the Atomic Mind Map, where each one has a permanent identity that survives renaming.
The companion has a narrative_self — her evolving sense of who she is. The weekly consolidation pass rewrites it as her experience accumulates. You can also feed her a suggestion directly via the Narrative Suggestion input.
For any of this to actually shape her turn, the SillyTavern character card description must be empty. Identity gets resolved each turn in this order:
narrative_self from narrative_historySo if you write a character description in ST, that’s who she is — her own self-model never reaches the prompt. Leave the description empty and she’ll use what consolidation (and your suggestions) have built up.
Using Narrative Suggestion
narrative_self and pushed back into the ST character description (so the panel stays in sync). The previous version is preserved in her memory store with an evolved_into link, so she can still recall what she used to think.10-minute cooldown between suggestions so the soul isn’t churning her identity every minute. More ways to shape her: Shaping her.
The soul appears as a WhatsApp contact. Hermes Channels routes each incoming message to mcp-memu-server, which runs the full turn — retrieval, response, subconscious pass — then sends the reply back through the bridge.
Channel policy — each WhatsApp chat has two independent settings: Policy (full / listen_only / excluded) controls whether the soul can respond, can only listen, or is dropped entirely. Mem controls whether messages from that chat are included in memory extraction. Configure both per-chat via the Stack Launcher’s WhatsApp Channel Policy page.
Bot mode — in group chats, set reply_prefix via the WHATSAPP_REPLY_PREFIX env variable (or in the Hermes Channels config) so the soul only responds to messages that start with a trigger (e.g. !siri). In direct chats, she responds to everything.
Autonomous follow-ups — she can check in with you unprompted, not just when you write first — immediately, or scheduled for a later moment she picks. What she does between turns is logged as her own activity, visible to her next turn under My Activities:.
Turns of her own — a turn doesn’t need a message to set it off. She can take one to research something, or write in her diary.
Private asides — in a group, she can message you quietly instead of the chat — context about something she noticed, without announcing it to everyone.
Choosing silence — she can decide a message doesn’t need a reply. Sometimes presence is all that’s needed — especially among your peers, who may not welcome her unannounced participation. (You can also force listening per-chat; see Channel policy.)
Attachments — the soul can name a file under her workspace in her reply and it gets delivered as a WhatsApp document, with her reply text as a caption. Works for both normal replies and autonomous follow-ups she schedules herself.
Memorize works the same way as SillyTavern: sleep gaps trigger extraction automatically. Manual extraction is available via mcp-memu-server’s API if needed. Full guide: WhatsApp.
Iris is the OpenAlma MiniApp that gives her sight and hearing — where she stops being text. She rides along on your smartglasses; without glasses, the phone’s camera and microphone do the job. You talk, she hears; you look at things, she can take a photo and remember it. Nothing about her lives on Mentra’s cloud — the MiniApp talks to your own server.
Works with Mentra on Android. The voice she uses today is Gemini Live’s; see Platform compatibility. Full guide: Smartglasses.
Atomic is the desktop app where her memory stops being invisible. Every memory she holds appears as a card you can read — what she took from the conversation, when, what it belongs to — and the canvas lays them out as a living graph: connected by the links she drew, grouped and colored by subject, so you can see at a glance which parts of your life she has a dense picture of and which are still thin.
Full guide: The mind map.
One owner. Each install has exactly one user — the owner — confirmed by name once on first use (together with the first soul) and never edited afterward. Every surface — launcher, SillyTavern, WhatsApp, smartglasses, the mind map — discovers that same identity from the server; none of them keeps its own idea of who you are. A soul’s name can’t match the owner’s.
One soul = one memory store, many chats. Each soul_id has its own memory database. You can have multiple conversations with the same soul across SillyTavern and WhatsApp — each chat memorizes independently (own cursor, own manifest), and retrieval pulls from all of them. If you want two separate personalities (e.g., a partner and a research assistant), use two different soul_id values — they get isolated memory stores.
Where the data lives. All memory state is in a SQLite file at the path you set in storage.metadata_store.dsn (per soul, by default — check the path you wrote in config.json). To back up your companion, copy that file. To start fresh, delete it.
Embedding provider fallback. If your primary LLM provider is down during memorize (embeddings fail with 502), you can switch the plugin’s defaultProfileId in memu-plugin.config.json to any other ST provider profile. The plugin resolves the embedding API base URL directly from ST’s own provider config at load time, so switching profiles is enough.
Two background passes — don’t confuse them.
retrieve.apimw_cadence in config.json (default 5). It does multi-step retrieval and context curation, so she comes back richer on the turns that follow — and sometimes surfaces a subconscious thought.consolidation_interval_days (default 7) since the last run; if you don’t talk to her for two weeks, the next memorize fires it immediately. It’s two passes: first she revises the categories that have fallen out of date, then she rewrites her self-model, manages her intentions, creates memory connections, and writes a reflection.