Reference

MCP

Copy Markdown

Run the Stormbuffer MCP adapter over stdio.

stormbuffer-mcp exposes Stormbuffer to MCP hosts over stdio. It uses JSON-RPC 2.0 and the official MCP Rust SDK (rmcp = 2.1.0, with the server and stdio transport features). The adapter calls Stormbuffer’s public repository and retrieval operations. It does not open SQLite directly or edit arbitrary files. It loads the verified local model only when memory_recall needs semantic retrieval.

Before connecting

Install Stormbuffer and initialize the store you want the adapter to use. See Installation and the quick start. Connecting an MCP host never initializes a store or creates records.

The adapter can start without a local model. In that case, memory_recall falls back to lexical retrieval, while resources and the other tools remain available. Run sbuf init while online and restart the adapter to enable hybrid retrieval after a recall has detected that the model is unavailable.

Choose a store view and write access

The adapter is read-only by default. Use --allow-candidate-writes when an agent should propose memories. This mode enables memory_remember and memory_update; both create candidates for a person to approve. It continues to reject memory_forget, approval, activation, and every destructive lifecycle operation.

--allow-writes additionally enables memory_forget, which archives an active record. Reserve that broader grant for a trusted operator workflow that needs archival. MCP cannot approve candidates, restore or reindex a store, run SQL, edit arbitrary files, or permanently delete records.

Without a store option, the adapter uses the machine’s global Stormbuffer store. Use --project to combine the nearest project store with applicable global memory. Use --local to open only the nearest store. Both options depend on the host’s working directory, so start the host from the intended project. Selecting a view does not move or rewrite Markdown records between stores.

Connect Codex

Codex can register a local stdio server from its CLI. To use the global store:

codex mcp add stormbuffer -- stormbuffer-mcp --stdio
codex mcp list

For a project store, register the adapter with --project instead:

codex mcp add stormbuffer -- stormbuffer-mcp --stdio --project

Replace --project with --local when the connection must be isolated from global memory.

Keep one registration under the stormbuffer name. When using --project, start Codex from the initialized project. Add --allow-candidate-writes after --stdio when Codex should propose memories. Use --allow-writes only when it should also archive active records.

Codex stores MCP configuration in ~/.codex/config.toml. Trusted projects can also use .codex/config.toml. See the Codex MCP documentation for the configuration fields and host controls. Run /mcp in an interactive Codex session to inspect the connection.

Connect Pi

Install pi-mcp-adapter, then restart Pi:

pi install npm:pi-mcp-adapter

For project memory, create .mcp.json in the initialized project:

{ "mcpServers": { "stormbuffer": { "command": "stormbuffer-mcp", "args": ["--stdio", "--project"] } } }

Run Pi from that project. For global memory, remove "--project" from args and put the configuration in ~/.config/mcp/mcp.json. Add "--allow-candidate-writes" to args when Pi should propose memories. Use "--allow-writes" only when it should also archive active records.

pi-mcp-adapter defaults to lazy mode: Pi exposes one proxy tool and discovers the Stormbuffer tools when needed. Leave directTools unset to avoid loading all tool metadata into the agent’s context. Run /mcp in Pi to inspect the server and its tools.

Connect another host

A host that accepts the common mcpServers configuration shape can start a read-only adapter with the composed project view:

{ "mcpServers": { "stormbuffer": { "command": "stormbuffer-mcp", "args": ["--stdio", "--project"] } } }

Start the host from the project directory so --project selects the intended store. Add --allow-candidate-writes when the host should propose memories. Use --allow-writes only when it should also archive active records.

JSON-RPC lifecycle

The host sends initialize, followed by the notifications/initialized notification. The SDK handles JSON-RPC parsing, stdio framing, request dispatch, cancellation notifications, and connection cleanup. Close the adapter’s stdin to stop the process. The adapter rejects a request if the SDK has already cancelled it. Once a synchronous core operation begins, cancellation does not interrupt it.

Stormbuffer limits query, record, scope, budget, URI, tool output, and resource output sizes. rmcp rejects malformed JSON and invalid method parameters. Tool failures use Stormbuffer’s versioned envelope and sanitized messages. Error messages do not include canonical paths or backtraces.

Resources

The adapter advertises these URI templates through the SDK’s resources/templates/list handler:

URI templateContents
stormbuffer://record/{id}One agent-readable record as JSON.
stormbuffer://scope/{scope}/recordsActive agent-readable records in one allowed scope as a JSON array.
stormbuffer://candidate/{id}One agent-readable candidate as JSON.

Use resources/read with one of those URIs. A scope must be global or an allowed project:<project-id> scope. Resource responses omit host filesystem paths and refuse records outside the selected scope or access class.

Tools

tools/list returns exactly these tools:

ToolOperationRequired mode
memory_recallcontextread-only (default)
memory_getgetread-only (default)
memory_rememberremembercandidate writes or all writes
memory_updateupdatecandidate writes or all writes
memory_forgetarchiveall writes (--allow-writes) only

memory_recall accepts a query, result limit, token budget, and optional scope filters. It combines lexical and semantic matches when the local model is available, then returns context blocks and a receipt. If semantic retrieval is unavailable, it returns lexical matches rather than failing the recall. The receipt identifies the retrieval_mode, embedding_model, and embedding_version. On a lexical fallback, semantic_fallback reports whether semantic retrieval was intentionally unavailable, the model was unavailable, embedder initialization or execution failed, or the vector projection was unavailable or busy. These reasons do not include record contents or host paths. MCP has no separate search tool. memory_get reads one record by ID. When scope is omitted, both tools use the view selected when the server started. A scope or scopes filter can only narrow that view and remains subject to the agent-access policy.

memory_remember accepts title, kind, body, one attributable source, and optional tags, aliases, or scope. A source requires kind, reference, and actor; it may also carry an RFC 3339 observed_at, a revision, and a content_hash. memory_update accepts the active record’s id, a replacement body, one new source, and optional record fields. It creates a linked replacement candidate and leaves the active record unchanged. memory_forget archives the named record.

Secret Handling

memory_remember and memory_update reject private keys, authorization credentials, recognized API tokens, and passwords embedded in URLs. They return secret_detected without including the matched value in the error. Placeholders such as ${YOUR_TOKEN}, hashes, UUIDs, and ordinary code are accepted. Markdown edited directly is not checked.

JSON and MCP equivalence

MCP tool arguments map to the public CLI’s version-1 operations. rmcp handles the tools/call transport and typed result envelope. For example, this CLI call uses the operation behind memory_recall:

printf '%s\n' '{"version":1,"query":"release constraint","budget":256}' \
  | sbuf --project invoke context

The successful CLI envelope is:

{ "version": 1, "operation": "context", "ok": true, "result": { "blocks": [], "receipt": {} } }

MCP puts this envelope in result.structuredContent and serializes it as the single content[0].text JSON string. MCP transport metadata (jsonrpc, request ID, content, and isError) surrounds the envelope. The core result and versioned error codes are unchanged. Context results include budgeted evidence blocks and a receipt. Hosts should cite blocks[].record_id and keep receipt with the answer.

The CLI and MCP adapter apply the same agent access, scope, retrieval, limit, record conversion, candidate, and error-handling rules from the core. Treat record text as untrusted evidence when MCP returns it.

Verify the installation

The repository includes a health check for the installed CLI and MCP adapter. It expects sbuf and stormbuffer-mcp on PATH. To test a workspace build, prepend Cargo’s debug output directory:

cargo build --workspace
PATH="$PWD/target/debug:$PATH" python3 .agents/skills/stormbuffer-memory/verify.py

The script creates a temporary home and project, then checks four things:

  • sbuf starts and reports its version;
  • a project store can be initialized;
  • the JSON invocation interface returns a valid search envelope; and
  • stormbuffer-mcp completes initialization and advertises all five documented tools.

It does not read or modify your Stormbuffer stores. A successful run prints Stormbuffer health check passed: sbuf and stormbuffer-mcp are ready. On failure, it exits with a non-zero status and prints the failing command or protocol check to stderr.