You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Action catalog for the system extension's MCP surface. Lists every system_*, system_sdwan_*, kubernetes_*, and docker_* action callable via the Powernode MCP server.
Audience: AI Concierge prompt authors, external operators integrating with the platform's MCP server, contributors adding new actions.
Where actions are registered (architecture note)
Architecture: The MCP registry (action-name → tool-class mapping) lives in the parent platform at server/app/services/ai/tools/platform_api_tool_registry.rb. The tool class implementations live in the extension at extensions/system/server/app/services/ai/tools/. Rails autoloading resolves the class names across both locations.
flowchart LR
subgraph Parent["Parent platform"]
Reg["platform_api_tool_registry.rb"]
M1["system_* → Ai::Tools::SystemFleetTool"]
M2["system_sdwan_* → Ai::Tools::SdwanTool"]
M3["kubernetes_* → Ai::Tools::Kubernetes*Tool"]
M4["docker_* → Ai::Tools::Docker*Tool"]
Reg --- M1
Reg --- M2
Reg --- M3
Reg --- M4
end
subgraph Ext["System extension"]
T1[system_fleet_tool.rb]
T2[sdwan_tool.rb]
T3[kubernetes_*_tool.rb]
T4[docker_*_tool.rb]
Svc[/services/system/<br/>*_service.rb<br/>lifecycle + biz logic/]
T1 --> Svc
T2 --> Svc
T3 --> Svc
T4 --> Svc
end
MCP[(MCP client<br/>call to action)] --> Reg
M1 -. "class-name string<br/>resolved by autoloader" .-> T1
M2 -.-> T2
M3 -.-> T3
M4 -.-> T4
Loading
To add a new MCP action: register the action-name → class-name mapping in the parent's registry file, then implement the action method in the corresponding tool class inside the extension. Both repos commit; bump the submodule pointer.
To regenerate the parent's full tool catalog with parameter schemas:
cd server && bundle exec rails mcp:generate_tool_catalog
# → writes to docs/platform/MCP_TOOL_CATALOG.md (gitignored)
This document is the system-extension subset of that catalog — manually curated, scannable for operator workflows.
Permission model
Every action requires a permission grant on the calling user/agent. Permissions follow the schema <resource>.<verb> (e.g., system.nodes.read, system.modules.write). The mapping lives in server/db/migrate/*_permissions.rb (parent platform). Agents have permissions assigned via Ai::AgentPermission.
Action catalog
system_* — Fleet, lifecycle, modules, storage, architecture, GitOps, CI workers, disk image CI, providers, topology (102 actions)
Backed by Ai::Tools::SystemFleetTool (parent platform) + Ai::Tools::DockerProvisioningTool (managed Docker runtimes).
Nodes + instances
Action
What it does
Audience
system_list_nodes
List Node rows (filter by status, lifecycle_class, etc.)
Add a module to a Template (with optional metadata like target_cluster_id)
system_list_modules
List NodeModules
system_get_module
Fetch a Module + its categories + dependencies
system_list_module_versions
List versions of a module
system_promote_module_version
Move a version through lifecycle states (built → staging → blessed → live)
system_validate_module_manifest
Dry-run validation of a manifest.yaml payload against the manifest schema before publishing
Tasks
Action
What it does
system_list_tasks
List Tasks (filter by status, type)
system_cancel_task
Cancel a pending or in-flight Task
Instance pools (slice 7)
Action
What it does
system_list_instance_pools
List InstancePools
system_get_instance_pool
Fetch a pool + its members
system_create_instance_pool
Create a new pool (target_size, min, max, region, type, template)
system_drain_instance_pool
Stop replenishing + destroy/release members
system_delete_instance_pool
Remove a drained pool (refuses while members are still attached)
system_acquire_pooled_instance
Atomic claim of a ready member
system_return_pooled_instance
Return a claimed member to the pool (reaper resets state)
system_replenish_instance_pool
Manual trigger of the reaper for this pool
Container runtimes
Action
What it does
system_provision_docker_runtime
Phase 1 Docker daemon provisioning on a NodeInstance
system_decommission_docker_runtime
Destroy managed DockerHost row + Vault TLS material
system_mark_docker_ready
Agent-side ack endpoint (mostly internal)
system_list_managed_docker_hosts
List Powernode-managed Docker hosts (excludes externally-registered)
Package repositories + catalog
Backed by Ai::Tools::SystemPackageRepositoryTool. Manages apt/rpm package repositories, browses the synced catalog with rich filtering, and materializes packages into NodeModules with full dependency closure.
Action
What it does
Audience
system_list_package_repositories
List accessible apt/rpm repositories (account-scoped + shared); filter by kind and node_platform_ids[]. Each row carries embedding_pending_count for catalog coverage.
operator, agent
system_get_package_repository
Fetch one repository with detail (apt_config, rpm_config, linked NodePlatforms)
operator, agent
system_create_package_repository
Register a new apt/rpm/dnf repository (visibility: shared requires system.package_repositories.manage_shared)
M:N link/unlink between repository and NodePlatform
operator
system_search_packages
Search the synced catalog. Hybrid trigram+embedding ranking (default), pure lexical, or pure semantic. Filters: q, mode (lexical/semantic/hybrid), repository_ids[], kind, architectures[] (canonical, cross-kind expanded), sections[], license, provides (capability lookup), sort, page, per_page. Back-compat with singular repository_id/architecture/section. Response includes similarity (when mode ≠ lexical), provides_names, license, applied_filters echo. total is null under semantic/hybrid (exact COUNT prohibitive on vector-filtered sets).
operator, agent
system_discover_packages
Intent-based semantic discovery — describe a capability ("reverse proxy", "distributed cache") and get ranked packages. Pure cosine-distance ranking via pgvector. Inputs: intent (required), repository_ids[], kind, architectures[], license, top_k (1-50, default 10). Returns {results: [{package_id, name, version, architecture, summary, similarity, repository_id, reason}], seed_count, confidence (high/medium/low)}. Use system_search_packages instead when you already know the package name.
operator, agent
system_get_package
Fetch one Package row with full metadata (depends, recommends, provides, conflicts, license, maintainer)
operator, agent
system_resolve_package_dependencies
Preview the dependency closure of a package without writes — required + recommends candidates the operator can opt into
operator, agent
system_create_module_from_package
Materialize a package + transitive deps as NodeModule rows + ModuleDependency edges; dispatches CI build per architecture
operator, agent
system_list_package_module_links
Auditable provenance — which NodeModules came from which packages, top-level vs auto-generated
operator, agent
system_refresh_package_module
Re-materialize a NodeModule when upstream drifts (replays persisted recommends_chosen for deterministic refreshes)
operator, agent
system_suggest_architectures_for_fleet
T2.B — fleet-aware architecture suggestion for materialization; intersects repo's archs with NodePlatform coverage
operator, agent
Embedding pipeline:Package.embedding (pgvector 1536-dim) is populated by SystemPackageEmbeddingJob (worker-side). The job is auto-enqueued after every sync that upserts ≥1 row, and can be manually run via rake system:packages:backfill_embeddings. Without embeddings, hybrid mode contributes only the trigram leg — search still works, just without semantic ranking.
Permissions:system.federation.{spawn,maintenance,resilience} (latter two are read-shape; bound to System Concierge)
See docs/federation/SPAWN_MODES.md for the spawn-mode comparison; the actual spawn endpoint is REST (POST /api/v1/system/federation/children/spawn) — system_deploy_platform is the MCP wrapper that thin-shims that call.
Additional lifecycle actions
Action
What it does
Audience
system_destroy_instance
Tear down a NodeInstance immediately (skips drain — operator must accept blast radius)
operator
system_drain_instance
Graceful shutdown — cordon + drain workloads, then stop services
operator
system_get_silent_instances
Audit query — list NodeInstances whose last_heartbeat_at exceeds the silent threshold
operator, agent
system_refresh_instance_modules
Force the agent to re-reconcile its module set against the platform's view
operator, agent
system_module_mark_canary
Mark a module as a honeypot canary (any access emits a high-severity FleetEvent)
operator
system_recycle_pool
Drain + replace all instances in an InstancePool (slice 7 — pool refresh)
operator
system_delete_template
Remove a NodeTemplate (refuses while in use)
operator
system_unassign_module_from_template
Drop a module → template binding (orphaned NodeModuleAssignments stay; purge_stale: true on re-apply removes them)
operator
system_delete_module
Remove a NodeModule (refuses while assigned)
operator
system_delete_node
Remove a Node row (refuses if any NodeInstance still exists; cascade delete is system_terminate_instance first)
operator
Permissions: the action verb on the matching resource (system.{node_instances,node_modules,instance_pools,…}.{view,destroy,delete,recycle,refresh,mark_canary,drain}).
CVE management
Action
What it does
Audience
system_get_cve
Fetch a single CVE row (CVE-id, severity, affected packages, references)
operator, agent
system_create_cve
Create a CVE row manually (typically driven by the NVD feed worker; operator override path)
operator
system_delete_cve
Remove a CVE row (audit-cleanup)
operator
system_get_cve_exposure
Per-NodeInstance exposure detail — which assigned modules ship the affected packages
operator, agent
Permissions:system.cves.{view,create,delete}, system.cve_exposures.view. CVE remediation runs through the CVE Responder agent's intervention policies (see FLEET_SENSORS.md §"CVE Responder agent (5 policies)") rather than direct MCP actions.
Vault credential rotation
Action
What it does
Audience
system_rotate_vault_transit_pepper
Rotate the Vault transit pepper used for per-account encryption-key wrapping (DR scenario; rare)
List KubernetesNodes for a cluster (control-plane + workers)
kubernetes_decommission_cluster
Cascade-delete cluster + its KubernetesNodes (NodeInstances NOT terminated)
kubernetes_get_kubeconfig
Retrieve kubeconfig YAML + api_endpoint VIP
docker_* — Docker daemon management (52 actions)
Backed by 7 tool classes: DockerContainerTool, DockerServiceTool, DockerStackTool, DockerClusterTool, DockerHostTool, DockerImageTool, DockerNetworkVolumeTool. Works on both managed (Powernode-provisioned) and external (operator-registered) hosts. Per memory powernode.docker_mcp_tools.
A small set of system_* / system_sdwan_* action names are referenced in operator runbooks + tutorials using platform.X(...) syntax but are not yet registered in platform_api_tool_registry.rb. The doc-verification harness reports these as unknown actions; they are intentional placeholders documenting the intended MCP surface, with a REST workaround called out at the call site.
The authoritative list (15 entries as of 2026-05-19) lives at .verify/ASPIRATIONAL_MCP.md. When adding a new doc reference to a not-yet-registered action, also append a row to that catalog so the harness output remains interpretable. When implementing one of the cataloged actions, remove its row + cross-link the new entry in the catalog below.
Operator runbooks under docs/runbooks/ should reference current registry actions only; cross-validate against this doc + the aspirational catalog before adding a new runbook step.
How to add a new action
Pick the right tool class in server/app/services/ai/tools/ (parent) — extend if it fits a domain; create new if introducing a new resource family.
Implement the action method on the tool class. Return a { success: bool, data: hash, error: string } shape.
Add an entry to platform_api_tool_registry.rb — "my_new_action" => "Ai::Tools::MyTool".
Add action_definitions for the new action describing description, parameters, permission. The MCP server uses these to advertise the tool to clients.
Add a permission row in a migration (db/migrate/<timestamp>_add_<name>_permission.rb).
Run bundle exec rails mcp:generate_tool_catalog — regenerates docs/platform/MCP_TOOL_CATALOG.md (gitignored).
Update this MCP_API_REFERENCE.md with the new action — the manually-curated subset for operators.