Convert US/ISO prose dates to EU format across iso docs (CHANGELOG, plans, handoffs, wiki-linked docs). Left as-is (data, not prose): the sample log lines in FIRSTBOOT.md and the ADMIN-PANEL.md UI mockup (timestamps/snapshot names); ISO is correct for machine output. Markdown format gate clean.
10 KiB
Setup: USB → Mother MCP Connection
23.jun.2026 | Step-by-step | Tested on OSA + 0.11 USB
Connects a booted Clawdie USB to the mother node (OSA) via MCP over SSH.
After setup, clawdie-hw-probe runs on the USB, the hardware profile is
sent to mother, and stored in PostgreSQL mother_hive.hive_nodes.
Hosts used in this guide
| Host | IP (Tailscale) | User for MCP | Role |
|---|---|---|---|
mother (OSA) |
<mother-tailscale-ip> |
colibri |
Mother — runs PostgreSQL, external MCP servers |
clawdie-usb (USB) |
<node-tailscale-ip> |
clawdie |
Operator workstation — sends hw-probe to mother |
How it works
┌─ USB ────────────────────────────────────────────────────────┐
│ │
│ colibri-daemon │
│ │ │
│ │ external-mcp.json (baked): │
│ │ "mother": { │
│ │ "command": "ssh", │
│ │ "args": ["-i", "/var/db/colibri/.ssh/mother-mcp", │
│ │ "mother"] │
│ │ } │
│ │ │
│ │ spawns persistent SSH child (no remote command) │
│ │ JSON-RPC flows over stdin/stdout ──────────────────────┐ │
│ │ │ │
│ │ clawdie-hw-probe → JSON → │ │
│ │ colibri_external_mcp_call_tool( │ │
│ │ server="mother", tool="node_register", ...) ──────┤ │
│ │ │ │
└────┼─────────────────────────────────────────────────────────┘ │
│ │
│ Tailscale (WireGuard encrypted) │
│ │
┌────┼─────────────────────────────────────────────────────────┐ │
│ ▼ Mother (OSA) │ │
│ │ │
│ /var/db/colibri/.ssh/authorized_keys: │ │
│ command="/usr/local/bin/colibri-mcp-ssh",restrict,... ◄────┘ │
│ │
│ colibri-mcp-ssh → starts colibri-mcp in stdio MCP mode │
│ │
│ PostgreSQL mother_hive.hive_nodes ← hw-probe JSON stored │
│ │
└───────────────────────────────────────────────────────────────┘
Step 1: SSH key + config (on USB)
Copy the mother-mcp private key to the USB. The public key is already
authorized on mother. For production: the seed partition places this
automatically. For testing: scp from OSA or copy manually.
# === ON USB, as clawdie ===
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Create the private key — replace with real key content
# This key is authorized on mother as:
# command="/usr/local/bin/colibri-mcp-ssh",restrict,no-pty,...
cat > ~/.ssh/mother-mcp << 'KEY'
-----BEGIN OPENSSH PRIVATE KEY-----
<your-private-key-here>
-----END OPENSSH PRIVATE KEY-----
KEY
chmod 600 ~/.ssh/mother-mcp
# SSH config — use Tailscale IP so it works without DNS.
# The Host alias "mother" must match the external-mcp.json entry
# baked into the ISO. The real IP lives only on the seed, never in the repo.
cat > ~/.ssh/config << 'SSH'
Host mother
HostName <mother-tailscale-ip>
User colibri
IdentityFile ~/.ssh/mother-mcp
IdentitiesOnly yes
StrictHostKeyChecking accept-new
SSH
chmod 600 ~/.ssh/config
# Test the connection:
ssh mother 'tools' 2>&1 | head -5
# Expected output:
# colibri_status Get Colibri daemon status...
# colibri_snapshot Get Glasspane snapshot...
# ...
Step 2: External MCP calls + registry (baked into ISO)
COLIBRI_MCP_EXTERNAL_CALL=1 and the mother external-mcp.json entry
are pre-configured in the ISO image by scripts/stage-colibri-iso.sh.
No manual steps are needed — the daemon picks up both on first boot.
Step 3: Install clawdie-hw-probe (on USB)
# === ON USB, as clawdie ===
# From the 0.12 feature branch (already committed):
# Option A — from local repo (if unshallowed):
cd /home/clawdie/ai/clawdie-iso
git fetch origin feature/0.12.0
git show origin/feature/0.12.0:live/operator-session/clawdie-hw-probe \
| sudo tee /usr/local/bin/clawdie-hw-probe > /dev/null
sudo chmod 755 /usr/local/bin/clawdie-hw-probe
# Option B — scp from mother:
# scp colibri@mother:/home/clawdie/ai/clawdie-iso/live/operator-session/clawdie-hw-probe \
# /tmp/ && sudo install -m 755 /tmp/clawdie-hw-probe /usr/local/bin/
# Test:
sudo clawdie-hw-probe 2>/dev/null | python3.11 -m json.tool | head -10
# Expected: JSON with hostname, ram_gb, cpu_model, disks, network_interfaces...
Step 4: Restart daemon + verify (on USB)
# === ON USB, as clawdie ===
# Restart the daemon so it picks up external-mcp.json and the env var
sudo service colibri_daemon restart
# Expected: Starting colibri_daemon.
# colibri-daemon socket ready after 1s
# Verify external MCP tools are visible
colibri-mcp tools 2>&1 | grep external
# Expected:
# colibri_external_mcp_servers List configured external MCP servers...
# colibri_external_mcp_list_tools List tools exposed by...
# colibri_external_mcp_call_tool Call a tool on an external MCP server...
# List mother's registered tools
colibri-mcp --external-config /usr/local/etc/colibri/external-mcp.json \
--external-call tools 2>&1 | head -10
# Expected: tools registered on mother (colibri_status, geodesic_dome, etc.)
End-to-end test
# === ON USB ===
# 1. Run hw-probe, capture JSON
HW_JSON=$(sudo clawdie-hw-probe 2>/dev/null)
# 2. View what would be sent to mother
echo "$HW_JSON" | python3.11 -m json.tool | head -15
# 3. Send to mother via MCP (node_register tool lives in the colibri repo: packaging/mother/node-register-mcp)
# The 0.12 daemon collects hw-probe at autospawn time and passes it to agents
# via CLAWDIE_HW_PROFILE env var. For manual testing, pipe JSON-RPC directly:
printf '{"jsonrpc":"2.0","method":"tools/call","id":1,"params":{"name":"node_register","arguments":{"hostname":"%s","hw_profile":%s}}}\n' \
"$(hostname)" "$HW_JSON" | ssh mother 'cat - | /usr/local/bin/node-register-mcp'
# 4. Verify on mother
ssh mother 'sudo -u postgres psql -d mother_hive \
-c "SELECT hostname, status, capabilities FROM hive_nodes;"'
# Expected: both osa.smilepowered.org and clawdie-usb listed
What happens after (future — 0.12+)
Once the daemon is restarted with COLIBRI_AUTOSPAWN=YES and
COLIBRI_AUTOSPAWN_BINARY=zot:
- zot autospawns — DeepSeek API key from seed partition
- Daemon collects hw-probe — runs
clawdie-hw-probeat spawn time, passes result to zot asCLAWDIE_HW_PROFILEenv var (zot doesn't run hw-probe itself in 0.12) - zot reads env var and calls mother:
colibri_external_mcp_call_tool(server="mother", tool="node_register", arguments={hostname:..., hw_profile:...}) - Mother stores the hardware profile in PostgreSQL
- Capability trigger fires — derives
has_gpu,ram_gb,cpu_cores,geodesic_dome_mcpetc. - Mother returns capabilities — zot now knows what this node can do
- zot logs: "node registered — 12GB RAM, 6 cores, no GPU, geodesic_dome_mcp=true"
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
ssh mother hangs |
Tailscale not up | sudo tailscale up on USB |
Permission denied (publickey) |
Key not in authorized_keys on mother | Verify: cat /var/db/colibri/.ssh/authorized_keys on mother |
Permission denied (publickey) |
Key permissions wrong on USB | chmod 600 /var/db/colibri/.ssh/mother-mcp (daemon user) or ~/.ssh/mother-mcp (clawdie user) |
daemon: open: Permission denied |
Log file ownership wrong | chown clawdie: /var/log/colibri/daemon.log |
| Daemon starts but no external tools | COLIBRI_MCP_EXTERNAL_CALL not set |
Check provider.env, restart daemon |
| Daemon starts, external tools visible, but calls fail | SSH key path wrong in external-mcp.json | Baked path: /var/db/colibri/.ssh/mother-mcp |
error: unrecognized subcommand |
SSH wrapper getting non-allowlisted command | Wrapper only allows "" (stdio) and "tools"; ssh mother tools is correct |