fix/ootb-mother-mcp #133
6 changed files with 92 additions and 94 deletions
5
build.sh
5
build.sh
|
|
@ -1743,6 +1743,11 @@ EOF
|
||||||
mkdir -p "${MOUNT_POINT}/home/clawdie/.ssh"
|
mkdir -p "${MOUNT_POINT}/home/clawdie/.ssh"
|
||||||
cp "${_mother_key_src}" "${MOUNT_POINT}/home/clawdie/.ssh/mother-mcp"
|
cp "${_mother_key_src}" "${MOUNT_POINT}/home/clawdie/.ssh/mother-mcp"
|
||||||
chmod 0600 "${MOUNT_POINT}/home/clawdie/.ssh/mother-mcp"
|
chmod 0600 "${MOUNT_POINT}/home/clawdie/.ssh/mother-mcp"
|
||||||
|
# Also install for the daemon user (colibri) — same key, different home.
|
||||||
|
mkdir -p "${MOUNT_POINT}/var/db/colibri/.ssh"
|
||||||
|
cp "${_mother_key_src}" "${MOUNT_POINT}/var/db/colibri/.ssh/mother-mcp"
|
||||||
|
chown -R colibri:colibri "${MOUNT_POINT}/var/db/colibri/.ssh" 2>/dev/null || true
|
||||||
|
chmod 0600 "${MOUNT_POINT}/var/db/colibri/.ssh/mother-mcp"
|
||||||
echo " Staged mother SSH key for USB→mother connectivity."
|
echo " Staged mother SSH key for USB→mother connectivity."
|
||||||
fi
|
fi
|
||||||
chmod 0755 \
|
chmod 0755 \
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ sent to mother, and stored in PostgreSQL `mother_hive.hive_nodes`.
|
||||||
|
|
||||||
## Hosts used in this guide
|
## Hosts used in this guide
|
||||||
|
|
||||||
| Host | IP (Tailscale) | User for MCP | Role |
|
| Host | IP (Tailscale) | User for MCP | Role |
|
||||||
| ---------------------- | --------------- | ------------ | ----------------------------------------------- |
|
| ------------------- | ----------------------- | ------------ | ----------------------------------------------- |
|
||||||
| `osa.smilepowered.org` | `100.72.229.63` | `colibri` | Mother — runs PostgreSQL, external MCP servers |
|
| `mother` (OSA) | `<mother-tailscale-ip>` | `colibri` | Mother — runs PostgreSQL, external MCP servers |
|
||||||
| `clawdie-usb` (USB) | `100.66.193.11` | `clawdie` | Operator workstation — sends hw-probe to mother |
|
| `clawdie-usb` (USB) | `<node-tailscale-ip>` | `clawdie` | Operator workstation — sends hw-probe to mother |
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
|
|
@ -20,20 +20,19 @@ sent to mother, and stored in PostgreSQL `mother_hive.hive_nodes`.
|
||||||
│ │
|
│ │
|
||||||
│ colibri-daemon │
|
│ colibri-daemon │
|
||||||
│ │ │
|
│ │ │
|
||||||
│ │ external-mcp.json: │
|
│ │ external-mcp.json (baked): │
|
||||||
│ │ "mother": { │
|
│ │ "mother": { │
|
||||||
│ │ "command": "ssh", │
|
│ │ "command": "ssh", │
|
||||||
│ │ "args": ["-i", "~/.ssh/m0th3r-mcp", │
|
│ │ "args": ["-i", "/var/db/colibri/.ssh/mother-mcp", │
|
||||||
│ │ "c0l1br1@100.72.229.63", │
|
│ │ "mother"] │
|
||||||
│ │ "colibri-mcp"] │
|
|
||||||
│ │ } │
|
│ │ } │
|
||||||
│ │ │
|
│ │ │
|
||||||
│ │ spawns persistent SSH child process │
|
│ │ spawns persistent SSH child (no remote command) │
|
||||||
│ │ JSON-RPC flows over stdin/stdout ──────────────────────┐ │
|
│ │ JSON-RPC flows over stdin/stdout ──────────────────────┐ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ │ clawdie-hw-probe → JSON → │ │
|
│ │ clawdie-hw-probe → JSON → │ │
|
||||||
│ │ colibri_external_mcp_call_tool( │ │
|
│ │ colibri_external_mcp_call_tool( │ │
|
||||||
│ │ server="m0th3r", tool="n0d3_r3g1st3r", ...) ──────┤ │
|
│ │ server="mother", tool="node_register", ...) ──────┤ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
└────┼─────────────────────────────────────────────────────────┘ │
|
└────┼─────────────────────────────────────────────────────────┘ │
|
||||||
│ │
|
│ │
|
||||||
|
|
@ -45,8 +44,7 @@ sent to mother, and stored in PostgreSQL `mother_hive.hive_nodes`.
|
||||||
│ /var/db/colibri/.ssh/authorized_keys: │ │
|
│ /var/db/colibri/.ssh/authorized_keys: │ │
|
||||||
│ command="/usr/local/bin/colibri-mcp-ssh",restrict,... ◄────┘ │
|
│ command="/usr/local/bin/colibri-mcp-ssh",restrict,... ◄────┘ │
|
||||||
│ │
|
│ │
|
||||||
│ colibri-mcp-ssh → strips forced-command wrapper │
|
│ colibri-mcp-ssh → starts colibri-mcp in stdio MCP mode │
|
||||||
│ → passes "tools" subcommand to colibri-mcp │
|
|
||||||
│ │
|
│ │
|
||||||
│ PostgreSQL mother_hive.hive_nodes ← hw-probe JSON stored │
|
│ PostgreSQL mother_hive.hive_nodes ← hw-probe JSON stored │
|
||||||
│ │
|
│ │
|
||||||
|
|
@ -68,83 +66,41 @@ chmod 700 ~/.ssh
|
||||||
# Create the private key — replace with real key content
|
# Create the private key — replace with real key content
|
||||||
# This key is authorized on mother as:
|
# This key is authorized on mother as:
|
||||||
# command="/usr/local/bin/colibri-mcp-ssh",restrict,no-pty,...
|
# command="/usr/local/bin/colibri-mcp-ssh",restrict,no-pty,...
|
||||||
cat > ~/.ssh/m0th3r-mcp << 'KEY'
|
cat > ~/.ssh/mother-mcp << 'KEY'
|
||||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
<your-private-key-here>
|
||||||
QyNTUxOQAAACB3aHk0cmUteTB1LXIzYWRpbmctdGgxcwAAAAh3aHk0cmUteTB1LXIzYWRp
|
|
||||||
bmctdGgxcwAAAAtzc2gtZWQyNTUxOQAAACB3aHk0cmUteTB1LXIzYWRpbmctdGgxcwAAAA
|
|
||||||
-----END OPENSSH PRIVATE KEY-----
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
KEY
|
KEY
|
||||||
chmod 600 ~/.ssh/m0th3r-mcp
|
chmod 600 ~/.ssh/mother-mcp
|
||||||
|
|
||||||
# SSH config — use Tailscale IP so it works without DNS
|
# 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'
|
cat > ~/.ssh/config << 'SSH'
|
||||||
Host m0th3r
|
Host mother
|
||||||
HostName 100.72.229.63
|
HostName <mother-tailscale-ip>
|
||||||
User c0l1br1
|
User colibri
|
||||||
IdentityFile ~/.ssh/m0th3r-mcp
|
IdentityFile ~/.ssh/mother-mcp
|
||||||
IdentitiesOnly yes
|
IdentitiesOnly yes
|
||||||
StrictHostKeyChecking accept-new
|
StrictHostKeyChecking accept-new
|
||||||
SSH
|
SSH
|
||||||
chmod 600 ~/.ssh/config
|
chmod 600 ~/.ssh/config
|
||||||
|
|
||||||
# Test the connection:
|
# Test the connection:
|
||||||
ssh m0th3r 'tools' 2>&1 | head -5
|
ssh mother 'tools' 2>&1 | head -5
|
||||||
# Expected output:
|
# Expected output:
|
||||||
# colibri_status Get Colibri daemon status...
|
# colibri_status Get Colibri daemon status...
|
||||||
# colibri_snapshot Get Glasspane snapshot...
|
# colibri_snapshot Get Glasspane snapshot...
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 2: Enable external MCP calls (on USB)
|
## Step 2: External MCP calls + registry (baked into ISO)
|
||||||
|
|
||||||
```bash
|
`COLIBRI_MCP_EXTERNAL_CALL=1` and the mother `external-mcp.json` entry
|
||||||
# === ON USB, as clawdie ===
|
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.
|
||||||
|
|
||||||
# Add to provider.env
|
## Step 3: Install clawdie-hw-probe (on USB)
|
||||||
echo 'COLIBRI_MCP_EXTERNAL_CALL=1' | \
|
|
||||||
sudo tee -a /usr/local/etc/colibri/provider.env
|
|
||||||
|
|
||||||
# Verify:
|
|
||||||
grep EXTERNAL_CALL /usr/local/etc/colibri/provider.env
|
|
||||||
# → COLIBRI_MCP_EXTERNAL_CALL=1
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 3: Register mother as external MCP server (on USB)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# === ON USB, as clawdie ===
|
|
||||||
|
|
||||||
sudo tee /usr/local/etc/colibri/external-mcp.json << 'JSON'
|
|
||||||
{
|
|
||||||
"servers": {
|
|
||||||
"m0th3r": {
|
|
||||||
"command": "ssh",
|
|
||||||
"args": [
|
|
||||||
"-i", "/home/clawdie/.ssh/m0th3r-mcp",
|
|
||||||
"-o", "StrictHostKeyChecking=accept-new",
|
|
||||||
"c0l1br1@100.72.229.63",
|
|
||||||
"colibri-mcp"
|
|
||||||
],
|
|
||||||
"env": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JSON
|
|
||||||
|
|
||||||
# Verify JSON syntax:
|
|
||||||
python3.11 -m json.tool /usr/local/etc/colibri/external-mcp.json > /dev/null \
|
|
||||||
&& echo "OK" || echo "INVALID JSON"
|
|
||||||
```
|
|
||||||
|
|
||||||
**What happens at daemon startup**: the daemon reads `external-mcp.json`,
|
|
||||||
spawns `ssh c0l1br1@100.72.229.63 colibri-mcp` as a persistent child process,
|
|
||||||
and pipes JSON-RPC over stdin/stdout. The mother-side `colibri-mcp-ssh`
|
|
||||||
wrapper (in `authorized_keys` via `command=`) strips the SSH forced-command
|
|
||||||
layer and passes subcommands directly to `colibri-mcp`. One SSH connection
|
|
||||||
per daemon lifetime — no reconnect overhead.
|
|
||||||
|
|
||||||
## Step 4: Install clawdie-hw-probe (on USB)
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# === ON USB, as clawdie ===
|
# === ON USB, as clawdie ===
|
||||||
|
|
@ -157,8 +113,8 @@ git show origin/feature/0.12.0:live/operator-session/clawdie-hw-probe \
|
||||||
| sudo tee /usr/local/bin/clawdie-hw-probe > /dev/null
|
| sudo tee /usr/local/bin/clawdie-hw-probe > /dev/null
|
||||||
sudo chmod 755 /usr/local/bin/clawdie-hw-probe
|
sudo chmod 755 /usr/local/bin/clawdie-hw-probe
|
||||||
|
|
||||||
# Option B — scp from OSA:
|
# Option B — scp from mother:
|
||||||
# scp clawdie@100.72.229.63:/home/clawdie/ai/clawdie-iso/live/operator-session/clawdie-hw-probe \
|
# 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/
|
# /tmp/ && sudo install -m 755 /tmp/clawdie-hw-probe /usr/local/bin/
|
||||||
|
|
||||||
# Test:
|
# Test:
|
||||||
|
|
@ -166,7 +122,7 @@ 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...
|
# Expected: JSON with hostname, ram_gb, cpu_model, disks, network_interfaces...
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 5: Restart daemon + verify (on USB)
|
## Step 4: Restart daemon + verify (on USB)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# === ON USB, as clawdie ===
|
# === ON USB, as clawdie ===
|
||||||
|
|
@ -204,10 +160,10 @@ echo "$HW_JSON" | python3.11 -m json.tool | head -15
|
||||||
# The 0.12 daemon collects hw-probe at autospawn time and passes it to agents
|
# 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:
|
# 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' \
|
printf '{"jsonrpc":"2.0","method":"tools/call","id":1,"params":{"name":"node_register","arguments":{"hostname":"%s","hw_profile":%s}}}\n' \
|
||||||
"$(hostname)" "$HW_JSON" | ssh m0th3r 'cat - | /usr/local/bin/node-register-mcp'
|
"$(hostname)" "$HW_JSON" | ssh mother 'cat - | /usr/local/bin/node-register-mcp'
|
||||||
|
|
||||||
# 4. Verify on mother
|
# 4. Verify on mother
|
||||||
ssh m0th3r 'sudo -u postgres psql -d mother_hive \
|
ssh mother 'sudo -u postgres psql -d mother_hive \
|
||||||
-c "SELECT hostname, status, capabilities FROM hive_nodes;"'
|
-c "SELECT hostname, status, capabilities FROM hive_nodes;"'
|
||||||
# Expected: both osa.smilepowered.org and clawdie-usb listed
|
# Expected: both osa.smilepowered.org and clawdie-usb listed
|
||||||
```
|
```
|
||||||
|
|
@ -220,7 +176,7 @@ Once the daemon is restarted with `COLIBRI_AUTOSPAWN=YES` and
|
||||||
1. **zot autospawns** — DeepSeek API key from seed partition
|
1. **zot autospawns** — DeepSeek API key from seed partition
|
||||||
2. **Daemon collects hw-probe** — runs `clawdie-hw-probe` at spawn time, passes result
|
2. **Daemon collects hw-probe** — runs `clawdie-hw-probe` at spawn time, passes result
|
||||||
to zot as `CLAWDIE_HW_PROFILE` env var (zot doesn't run hw-probe itself in 0.12)
|
to zot as `CLAWDIE_HW_PROFILE` env var (zot doesn't run hw-probe itself in 0.12)
|
||||||
3. **zot reads env var and calls mother**: `colibri_external_mcp_call_tool(server="m0th3r", tool="node_register", arguments={hostname:..., hw_profile:...})`
|
3. **zot reads env var and calls mother**: `colibri_external_mcp_call_tool(server="mother", tool="node_register", arguments={hostname:..., hw_profile:...})`
|
||||||
4. **Mother stores** the hardware profile in PostgreSQL
|
4. **Mother stores** the hardware profile in PostgreSQL
|
||||||
5. **Capability trigger fires** — derives `has_gpu`, `ram_gb`, `cpu_cores`, `geodesic_dome_mcp` etc.
|
5. **Capability trigger fires** — derives `has_gpu`, `ram_gb`, `cpu_cores`, `geodesic_dome_mcp` etc.
|
||||||
6. **Mother returns capabilities** — zot now knows what this node can do
|
6. **Mother returns capabilities** — zot now knows what this node can do
|
||||||
|
|
@ -228,12 +184,12 @@ Once the daemon is restarted with `COLIBRI_AUTOSPAWN=YES` and
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
| Symptom | Likely cause | Fix |
|
| Symptom | Likely cause | Fix |
|
||||||
| ----------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
| ----------------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||||
| `ssh m0th3r` hangs | Tailscale not up | `sudo tailscale up` on USB |
|
| `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/c0l1br1/.ssh/authorized_keys` on OSA |
|
| `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 ~/.ssh/m0th3r-mcp` |
|
| `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: 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 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 | Use absolute path: `/home/clawdie/.ssh/m0th3r-mcp` |
|
| 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 "colibri-mcp tools" instead of "tools" | Use single-word invocation: `ssh m0th3r 'tools'` not `ssh m0th3r 'colibri-mcp tools'` |
|
| `error: unrecognized subcommand` | SSH wrapper getting non-allowlisted command | Wrapper only allows `""` (stdio) and `"tools"`; `ssh mother tools` is correct |
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ chmod 600 ~/.ssh/mother-mcp
|
||||||
# SSH config for Tailscale hostname
|
# SSH config for Tailscale hostname
|
||||||
cat >> ~/.ssh/config << 'SSH'
|
cat >> ~/.ssh/config << 'SSH'
|
||||||
Host mother
|
Host mother
|
||||||
HostName 100.72.229.63
|
HostName <mother-tailscale-ip>
|
||||||
User colibri
|
User colibri
|
||||||
IdentityFile ~/.ssh/mother-mcp
|
IdentityFile ~/.ssh/mother-mcp
|
||||||
IdentitiesOnly yes
|
IdentitiesOnly yes
|
||||||
|
|
@ -79,7 +79,7 @@ sudo tee /usr/local/etc/colibri/external-mcp.json << 'JSON'
|
||||||
"args": [
|
"args": [
|
||||||
"-i", "/home/clawdie/.ssh/mother-mcp",
|
"-i", "/home/clawdie/.ssh/mother-mcp",
|
||||||
"-o", "StrictHostKeyChecking=accept-new",
|
"-o", "StrictHostKeyChecking=accept-new",
|
||||||
"colibri@100.72.229.63",
|
"colibri@<mother-tailscale-ip>",
|
||||||
"colibri-mcp"
|
"colibri-mcp"
|
||||||
],
|
],
|
||||||
"env": {}
|
"env": {}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,11 @@ SEED_MOUNT="${SEED_MOUNT:-/mnt/clawdie-seed}"
|
||||||
SEED_LOG="${SEED_LOG:-/var/log/clawdie-live-seed.log}"
|
SEED_LOG="${SEED_LOG:-/var/log/clawdie-live-seed.log}"
|
||||||
SEED_USER="${SEED_USER:-clawdie}"
|
SEED_USER="${SEED_USER:-clawdie}"
|
||||||
SEED_USER_HOME="${SEED_USER_HOME:-/home/clawdie}"
|
SEED_USER_HOME="${SEED_USER_HOME:-/home/clawdie}"
|
||||||
|
# Daemon user — the colibri_daemon runs as colibri and needs outbound SSH
|
||||||
|
# material (mother-mcp key + config + known_hosts) installed to its home so
|
||||||
|
# external MCP SSH connections to mother work.
|
||||||
|
SEED_DAEMON_USER="${SEED_DAEMON_USER:-colibri}"
|
||||||
|
SEED_DAEMON_HOME="${SEED_DAEMON_HOME:-/var/db/colibri}"
|
||||||
# Where imported agent payloads are staged. Runtime consumption (loading a soul
|
# Where imported agent payloads are staged. Runtime consumption (loading a soul
|
||||||
# into the agent workspace cwd, launching the chosen harness) reads from here.
|
# into the agent workspace cwd, launching the chosen harness) reads from here.
|
||||||
SEED_IMPORT_ROOT="${SEED_IMPORT_ROOT:-/var/db/clawdie/seed}"
|
SEED_IMPORT_ROOT="${SEED_IMPORT_ROOT:-/var/db/clawdie/seed}"
|
||||||
|
|
@ -348,6 +353,10 @@ _seed_activate_agent() {
|
||||||
# connectivity, delivered via the offline seed rather than baked in the image.
|
# connectivity, delivered via the offline seed rather than baked in the image.
|
||||||
if [ -d "${_dir}/ssh" ]; then
|
if [ -d "${_dir}/ssh" ]; then
|
||||||
_seed_install_ssh_material "${_dir}/ssh" "${_user}" "${_home}"
|
_seed_install_ssh_material "${_dir}/ssh" "${_user}" "${_home}"
|
||||||
|
# Also install for the daemon user (colibri) — the daemon spawns the
|
||||||
|
# external-MCP SSH connection to mother, not the operator (clawdie).
|
||||||
|
# Same seed material, same private key, separate ~/.ssh directory.
|
||||||
|
_seed_install_ssh_material "${_dir}/ssh" "${SEED_DAEMON_USER}" "${SEED_DAEMON_HOME}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_seed_log "activated agent '${_agent}' for user ${_user} (home ${_home})"
|
_seed_log "activated agent '${_agent}' for user ${_user} (home ${_home})"
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,11 @@ Inside it, any of these are honored:
|
||||||
/<agent>/ssh/known_hosts OUTBOUND: merged into ~/.ssh/known_hosts (0644),
|
/<agent>/ssh/known_hosts OUTBOUND: merged into ~/.ssh/known_hosts (0644),
|
||||||
de-duplicated. Pin the mother server's host key
|
de-duplicated. Pin the mother server's host key
|
||||||
here so the first node -> mother connection does
|
here so the first node -> mother connection does
|
||||||
not stop on an unknown-host prompt. Get the line
|
not stop on an unknown-host prompt. Scan the
|
||||||
with: ssh-keyscan osa.smilepowered.org
|
TARGET that ssh/config actually connects to
|
||||||
|
(the Tailscale IP in HostName, not necessarily
|
||||||
|
the DNS name):
|
||||||
|
ssh-keyscan <mother-tailscale-ip>
|
||||||
|
|
||||||
/<agent>/ssh/mother-mcp DUAL-PURPOSE OUTBOUND KEY. This private key
|
/<agent>/ssh/mother-mcp DUAL-PURPOSE OUTBOUND KEY. This private key
|
||||||
serves two roles with a single identity:
|
serves two roles with a single identity:
|
||||||
|
|
@ -136,6 +139,12 @@ Inside it, any of these are honored:
|
||||||
destinations. No other key is needed for either
|
destinations. No other key is needed for either
|
||||||
purpose.
|
purpose.
|
||||||
|
|
||||||
|
The importer installs this material to TWO homes:
|
||||||
|
/home/clawdie/.ssh/ (operator) and
|
||||||
|
/var/db/colibri/.ssh/ (daemon). The daemon
|
||||||
|
spawns the external-MCP SSH connection to mother,
|
||||||
|
so it needs its own copy of the key + config.
|
||||||
|
|
||||||
Agent directory names may contain only A-Z a-z 0-9 . _ - (no spaces or
|
Agent directory names may contain only A-Z a-z 0-9 . _ - (no spaces or
|
||||||
slashes). The name `ssh` is reserved for Layer 1.
|
slashes). The name `ssh` is reserved for Layer 1.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,16 +124,35 @@ COLIBRI_AUTOSPAWN_BINARY="zot"
|
||||||
# Telegram bot token — set this to enable the bot channel (@your_bot).
|
# Telegram bot token — set this to enable the bot channel (@your_bot).
|
||||||
# Leave blank to use CLI/TUI/Dashboard channels only.
|
# Leave blank to use CLI/TUI/Dashboard channels only.
|
||||||
# TELEGRAM_BOT_TOKEN=""
|
# TELEGRAM_BOT_TOKEN=""
|
||||||
|
|
||||||
|
# Enable external MCP server calls so the daemon can connect to mother
|
||||||
|
# (OSA) for hive-node registration. The SSH key comes from the seed
|
||||||
|
# partition; without it the connection fails gracefully.
|
||||||
|
COLIBRI_MCP_EXTERNAL_CALL="1"
|
||||||
EOF
|
EOF
|
||||||
chmod 0600 "${ETC_DIR}/provider.env" 2>/dev/null || true
|
chmod 0600 "${ETC_DIR}/provider.env" 2>/dev/null || true
|
||||||
|
|
||||||
# External MCP server registry — empty by default. The "Enable Mother Link"
|
# External MCP server registry. The mother server entry is pre-configured so
|
||||||
# action (clawdie-enable-mother) adds a server entry here; colibri-mcp reads it
|
# the daemon (running as user colibri) connects to mother OOTB via the
|
||||||
# when launched with COLIBRI_MCP_EXTERNAL_CALL=1. Path matches colibri-mcp's
|
# "mother" SSH config alias. The SSH key, known_hosts, and Host definition
|
||||||
# default COLIBRI_MCP_EXTERNAL_CONFIG.
|
# for "mother" come from the CLAWDIESEED seed partition and are installed
|
||||||
|
# to /var/db/colibri/.ssh/ by the importer (see clawdie-live-seed.README.txt).
|
||||||
|
# Without the seed the connection fails gracefully — the daemon keeps running.
|
||||||
|
# Path matches colibri-mcp's default COLIBRI_MCP_EXTERNAL_CONFIG.
|
||||||
cat > "${ETC_DIR}/external-mcp.json" <<'EOF'
|
cat > "${ETC_DIR}/external-mcp.json" <<'EOF'
|
||||||
{
|
{
|
||||||
"servers": {}
|
"servers": {
|
||||||
|
"mother": {
|
||||||
|
"command": "ssh",
|
||||||
|
"args": [
|
||||||
|
"-i", "/var/db/colibri/.ssh/mother-mcp",
|
||||||
|
"-F", "/var/db/colibri/.ssh/config",
|
||||||
|
"-o", "StrictHostKeyChecking=accept-new",
|
||||||
|
"mother"
|
||||||
|
],
|
||||||
|
"env": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
chmod 0644 "${ETC_DIR}/external-mcp.json" 2>/dev/null || true
|
chmod 0644 "${ETC_DIR}/external-mcp.json" 2>/dev/null || true
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue