Client setup
One endpoint serves every profile; each assistant reaches it through the spoke, one connector per profile boundary. The endpoint used through this manual is:
https://memory.op2.uk/mcp
What lives where
-
System configuration (
/etc/shampoo/, root-owned with a dedicated group): non-secret endpoint and profile wiring. Never secrets. -
Secrets (bootstrap material,
0600, never user-owned under/etc): referenced by path from the configuration, never pasted into assistant configs, shell history, git, or docs. -
Mutable session state (session credentials the spoke renews):
under the user's state directory (
~/.local/state/shampoo/), never under/etc.
If a setup snippet asks for a secret inline, it is wrong. Stop and re-check paths.
The spoke invocation (endpoint mode)
The product path runs the spoke against the network endpoint; no local daemon is spawned and no database config is read:
saphira-memory-spoke --serve \
--endpoint https://memory.op2.uk/mcp \
--profile <profile> \
--client-id <id> \
--bootstrap-secret-file <0600 path> \
--jwe-file <state-dir path>
--ca-file adds private or test trust anchors; public chains verify via
system roots alone. --profile names the requested boundary (server
grants decide; unknown names deny like bad credentials). The spoke
presents MCP stdio locally and forwards everything sealed. See
saphira-memory-spoke(1).
OpenCode
One connector entry per boundary (example names: op2-akadata for a
private profile, op2-shared for a shared one), each spawning the spoke
command above with that boundary's profile, identity, secret path, and
state path. Environment carries no secrets, only paths. After (re)start,
prove behaviour, not just connection: a private write/read round-trip on
the private connector, a shared write/read on the shared one, and
confirmed absence across the boundary.
Codex
The same connector names (op2-akadata, op2-shared) with the same
spoke command and the same endpoint. Verify independently from OpenCode:
read shared material the other client wrote, write back, and exercise
session save/recall plus a task create/query/update round-trip.
Claude Code
Claude Code consumes MCP servers over stdio with the identical spoke command per boundary. Register one server per profile boundary, restart the client, and run the same behavioural proof (private round-trip, shared round-trip, cross-boundary absence) before trusting the wiring.
First-run proof (every client, every boundary)
- Private connector: write a note, read it back, query it.
- Shared connector: write, have the other client read it, write back.
- Cross-boundary: confirm the private connector cannot see shared content and vice versa (empty results, never errors; absence is the designed answer).
- Sessions: save, recall, and confirm renewal happens without intervention (credentials rotate hourly; spokes handle it).
The exact copy-paste snippets shipped to a user are validated literally during pack testing before anyone receives them; this chapter states the model they follow.