Skip to content
SHAMPOO

Manual ยท Chapter 15 of 19

Client setup

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)

  1. Private connector: write a note, read it back, query it.
  2. Shared connector: write, have the other client read it, write back.
  3. Cross-boundary: confirm the private connector cannot see shared content and vice versa (empty results, never errors; absence is the designed answer).
  4. 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.

On this page