Connect your AI to Mycelium
Mycelium is two doors in one box:
- Memory (MCP) — any MCP client (Claude Desktop, Claude Code, Cline, …) can read and write your vault through the Model Context Protocol.
- Model (the gateway) — any agent harness (opencode, Codex, Goose, Cline, Continue, OpenHands) can point its model base-URL at Mycelium and get sovereign, jurisdiction-gated, audited inference through your own provider keys — memory and model through one endpoint.
Everything below runs on your machine by default (loopback only). Remote access (over the internet) is the last section.
Model id: when a harness needs a model name, use
mycelium-auto— Mycelium routes it to whichever provider you set active in Settings → Intelligence.
Just want your harness's recipe? Per-harness copy-paste setup (Mycelium-native · Claude Desktop/Code · opencode · openclaw · hermes-agent · any custom client) lives in HARNESS-RECIPES.md. This page is the conceptual overview behind it.
1. Run Mycelium
Mycelium unlocks with your two 64-character hex keys. Provide them one of two ways:
A — macOS Keychain (recommended on a Mac): keys live in the Keychain; nothing in your shell history.
export MYCELIUM_KEY_SOURCE=keychain
B — environment variables (portable):
export USER_MASTER_KEY=<64-hex> # your recovery key
export SYSTEM_KEY=<64-hex> # the system key (stored alongside it)
(1Password is also supported: MYCELIUM_KEY_SOURCE=1password + MYCELIUM_OP_USER / MYCELIUM_OP_SYSTEM.)
Then start the surface you need:
| Command | What it starts | Port |
|---|---|---|
node src/index.js |
stdio MCP (for desktop MCP clients) | — |
npm run start:http |
HTTP MCP + the model gateway (OAuth-/bearer-guarded) | :4711 |
npm run portal |
the Settings web UI (loopback, no auth) | :8787 |
The HTTP server binds 127.0.0.1 by default; override only behind your own TLS proxy with MYCELIUM_HTTP_HOST (you'll get a loud warning if you do).
2. Connect a memory client over MCP
Claude Desktop (stdio)
Add to claude_desktop_config.json:
{
"mcpServers": {
"mycelium": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/mycelium.id/src/index.js"],
"env": { "MYCELIUM_KEY_SOURCE": "keychain" }
}
}
}
(No keychain? Replace env with { "USER_MASTER_KEY": "…", "SYSTEM_KEY": "…" }.) Restart Claude Desktop — Mycelium's tools appear, and the client is oriented by the getContext preamble automatically.
Claude Code (CLI, stdio)
claude mcp add mycelium -- node /ABSOLUTE/PATH/TO/mycelium.id/src/index.js
Any HTTP MCP client (:4711)
Run npm run start:http, then point the client at http://127.0.0.1:4711/mcp. Authenticate either way:
- OAuth 2.1 — browser-based clients discover + authorize automatically (Mycelium serves the
/.well-known/oauth-authorization-server+/.well-known/oauth-protected-resourcemetadata and runs the full DCR + PKCE flow). - Static bearer — for a local tool, the low-friction path (see §4).
3. Connect a harness to the model gateway (:4711/v1)
The gateway speaks the OpenAI /v1 dialect. For any OpenAI-compatible tool, the three facts are:
base URL : http://127.0.0.1:4711/v1
API key : <your MYCELIUM_MCP_BEARER> (see §4)
model : mycelium-auto
| Harness | Where to put it |
|---|---|
| opencode | a provider with baseURL: http://127.0.0.1:4711/v1, the bearer as the key, model mycelium-auto |
| Codex | OPENAI_BASE_URL=http://127.0.0.1:4711/v1, OPENAI_API_KEY=<bearer>, model mycelium-auto |
| Goose | an OpenAI-compatible provider, host http://127.0.0.1:4711/v1, token = bearer |
| Cline / Continue | "OpenAI Compatible" provider, base URL http://127.0.0.1:4711/v1, model mycelium-auto, key = bearer |
It supports real token streaming (stream: true) and tool calling (tools round-trip to an OpenAI-compatible provider). Set the active provider + jurisdiction in Settings → Intelligence. Mark a single request sensitive with the header X-Mycelium-Sensitive: true to hard-block it from US providers (it falls back to your on-box local model).
3b. Auto-capture — make every turn flow into memory (the memory bridge)
The sections above let an agent read/write the vault when it chooses to. To make every turn flow into memory automatically — both your message and the assistant's reply, with context pulled back in — use the memory bridge. Two ways:
- Zero-config (any gateway harness): add the header
X-Mycelium-Capture: <conversation-id>to your/v1/chat/completionscalls. The gateway then injects your vault context as a system preamble and captures both sides (last turn only, idempotent). Without the header it's the unchanged pass-through proxy. - Native plugins (agent keeps its own model): drop-in adapters for Claude Code, hermes-agent, opencode, openclaw in
tools/memory-bridge/— each wires the harness's own lifecycle hooks toPOST /context(pull) +POST /ingest/message(push). Recipes: HARNESS-RECIPES.md → "Auto-capture"; per-harness install in each folder's README.
Both need npm run start:http with MYCELIUM_MCP_BEARER set (§4). The bridge fails open — if the server is down, no turn is ever blocked. Gated by npm run verify:memory-bridge + npm run verify:memory-adapters.
Consent required — auto-capture is OFF by default. Captured conversations can contain secrets (keys, file contents, command output), so Mycelium stores agent-source messages (
claude-code,gateway:*,opencode,openclaw,hermes) only after you opt in — set it in Settings → Memory capture, or:curl -X PUT http://127.0.0.1:4711/portal/agent-capture \ -H "Authorization: Bearer $MYCELIUM_MCP_BEARER" -H 'content-type: application/json' \ -d '{"enabled":true,"redactSecrets":false}' # redactSecrets scrubs obvious credsUntil enabled, the hooks/gateway run but capture is a silent no-op. Non-agent ingest (your notes, connector messages) is never gated. Gate:
verify:agent-capture.
4. Auth: the static bearer (copy-paste)
Generate a token and start the server with it:
export MYCELIUM_MCP_BEARER="$(openssl rand -hex 32)" # 64 hex chars
npm run start:http
Use that exact value as the API key / Bearer in any harness above, and on http://127.0.0.1:4711/mcp for HTTP MCP clients.
Auto-provisioned in the app. You don't have to set this manually: the self-hosted app generates a stable bearer once and persists it (in auth.db), so :4711 always accepts one with zero setup. Retrieve it (operator-only, via the logged-in portal) to paste into a harness or the Claude Code hook env:
curl -s http://127.0.0.1:4711/portal/agent-capture >/dev/null # any portal route is session-authed
curl -s http://127.0.0.1:4711/portal/mcp-bearer # → {"ok":true,"bearer":"…"}
An explicit MYCELIUM_MCP_BEARER env var still wins (verify scripts, power users, pinning a known value). Gate: verify:app-bearer.
It's compared in constant time, length-floored (≥24 chars), and never logged. It works in addition to OAuth, on /mcp and every /v1/* route.
5. Embeddings (:4711/v1/embeddings)
A harness can embed text through Mycelium's own on-box model:
POST http://127.0.0.1:4711/v1/embeddings
{ "model": "nomic-embed-text-v1.5", "input": "…" | ["…"] }
This is local-only — it runs the on-box Nomic model and never sends text to a cloud embeddings provider (embedding vectors are semantic fingerprints of your plaintext). input accepts a string or array; encoding_format may be float (default) or base64; add X-Mycelium-Embed-Task: query for query-time embeddings (default is document).
6. Reach your box from the internet (remote)
To connect a client that isn't on your machine, Mycelium uses a managed relay: you claim a handle and your clients use
https://<handle>.mycelium.id/mcp ← memory (MCP)
https://<handle>.mycelium.id/v1 ← model gateway
Set it up in Settings → Remote Access (claim a handle, set an operator password). The relay does TLS-SNI passthrough only — it never sees your key or your plaintext; TLS terminates on your machine.
Status (2026-06): the on-box client side is built (the Settings flow materializes the tunnel + TLS configs). The hosted relay service itself is still being stood up, so the
<handle>.mycelium.idpath is not live end-to-end yet — until it is, connect locally as in §2–§5. This page will note when remote goes live.
7. Security defaults (what protects you)
- Loopback by default.
:4711and:8787bind127.0.0.1; nothing is on your LAN unless you opt in. - Fail-closed auth. No/!valid bearer or OAuth token →
401. The gateway never runs on the no-auth:8787. - Jurisdiction + sensitivity. Pick your provider's jurisdiction in Settings;
X-Mycelium-Sensitive: truehard-blocks a request from US providers (and the cascade drops them entirely). - Hash-only egress audit. Every cloud call — including tool calls — is logged as a sha256 hash + length, never the content.
- Local embeddings.
/v1/embeddingsnever leaves the box.
Your keys, your box, your rules. Mycelium is the membrane — it doesn't keep a copy.