complete MCP tool surface — Matrix approval webhook loop + token verification

Plan #6 (MCP Tool Completion / bin/homelab Migration) done.

- Approval records created for gated request_execution actions
- Notifier sends Matrix messages with HMAC approval tokens
- Stores matrix_event_id, polls /relations/{id}/m.annotation for /
- Reaction detection triggers DecideApproval API call
- Token verification added to DecideApproval endpoint
- Migration 013: matrix_event_id + alert_sent_at on approvals
- AGENTS.md: 21-tool surface documented, stale homelab CLI refs removed
- Plan index updated, audit cross-reference refreshed
This commit is contained in:
2026-07-08 11:02:06 +02:00
parent 5b22f2367b
commit 7c6cffb5f5
12 changed files with 907 additions and 235 deletions

View File

@@ -51,29 +51,45 @@ the operator to run `homelab client add <hostname>` from an existing client.
The homelab exposes a Model Context Protocol server with structured tools.
Endpoint: `https://mcp.hubris.network/mcp`.
Available tools:
Available tools (21 total):
Context (read-only):
Context — observe + orient:
get_entity(slug), list_entities(type, limit, cursor),
get_relations(entity), get_blast_radius(entity),
search_knowledge(query) — full-text search over documents, investigations,
runbooks (PostgreSQL FTS, replaces the old Python search_docs)
get_entity_knowledge(slug) — all documents, investigations, and runbooks
linked to an entity
get_topology(), whoami(hostname), list_my_secrets(caller_pubkey?)
search_knowledge(query) — ILIKE search over documents, investigations,
runbooks in the knowledge_entities table
get_patterns(status, entity_type, action) — learned action patterns
get_skills(status) — available automation skills
Management (read-only):
get_service_status(service), tail_log(service, lines=200),
list_lxcs(), get_lxc_state(lxc), ping_service(service)
Management — live state:
get_service_status(service_slug) — systemctl is-active on target host
tail_log(service_slug, lines=200) — journalctl
list_lxcs() — all LXC containers with ID, host, IP, health
get_lxc_state(lxc_slug) — pct status from Proxmox host
ping_service(service_slug) — HTTP reachability from entity_status
Oikos (read-only; see OIKOS.md):
explain(service) — compact context card
preflight(service) — risk class, approval requirement, verification command
get_change_history(entity, limit=20) — change-ledger entries
get_state_snapshot() — last scheduler Observe-pass (health, disk, drift count)
Oikos — decisions:
explain(service_slug) — compact context card (type, state, health, relations)
preflight(service_slug, action) — risk class + approval requirement
whoami(hostname) — entity record, peers, health for a client
get_change_history(entity_slug, limit=20) — last audit-log entries per entity
get_state_snapshot() — fleet health, disk, drift count
Mutations are **not** exposed via MCP. Use the `homelab` CLI for those, with
operator confirmation — see OIKOS.md's risk classes and approval flow.
Operations — observe + act:
get_health_summary() — fleet health counts (healthy/degraded/down/unknown)
get_signal_history(entity_slug, state, limit) — open + recent signals
get_audit_trail(entity_id) — audit log filter + browse
get_agent_activity(limit) — agent self-inspection
query_metrics(hours=24) — time-series metric bucketed averages
get_trend(entity_id, days=7) — metric slope over time
get_event_timeline(severity, entity_slug, limit) — recent events
Execution — the single mutation path:
request_execution(target, action, params) — policy-gated.
reversible_low (restart, reload, pct_exec, apt audit) runs immediately;
config_mutation (systemctl enable/disable, apt upgrade) queues for operator
approval via Matrix, then executes on ✅.
get_execution_status(execution_id) — poll progress
**When to prefer MCP over grepping the clone:** always for knowledge queries.
`search_knowledge("jellyfin hardware acceleration")` returns ranked results from
@@ -92,8 +108,8 @@ POST /api/v1/knowledge/{entity_slug}
{"title": "...", "content": "...", "tags": ["..."]}
```
The DB is the truth. The old wiki files are archived at `archive/knowledge/` for
historical reference.
The DB is the truth. The old wiki files are in `knowledge/wiki/` pending archive
per the DB-as-source-of-truth plan.
- **Runbook procedures** live as `runbook` entities in the DB and as SKILL.md
files under `.agents/skills/<name>/`. They carry `risk_class`, `procedure`