feat(mother): MCP infra — hive_nodes registry, hardened wrapper/builder, idempotent setup #161

Merged
clawdie merged 2 commits from feature/mother-mcp-infra into main 2026-06-24 10:00:54 +02:00
Owner

Mother-node MCP infrastructure, with a review/hardening pass on top of the initial draft.

Adds

  • mother_schema.sql updates, node-register-mcp, setup-mother.sh, colibri-mcp-ssh, build-colibri.sh, MOTHER-SETUP.md — all under packaging/mother/ (committed + idempotent, deployed via setup-mother.sh, not hand-authored on osa).

Review pass (this branch's hardening)

  • usb_nodeshive_nodes + node_type column. A node is any host that joined the hive (live-usb/disk/vps/mother), not only a USB boot. node_type TEXT (live-usb|disk|vps|mother|unknown) is first-class. The schema migrates an existing osa DB in placeALTER TABLE/ALTER SEQUENCE guarded by to_regclass, plus ADD COLUMN IF NOT EXISTS — data preserved, fully idempotent; FKs/trigger/indexes follow.
  • node-register-mcp: safe psql -v + :'var' UPSERT into hive_nodes, validated node_type. Added ON_ERROR_STOP=1 (psql otherwise exits 0 on a SQL error → false success) and folds stderr into the result so failures are reported.
  • colibri-mcp-ssh: forced-command wrapper now allowlists ("" → stdio MCP, "tools" → discovery, else reject) and quotes safely.
  • build-colibri.sh: branch allowlist (main + semver tags + env override) closes the arbitrary-branch build.rs RCE; features regex + positional-array cargo args close flag injection; now fast-forwards a branch checkout to origin so it builds current code.
  • setup-mother.sh: apply schema before granting on its tables (fresh installs failed otherwise); pipe the schema via stdin (postgres needn't read the repo checkout); locate pg_hba via SHOW hba_file (was hardcoded) and prepend the peer rule (pg_hba is first-match); grants target hive_nodes.

Validation

prettier + sh -n green here. Schema migration/UPSERT and the SSH/MCP path to be exercised on osa (no local postgres server in this env). Build colibri 0.12 on FreeBSD from current main before installing (binaries built earlier were Linux).

Companion (separate, clawdie-iso)

4 iso docs still say mother_hive.usb_nodes (SETUP-USB-TO-MOTHER.md, USB-MOTHER-MCP-CONNECTION.md, DOME-GEOMETRY-CAPABILITY.md) — small follow-up PR to align them to hive_nodes.

🤖 Generated with Claude Code

Mother-node MCP infrastructure, with a review/hardening pass on top of the initial draft. ## Adds - `mother_schema.sql` updates, `node-register-mcp`, `setup-mother.sh`, `colibri-mcp-ssh`, `build-colibri.sh`, `MOTHER-SETUP.md` — all under `packaging/mother/` (committed + idempotent, deployed via `setup-mother.sh`, not hand-authored on osa). ## Review pass (this branch's hardening) - **`usb_nodes` → `hive_nodes` + `node_type` column.** A node is any host that joined the hive (live-usb/disk/vps/mother), not only a USB boot. `node_type TEXT` (live-usb|disk|vps|mother|unknown) is first-class. The schema **migrates an existing osa DB in place** — `ALTER TABLE`/`ALTER SEQUENCE` guarded by `to_regclass`, plus `ADD COLUMN IF NOT EXISTS` — data preserved, fully idempotent; FKs/trigger/indexes follow. - **`node-register-mcp`:** safe `psql -v` + `:'var'` UPSERT into `hive_nodes`, validated `node_type`. Added `ON_ERROR_STOP=1` (psql otherwise exits 0 on a SQL error → false success) and folds stderr into the result so failures are reported. - **`colibri-mcp-ssh`:** forced-command wrapper now **allowlists** (`""` → stdio MCP, `"tools"` → discovery, else reject) and quotes safely. - **`build-colibri.sh`:** branch **allowlist** (main + semver tags + env override) closes the arbitrary-branch `build.rs` RCE; `features` regex + positional-array cargo args close flag injection; now fast-forwards a branch checkout to origin so it builds current code. - **`setup-mother.sh`:** apply schema **before** granting on its tables (fresh installs failed otherwise); pipe the schema via stdin (postgres needn't read the repo checkout); locate `pg_hba` via `SHOW hba_file` (was hardcoded) and **prepend** the peer rule (pg_hba is first-match); grants target `hive_nodes`. ## Validation prettier + `sh -n` green here. Schema migration/UPSERT and the SSH/MCP path to be exercised on osa (no local postgres server in this env). Build colibri 0.12 on FreeBSD from current `main` before installing (binaries built earlier were Linux). ## Companion (separate, clawdie-iso) 4 iso docs still say `mother_hive.usb_nodes` (`SETUP-USB-TO-MOTHER.md`, `USB-MOTHER-MCP-CONNECTION.md`, `DOME-GEOMETRY-CAPABILITY.md`) — small follow-up PR to align them to `hive_nodes`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
clawdie added 2 commits 2026-06-24 09:46:14 +02:00
Consolidates mother MCP infrastructure into packaging/mother/:

- setup-mother.sh: idempotent deploy script (binaries, MCP tools, SSH keys,
  PostgreSQL peer auth, jq-merge external-mcp.json, daemon env update)
- node-register-mcp: UPSERT hw-probe JSON into mother_hive.usb_nodes
  using psql -v :variable heredoc (bound parameter, no SQL interpolation)
- colibri-mcp-ssh: SSH forced-command wrapper with allowlist
  (only "" → stdio MCP mode, "tools" → discovery; everything else rejected)
- build-colibri.sh: branch-allowlisted builder (main + semver tags +
  COLIBRI_BUILD_ALLOW_BRANCHES), features validated, array-quoted cargo args
- MOTHER-SETUP.md: architecture document with security properties

Security fixes vs. the clawdie-iso versions:
- node-register-mcp: was E${ESCAPED} (vulnerable to E backslash
  interpretation); now psql -v :variable in a heredoc
- colibri-mcp-ssh: was unquoted ${SSH_ORIGINAL_COMMAND} passthrough;
  now case-match allowlist
- build-colibri.sh: was arbitrary git checkout + unquoted cargo flags;
  now branch allowlist + features validation + array args
- USB spawn args: no trailing "colibri-mcp" remote command;
  forced-command wrapper handles empty command
- Key management: one key per trust domain (mother-mcp != Forgejo);
  key lives on seed partition, not baked into image
mother: rename usb_nodes→hive_nodes (+node_type), harden setup/register
Some checks failed
CI / rust (pull_request) Has been cancelled
CI / markdown (pull_request) Has been cancelled
CI / port (pull_request) Has been cancelled
CI / agent-jail-pkgs (pull_request) Has been cancelled
e941fdd494
Review pass on the mother MCP infra:

- Rename usb_nodes → hive_nodes: a node is any host that joined the hive
  (live-usb/disk/vps/mother), not just a USB boot. Add a first-class
  node_type column (live-usb|disk|vps|mother|unknown). The schema migrates an
  existing osa DB in place (ALTER TABLE + ALTER SEQUENCE, guarded by
  to_regclass) and ADD COLUMN IF NOT EXISTS for already-renamed tables — data
  preserved, idempotent. FKs/trigger/indexes follow.
- node-register-mcp: accepts + validates node_type, UPSERTs into hive_nodes.
  Add ON_ERROR_STOP=1 (psql otherwise exits 0 on SQL error → false success)
  and fold stderr into the captured result so failures are reported.
- setup-mother.sh: apply schema BEFORE granting on its tables (fresh installs
  had no tables when grants ran); pipe the schema via stdin so the postgres
  user need not read the repo checkout; locate pg_hba via SHOW hba_file (was
  hardcoded) and PREPEND the peer rule (pg_hba is first-match); grants target
  hive_nodes/hive_nodes_id_seq.
- build-colibri.sh: fast-forward a checked-out branch to origin so it builds
  current upstream code, not a stale local copy.

Validated: prettier + sh -n green. Schema migration/UPSERT to be exercised on
osa (no local postgres server here).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
clawdie merged commit 405a2e52e3 into main 2026-06-24 10:00:54 +02:00
clawdie deleted branch feature/mother-mcp-infra 2026-06-24 10:00:55 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: clawdie/colibri#161
No description provided.