vriōus — Multi-Agent Orchestration & Shared Memory Patterns

Canonical patterns for orchestrating coding agents (pi, opencode, claude-code) from Hermes, with shared memory across a distributed, multi-container fleet.

Architecture Model

This is multi-host, multi-container — not single-host. Each agent runs in its own container or host:

┌─────────────────────────────────────────────────────────────────┐
│                     Hermes (hertz) — orchestrator                │
│  fact_store / memory tool / MCP client                          │
│  Skills: codex, opencode, claude-code, hermes-agent              │
└──────┬───────────────────────────┬────────────────────┬──────────┘
       │                           │                    │
       ▼                           ▼                    ▼
┌──────────────┐    ┌──────────────────┐    ┌──────────────────┐
│ pi agent      │    │ opencode         │    │ claude-code      │
│ (pica)        │    │ (orca.fritz.box) │    │ (noether.fritz   │
│ Codex CLI     │    │ OpenCode CLI     │    │ .box)            │
│ --print       │    │ run / TUI        │    │ Claude Code CLI  │
│ NPU inference │    │ provider-agnostic│    │ Anthropic Claude │
└──────┬───────┘    └────────┬─────────┘    └────────┬─────────┘
       │                     │                        │
       └─────────────────────┼────────────────────────┘
                             │
                    ┌────────▼────────┐
                    │  Stash / MCP    │
                    │  memory server  │
                    │ (memory.fritz   │
                    │ .box:8080/sse)  │
                    │ (boltzmann)     │
                    └─────────────────┘

Each agent is independent — separate host, separate Incus container, separate config. Hermes invokes them via SSH or lmcp:

Agents

Agent CLI Invocation Transport Location MCP Client MCP Server
Hermes hermes n/a (orchestrator) hertz stash, boltzmann, pica hermes mcp serve
pi pi --print pi_exec MCP tool, SSH+nohup MCP / SSH pica (Incus) stash, hertz, boltzmann codex mcp-server (2 tools)
opencode opencode run SSH / lmcp / direct terminal SSH / MCP orca.fritz.box (Incus) stash (configurable) opencode serve
claude-code claude SSH / lmcp / direct terminal SSH / MCP noether.fritz.box (Incus) stash (via claude.json)

Invocation Patterns

One-Shot (pi)

# Via pi_exec MCP tool (preferred — configurable timeout)
mcp__pica__pi_exec(
    prompt="Read /path/to/file and summarize it",
    model="qwen3.5-9b-npu",
    provider="hossenfelder"
)

# Via SSH (fallback)
ssh mfritsche@pica "pi --print --provider hossenfelder --model qwen3.5-9b-npu 'prompt'"

One-Shot (opencode)

# Via SSH on orca
ssh mfritsche@orca "opencode run 'Implement retry logic for API calls' --model openrouter/anthropic/claude-sonnet-4"

# Or via lmcp on orca
curl -s http://orca.fritz.box:8080/mcp -H "Authorization: Bearer <token>" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"shell","arguments":{"command":"opencode run '...'","timeout":120}}}'

One-Shot (claude-code)

# Via SSH on noether
ssh mfritsche@noether "claude execute -p 'Refactor the auth module and add tests'"

# Or via lmcp on noether
curl -s http://noether.fritz.box:8080/mcp -H "Authorization: Bearer <token>" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"shell","arguments":{"command":"claude execute -p '...'","timeout":120}}}'

Background / Long-Running Tasks

# pi: SSH + nohup with lock file, timeout per file
# See references/batch-pi-processing.md for full pattern

# opencode on orca: SSH background
ssh -f mfritsche@orca "opencode run 'Long task' > /tmp/opencode.log 2>&1"

# claude-code on noether: SSH background
ssh -f mfritsche@noether "claude execute -p 'Long task' > /tmp/claude.log 2>&1"

# Or via lmcp with shell_bg on either host
curl -s http://orca.fritz.box:8080/mcp -H "Authorization: Bearer ***" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"shell_bg","arguments":{"command":"opencode run '...'","log":"/tmp/opencode-task.log"}}}'

Codex as MCP Server

The official codex CLI (v0.143+) can run as an stdio MCP server, exposing pi's coding capabilities as callable tools. Start it on pica:

codex mcp-server --config model="o4-mini"

Handshake exposes:

  • Server: codex-mcp-server v0.143.0
  • Protocol: 2024-11-05
  • Capabilities: tools.listChanged

Exposed Tools

codex — Start a session

Input:  prompt (required), model?, cwd?, sandbox?,
        approval-policy?, base-instructions?,
        developer-instructions?, config?
Output: { threadId, content }

codex-reply — Continue a conversation

Input:  threadId (required), prompt (required)
Output: { threadId, content }

Wiring into Hermes

Add the stdio server to Hermes's config.yaml:

mcp_servers:
  codex-pica:
    command: ssh
    args: [mfritsche@pica, /home/mfritsche/.local/share/pi-node/current/bin/codex, mcp-server]

Then mcp__codex_pica__codex and mcp__codex_pica__codex_reply appear as native Hermes tools.

Wiring into opencode

In ~/.config/opencode/opencode.jsonc on orca:

"mcp": {
  "codex": {
    "type": "local",
    "command": ["ssh", "mfritsche@pica", "/home/mfritsche/.local/share/pi-node/current/bin/codex", "mcp-server"],
    "enabled": true
  }
}

Current pi Setup on pica

Two installations coexist:

Version Binary MCP Server? Notes
@earendil-works/pi-coding-agent v0.80.3 pi No (--mode rpc only) Community fork, NPU inference, MCP client
@openai/codex v0.143.0 codex Yes (codex mcp-server) Official OpenAI CLI, needs API key

pi (community fork) is already configured as an MCP client connected to stash, hertz, and boltzmann:

// ~/.pi/agent/mcp.json
{
  "mcpServers": {
    "stash":    { "url": "http://192.168.88.184:8080/sse" },
    "hertz":    { "url": "http://hertz.fritz.box:8080/mcp",
                  "directTools": ["write_file","shell_bg","shell","fetch","web_search"] },
    "boltzmann":{ "url": "http://boltzmann.fritz.box:8080/mcp" }
  }
}

Shared Memory Patterns

Tier 1: Hermes Holographic Memory (Hermes-only)

fact_store(action='add', content='...', category='general')

Accessed exclusively by Hermes via fact_store and fact_feedback tools. Agents report results, Hermes extracts facts and stores them.

Tier 2: Stash MCP Server (Any MCP-capable agent)

Memory server at memory.fritz.box:8080/sse (boltzmann container)
- Postgres + pgvector + Ollama
- 28 MCP tools
- Query via /stash recall --namespaces "/" -- "query"

If pi, opencode, or claude-code support MCP client configuration, they can read/write to the same stash namespace directly. Otherwise, all memory flows through Hermes.

Tier 3: File-Based (Every agent)

Shared facts.md — agents append with >>, Hermes reads with read_file

Simple, universal. Used in the batch-pi-processing pattern.

Multi-Host, Multi-Container Design

YES — this is designed for separate hosts/containers. Each agent is independently deployed:

|| Host | IP / FQDN | Container? | Agent | Notes | ||------|-----------|-----------|-------|-------| || hertz | hertz.fritz.box | bare metal | Hermes | Orchestrator, MCP client | || pica | pica.fritz.box | Incus | pi agent | RPi5, RK3588 NPU, qwen3.5-9b-npu | || orca | orca.fritz.box | Incus | opencode | OpenCode CLI | || noether | noether.fritz.box | Incus | claude-code | Claude Code CLI | || boltzmann | boltzmann.fritz.box | Incus | Stash / memory | Postgres, pgvector |

No shared filesystem required. Communication is via:

  • SSH — primary transport to orca, noether, and pica
  • lmcp — HTTP MCP bridge running on each container (where set up)
  • MCP (SSE) — stash memory server on boltzmann

Recommendations

  1. New agents go in their own container — keeps dependencies, configs, and sessions isolated
  2. Stash as shared memory — structured, queryable, MCP-accessible. Best upgrade path from file-based
  3. Hermes as sole memory curator — extracts durable facts from agent outputs, stores in fact_store with trust scoring
  4. One-shot for bounded tasks, background TUI for iterative — match the invocation pattern to the task
  5. AGENTS.md per repo — project-level context that all agents respect
S
Description
Multi-agent orchestration and shared memory patterns
Readme 38 KiB