{"id":"512beb6c-ff72-4abc-9860-ff8a67111fd5","entityType":"agent","slug":"clawhub-zw008-container-host-aiops","name":"container-host-aiops","canonicalUrl":"https://www.xpersona.co/agent/clawhub-zw008-container-host-aiops","canonicalPath":"/agent/clawhub-zw008-container-host-aiops","generatedAt":"2026-10-10T15:52:46.944Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:19:49.871Z","emptyReason":null},"description":"Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list, inspect); system reads (info, version, df disk-usage, recent events); Portainer stacks + endpoints; Compose-project rollups (list_compose_stacks, docker+podman); Podman pods (list_pods, podman-only); three flagship analyses — restart-loop RCA (crash-looping containers + cause/action), resource-pressure analysis (CPU/memory vs limits), and image & volume bloat (prune candidates + reclaimable bytes); and eight guarded writes (restart/stop/start/remove a container, prune images/volumes, update resource limits, recreate a Portainer stack). Always use this skill for \"Docker host overview\", \"which containers are crash-looping\", \"restart loop\", \"why does this container keep restarting\", \"container CPU/memory usage\", \"docker logs\", \"which containers are near their limits\", \"resource pressure\", \"dangling images/volumes\", \"reclaim disk\", \"prune images\", \"stop/start/restart a container\", \"update a container's memory limit\", \"Portainer stacks\", \"compose stacks\", \"Podman pods\" when the context is a Docker, Portainer, or Podman container host. Do NOT use when the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment — route those to the appropriate other AIops-tools skill. This is for NON-orchestrator container hosts. Governed Docker/Portainer/Podman container-host operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See docs/VERIFICATION.md.","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:container-host-aiops","sourceUrl":"https://clawhub.ai/zw008/container-host-aiops","homepage":"https://clawhub.ai/zw008/skills/container-host-aiops","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/zw008/container-host-aiops","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/zw008/skills/container-host-aiops","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"container-host-aiops technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:19:49.871Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:19:49.871Z","emptyReason":null},"stars":null,"forks":null,"downloads":1415,"packageName":null,"latestVersion":"0.11.3","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:19:49.871Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T13:19:49.871Z","lastCrawledAt":"2026-10-10T13:19:49.871Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T13:19:49.871Z","lastVerifiedAt":null,"highlights":[{"version":"0.11.3","createdAt":"2026-09-15T05:53:25.853Z","changelog":"container-host-aiops 0.11.3 - Removed the sample file skill-card.md from the repository. - No user-facing functionality changes in this release.","fileCount":7,"zipByteSize":19735},{"version":"0.11.2","createdAt":"2026-09-12T14:08:09.449Z","changelog":"- Removed the redundant skill-card.md file. - SKILL.md updated; no functional changes to the skill's behavior. - No impact to users; skill features and compatibility remain unchanged.","fileCount":7,"zipByteSize":19723},{"version":"0.11.1","createdAt":"2026-09-12T10:00:43.772Z","changelog":"- Removed redundant skill-card.md file, consolidating documentation. - Minor update to SKILL.md to reflect file cleanup and current features. - No changes to functionality or APIs; this update is documentation-only. - The skill's scope, compatibility, and usage details remain unchanged.","fileCount":7,"zipByteSize":19762},{"version":"0.11.0","createdAt":"2026-09-12T00:49:35.825Z","changelog":"container-host-aiops 0.11.0 - Updated metadata requirements: now accepts either \"container-host-aiops\" or \"uvx\" binaries and adjusts required/optional environment variables. - Removed the skill-card.md file. - SKILL.md was updated for clarified metadata and compatibility requirements; the supported operating systems, binaries, and environment hints were refined. - No changes to user-facing skill commands or core functionality.","fileCount":7,"zipByteSize":19591},{"version":"0.10.0","createdAt":"2026-08-10T06:50:19.552Z","changelog":"- Removed the skill-card.md file. - No changes to features or functionality. - Documentation cleanup only; no user-facing impact.","fileCount":7,"zipByteSize":19615},{"version":"0.9.0","createdAt":"2026-08-10T03:58:03.260Z","changelog":"container-host-aiops v0.9.0 - Updated documentation in SKILL.md, capabilities, and CLI reference for accuracy and clarity. - Removed the obsolete skill-card.md file. - No breaking changes; all feature-set and interfaces remain compatible. - Improved descriptions and usage details across skill docs.","fileCount":7,"zipByteSize":19576},{"version":"0.8.0","createdAt":"2026-08-03T05:52:13.470Z","changelog":"- Removed the file: skill-card.md - No user-facing changes to skill content or features - Documentation footprint simplified","fileCount":7,"zipByteSize":19443},{"version":"0.7.0","createdAt":"2026-08-02T09:38:29.544Z","changelog":"- Removed the documentation file skill-card.md. - No functional changes to the skill; documentation cleanup only.","fileCount":7,"zipByteSize":19481}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:container-host-aiops","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:container-host-aiops` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/zw008/container-host-aiops before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T15:52:46.936Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-container-host-aiops/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:19:49.871Z","emptyReason":null},"readme":"Skill: container-host-aiops\n\nOwner: zw008\n\nSummary: Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list, inspect); system reads (info, version, df disk-usage, recent events); Portainer stacks + endpoints; Compose-project rollups (list_compose_stacks, docker+podman); Podman pods (list_pods, podman-only); three flagship analyses — restart-loop RCA (crash-looping containers + cause/action), resource-pressure analysis (CPU/memory vs limits), and image & volume bloat (prune candidates + reclaimable bytes); and eight guarded writes (restart/stop/start/remove a container, prune images/volumes, update resource limits, recreate a Portainer stack). Always use this skill for \"Docker host overview\", \"which containers are crash-looping\", \"restart loop\", \"why does this container keep restarting\", \"container CPU/memory usage\", \"docker logs\", \"which containers are near their limits\", \"resource pressure\", \"dangling images/volumes\", \"reclaim disk\", \"prune images\", \"stop/start/restart a container\", \"update a container's memory limit\", \"Portainer stacks\", \"compose stacks\", \"Podman pods\" when the context is a Docker, Portainer, or Podman container host. Do NOT use when the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment — route those to the appropriate other AIops-tools skill. This is for NON-orchestrator container hosts. Governed Docker/Portainer/Podman container-host operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See docs/VERIFICATION.md.\n\nTags: latest:0.11.3\n\nVersion history:\n\nv0.11.3 | 2026-09-15T05:53:25.853Z | auto\n\ncontainer-host-aiops 0.11.3\n\n- Removed the sample file skill-card.md from the repository.\n- No user-facing functionality changes in this release.\n\nv0.11.2 | 2026-09-12T14:08:09.449Z | auto\n\n- Removed the redundant skill-card.md file.\n- SKILL.md updated; no functional changes to the skill's behavior.\n- No impact to users; skill features and compatibility remain unchanged.\n\nv0.11.1 | 2026-09-12T10:00:43.772Z | auto\n\n- Removed redundant skill-card.md file, consolidating documentation.\n- Minor update to SKILL.md to reflect file cleanup and current features.\n- No changes to functionality or APIs; this update is documentation-only.\n- The skill's scope, compatibility, and usage details remain unchanged.\n\nv0.11.0 | 2026-09-12T00:49:35.825Z | auto\n\ncontainer-host-aiops 0.11.0\n\n- Updated metadata requirements: now accepts either \"container-host-aiops\" or \"uvx\" binaries and adjusts required/optional environment variables.\n- Removed the skill-card.md file.\n- SKILL.md was updated for clarified metadata and compatibility requirements; the supported operating systems, binaries, and environment hints were refined.\n- No changes to user-facing skill commands or core functionality.\n\nv0.10.0 | 2026-08-10T06:50:19.552Z | auto\n\n- Removed the skill-card.md file.\n- No changes to features or functionality.\n- Documentation cleanup only; no user-facing impact.\n\nv0.9.0 | 2026-08-10T03:58:03.260Z | auto\n\ncontainer-host-aiops v0.9.0\n\n- Updated documentation in SKILL.md, capabilities, and CLI reference for accuracy and clarity.\n- Removed the obsolete skill-card.md file.\n- No breaking changes; all feature-set and interfaces remain compatible.\n- Improved descriptions and usage details across skill docs.\n\nv0.8.0 | 2026-08-03T05:52:13.470Z | auto\n\n- Removed the file: skill-card.md\n- No user-facing changes to skill content or features\n- Documentation footprint simplified\n\nv0.7.0 | 2026-08-02T09:38:29.544Z | auto\n\n- Removed the documentation file skill-card.md.\n- No functional changes to the skill; documentation cleanup only.\n\nv0.6.0 | 2026-07-21T09:40:31.881Z | auto\n\ncontainer-host-aiops 0.6.0\n\n- Governance audit now always records, but permission to write is up to the agent/account, not enforced by the skill\n- Governance @governed_tool decorator now notes: it records actions, does not authorize writes\n- Updated documentation for governance harness and clarified write-operation guardrails\n- Removed obsolete skill-card.md file for streamlining documentation\n- Minor doc and compatibility wording improvements across reference guides\n\nv0.5.0 | 2026-07-20T11:14:40.965Z | auto\n\n- Removed the file skill-card.md.\n- No user-facing features or functionality were changed.\n\nv0.4.0 | 2026-07-19T03:50:46.406Z | auto\n\ncontainer-host-aiops v0.4.0\n\n- Added agent guardrails documentation (references/agent-guardrails.md).\n- Refined documentation and skill metadata for clarity and completeness.\n- Increased tool count to 38; improved summary and scope details.\n- Updated verification status: now validated against a live Docker Engine for core analyses and governed writes; Portainer and Podman APIs remain mock-validated.\n- Removed obsolete skill-card.md; improved and reorganized references and guides.\n\nv0.3.0 | 2026-07-17T05:57:01.102Z | auto\n\nContainer-host-aiops 0.3.0\n\n- Added Podman support: now operates on Docker, Portainer, and Podman standalone hosts\n- New tools: Podman pod listing and Compose project rollup (supporting both Docker and Podman)\n- Updated documentation to reflect Podman features and expanded matrix of supported operations\n- Platform field now allows 'podman' in addition to 'docker' and 'portainer'\n- skill-card.md removed; references and guides updated for new capabilities\n\nv0.2.0 | 2026-07-13T13:10:33.904Z | auto\n\ncontainer-host-aiops 0.2.0\n\n- Removed skill-card.md for streamlined packaging and reduced redundancy.\n- Updated documentation in SKILL.md for improved clarity and completeness.\n- No changes to functional capabilities or compatibility.\n\nv0.1.0 | 2026-07-13T06:24:59.380Z | auto\n\nInitial public preview release of container-host-aiops.\n\n- Provides governed Docker and Portainer container-host operations via a standalone skill.\n- Supports a comprehensive set of read operations (host overview, container/logs/stats, images, volumes, networks, system info, Portainer stacks/endpoints).\n- Includes three flagship analyses: restart loop root-cause analysis, resource pressure, and image/volume bloat.\n- Eight guarded write operations: container lifecycle actions (restart/stop/start/remove), image/volume pruning, resource limit update, and Portainer stack recreation.\n- All state-changing operations pass through a bundled governance harness (audit, policy, risk-tiers, undo support, dry-run, and double confirmation).\n- Secure credential handling: Portainer API tokens are stored encrypted, never in plaintext.\n- PREVIEW: validated against public Docker & Portainer API shape, but not yet live-verified.\n\nArchive index:\n\nArchive v0.11.3: 7 files, 19735 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6870b), references/cli-reference.md (4534b), references/setup-guide.md (5258b), skill-card.md (2789b), SKILL.md (18017b), _meta.json (140b)\n\nFile v0.11.3:SKILL.md\n\n---\nname: container-host-aiops\nslug: container-host-aiops\ndisplayName: \"Container Host AIops\"\nsummary: \"Governed Docker + Portainer container-host ops: reads, RCA analyses, guarded writes. 38 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/Container-Host-AIops\ntags: [aiops, mcp, governance, container-host]\ndescription: >\n  Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list, inspect); system reads (info, version, df disk-usage, recent events); Portainer stacks + endpoints; Compose-project rollups (list_compose_stacks, docker+podman); Podman pods (list_pods, podman-only); three flagship analyses — restart-loop RCA (crash-looping containers + cause/action), resource-pressure analysis (CPU/memory vs limits), and image & volume bloat (prune candidates + reclaimable bytes); and eight guarded writes (restart/stop/start/remove a container, prune images/volumes, update resource limits, recreate a Portainer stack).\n  Always use this skill for \"Docker host overview\", \"which containers are crash-looping\", \"restart loop\", \"why does this container keep restarting\", \"container CPU/memory usage\", \"docker logs\", \"which containers are near their limits\", \"resource pressure\", \"dangling images/volumes\", \"reclaim disk\", \"prune images\", \"stop/start/restart a container\", \"update a container's memory limit\", \"Portainer stacks\", \"compose stacks\", \"Podman pods\" when the context is a Docker, Portainer, or Podman container host.\n  Do NOT use when the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment — route those to the appropriate other AIops-tools skill. This is for NON-orchestrator container hosts.\n  Governed Docker/Portainer/Podman container-host operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See docs/VERIFICATION.md.\ninstaller:\n  kind: uv\n  package: container-host-aiops\nargument-hint: \"[container/image/volume id or describe your container-host task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"container-host-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CONTAINER_HOST_AIOPS_CONFIG\",\"CONTAINER_HOST_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/Container-Host-AIops\",\"emoji\":\"🐳\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed Docker + Portainer + Podman container-host operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Multi-platform by construction (a platform registry); a per-target 'platform' field (docker / portainer / podman) selects the API shape.\n  All write operations are audited to a local SQLite DB under ~/.container-host-aiops/ (relocatable via CONTAINER_HOST_AIOPS_HOME).\n  Connection: a Docker target speaks the Docker Engine API over a local unix socket (httpx uds transport, default /var/run/docker.sock — treat socket access as root-equivalent) or a TCP host; a Portainer target speaks the Portainer management API over HTTPS with an X-API-Key token, and also proxies the Docker API of a managed endpoint at /api/endpoints/{id}/docker/...; a Podman target speaks over the rootful/rootless service socket (autodetected: $XDG_RUNTIME_DIR/podman/podman.sock, then /run/podman/podman.sock), reusing the Docker-compat paths at the root plus libpod-native endpoints (pods) under the libpod prefix.\n  Credentials: only Portainer needs a secret — its API token is stored ENCRYPTED in ~/.container-host-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. A local Docker or Podman socket needs no secret. Run 'container-host-aiops init' to onboard, or 'container-host-aiops secret set <target>' to add a Portainer token. The store is unlocked by a master password from CONTAINER_HOST_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN is still honoured as a fallback with a deprecation warning (migrate with 'container-host-aiops secret migrate'). The token is sent in the X-API-Key header at request time and held only in memory; secrets are never logged or echoed.\n  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget/runaway guard + audit + risk-tier label — it records, it does not authorize) and take a dry_run preview. Prune previews list what would be removed + reclaimable bytes before doing it. Mutating/reversible writes fetch the real before-state first and record a faithful inverse undo descriptor (stop→start, update_container→restore prior limits); irreversible ops (remove, prune, recreate) record only the before-state.\n  Webhooks: none — no outbound network calls beyond the configured Docker socket / TCP host or the Portainer API base URL.\n  SSL: verify_ssl defaults to true; disable only for a self-signed Portainer / TLS Docker daemon. A unix-socket Docker target does not use TLS.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  VERIFICATION: Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. Community-maintained; not affiliated with or endorsed by Docker/Portainer/Podman — trademarks belong to their owners.\n---\n\n# Container Host AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by Docker, Inc., Portainer.io, or any container-platform vendor.** Product and trademark names belong to their owners. Source at [github.com/AIops-tools/Container-Host-AIops](https://github.com/AIops-tools/Container-Host-AIops) under the MIT license.\n\nGoverned Docker + Portainer + Podman container-host operations — **38 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.container-host-aiops/` (MCP + CLI alike), a runaway/budget safety guard, and undo-token recording. It records every operation; whether a write is permitted is the agent's or the account's call, not the skill's. A Docker target speaks the Docker Engine API over a unix socket or TCP; a Portainer target speaks the Portainer API (and proxies Docker); a Podman target speaks over its rootful/rootless socket (Docker-compat + libpod). The Portainer API token is stored **encrypted** (`~/.container-host-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk; a local Docker/Podman socket needs no secret.\n\n> **Standalone**: the governance harness is bundled in the package (`container_host_aiops.governance`) — container-host-aiops has no external skill-family dependency. **Verification**: Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See `docs/VERIFICATION.md`.\n\n## What This Skill Does\n\n| Domain | Tools | Count | Read or Write |\n|--------|-------|:-----:|:-------------:|\n| **Overview** | one-shot host health | 1 | 1 read |\n| **Containers** | list/inspect, logs, stats, top, restart summary | 6 | 6 read |\n| **Images** | list, inspect (+history), dangling, disk usage | 4 | 4 read |\n| **Volumes** | list, inspect, dangling | 3 | 3 read |\n| **Networks** | list, inspect | 2 | 2 read |\n| **System** | info, version, df, events | 4 | 4 read |\n| **Stacks** | endpoints, stacks, stack detail (Portainer), compose-stack rollup (docker+podman) | 4 | 4 read |\n| **Pods (Podman)** | list pods (libpod) | 1 | 1 read |\n| **Analyses (flagship)** | restart-loop RCA, resource pressure, image/volume bloat | 3 | 3 read |\n| **Writes** | remove container, prune images, prune volumes, recreate stack | 4 | 4 write (high) |\n| | restart, stop, start, update container | 4 | 4 write (medium) |\n\nThe three analyses accept injected data for offline analysis, or pull live from a configured target. Portainer endpoints/stacks require a `portainer` target; `list_compose_stacks` works on docker or podman; `list_pods` requires a `podman` target.\n\n## Quick Install\n\n```bash\nuv tool install container-host-aiops\ncontainer-host-aiops init       # interactive wizard: Docker/Podman socket or Portainer target\ncontainer-host-aiops doctor\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/container-host-aiops\nopenclaw skills info container-host-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a host (`overview`): version + container state rollup + disk headline\n- Find crash-looping containers (`analyze restart-loop` / `restart_loop_rca`): ranked by restart count with a likely cause and action from the exit code, plus a log tail\n- Spot resource pressure (`analyze resource-pressure` / `resource_pressure_analysis`): CPU%/mem% vs each container's limits, worst first, with a recommendation\n- Reclaim disk (`analyze bloat` / `image_and_volume_bloat`): dangling images + volumes + build cache as prune candidates with reclaimable bytes\n- List/inspect containers, images, volumes, networks; tail logs; read stats/top\n- Restart/stop/start a container, update its resource limits (reversible), remove a container, prune images/volumes, or recreate a Portainer stack — all with dry-run + double-confirm\n\n**Do NOT use when** the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| Docker / Portainer single-host container ops | **container-host-aiops** (this skill) |\n| A cluster orchestrator's workloads/rollouts | a cluster ops skill |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| OT / industrial edge (Modbus, OPC-UA, PLC) | the industrial-aiops line |\n\n## Common Workflows\n\n### 1. A container is crash-looping\n\n1. `container-host-aiops doctor` → confirm the socket/endpoint is reachable before you\n   trust any read.\n2. `container-host-aiops analyze restart-loop` → containers ranked by restart count,\n   each with a likely cause read off the real exit code (137 OOM/SIGKILL, 143 SIGTERM,\n   139 segfault, 127 bad entrypoint, …), a recommended action, and a log tail.\n3. `container-host-aiops container logs <id> --tail 200` → read the actual crash output;\n   `container-host-aiops container inspect <id>` → confirm the exit code, restart policy,\n   and configured limits the RCA cited.\n4. If the cause is memory: `container-host-aiops analyze resource-pressure --mem 75` →\n   see how close the container runs to its ceiling, then\n   `container-host-aiops manage update <id> '{\"Memory\": 1073741824}' --dry-run` and\n   re-run without `--dry-run` (double-confirm; the write captures the prior limits as its\n   undo descriptor).\n5. `container-host-aiops manage restart <id>` → bring it up on the new limit, then\n   re-run `analyze restart-loop` to confirm the loop stopped.\n6. **Failure branch**: if it still loops, the limit was not the cause — reverse the\n   change with `container-host-aiops undo list` → `undo apply <id>` (restores the *prior*\n   limits, not a guess) and go back to step 3 with the fresh log tail. If the container\n   will not stop at all, `manage remove <id> --force --dry-run` first: force-remove is\n   high-risk and irreversible, so read the dry-run before committing.\n\n### 2. The host is out of disk\n\n1. `container-host-aiops system df` → where the space actually went (images vs\n   containers vs volumes vs build cache).\n2. `container-host-aiops analyze bloat` → dangling images, dangling volumes, and build\n   cache as ranked prune candidates with reclaimable bytes per item.\n3. `container-host-aiops image dangling` and `container-host-aiops volume dangling` →\n   eyeball the concrete list before deleting anything. A \"dangling\" volume holding data\n   you still want is the classic way this goes wrong.\n4. `container-host-aiops manage prune-images --dry-run` → exactly what would be removed;\n   re-run without `--dry-run` (double-confirm, high risk).\n5. `container-host-aiops manage prune-volumes --dry-run` → **read this one carefully**;\n   volume pruning destroys data and records no undo. Note that Docker's default\n   prune removes only ANONYMOUS unused volumes — the preview reports the named\n   unused ones it will not touch as `alsoUnusedNamed*`; add `--all` to include\n   them. Only then re-run for real.\n6. `container-host-aiops system df` again → confirm the space came back.\n7. **Failure branch**: pruning is not reversible. If you removed a volume you needed,\n   the undo store cannot help — restore from your backup. The dry-run in steps 4–5 is\n   the only safety net, which is why both are separate confirm-gated steps.\n\n### 3. \"Everything on this box is slow\"\n\n1. `container-host-aiops overview` → one-shot: platform/version, container counts by\n   state, and the headline resource picture.\n2. `container-host-aiops analyze resource-pressure --cpu 80 --mem 80` → running\n   containers ranked against **their own limits**, each row citing the measured\n   percentage rather than a verdict.\n3. `container-host-aiops container stats <id>` and `container-host-aiops container top <id>`\n   → confirm the top offender at the process level before you act on it.\n4. `container-host-aiops system events` → correlate the pressure with what changed\n   (a recent deploy, restart storm, or image pull).\n5. Act on the worst offender: `manage update <id> '{\"NanoCpus\": 2000000000}'` to cap it\n   (dry-run first, undo-recorded), or `manage stop <id>` to shed it entirely.\n6. **Failure branch**: if capping the top container just moves the pressure elsewhere,\n   the host is genuinely undersized rather than misconfigured — reverse your change with\n   `undo apply <id>` so you are not left with a half-applied limit, and take the sizing\n   result to whoever owns capacity.\n\n### 4. Stack drift after a bad deploy (Portainer)\n\n1. `container-host-aiops stack endpoints` → the endpoints this Portainer manages;\n   `container-host-aiops stack list` → the stacks on the one you care about.\n2. `container-host-aiops stack detail <stack-id>` → the stack's current definition;\n   `container-host-aiops stack compose <stack-id>` → the compose file it is running from.\n3. `container-host-aiops container list --running` and\n   `container-host-aiops container restarts` → which of the stack's containers are\n   actually unhealthy versus merely restarted.\n4. `container-host-aiops manage recreate-stack <stack-id> --dry-run` → preview the\n   redeploy; re-run without `--dry-run` (double-confirm, high risk).\n5. Validate with `container-host-aiops overview` and `analyze restart-loop`.\n6. **Failure branch**: `recreate-stack` redeploys from the stack's stored definition — if\n   that definition is itself the broken thing, recreating will faithfully reproduce the\n   breakage. Fix the compose source in Portainer first, and use\n   `container-host-aiops undo list` to check what the session already changed before\n   layering another write on top.\n\n### Offline analysis (no live host)\n\nPass data straight to the analysis tools — `restart_loop_rca(containers=[...])`, `resource_pressure_analysis(samples=[...])`, or `image_and_volume_bloat(dangling_images=..., dangling_volumes=..., df=...)` — to analyse an exported dataset without connecting to a host.\n\n## Governance & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide\nwhether a write is permitted. That is your agent's judgement, or the permission\nof the account you connect it with (a read-only Docker socket, a Portainer\naccount without write scope — writes then fail at the server). There is no\nread-only switch, policy file, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.container-host-aiops/audit.db` (relocatable via `CONTAINER_HOST_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `CONTAINER_HOST_AUDIT_APPROVED_BY` / `CONTAINER_HOST_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: the same call looped in a tight window trips a circuit breaker. Disable with `CONTAINER_HOST_RUNAWAY_MAX=0`.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI; prune previews list what would be removed + reclaimable bytes.\n- Mutating/reversible writes fetch the real before-state and record an inverse descriptor (stop→start, update_container→restore prior limits); irreversible ops record only the before-state.\n\n## References\n\n- `references/capabilities.md` — full tool + field reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n\nFile v0.11.3:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"container-host-aiops\",\n  \"version\": \"0.11.3\",\n  \"publishedAt\": 1789451605853\n}\n\nFile v0.11.3:references/agent-guardrails.md\n\n# Agent guardrails — running container-host-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Give it a Docker socket mounted read-only,\n  or a Portainer account without write scope. A write then fails at the server,\n  which is the only place the permission actually lives — no skill-side flag can\n  be argued around by a model, but a revoked permission cannot be.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Log everything you do, over both MCP and the CLI\" | Every operation is audited to `~/.container-host-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. Reversible writes also record an undo token capturing the *prior* state. |\n| \"Don't invent a value when a field is missing\" | The Docker Engine omits keys it has nothing to say about — a created-but-never-started container has no `Status`, a dangling image has no `RepoTags`. Those come back as `null`, never as `\"\"`. An id in particular is `null` when unknown, so a blank string is never mistaken for a real identifier. |\n| \"Tell me if the log was cut off\" | `container_logs` returns `{\"lines\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`, and `system_events` the same shape. Truncation is measured — one extra line is requested from Docker — not guessed from a length coincidence. |\n| \"Preserve the ordering / tell me what's most urgent\" | `restart_loop_rca` and `resource_pressure_analysis` rank worst-first and carry the measured number (restart count, exit code, CPU%, memory%) in each entry. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `remove_container`, `prune_images` and `prune_volumes` require a `--dry-run`-able preview plus double confirmation at the CLI. |\n| \"Don't get stuck retrying\" | The runaway guard trips a circuit breaker if the same call is hammered in a tight loop — a stuck agent is stopped rather than left to burn calls and time. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a Docker or Podman container host (optionally via Portainer)\nthrough the container-host-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current host, you MUST call a tool.\n  Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher tail instead of treating\n  the partial result as the container's complete log. A container that has been\n  restarting for hours has far more log history than the default tail shows.\n- A null field means Docker did not report that value. Report it as \"not\n  available\" — never infer it. A null id is not a container named \"None\".\n- Report values exactly as returned. Do not normalise, translate, or prettify\n  container states, exit codes, or image tags.\n- Exit code 0 with a high restart count is a container completing and being\n  restarted by policy, not a crash. Do not call it a failure.\n- \"oomKilled\": true is the memory limit being hit — cite it rather than\n  guessing at a memory problem from CPU numbers.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert that a container is failing for a particular reason unless the\n  log tail or exit-code classification in the result supports it.\n- Do not add generic Docker advice that does not follow from the tool output.\n- Do not confuse a container id with an image id, a short id with a full one, a\n  container name with its image name, or a compose stack with a container.\n- Volumes and images are not deleted with the container. Pruning is a separate,\n  destructive, and irreversible operation — never fold it into a cleanup\n  suggestion casually.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the account's\npermission only when you trust the setup — the destructive operations on a\ncontainer host are unusually cheap to invoke and unusually expensive to undo\n(`prune_volumes` deletes data no undo token can bring back):\n\n```bash\n# e.g. mount the Docker socket read-only for the container running this tool,\n# or use a Portainer account without write scope. Then:\ncontainer-host-aiops doctor\n```\n\nOptionally annotate the audit trail with who is operating and why — recorded on\nevery row, never required:\n\n```bash\nexport CONTAINER_HOST_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport CONTAINER_HOST_AUDIT_RATIONALE=\"clearing disk on the build host\"\n```\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer the analysis tools —\n  `restart_loop_rca` correlates restart counts, exit codes, OOM flags and log\n  tails inside one call, so the model does not have to chain a list, an inspect\n  and a logs call per container while keeping ids straight.\n- **The model ignores later tool results in a long context.** Container logs are\n  the big payload here. Ask narrower questions and use `tail` deliberately\n  rather than pulling 2000 lines from every container.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\n## Verification status\n\nUnlike most of this tool line, container-host-aiops has been **live-verified\nagainst a real Docker 27.5.1 daemon** (socket at `~/.docker/run/docker.sock`):\n`doctor`, `overview`, all three flagship RCAs (`restart_loop_rca` genuinely\ncaught a crash-looping container on the machine; `image_and_volume_bloat`\nmeasured ~2 GiB), and a governed `stop_container` write with its audit row and\nundo token landing in the store. Podman and Portainer paths remain mock-only.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/Container-Host-AIops](https://github.com/AIops-tools/Container-Host-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.11.3:references/capabilities.md\n\n# container-host-aiops capabilities\n\n> **38 MCP tools** (29 read, 9 write) across the Docker\n> Engine API (unix socket or TCP), Portainer (management API + proxied Docker),\n> and Podman (rootful/rootless socket — Docker-compat layer + libpod-native\n> endpoints). Docker/Portainer/Podman API responses are mocked and need live\n> verification.\n\nEvery tool is wrapped with the bundled `@governed_tool` harness (audit, policy,\ntoken/runaway budget, undo, risk-tiers). All host-returned text is sanitized.\n\n## Overview (read)\n\n| Tool | Docker/Portainer path | Returns |\n|------|-----------------------|---------|\n| `overview` | `/info` + `/containers/json` + `/system/df` | host summary: platform, server version, container state rollup, disk headline |\n\n## Containers (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_containers` | `/containers/json?all=` | containers bucketed by state (running/exited/…), compact rows |\n| `inspect_container` | `/containers/{id}/json` | full inspect (config, state, mounts, network) |\n| `container_logs` | `/containers/{id}/logs?tail=N` | last N log lines (demuxed stdout+stderr) |\n| `container_stats` | `/containers/{id}/stats?stream=false` | CPU% + memory% snapshot (Docker's own delta formula) |\n| `container_top` | `/containers/{id}/top` | processes running inside the container |\n| `container_restart_summary` | `/containers/json` + per-container inspect | restart count + exit code + OOM, worst-first |\n\n## Images (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_images` | `/images/json` | images (tags, size, dangling), largest first |\n| `inspect_image` | `/images/{id}/json` + `/images/{id}/history` | inspect + build history (layers, sizes, commands) |\n| `dangling_images` | `/images/json?filters=dangling` | untagged images + reclaimable bytes |\n| `image_disk_usage` | `/system/df` (Images) | total, shared, reclaimable image bytes |\n\n## Volumes (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_volumes` | `/volumes` | named volumes (driver, mountpoint, scope) |\n| `inspect_volume` | `/volumes/{name}` | one volume in detail |\n| `dangling_volumes` | `/system/df` (Volumes, RefCount=0) | unreferenced volumes + reclaimable bytes |\n\n## Networks (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_networks` | `/networks` | networks bucketed by driver |\n| `inspect_network` | `/networks/{id}` | driver, IPAM subnet/gateway, attached containers |\n\n## System (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `system_info` | `/info` | container/image counts, storage driver, kernel, resources |\n| `system_version` | `/version` | version, API version, Go version, components |\n| `system_df` | `/system/df` | disk-usage breakdown: images, containers, volumes, build cache |\n| `system_events` | `/events?since=&until=` | recent daemon events, rolled up by type+action |\n\n## Stacks — Portainer (read; requires a portainer target)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_endpoints` | `/api/endpoints` | Portainer managed hosts (id, name, type, status, url) |\n| `list_stacks` | `/api/stacks` | Portainer stacks (id, name, type, endpoint, status) |\n| `stack_detail` | `/api/stacks/{id}` | one stack in detail (env, entrypoint, resource control) |\n\n## Compose stacks (read; docker or podman)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_compose_stacks` | `/containers/json?all=true` | Compose projects grouped by the `com.docker.compose.project` label, each with its services, per-state counts, and a health verdict (healthy = all running / degraded = some / down = none); ungrouped containers counted separately. Works on **docker and podman** (the label is set by both `docker compose` and `podman compose`). |\n\n## Pods — Podman (read; requires a podman target)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_pods` | `/{libpod}/pods/json` | Podman pods (id, name, status, created, infra id, member-container count + status rollup), bucketed by pod status. Pods are a Podman-only libpod concept — teaching-errors on docker/portainer. |\n\n## Podman platform notes\n\n- **Socket autodetection** (a `podman` target with no explicit `socket_path`): probe\n  `$XDG_RUNTIME_DIR/podman/podman.sock` (rootless) first, then `/run/podman/podman.sock`\n  (rootful); first existing wins, else fall back to the rootful path. An explicit\n  `socket_path` always overrides.\n- **Docker-compat reuse**: Podman serves the Docker-compatible API at the root\n  (unversioned), so every read/write/analysis above is reused wholesale — a `podman`\n  target behaves identically to `docker` for containers/images/volumes/networks/system\n  and all three flagship analyses and lifecycle/prune writes.\n- **libpod-native**: only pod reads use the libpod prefix; everything else stays on the\n  compat layer. A local Podman socket needs no secret.\n\n## Flagship analyses (read; injected or live)\n\n| Tool | Inputs | Returns |\n|------|--------|---------|\n| `restart_loop_rca` | container restart rows (+ optional log tails) or live pull | crash-looping containers ranked by restart count, each with cause+action from exit code (137 OOM/SIGKILL, 143 SIGTERM, 139 segfault, 127 bad entrypoint, …) + a log tail |\n| `resource_pressure_analysis` | CPU%/mem% samples or live pull | containers flagged near (≥80% of a threshold) / over, worst-first, with a recommendation |\n| `image_and_volume_bloat` | dangling images + volumes + system/df, or live pull | prune candidates with reclaimable bytes, largest first |\n\n## Writes (guarded)\n\n| Tool | Risk | Path | Notes |\n|------|:----:|------|-------|\n| `restart_container` | med | `POST /containers/{id}/restart` | captures prior state for audit; no meaningful inverse |\n| `stop_container` | med | `POST /containers/{id}/stop` | undo → `start_container` |\n| `start_container` | med | `POST /containers/{id}/start` | undo → `stop_container` |\n| `update_container` | med | `POST /containers/{id}/update` | captures prior CPU/memory limits; undo restores them |\n| `remove_container` | **high** | `DELETE /containers/{id}` | `dry_run` + double-confirm; captures full inspect BEFORE; no undo |\n| `prune_images` | **high** | `POST /images/prune` | `dry_run` LISTS candidates + reclaimable bytes first; no undo |\n| `prune_volumes` | **high** | `POST /volumes/prune` | anonymous unused volumes only unless `all_unused`; `dry_run` LISTS the candidates for that same scope + reclaimable bytes; no undo |\n| `recreate_stack` | **high** | `PUT /api/stacks/{id}/git/redeploy` | Portainer; captures prior stack; no undo |\n\n## Not in scope\n\n- Cluster orchestrators, hypervisors, storage appliances, backup products (separate AIops-tools)\n- Creating containers/images/networks from scratch, `docker build`, registry push/pull, exec-into-container\n- Swarm service scaling beyond a Portainer stack redeploy\n\nFile v0.11.3:references/cli-reference.md\n\n# container-host-aiops CLI reference\n\n> Covers the Docker Engine API (unix socket or TCP), Portainer (management API), and\n> Podman (rootful/rootless socket — Docker-compat + libpod). The Docker path has been\n> exercised against a live daemon; Portainer and Podman responses are mock-validated\n> only — see `docs/VERIFICATION.md`.\n\n## Setup\n\n```bash\ncontainer-host-aiops init                      # interactive wizard (Docker/Podman socket or Portainer)\ncontainer-host-aiops doctor                     # verify config, secrets, connectivity\n                                                #   Docker/Podman: GET /version · Portainer: GET /api/endpoints\ncontainer-host-aiops doctor --skip-auth         # config/secret checks only (no connectivity)\n```\n\n## Secrets (Portainer only)\n\n```bash\ncontainer-host-aiops secret set <target> [--value <token>]  # store a Portainer token (hidden prompt if no --value)\ncontainer-host-aiops secret list                            # list target names with a stored token\ncontainer-host-aiops secret rm <target>                     # delete a stored token\ncontainer-host-aiops secret migrate                         # import a legacy plaintext .env\ncontainer-host-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Overview\n\n```bash\ncontainer-host-aiops overview [--target <name>]   # one-shot host health\n```\n\n## Containers\n\n```bash\ncontainer-host-aiops container list [--running]            # all states, or only running\ncontainer-host-aiops container inspect <id>\ncontainer-host-aiops container logs <id> [--tail 200]\ncontainer-host-aiops container stats <id>                  # CPU% / memory%\ncontainer-host-aiops container top <id>                    # processes inside\ncontainer-host-aiops container restarts                    # restart-count + exit-code summary\n```\n\n## Images / Volumes / Networks\n\n```bash\ncontainer-host-aiops image list [--all]\ncontainer-host-aiops image inspect <id>                    # + build history\ncontainer-host-aiops image dangling\ncontainer-host-aiops image disk-usage\n\ncontainer-host-aiops volume list\ncontainer-host-aiops volume inspect <name>\ncontainer-host-aiops volume dangling\n\ncontainer-host-aiops network list\ncontainer-host-aiops network inspect <id>\n```\n\n## System\n\n```bash\ncontainer-host-aiops system info\ncontainer-host-aiops system version\ncontainer-host-aiops system df                             # disk-usage breakdown\ncontainer-host-aiops system events [--since 3600] [--type container]\n```\n\n## Stacks\n\n```bash\ncontainer-host-aiops stack endpoints          # Portainer target\ncontainer-host-aiops stack list               # Portainer target\ncontainer-host-aiops stack detail <stack_id>  # Portainer target\ncontainer-host-aiops stack compose            # Compose projects by label (docker OR podman) + health rollup\n```\n\n## Pods (Podman target)\n\n```bash\ncontainer-host-aiops pod list                 # Podman pods (libpod); errors on docker/portainer\n```\n\n## Analyses (flagship)\n\n```bash\ncontainer-host-aiops analyze restart-loop [--threshold 3]\ncontainer-host-aiops analyze resource-pressure [--cpu 80] [--mem 80]\ncontainer-host-aiops analyze bloat\n```\n\n## Manage (guarded writes — `--dry-run` + double confirmation)\n\n```bash\ncontainer-host-aiops manage restart <id> [--dry-run]\ncontainer-host-aiops manage stop <id> [--dry-run]          # undo: start\ncontainer-host-aiops manage start <id> [--dry-run]         # undo: stop\ncontainer-host-aiops manage update <id> '{\"Memory\":1073741824}' [--dry-run]   # undo restores prior limits\ncontainer-host-aiops manage remove <id> [--force] [--volumes] [--dry-run]     # high; captures full inspect first\ncontainer-host-aiops manage prune-images [--all] [--dry-run]                  # high; dry-run lists candidates\ncontainer-host-aiops manage prune-volumes [--all] [--dry-run]                 # high; anonymous only unless --all\ncontainer-host-aiops manage recreate-stack <stack_id> [--endpoint-id N] [--dry-run]   # high; Portainer\n```\n\n## MCP server\n\n```bash\ncontainer-host-aiops mcp          # stdio transport (or: container-host-aiops-mcp)\n```\n\n## Notes\n\n- Every command accepts `--target <name>` (`-t`) to pick a configured host; omit for the default (first) target.\n- The full 36-tool surface (all reads + writes) is exposed through the MCP server; the CLI is a convenient subset.\n- `stack endpoints`/`list`/`detail` and `recreate-stack` require a `portainer` target; `stack compose` works on docker or podman; `pod list` requires a `podman` target.\n\nFile v0.11.3:references/setup-guide.md\n\n# container-host-aiops setup & security guide\n\n> The Docker path has been exercised against a live daemon; the Portainer and Podman\n> paths are mock-validated only (see `docs/VERIFICATION.md`).\n> `container-host-aiops doctor` is the fastest live check on any platform.\n\n## 1. Install\n\n```bash\nuv tool install container-host-aiops     # or: pipx install container-host-aiops\n```\n\n## 2. What you need\n\n- **Docker (unix socket)** — read/write access to the Docker socket (default\n  `/var/run/docker.sock`). No secret is stored; the socket's file permissions are\n  the trust boundary. Treat socket access as **root-equivalent** on the host.\n- **Docker (TCP)** — a host + port (2375 plain, 2376 TLS). Enable TLS in\n  production; a plain TCP daemon is unauthenticated.\n- **Portainer** — the Portainer host + HTTPS port (default 9443), an **API token**\n  (Portainer → My account → Access tokens), and the **endpoint id** of the managed\n  Docker environment you want to read/manage (list them with `stack endpoints`).\n- **Podman (unix socket)** — a running Podman **service** socket (rootful\n  `/run/podman/podman.sock`, or rootless `$XDG_RUNTIME_DIR/podman/podman.sock` after\n  `systemctl --user enable --now podman.socket`). No secret; the socket's file\n  permissions are the trust boundary. Autodetection prefers the rootless socket,\n  then the rootful one.\n\n## 3. Onboard (interactive)\n\n```bash\ncontainer-host-aiops init\n```\n\nThe wizard asks, per target, for the **platform** (`docker` / `portainer` / `podman`):\n\n- **docker** — connect over a **unix socket** (path, default `/var/run/docker.sock`)\n  or a **TCP host** (host + optional TLS). No secret.\n- **portainer** — host, HTTPS port, managed **endpoint id**, TLS verification, and\n  the **API token** (stored encrypted). A master password (used to encrypt\n  `secrets.enc`) is prompted the first time a Portainer token is stored.\n- **podman** — connect over a **unix socket** (path defaults to the autodetected\n  rootless/rootful Podman socket) or a **TCP host**. No secret. Podman speaks the\n  Docker-compatible API (so all Docker reads/writes/analyses work) plus libpod-native\n  pod reads (`pod list`).\n\nNon-secret connection details go to `~/.container-host-aiops/config.yaml`; a\nPortainer token goes to `~/.container-host-aiops/secrets.enc` (encrypted).\n\n### Manual config (`~/.container-host-aiops/config.yaml`)\n\n```yaml\ntargets:\n  - name: local\n    platform: docker\n    socket_path: /var/run/docker.sock\n\n  - name: remote-tcp\n    platform: docker\n    host: 10.0.0.5\n    port: 2376\n    verify_ssl: true\n\n  - name: portainer1\n    platform: portainer\n    host: portainer.lan\n    port: 9443\n    endpoint_id: \"1\"\n    verify_ssl: false        # true in production\n\n  - name: podman-local\n    platform: podman\n    # socket_path omitted → autodetect rootless ($XDG_RUNTIME_DIR/podman/podman.sock)\n    # then rootful (/run/podman/podman.sock); set socket_path to pin one explicitly.\n```\n\nThen store the Portainer token (encrypted):\n\n```bash\ncontainer-host-aiops secret set portainer1\ncontainer-host-aiops doctor\n```\n\n## 4. Credentials & security\n\n- Only **Portainer** needs a secret; **Docker and Podman** sockets need none (file\n  permissions are the boundary). The Portainer API token is **never** written to disk\n  in plaintext — it lives encrypted in `~/.container-host-aiops/secrets.enc` (Fernet /\n  AES-128 + a scrypt-derived key; chmod 600). The master password is never stored.\n- The master password is resolved from `CONTAINER_HOST_AIOPS_MASTER_PASSWORD`\n  (non-interactive / MCP / CI) or an interactive prompt (CLI on a TTY).\n- A legacy plaintext env var `CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN` is honoured\n  as a fallback with a deprecation warning (migrate with `secret migrate`).\n- The token is sent in the `X-API-Key` header at request time and held only in\n  memory; secrets are never logged or echoed.\n- `verify_ssl` defaults to true; disable only for a self-signed Portainer / TLS\n  Docker daemon in a lab. A unix-socket Docker/Podman target does not use TLS.\n\n## 5. Governance\n\nEvery MCP tool runs through the bundled `@governed_tool` harness:\n\n- **Audit** — all calls logged to `~/.container-host-aiops/audit.db` (relocatable via\n  `CONTAINER_HOST_AIOPS_HOME`), agent-attributed, secret-redacted.\n- **Runaway guard** — a safety backstop (not authorization): a tight-loop breaker\n  plus optional call/time ceilings. Disable with `CONTAINER_HOST_RUNAWAY_MAX=0`.\n- **Risk tier** — a descriptive label on each audit row derived from `risk_level`;\n  it gates nothing. `CONTAINER_HOST_AUDIT_APPROVED_BY` / `CONTAINER_HOST_AUDIT_RATIONALE`\n  are optional annotations recorded on the row, never required.\n- **Undo recording** — reversible writes capture the before-state and record an\n  inverse (`stop`→`start`, `update_container`→restore prior limits).\n\n## 6. Verify\n\n```bash\ncontainer-host-aiops doctor            # Docker/Podman: GET /version · Portainer: GET /api/endpoints\ncontainer-host-aiops overview          # one-shot host health\n```\n\n## Missing a capability?\n\nCoverage is a curated subset of the Docker Engine + Portainer + Podman (libpod)\nAPIs. Missing a call or want another container host family? **Open an issue or PR**\n— contributions welcome.\n\nFile v0.11.3:skill-card.md\n\n## Description:\n\nOperates and analyzes single Docker, Portainer, or Podman container hosts with governed reads, restart-loop and resource-pressure analysis, storage-bloat analysis, and guarded lifecycle or cleanup writes.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and operations engineers use this skill to triage single container hosts, inspect containers, images, volumes, networks, stacks, and pods, and run focused analyses for restart loops, resource pressure, and reclaimable storage. It also supports audited, guarded writes such as restart, stop, start, remove, prune, resource-limit update, and Portainer stack recreation.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Container-host access can be root-equivalent, and write-enabled MCP use can stop services or delete data.\n\nMitigation: Install only in a controlled environment, start with read-only or narrowly scoped accounts, and prefer external authorization or separate read-only and write-capable deployments.\n\nRisk: Plain Docker TCP or disabled TLS verification can expose host-control traffic.\n\nMitigation: Avoid plaintext Docker TCP and avoid disabling TLS verification for Portainer or TLS Docker endpoints outside a lab.\n\nRisk: High-risk cleanup and lifecycle operations such as container removal, image or volume pruning, and stack recreation may be destructive or irreversible.\n\nMitigation: Use dry-run previews, review candidates before execution, keep backups for data-bearing volumes, and rely on narrowly scoped host or Portainer permissions for enforcement.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/zw008/skills/container-host-aiops)\n- [Project homepage](https://github.com/AIops-tools/Container-Host-AIops)\n- [Capabilities reference](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup and security guide](references/setup-guide.md)\n- [Agent guardrails](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown with inline shell commands and configuration snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include live host observations, ranked analyses, dry-run previews, and audit or undo guidance.]\n\n## Skill Version(s):\n\n0.11.3 (source: server release metadata and release changelog)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.11.2: 7 files, 19723 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6870b), references/cli-reference.md (4534b), references/setup-guide.md (5258b), skill-card.md (2792b), SKILL.md (18017b), _meta.json (140b)\n\nFile v0.11.2:SKILL.md\n\n---\nname: container-host-aiops\nslug: container-host-aiops\ndisplayName: \"Container Host AIops\"\nsummary: \"Governed Docker + Portainer container-host ops: reads, RCA analyses, guarded writes. 38 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/Container-Host-AIops\ntags: [aiops, mcp, governance, container-host]\ndescription: >\n  Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list, inspect); system reads (info, version, df disk-usage, recent events); Portainer stacks + endpoints; Compose-project rollups (list_compose_stacks, docker+podman); Podman pods (list_pods, podman-only); three flagship analyses — restart-loop RCA (crash-looping containers + cause/action), resource-pressure analysis (CPU/memory vs limits), and image & volume bloat (prune candidates + reclaimable bytes); and eight guarded writes (restart/stop/start/remove a container, prune images/volumes, update resource limits, recreate a Portainer stack).\n  Always use this skill for \"Docker host overview\", \"which containers are crash-looping\", \"restart loop\", \"why does this container keep restarting\", \"container CPU/memory usage\", \"docker logs\", \"which containers are near their limits\", \"resource pressure\", \"dangling images/volumes\", \"reclaim disk\", \"prune images\", \"stop/start/restart a container\", \"update a container's memory limit\", \"Portainer stacks\", \"compose stacks\", \"Podman pods\" when the context is a Docker, Portainer, or Podman container host.\n  Do NOT use when the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment — route those to the appropriate other AIops-tools skill. This is for NON-orchestrator container hosts.\n  Governed Docker/Portainer/Podman container-host operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See docs/VERIFICATION.md.\ninstaller:\n  kind: uv\n  package: container-host-aiops\nargument-hint: \"[container/image/volume id or describe your container-host task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"container-host-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CONTAINER_HOST_AIOPS_CONFIG\",\"CONTAINER_HOST_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/Container-Host-AIops\",\"emoji\":\"🐳\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed Docker + Portainer + Podman container-host operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Multi-platform by construction (a platform registry); a per-target 'platform' field (docker / portainer / podman) selects the API shape.\n  All write operations are audited to a local SQLite DB under ~/.container-host-aiops/ (relocatable via CONTAINER_HOST_AIOPS_HOME).\n  Connection: a Docker target speaks the Docker Engine API over a local unix socket (httpx uds transport, default /var/run/docker.sock — treat socket access as root-equivalent) or a TCP host; a Portainer target speaks the Portainer management API over HTTPS with an X-API-Key token, and also proxies the Docker API of a managed endpoint at /api/endpoints/{id}/docker/...; a Podman target speaks over the rootful/rootless service socket (autodetected: $XDG_RUNTIME_DIR/podman/podman.sock, then /run/podman/podman.sock), reusing the Docker-compat paths at the root plus libpod-native endpoints (pods) under the libpod prefix.\n  Credentials: only Portainer needs a secret — its API token is stored ENCRYPTED in ~/.container-host-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. A local Docker or Podman socket needs no secret. Run 'container-host-aiops init' to onboard, or 'container-host-aiops secret set <target>' to add a Portainer token. The store is unlocked by a master password from CONTAINER_HOST_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN is still honoured as a fallback with a deprecation warning (migrate with 'container-host-aiops secret migrate'). The token is sent in the X-API-Key header at request time and held only in memory; secrets are never logged or echoed.\n  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget/runaway guard + audit + risk-tier label — it records, it does not authorize) and take a dry_run preview. Prune previews list what would be removed + reclaimable bytes before doing it. Mutating/reversible writes fetch the real before-state first and record a faithful inverse undo descriptor (stop→start, update_container→restore prior limits); irreversible ops (remove, prune, recreate) record only the before-state.\n  Webhooks: none — no outbound network calls beyond the configured Docker socket / TCP host or the Portainer API base URL.\n  SSL: verify_ssl defaults to true; disable only for a self-signed Portainer / TLS Docker daemon. A unix-socket Docker target does not use TLS.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  VERIFICATION: Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. Community-maintained; not affiliated with or endorsed by Docker/Portainer/Podman — trademarks belong to their owners.\n---\n\n# Container Host AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by Docker, Inc., Portainer.io, or any container-platform vendor.** Product and trademark names belong to their owners. Source at [github.com/AIops-tools/Container-Host-AIops](https://github.com/AIops-tools/Container-Host-AIops) under the MIT license.\n\nGoverned Docker + Portainer + Podman container-host operations — **38 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.container-host-aiops/` (MCP + CLI alike), a runaway/budget safety guard, and undo-token recording. It records every operation; whether a write is permitted is the agent's or the account's call, not the skill's. A Docker target speaks the Docker Engine API over a unix socket or TCP; a Portainer target speaks the Portainer API (and proxies Docker); a Podman target speaks over its rootful/rootless socket (Docker-compat + libpod). The Portainer API token is stored **encrypted** (`~/.container-host-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk; a local Docker/Podman socket needs no secret.\n\n> **Standalone**: the governance harness is bundled in the package (`container_host_aiops.governance`) — container-host-aiops has no external skill-family dependency. **Verification**: Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See `docs/VERIFICATION.md`.\n\n## What This Skill Does\n\n| Domain | Tools | Count | Read or Write |\n|--------|-------|:-----:|:-------------:|\n| **Overview** | one-shot host health | 1 | 1 read |\n| **Containers** | list/inspect, logs, stats, top, restart summary | 6 | 6 read |\n| **Images** | list, inspect (+history), dangling, disk usage | 4 | 4 read |\n| **Volumes** | list, inspect, dangling | 3 | 3 read |\n| **Networks** | list, inspect | 2 | 2 read |\n| **System** | info, version, df, events | 4 | 4 read |\n| **Stacks** | endpoints, stacks, stack detail (Portainer), compose-stack rollup (docker+podman) | 4 | 4 read |\n| **Pods (Podman)** | list pods (libpod) | 1 | 1 read |\n| **Analyses (flagship)** | restart-loop RCA, resource pressure, image/volume bloat | 3 | 3 read |\n| **Writes** | remove container, prune images, prune volumes, recreate stack | 4 | 4 write (high) |\n| | restart, stop, start, update container | 4 | 4 write (medium) |\n\nThe three analyses accept injected data for offline analysis, or pull live from a configured target. Portainer endpoints/stacks require a `portainer` target; `list_compose_stacks` works on docker or podman; `list_pods` requires a `podman` target.\n\n## Quick Install\n\n```bash\nuv tool install container-host-aiops\ncontainer-host-aiops init       # interactive wizard: Docker/Podman socket or Portainer target\ncontainer-host-aiops doctor\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/container-host-aiops\nopenclaw skills info container-host-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a host (`overview`): version + container state rollup + disk headline\n- Find crash-looping containers (`analyze restart-loop` / `restart_loop_rca`): ranked by restart count with a likely cause and action from the exit code, plus a log tail\n- Spot resource pressure (`analyze resource-pressure` / `resource_pressure_analysis`): CPU%/mem% vs each container's limits, worst first, with a recommendation\n- Reclaim disk (`analyze bloat` / `image_and_volume_bloat`): dangling images + volumes + build cache as prune candidates with reclaimable bytes\n- List/inspect containers, images, volumes, networks; tail logs; read stats/top\n- Restart/stop/start a container, update its resource limits (reversible), remove a container, prune images/volumes, or recreate a Portainer stack — all with dry-run + double-confirm\n\n**Do NOT use when** the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| Docker / Portainer single-host container ops | **container-host-aiops** (this skill) |\n| A cluster orchestrator's workloads/rollouts | a cluster ops skill |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| OT / industrial edge (Modbus, OPC-UA, PLC) | the industrial-aiops line |\n\n## Common Workflows\n\n### 1. A container is crash-looping\n\n1. `container-host-aiops doctor` → confirm the socket/endpoint is reachable before you\n   trust any read.\n2. `container-host-aiops analyze restart-loop` → containers ranked by restart count,\n   each with a likely cause read off the real exit code (137 OOM/SIGKILL, 143 SIGTERM,\n   139 segfault, 127 bad entrypoint, …), a recommended action, and a log tail.\n3. `container-host-aiops container logs <id> --tail 200` → read the actual crash output;\n   `container-host-aiops container inspect <id>` → confirm the exit code, restart policy,\n   and configured limits the RCA cited.\n4. If the cause is memory: `container-host-aiops analyze resource-pressure --mem 75` →\n   see how close the container runs to its ceiling, then\n   `container-host-aiops manage update <id> '{\"Memory\": 1073741824}' --dry-run` and\n   re-run without `--dry-run` (double-confirm; the write captures the prior limits as its\n   undo descriptor).\n5. `container-host-aiops manage restart <id>` → bring it up on the new limit, then\n   re-run `analyze restart-loop` to confirm the loop stopped.\n6. **Failure branch**: if it still loops, the limit was not the cause — reverse the\n   change with `container-host-aiops undo list` → `undo apply <id>` (restores the *prior*\n   limits, not a guess) and go back to step 3 with the fresh log tail. If the container\n   will not stop at all, `manage remove <id> --force --dry-run` first: force-remove is\n   high-risk and irreversible, so read the dry-run before committing.\n\n### 2. The host is out of disk\n\n1. `container-host-aiops system df` → where the space actually went (images vs\n   containers vs volumes vs build cache).\n2. `container-host-aiops analyze bloat` → dangling images, dangling volumes, and build\n   cache as ranked prune candidates with reclaimable bytes per item.\n3. `container-host-aiops image dangling` and `container-host-aiops volume dangling` →\n   eyeball the concrete list before deleting anything. A \"dangling\" volume holding data\n   you still want is the classic way this goes wrong.\n4. `container-host-aiops manage prune-images --dry-run` → exactly what would be removed;\n   re-run without `--dry-run` (double-confirm, high risk).\n5. `container-host-aiops manage prune-volumes --dry-run` → **read this one carefully**;\n   volume pruning destroys data and records no undo. Note that Docker's default\n   prune removes only ANONYMOUS unused volumes — the preview reports the named\n   unused ones it will not touch as `alsoUnusedNamed*`; add `--all` to include\n   them. Only then re-run for real.\n6. `container-host-aiops system df` again → confirm the space came back.\n7. **Failure branch**: pruning is not reversible. If you removed a volume you needed,\n   the undo store cannot help — restore from your backup. The dry-run in steps 4–5 is\n   the only safety net, which is why both are separate confirm-gated steps.\n\n### 3. \"Everything on this box is slow\"\n\n1. `container-host-aiops overview` → one-shot: platform/version, container counts by\n   state, and the headline resource picture.\n2. `container-host-aiops analyze resource-pressure --cpu 80 --mem 80` → running\n   containers ranked against **their own limits**, each row citing the measured\n   percentage rather than a verdict.\n3. `container-host-aiops container stats <id>` and `container-host-aiops container top <id>`\n   → confirm the top offender at the process level before you act on it.\n4. `container-host-aiops system events` → correlate the pressure with what changed\n   (a recent deploy, restart storm, or image pull).\n5. Act on the worst offender: `manage update <id> '{\"NanoCpus\": 2000000000}'` to cap it\n   (dry-run first, undo-recorded), or `manage stop <id>` to shed it entirely.\n6. **Failure branch**: if capping the top container just moves the pressure elsewhere,\n   the host is genuinely undersized rather than misconfigured — reverse your change with\n   `undo apply <id>` so you are not left with a half-applied limit, and take the sizing\n   result to whoever owns capacity.\n\n### 4. Stack drift after a bad deploy (Portainer)\n\n1. `container-host-aiops stack endpoints` → the endpoints this Portainer manages;\n   `container-host-aiops stack list` → the stacks on the one you care about.\n2. `container-host-aiops stack detail <stack-id>` → the stack's current definition;\n   `container-host-aiops stack compose <stack-id>` → the compose file it is running from.\n3. `container-host-aiops container list --running` and\n   `container-host-aiops container restarts` → which of the stack's containers are\n   actually unhealthy versus merely restarted.\n4. `container-host-aiops manage recreate-stack <stack-id> --dry-run` → preview the\n   redeploy; re-run without `--dry-run` (double-confirm, high risk).\n5. Validate with `container-host-aiops overview` and `analyze restart-loop`.\n6. **Failure branch**: `recreate-stack` redeploys from the stack's stored definition — if\n   that definition is itself the broken thing, recreating will faithfully reproduce the\n   breakage. Fix the compose source in Portainer first, and use\n   `container-host-aiops undo list` to check what the session already changed before\n   layering another write on top.\n\n### Offline analysis (no live host)\n\nPass data straight to the analysis tools — `restart_loop_rca(containers=[...])`, `resource_pressure_analysis(samples=[...])`, or `image_and_volume_bloat(dangling_images=..., dangling_volumes=..., df=...)` — to analyse an exported dataset without connecting to a host.\n\n## Governance & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide\nwhether a write is permitted. That is your agent's judgement, or the permission\nof the account you connect it with (a read-only Docker socket, a Portainer\naccount without write scope — writes then fail at the server). There is no\nread-only switch, policy file, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.container-host-aiops/audit.db` (relocatable via `CONTAINER_HOST_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `CONTAINER_HOST_AUDIT_APPROVED_BY` / `CONTAINER_HOST_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: the same call looped in a tight window trips a circuit breaker. Disable with `CONTAINER_HOST_RUNAWAY_MAX=0`.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI; prune previews list what would be removed + reclaimable bytes.\n- Mutating/reversible writes fetch the real before-state and record an inverse descriptor (stop→start, update_container→restore prior limits); irreversible ops record only the before-state.\n\n## References\n\n- `references/capabilities.md` — full tool + field reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n\nFile v0.11.2:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"container-host-aiops\",\n  \"version\": \"0.11.2\",\n  \"publishedAt\": 1789222089449\n}\n\nFile v0.11.2:references/agent-guardrails.md\n\n# Agent guardrails — running container-host-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Give it a Docker socket mounted read-only,\n  or a Portainer account without write scope. A write then fails at the server,\n  which is the only place the permission actually lives — no skill-side flag can\n  be argued around by a model, but a revoked permission cannot be.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Log everything you do, over both MCP and the CLI\" | Every operation is audited to `~/.container-host-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. Reversible writes also record an undo token capturing the *prior* state. |\n| \"Don't invent a value when a field is missing\" | The Docker Engine omits keys it has nothing to say about — a created-but-never-started container has no `Status`, a dangling image has no `RepoTags`. Those come back as `null`, never as `\"\"`. An id in particular is `null` when unknown, so a blank string is never mistaken for a real identifier. |\n| \"Tell me if the log was cut off\" | `container_logs` returns `{\"lines\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`, and `system_events` the same shape. Truncation is measured — one extra line is requested from Docker — not guessed from a length coincidence. |\n| \"Preserve the ordering / tell me what's most urgent\" | `restart_loop_rca` and `resource_pressure_analysis` rank worst-first and carry the measured number (restart count, exit code, CPU%, memory%) in each entry. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `remove_container`, `prune_images` and `prune_volumes` require a `--dry-run`-able preview plus double confirmation at the CLI. |\n| \"Don't get stuck retrying\" | The runaway guard trips a circuit breaker if the same call is hammered in a tight loop — a stuck agent is stopped rather than left to burn calls and time. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a Docker or Podman container host (optionally via Portainer)\nthrough the container-host-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current host, you MUST call a tool.\n  Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher tail instead of treating\n  the partial result as the container's complete log. A container that has been\n  restarting for hours has far more log history than the default tail shows.\n- A null field means Docker did not report that value. Report it as \"not\n  available\" — never infer it. A null id is not a container named \"None\".\n- Report values exactly as returned. Do not normalise, translate, or prettify\n  container states, exit codes, or image tags.\n- Exit code 0 with a high restart count is a container completing and being\n  restarted by policy, not a crash. Do not call it a failure.\n- \"oomKilled\": true is the memory limit being hit — cite it rather than\n  guessing at a memory problem from CPU numbers.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert that a container is failing for a particular reason unless the\n  log tail or exit-code classification in the result supports it.\n- Do not add generic Docker advice that does not follow from the tool output.\n- Do not confuse a container id with an image id, a short id with a full one, a\n  container name with its image name, or a compose stack with a container.\n- Volumes and images are not deleted with the container. Pruning is a separate,\n  destructive, and irreversible operation — never fold it into a cleanup\n  suggestion casually.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the account's\npermission only when you trust the setup — the destructive operations on a\ncontainer host are unusually cheap to invoke and unusually expensive to undo\n(`prune_volumes` deletes data no undo token can bring back):\n\n```bash\n# e.g. mount the Docker socket read-only for the container running this tool,\n# or use a Portainer account without write scope. Then:\ncontainer-host-aiops doctor\n```\n\nOptionally annotate the audit trail with who is operating and why — recorded on\nevery row, never required:\n\n```bash\nexport CONTAINER_HOST_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport CONTAINER_HOST_AUDIT_RATIONALE=\"clearing disk on the build host\"\n```\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer the analysis tools —\n  `restart_loop_rca` correlates restart counts, exit codes, OOM flags and log\n  tails inside one call, so the model does not have to chain a list, an inspect\n  and a logs call per container while keeping ids straight.\n- **The model ignores later tool results in a long context.** Container logs are\n  the big payload here. Ask narrower questions and use `tail` deliberately\n  rather than pulling 2000 lines from every container.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\n## Verification status\n\nUnlike most of this tool line, container-host-aiops has been **live-verified\nagainst a real Docker 27.5.1 daemon** (socket at `~/.docker/run/docker.sock`):\n`doctor`, `overview`, all three flagship RCAs (`restart_loop_rca` genuinely\ncaught a crash-looping container on the machine; `image_and_volume_bloat`\nmeasured ~2 GiB), and a governed `stop_container` write with its audit row and\nundo token landing in the store. Podman and Portainer paths remain mock-only.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/Container-Host-AIops](https://github.com/AIops-tools/Container-Host-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.11.2:references/capabilities.md\n\n# container-host-aiops capabilities\n\n> **38 MCP tools** (29 read, 9 write) across the Docker\n> Engine API (unix socket or TCP), Portainer (management API + proxied Docker),\n> and Podman (rootful/rootless socket — Docker-compat layer + libpod-native\n> endpoints). Docker/Portainer/Podman API responses are mocked and need live\n> verification.\n\nEvery tool is wrapped with the bundled `@governed_tool` harness (audit, policy,\ntoken/runaway budget, undo, risk-tiers). All host-returned text is sanitized.\n\n## Overview (read)\n\n| Tool | Docker/Portainer path | Returns |\n|------|-----------------------|---------|\n| `overview` | `/info` + `/containers/json` + `/system/df` | host summary: platform, server version, container state rollup, disk headline |\n\n## Containers (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_containers` | `/containers/json?all=` | containers bucketed by state (running/exited/…), compact rows |\n| `inspect_container` | `/containers/{id}/json` | full inspect (config, state, mounts, network) |\n| `container_logs` | `/containers/{id}/logs?tail=N` | last N log lines (demuxed stdout+stderr) |\n| `container_stats` | `/containers/{id}/stats?stream=false` | CPU% + memory% snapshot (Docker's own delta formula) |\n| `container_top` | `/containers/{id}/top` | processes running inside the container |\n| `container_restart_summary` | `/containers/json` + per-container inspect | restart count + exit code + OOM, worst-first |\n\n## Images (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_images` | `/images/json` | images (tags, size, dangling), largest first |\n| `inspect_image` | `/images/{id}/json` + `/images/{id}/history` | inspect + build history (layers, sizes, commands) |\n| `dangling_images` | `/images/json?filters=dangling` | untagged images + reclaimable bytes |\n| `image_disk_usage` | `/system/df` (Images) | total, shared, reclaimable image bytes |\n\n## Volumes (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_volumes` | `/volumes` | named volumes (driver, mountpoint, scope) |\n| `inspect_volume` | `/volumes/{name}` | one volume in detail |\n| `dangling_volumes` | `/system/df` (Volumes, RefCount=0) | unreferenced volumes + reclaimable bytes |\n\n## Networks (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_networks` | `/networks` | networks bucketed by driver |\n| `inspect_network` | `/networks/{id}` | driver, IPAM subnet/gateway, attached containers |\n\n## System (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `system_info` | `/info` | container/image counts, storage driver, kernel, resources |\n| `system_version` | `/version` | version, API version, Go version, components |\n| `system_df` | `/system/df` | disk-usage breakdown: images, containers, volumes, build cache |\n| `system_events` | `/events?since=&until=` | recent daemon events, rolled up by type+action |\n\n## Stacks — Portainer (read; requires a portainer target)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_endpoints` | `/api/endpoints` | Portainer managed hosts (id, name, type, status, url) |\n| `list_stacks` | `/api/stacks` | Portainer stacks (id, name, type, endpoint, status) |\n| `stack_detail` | `/api/stacks/{id}` | one stack in detail (env, entrypoint, resource control) |\n\n## Compose stacks (read; docker or podman)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_compose_stacks` | `/containers/json?all=true` | Compose projects grouped by the `com.docker.compose.project` label, each with its services, per-state counts, and a health verdict (healthy = all running / degraded = some / down = none); ungrouped containers counted separately. Works on **docker and podman** (the label is set by both `docker compose` and `podman compose`). |\n\n## Pods — Podman (read; requires a podman target)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_pods` | `/{libpod}/pods/json` | Podman pods (id, name, status, created, infra id, member-container count + status rollup), bucketed by pod status. Pods are a Podman-only libpod concept — teaching-errors on docker/portainer. |\n\n## Podman platform notes\n\n- **Socket autodetection** (a `podman` target with no explicit `socket_path`): probe\n  `$XDG_RUNTIME_DIR/podman/podman.sock` (rootless) first, then `/run/podman/podman.sock`\n  (rootful); first existing wins, else fall back to the rootful path. An explicit\n  `socket_path` always overrides.\n- **Docker-compat reuse**: Podman serves the Docker-compatible API at the root\n  (unversioned), so every read/write/analysis above is reused wholesale — a `podman`\n  target behaves identically to `docker` for containers/images/volumes/networks/system\n  and all three flagship analyses and lifecycle/prune writes.\n- **libpod-native**: only pod reads use the libpod prefix; everything else stays on the\n  compat layer. A local Podman socket needs no secret.\n\n## Flagship analyses (read; injected or live)\n\n| Tool | Inputs | Returns |\n|------|--------|---------|\n| `restart_loop_rca` | container restart rows (+ optional log tails) or live pull | crash-looping containers ranked by restart count, each with cause+action from exit code (137 OOM/SIGKILL, 143 SIGTERM, 139 segfault, 127 bad entrypoint, …) + a log tail |\n| `resource_pressure_analysis` | CPU%/mem% samples or live pull | containers flagged near (≥80% of a threshold) / over, worst-first, with a recommendation |\n| `image_and_volume_bloat` | dangling images + volumes + system/df, or live pull | prune candidates with reclaimable bytes, largest first |\n\n## Writes (guarded)\n\n| Tool | Risk | Path | Notes |\n|------|:----:|------|-------|\n| `restart_container` | med | `POST /containers/{id}/restart` | captures prior state for audit; no meaningful inverse |\n| `stop_container` | med | `POST /containers/{id}/stop` | undo → `start_container` |\n| `start_container` | med | `POST /containers/{id}/start` | undo → `stop_container` |\n| `update_container` | med | `POST /containers/{id}/update` | captures prior CPU/memory limits; undo restores them |\n| `remove_container` | **high** | `DELETE /containers/{id}` | `dry_run` + double-confirm; captures full inspect BEFORE; no undo |\n| `prune_images` | **high** | `POST /images/prune` | `dry_run` LISTS candidates + reclaimable bytes first; no undo |\n| `prune_volumes` | **high** | `POST /volumes/prune` | anonymous unused volumes only unless `all_unused`; `dry_run` LISTS the candidates for that same scope + reclaimable bytes; no undo |\n| `recreate_stack` | **high** | `PUT /api/stacks/{id}/git/redeploy` | Portainer; captures prior stack; no undo |\n\n## Not in scope\n\n- Cluster orchestrators, hypervisors, storage appliances, backup products (separate AIops-tools)\n- Creating containers/images/networks from scratch, `docker build`, registry push/pull, exec-into-container\n- Swarm service scaling beyond a Portainer stack redeploy\n\nFile v0.11.2:references/cli-reference.md\n\n# container-host-aiops CLI reference\n\n> Covers the Docker Engine API (unix socket or TCP), Portainer (management API), and\n> Podman (rootful/rootless socket — Docker-compat + libpod). The Docker path has been\n> exercised against a live daemon; Portainer and Podman responses are mock-validated\n> only — see `docs/VERIFICATION.md`.\n\n## Setup\n\n```bash\ncontainer-host-aiops init                      # interactive wizard (Docker/Podman socket or Portainer)\ncontainer-host-aiops doctor                     # verify config, secrets, connectivity\n                                                #   Docker/Podman: GET /version · Portainer: GET /api/endpoints\ncontainer-host-aiops doctor --skip-auth         # config/secret checks only (no connectivity)\n```\n\n## Secrets (Portainer only)\n\n```bash\ncontainer-host-aiops secret set <target> [--value <token>]  # store a Portainer token (hidden prompt if no --value)\ncontainer-host-aiops secret list                            # list target names with a stored token\ncontainer-host-aiops secret rm <target>                     # delete a stored token\ncontainer-host-aiops secret migrate                         # import a legacy plaintext .env\ncontainer-host-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Overview\n\n```bash\ncontainer-host-aiops overview [--target <name>]   # one-shot host health\n```\n\n## Containers\n\n```bash\ncontainer-host-aiops container list [--running]            # all states, or only running\ncontainer-host-aiops container inspect <id>\ncontainer-host-aiops container logs <id> [--tail 200]\ncontainer-host-aiops container stats <id>                  # CPU% / memory%\ncontainer-host-aiops container top <id>                    # processes inside\ncontainer-host-aiops container restarts                    # restart-count + exit-code summary\n```\n\n## Images / Volumes / Networks\n\n```bash\ncontainer-host-aiops image list [--all]\ncontainer-host-aiops image inspect <id>                    # + build history\ncontainer-host-aiops image dangling\ncontainer-host-aiops image disk-usage\n\ncontainer-host-aiops volume list\ncontainer-host-aiops volume inspect <name>\ncontainer-host-aiops volume dangling\n\ncontainer-host-aiops network list\ncontainer-host-aiops network inspect <id>\n```\n\n## System\n\n```bash\ncontainer-host-aiops system info\ncontainer-host-aiops system version\ncontainer-host-aiops system df                             # disk-usage breakdown\ncontainer-host-aiops system events [--since 3600] [--type container]\n```\n\n## Stacks\n\n```bash\ncontainer-host-aiops stack endpoints          # Portainer target\ncontainer-host-aiops stack list               # Portainer target\ncontainer-host-aiops stack detail <stack_id>  # Portainer target\ncontainer-host-aiops stack compose            # Compose projects by label (docker OR podman) + health rollup\n```\n\n## Pods (Podman target)\n\n```bash\ncontainer-host-aiops pod list                 # Podman pods (libpod); errors on docker/portainer\n```\n\n## Analyses (flagship)\n\n```bash\ncontainer-host-aiops analyze restart-loop [--threshold 3]\ncontainer-host-aiops analyze resource-pressure [--cpu 80] [--mem 80]\ncontainer-host-aiops analyze bloat\n```\n\n## Manage (guarded writes — `--dry-run` + double confirmation)\n\n```bash\ncontainer-host-aiops manage restart <id> [--dry-run]\ncontainer-host-aiops manage stop <id> [--dry-run]          # undo: start\ncontainer-host-aiops manage start <id> [--dry-run]         # undo: stop\ncontainer-host-aiops manage update <id> '{\"Memory\":1073741824}' [--dry-run]   # undo restores prior limits\ncontainer-host-aiops manage remove <id> [--force] [--volumes] [--dry-run]     # high; captures full inspect first\ncontainer-host-aiops manage prune-images [--all] [--dry-run]                  # high; dry-run lists candidates\ncontainer-host-aiops manage prune-volumes [--all] [--dry-run]                 # high; anonymous only unless --all\ncontainer-host-aiops manage recreate-stack <stack_id> [--endpoint-id N] [--dry-run]   # high; Portainer\n```\n\n## MCP server\n\n```bash\ncontainer-host-aiops mcp          # stdio transport (or: container-host-aiops-mcp)\n```\n\n## Notes\n\n- Every command accepts `--target <name>` (`-t`) to pick a configured host; omit for the default (first) target.\n- The full 36-tool surface (all reads + writes) is exposed through the MCP server; the CLI is a convenient subset.\n- `stack endpoints`/`list`/`detail` and `recreate-stack` require a `portainer` target; `stack compose` works on docker or podman; `pod list` requires a `podman` target.\n\nFile v0.11.2:references/setup-guide.md\n\n# container-host-aiops setup & security guide\n\n> The Docker path has been exercised against a live daemon; the Portainer and Podman\n> paths are mock-validated only (see `docs/VERIFICATION.md`).\n> `container-host-aiops doctor` is the fastest live check on any platform.\n\n## 1. Install\n\n```bash\nuv tool install container-host-aiops     # or: pipx install container-host-aiops\n```\n\n## 2. What you need\n\n- **Docker (unix socket)** — read/write access to the Docker socket (default\n  `/var/run/docker.sock`). No secret is stored; the socket's file permissions are\n  the trust boundary. Treat socket access as **root-equivalent** on the host.\n- **Docker (TCP)** — a host + port (2375 plain, 2376 TLS). Enable TLS in\n  production; a plain TCP daemon is unauthenticated.\n- **Portainer** — the Portainer host + HTTPS port (default 9443), an **API token**\n  (Portainer → My account → Access tokens), and the **endpoint id** of the managed\n  Docker environment you want to read/manage (list them with `stack endpoints`).\n- **Podman (unix socket)** — a running Podman **service** socket (rootful\n  `/run/podman/podman.sock`, or rootless `$XDG_RUNTIME_DIR/podman/podman.sock` after\n  `systemctl --user enable --now podman.socket`). No secret; the socket's file\n  permissions are the trust boundary. Autodetection prefers the rootless socket,\n  then the rootful one.\n\n## 3. Onboard (interactive)\n\n```bash\ncontainer-host-aiops init\n```\n\nThe wizard asks, per target, for the **platform** (`docker` / `portainer` / `podman`):\n\n- **docker** — connect over a **unix socket** (path, default `/var/run/docker.sock`)\n  or a **TCP host** (host + optional TLS). No secret.\n- **portainer** — host, HTTPS port, managed **endpoint id**, TLS verification, and\n  the **API token** (stored encrypted). A master password (used to encrypt\n  `secrets.enc`) is prompted the first time a Portainer token is stored.\n- **podman** — connect over a **unix socket** (path defaults to the autodetected\n  rootless/rootful Podman socket) or a **TCP host**. No secret. Podman speaks the\n  Docker-compatible API (so all Docker reads/writes/analyses work) plus libpod-native\n  pod reads (`pod list`).\n\nNon-secret connection details go to `~/.container-host-aiops/config.yaml`; a\nPortainer token goes to `~/.container-host-aiops/secrets.enc` (encrypted).\n\n### Manual config (`~/.container-host-aiops/config.yaml`)\n\n```yaml\ntargets:\n  - name: local\n    platform: docker\n    socket_path: /var/run/docker.sock\n\n  - name: remote-tcp\n    platform: docker\n    host: 10.0.0.5\n    port: 2376\n    verify_ssl: true\n\n  - name: portainer1\n    platform: portainer\n    host: portainer.lan\n    port: 9443\n    endpoint_id: \"1\"\n    verify_ssl: false        # true in production\n\n  - name: podman-local\n    platform: podman\n    # socket_path omitted → autodetect rootless ($XDG_RUNTIME_DIR/podman/podman.sock)\n    # then rootful (/run/podman/podman.sock); set socket_path to pin one explicitly.\n```\n\nThen store the Portainer token (encrypted):\n\n```bash\ncontainer-host-aiops secret set portainer1\ncontainer-host-aiops doctor\n```\n\n## 4. Credentials & security\n\n- Only **Portainer** needs a secret; **Docker and Podman** sockets need none (file\n  permissions are the boundary). The Portainer API token is **never** written to disk\n  in plaintext — it lives encrypted in `~/.container-host-aiops/secrets.enc` (Fernet /\n  AES-128 + a scrypt-derived key; chmod 600). The master password is never stored.\n- The master password is resolved from `CONTAINER_HOST_AIOPS_MASTER_PASSWORD`\n  (non-interactive / MCP / CI) or an interactive prompt (CLI on a TTY).\n- A legacy plaintext env var `CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN` is honoured\n  as a fallback with a deprecation warning (migrate with `secret migrate`).\n- The token is sent in the `X-API-Key` header at request time and held only in\n  memory; secrets are never logged or echoed.\n- `verify_ssl` defaults to true; disable only for a self-signed Portainer / TLS\n  Docker daemon in a lab. A unix-socket Docker/Podman target does not use TLS.\n\n## 5. Governance\n\nEvery MCP tool runs through the bundled `@governed_tool` harness:\n\n- **Audit** — all calls logged to `~/.container-host-aiops/audit.db` (relocatable via\n  `CONTAINER_HOST_AIOPS_HOME`), agent-attributed, secret-redacted.\n- **Runaway guard** — a safety backstop (not authorization): a tight-loop breaker\n  plus optional call/time ceilings. Disable with `CONTAINER_HOST_RUNAWAY_MAX=0`.\n- **Risk tier** — a descriptive label on each audit row derived from `risk_level`;\n  it gates nothing. `CONTAINER_HOST_AUDIT_APPROVED_BY` / `CONTAINER_HOST_AUDIT_RATIONALE`\n  are optional annotations recorded on the row, never required.\n- **Undo recording** — reversible writes capture the before-state and record an\n  inverse (`stop`→`start`, `update_container`→restore prior limits).\n\n## 6. Verify\n\n```bash\ncontainer-host-aiops doctor            # Docker/Podman: GET /version · Portainer: GET /api/endpoints\ncontainer-host-aiops overview          # one-shot host health\n```\n\n## Missing a capability?\n\nCoverage is a curated subset of the Docker Engine + Portainer + Podman (libpod)\nAPIs. Missing a call or want another container host family? **Open an issue or PR**\n— contributions welcome.\n\nFile v0.11.2:skill-card.md\n\n## Description:\n\nContainer Host AIops helps agents inspect and manage single Docker, Portainer, or Podman hosts, including host health, container diagnostics, resource and bloat analyses, and guarded lifecycle or cleanup actions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and infrastructure operators use this skill to triage non-orchestrated container hosts, inspect runtime state, analyze restart, resource, and disk issues, and perform audited lifecycle or cleanup actions when authorized.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can change or delete Docker, Podman, or Portainer resources.\n\nMitigation: Install only in trusted administrator environments, use least-privileged accounts or read-only access where possible, and require explicit operator authorization before write actions.\n\nRisk: Unrestricted Docker or Podman socket access can be equivalent to host administrator access.\n\nMitigation: Avoid exposing unrestricted sockets to agents; prefer least-privileged Portainer credentials or a Docker authorization proxy when write access is not required.\n\nRisk: The executable package may be installed without a pinned version.\n\nMitigation: Pin and verify the container-host-aiops package before granting access to container-host resources.\n\nRisk: Prune, remove, and redeploy operations can disrupt services or cause data loss.\n\nMitigation: Use dry-run previews, review candidates carefully, keep backups for data-bearing volumes, and rely on audit and undo records only for reversible operations.\n\n## Reference(s):\n\n- [Container Host AIops project homepage](https://github.com/AIops-tools/Container-Host-AIops)\n- [Capabilities reference](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup and security guide](references/setup-guide.md)\n- [Agent guardrails](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown or structured text with CLI commands, configuration guidance, and host-operation results.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Results may include live Docker, Portainer, or Podman state; log and event outputs can be bounded or truncated and should be treated as operational evidence.]\n\n## Skill Version(s):\n\n0.11.2 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.11.1: 7 files, 19762 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6870b), references/cli-reference.md (4534b), references/setup-guide.md (5258b), skill-card.md (2889b), SKILL.md (18023b), _meta.json (140b)\n\nFile v0.11.1:SKILL.md\n\n---\nname: container-host-aiops\nslug: container-host-aiops\ndisplayName: \"Container Host AIops\"\nsummary: \"Governed Docker + Portainer container-host ops: reads, RCA analyses, guarded writes. 38 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/Container-Host-AIops\ntags: [aiops, mcp, governance, container-host]\ndescription: >\n  Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list, inspect); system reads (info, version, df disk-usage, recent events); Portainer stacks + endpoints; Compose-project rollups (list_compose_stacks, docker+podman); Podman pods (list_pods, podman-only); three flagship analyses — restart-loop RCA (crash-looping containers + cause/action), resource-pressure analysis (CPU/memory vs limits), and image & volume bloat (prune candidates + reclaimable bytes); and eight guarded writes (restart/stop/start/remove a container, prune images/volumes, update resource limits, recreate a Portainer stack).\n  Always use this skill for \"Docker host overview\", \"which containers are crash-looping\", \"restart loop\", \"why does this container keep restarting\", \"container CPU/memory usage\", \"docker logs\", \"which containers are near their limits\", \"resource pressure\", \"dangling images/volumes\", \"reclaim disk\", \"prune images\", \"stop/start/restart a container\", \"update a container's memory limit\", \"Portainer stacks\", \"compose stacks\", \"Podman pods\" when the context is a Docker, Portainer, or Podman container host.\n  Do NOT use when the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment — route those to the appropriate other AIops-tools skill. This is for NON-orchestrator container hosts.\n  Governed Docker/Portainer/Podman container-host operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See docs/VERIFICATION.md.\ninstaller:\n  kind: uv\n  package: container-host-aiops\nargument-hint: \"[container/image/volume id or describe your container-host task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"container-host-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CONTAINER_HOST_AIOPS_CONFIG\",\"CONTAINER_HOST_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/Container-Host-AIops\",\"emoji\":\"🐳\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed Docker + Portainer + Podman container-host operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Multi-platform by construction (a platform registry); a per-target 'platform' field (docker / portainer / podman) selects the API shape.\n  All write operations are audited to a local SQLite DB under ~/.container-host-aiops/ (relocatable via CONTAINER_HOST_AIOPS_HOME).\n  Connection: a Docker target speaks the Docker Engine API over a local unix socket (httpx uds transport, default /var/run/docker.sock — treat socket access as root-equivalent) or a TCP host; a Portainer target speaks the Portainer management API over HTTPS with an X-API-Key token, and also proxies the Docker API of a managed endpoint at /api/endpoints/{id}/docker/...; a Podman target speaks over the rootful/rootless service socket (autodetected: $XDG_RUNTIME_DIR/podman/podman.sock, then /run/podman/podman.sock), reusing the Docker-compat paths at the root plus libpod-native endpoints (pods) under the libpod prefix.\n  Credentials: only Portainer needs a secret — its API token is stored ENCRYPTED in ~/.container-host-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. A local Docker or Podman socket needs no secret. Run 'container-host-aiops init' to onboard, or 'container-host-aiops secret set <target>' to add a Portainer token. The store is unlocked by a master password from CONTAINER_HOST_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN is still honoured as a fallback with a deprecation warning (migrate with 'container-host-aiops secret migrate'). The token is sent in the X-API-Key header at request time and held only in memory; secrets are never logged or echoed.\n  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget/runaway guard + audit + risk-tier label — it records, it does not authorize) and take a dry_run preview. Prune previews list what would be removed + reclaimable bytes before doing it. Mutating/reversible writes fetch the real before-state first and record a faithful inverse undo descriptor (stop→start, update_container→restore prior limits); irreversible ops (remove, prune, recreate) record only the before-state.\n  Webhooks: none — no outbound network calls beyond the configured Docker socket / TCP host or the Portainer API base URL.\n  SSL: verify_ssl defaults to true; disable only for a self-signed Portainer / TLS Docker daemon. A unix-socket Docker target does not use TLS.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  VERIFICATION: Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. Community-maintained; not affiliated with or endorsed by Docker/Portainer/Podman — trademarks belong to their owners.\n---\n\n# Container Host AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by Docker, Inc., Portainer.io, or any container-platform vendor.** Product and trademark names belong to their owners. Source at [github.com/AIops-tools/Container-Host-AIops](https://github.com/AIops-tools/Container-Host-AIops) under the MIT license.\n\nGoverned Docker + Portainer + Podman container-host operations — **38 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.container-host-aiops/` (MCP + CLI alike), a runaway/budget safety guard, and undo-token recording. It records every operation; whether a write is permitted is the agent's or the account's call, not the skill's. A Docker target speaks the Docker Engine API over a unix socket or TCP; a Portainer target speaks the Portainer API (and proxies Docker); a Podman target speaks over its rootful/rootless socket (Docker-compat + libpod). The Portainer API token is stored **encrypted** (`~/.container-host-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk; a local Docker/Podman socket needs no secret.\n\n> **Standalone**: the governance harness is bundled in the package (`container_host_aiops.governance`) — container-host-aiops has no external skill-family dependency. **Verification**: Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See `docs/VERIFICATION.md`.\n\n## What This Skill Does\n\n| Domain | Tools | Count | Read or Write |\n|--------|-------|:-----:|:-------------:|\n| **Overview** | one-shot host health | 1 | 1 read |\n| **Containers** | list/inspect, logs, stats, top, restart summary | 6 | 6 read |\n| **Images** | list, inspect (+history), dangling, disk usage | 4 | 4 read |\n| **Volumes** | list, inspect, dangling | 3 | 3 read |\n| **Networks** | list, inspect | 2 | 2 read |\n| **System** | info, version, df, events | 4 | 4 read |\n| **Stacks** | endpoints, stacks, stack detail (Portainer), compose-stack rollup (docker+podman) | 4 | 4 read |\n| **Pods (Podman)** | list pods (libpod) | 1 | 1 read |\n| **Analyses (flagship)** | restart-loop RCA, resource pressure, image/volume bloat | 3 | 3 read |\n| **Writes** | remove container, prune images, prune volumes, recreate stack | 4 | 4 write (high) |\n| | restart, stop, start, update container | 4 | 4 write (medium) |\n\nThe three analyses accept injected data for offline analysis, or pull live from a configured target. Portainer endpoints/stacks require a `portainer` target; `list_compose_stacks` works on docker or podman; `list_pods` requires a `podman` target.\n\n## Quick Install\n\n```bash\nuv tool install container-host-aiops\ncontainer-host-aiops init       # interactive wizard: Docker/Podman socket or Portainer target\ncontainer-host-aiops doctor\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@aiops-tools/container-host-aiops\nopenclaw skills info container-host-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a host (`overview`): version + container state rollup + disk headline\n- Find crash-looping containers (`analyze restart-loop` / `restart_loop_rca`): ranked by restart count with a likely cause and action from the exit code, plus a log tail\n- Spot resource pressure (`analyze resource-pressure` / `resource_pressure_analysis`): CPU%/mem% vs each container's limits, worst first, with a recommendation\n- Reclaim disk (`analyze bloat` / `image_and_volume_bloat`): dangling images + volumes + build cache as prune candidates with reclaimable bytes\n- List/inspect containers, images, volumes, networks; tail logs; read stats/top\n- Restart/stop/start a container, update its resource limits (reversible), remove a container, prune images/volumes, or recreate a Portainer stack — all with dry-run + double-confirm\n\n**Do NOT use when** the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| Docker / Portainer single-host container ops | **container-host-aiops** (this skill) |\n| A cluster orchestrator's workloads/rollouts | a cluster ops skill |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| OT / industrial edge (Modbus, OPC-UA, PLC) | the industrial-aiops line |\n\n## Common Workflows\n\n### 1. A container is crash-looping\n\n1. `container-host-aiops doctor` → confirm the socket/endpoint is reachable before you\n   trust any read.\n2. `container-host-aiops analyze restart-loop` → containers ranked by restart count,\n   each with a likely cause read off the real exit code (137 OOM/SIGKILL, 143 SIGTERM,\n   139 segfault, 127 bad entrypoint, …), a recommended action, and a log tail.\n3. `container-host-aiops container logs <id> --tail 200` → read the actual crash output;\n   `container-host-aiops container inspect <id>` → confirm the exit code, restart policy,\n   and configured limits the RCA cited.\n4. If the cause is memory: `container-host-aiops analyze resource-pressure --mem 75` →\n   see how close the container runs to its ceiling, then\n   `container-host-aiops manage update <id> '{\"Memory\": 1073741824}' --dry-run` and\n   re-run without `--dry-run` (double-confirm; the write captures the prior limits as its\n   undo descriptor).\n5. `container-host-aiops manage restart <id>` → bring it up on the new limit, then\n   re-run `analyze restart-loop` to confirm the loop stopped.\n6. **Failure branch**: if it still loops, the limit was not the cause — reverse the\n   change with `container-host-aiops undo list` → `undo apply <id>` (restores the *prior*\n   limits, not a guess) and go back to step 3 with the fresh log tail. If the container\n   will not stop at all, `manage remove <id> --force --dry-run` first: force-remove is\n   high-risk and irreversible, so read the dry-run before committing.\n\n### 2. The host is out of disk\n\n1. `container-host-aiops system df` → where the space actually went (images vs\n   containers vs volumes vs build cache).\n2. `container-host-aiops analyze bloat` → dangling images, dangling volumes, and build\n   cache as ranked prune candidates with reclaimable bytes per item.\n3. `container-host-aiops image dangling` and `container-host-aiops volume dangling` →\n   eyeball the concrete list before deleting anything. A \"dangling\" volume holding data\n   you still want is the classic way this goes wrong.\n4. `container-host-aiops manage prune-images --dry-run` → exactly what would be removed;\n   re-run without `--dry-run` (double-confirm, high risk).\n5. `container-host-aiops manage prune-volumes --dry-run` → **read this one carefully**;\n   volume pruning destroys data and records no undo. Note that Docker's default\n   prune removes only ANONYMOUS unused volumes — the preview reports the named\n   unused ones it will not touch as `alsoUnusedNamed*`; add `--all` to include\n   them. Only then re-run for real.\n6. `container-host-aiops system df` again → confirm the space came back.\n7. **Failure branch**: pruning is not reversible. If you removed a volume you needed,\n   the undo store cannot help — restore from your backup. The dry-run in steps 4–5 is\n   the only safety net, which is why both are separate confirm-gated steps.\n\n### 3. \"Everything on this box is slow\"\n\n1. `container-host-aiops overview` → one-shot: platform/version, container counts by\n   state, and the headline resource picture.\n2. `container-host-aiops analyze resource-pressure --cpu 80 --mem 80` → running\n   containers ranked against **their own limits**, each row citing the measured\n   percentage rather than a verdict.\n3. `container-host-aiops container stats <id>` and `container-host-aiops container top <id>`\n   → confirm the top offender at the process level before you act on it.\n4. `container-host-aiops system events` → correlate the pressure with what changed\n   (a recent deploy, restart storm, or image pull).\n5. Act on the worst offender: `manage update <id> '{\"NanoCpus\": 2000000000}'` to cap it\n   (dry-run first, undo-recorded), or `manage stop <id>` to shed it entirely.\n6. **Failure branch**: if capping the top container just moves the pressure elsewhere,\n   the host is genuinely undersized rather than misconfigured — reverse your change with\n   `undo apply <id>` so you are not left with a half-applied limit, and take the sizing\n   result to whoever owns capacity.\n\n### 4. Stack drift after a bad deploy (Portainer)\n\n1. `container-host-aiops stack endpoints` → the endpoints this Portainer manages;\n   `container-host-aiops stack list` → the stacks on the one you care about.\n2. `container-host-aiops stack detail <stack-id>` → the stack's current definition;\n   `container-host-aiops stack compose <stack-id>` → the compose file it is running from.\n3. `container-host-aiops container list --running` and\n   `container-host-aiops container restarts` → which of the stack's containers are\n   actually unhealthy versus merely restarted.\n4. `container-host-aiops manage recreate-stack <stack-id> --dry-run` → preview the\n   redeploy; re-run without `--dry-run` (double-confirm, high risk).\n5. Validate with `container-host-aiops overview` and `analyze restart-loop`.\n6. **Failure branch**: `recreate-stack` redeploys from the stack's stored definition — if\n   that definition is itself the broken thing, recreating will faithfully reproduce the\n   breakage. Fix the compose source in Portainer first, and use\n   `container-host-aiops undo list` to check what the session already changed before\n   layering another write on top.\n\n### Offline analysis (no live host)\n\nPass data straight to the analysis tools — `restart_loop_rca(containers=[...])`, `resource_pressure_analysis(samples=[...])`, or `image_and_volume_bloat(dangling_images=..., dangling_volumes=..., df=...)` — to analyse an exported dataset without connecting to a host.\n\n## Governance & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide\nwhether a write is permitted. That is your agent's judgement, or the permission\nof the account you connect it with (a read-only Docker socket, a Portainer\naccount without write scope — writes then fail at the server). There is no\nread-only switch, policy file, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.container-host-aiops/audit.db` (relocatable via `CONTAINER_HOST_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `CONTAINER_HOST_AUDIT_APPROVED_BY` / `CONTAINER_HOST_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: the same call looped in a tight window trips a circuit breaker. Disable with `CONTAINER_HOST_RUNAWAY_MAX=0`.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI; prune previews list what would be removed + reclaimable bytes.\n- Mutating/reversible writes fetch the real before-state and record an inverse descriptor (stop→start, update_container→restore prior limits); irreversible ops record only the before-state.\n\n## References\n\n- `references/capabilities.md` — full tool + field reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n\nFile v0.11.1:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"container-host-aiops\",\n  \"version\": \"0.11.1\",\n  \"publishedAt\": 1789207243772\n}\n\nFile v0.11.1:references/agent-guardrails.md\n\n# Agent guardrails — running container-host-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Give it a Docker socket mounted read-only,\n  or a Portainer account without write scope. A write then fails at the server,\n  which is the only place the permission actually lives — no skill-side flag can\n  be argued around by a model, but a revoked permission cannot be.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Log everything you do, over both MCP and the CLI\" | Every operation is audited to `~/.container-host-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. Reversible writes also record an undo token capturing the *prior* state. |\n| \"Don't invent a value when a field is missing\" | The Docker Engine omits keys it has nothing to say about — a created-but-never-started container has no `Status`, a dangling image has no `RepoTags`. Those come back as `null`, never as `\"\"`. An id in particular is `null` when unknown, so a blank string is never mistaken for a real identifier. |\n| \"Tell me if the log was cut off\" | `container_logs` returns `{\"lines\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`, and `system_events` the same shape. Truncation is measured — one extra line is requested from Docker — not guessed from a length coincidence. |\n| \"Preserve the ordering / tell me what's most urgent\" | `restart_loop_rca` and `resource_pressure_analysis` rank worst-first and carry the measured number (restart count, exit code, CPU%, memory%) in each entry. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `remove_container`, `prune_images` and `prune_volumes` require a `--dry-run`-able preview plus double confirmation at the CLI. |\n| \"Don't get stuck retrying\" | The runaway guard trips a circuit breaker if the same call is hammered in a tight loop — a stuck agent is stopped rather than left to burn calls and time. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a Docker or Podman container host (optionally via Portainer)\nthrough the container-host-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current host, you MUST call a tool.\n  Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher tail instead of treating\n  the partial result as the container's complete log. A container that has been\n  restarting for hours has far more log history than the default tail shows.\n- A null field means Docker did not report that value. Report it as \"not\n  available\" — never infer it. A null id is not a container named \"None\".\n- Report values exactly as returned. Do not normalise, translate, or prettify\n  container states, exit codes, or image tags.\n- Exit code 0 with a high restart count is a container completing and being\n  restarted by policy, not a crash. Do not call it a failure.\n- \"oomKilled\": true is the memory limit being hit — cite it rather than\n  guessing at a memory problem from CPU numbers.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert that a container is failing for a particular reason unless the\n  log tail or exit-code classification in the result supports it.\n- Do not add generic Docker advice that does not follow from the tool output.\n- Do not confuse a container id with an image id, a short id with a full one, a\n  container name with its image name, or a compose stack with a container.\n- Volumes and images are not deleted with the container. Pruning is a separate,\n  destructive, and irreversible operation — never fold it into a cleanup\n  suggestion casually.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the account's\npermission only when you trust the setup — the destructive operations on a\ncontainer host are unusually cheap to invoke and unusually expensive to undo\n(`prune_volumes` deletes data no undo token can bring back):\n\n```bash\n# e.g. mount the Docker socket read-only for the container running this tool,\n# or use a Portainer account without write scope. Then:\ncontainer-host-aiops doctor\n```\n\nOptionally annotate the audit trail with who is operating and why — recorded on\nevery row, never required:\n\n```bash\nexport CONTAINER_HOST_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport CONTAINER_HOST_AUDIT_RATIONALE=\"clearing disk on the build host\"\n```\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer the analysis tools —\n  `restart_loop_rca` correlates restart counts, exit codes, OOM flags and log\n  tails inside one call, so the model does not have to chain a list, an inspect\n  and a logs call per container while keeping ids straight.\n- **The model ignores later tool results in a long context.** Container logs are\n  the big payload here. Ask narrower questions and use `tail` deliberately\n  rather than pulling 2000 lines from every container.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\n## Verification status\n\nUnlike most of this tool line, container-host-aiops has been **live-verified\nagainst a real Docker 27.5.1 daemon** (socket at `~/.docker/run/docker.sock`):\n`doctor`, `overview`, all three flagship RCAs (`restart_loop_rca` genuinely\ncaught a crash-looping container on the machine; `image_and_volume_bloat`\nmeasured ~2 GiB), and a governed `stop_container` write with its audit row and\nundo token landing in the store. Podman and Portainer paths remain mock-only.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/Container-Host-AIops](https://github.com/AIops-tools/Container-Host-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.11.1:references/capabilities.md\n\n# container-host-aiops capabilities\n\n> **38 MCP tools** (29 read, 9 write) across the Docker\n> Engine API (unix socket or TCP), Portainer (management API + proxied Docker),\n> and Podman (rootful/rootless socket — Docker-compat layer + libpod-native\n> endpoints). Docker/Portainer/Podman API responses are mocked and need live\n> verification.\n\nEvery tool is wrapped with the bundled `@governed_tool` harness (audit, policy,\ntoken/runaway budget, undo, risk-tiers). All host-returned text is sanitized.\n\n## Overview (read)\n\n| Tool | Docker/Portainer path | Returns |\n|------|-----------------------|---------|\n| `overview` | `/info` + `/containers/json` + `/system/df` | host summary: platform, server version, container state rollup, disk headline |\n\n## Containers (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_containers` | `/containers/json?all=` | containers bucketed by state (running/exited/…), compact rows |\n| `inspect_container` | `/containers/{id}/json` | full inspect (config, state, mounts, network) |\n| `container_logs` | `/containers/{id}/logs?tail=N` | last N log lines (demuxed stdout+stderr) |\n| `container_stats` | `/containers/{id}/stats?stream=false` | CPU% + memory% snapshot (Docker's own delta formula) |\n| `container_top` | `/containers/{id}/top` | processes running inside the container |\n| `container_restart_summary` | `/containers/json` + per-container inspect | restart count + exit code + OOM, worst-first |\n\n## Images (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_images` | `/images/json` | images (tags, size, dangling), largest first |\n| `inspect_image` | `/images/{id}/json` + `/images/{id}/history` | inspect + build history (layers, sizes, commands) |\n| `dangling_images` | `/images/json?filters=dangling` | untagged images + reclaimable bytes |\n| `image_disk_usage` | `/system/df` (Images) | total, shared, reclaimable image bytes |\n\n## Volumes (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_volumes` | `/volumes` | named volumes (driver, mountpoint, scope) |\n| `inspect_volume` | `/volumes/{name}` | one volume in detail |\n| `dangling_volumes` | `/system/df` (Volumes, RefCount=0) | unreferenced volumes + reclaimable bytes |\n\n## Networks (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_networks` | `/networks` | networks bucketed by driver |\n| `inspect_network` | `/networks/{id}` | driver, IPAM subnet/gateway, attached containers |\n\n## System (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `system_info` | `/info` | container/image counts, storage driver, kernel, resources |\n| `system_version` | `/version` | version, API version, Go version, components |\n| `system_df` | `/system/df` | disk-usage breakdown: images, containers, volumes, build cache |\n| `system_events` | `/events?since=&until=` | recent daemon events, rolled up by type+action |\n\n## Stacks — Portainer (read; requires a portainer target)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_endpoints` | `/api/endpoints` | Portainer managed hosts (id, name, type, status, url) |\n| `list_stacks` | `/api/stacks` | Portainer stacks (id, name, type, endpoint, status) |\n| `stack_detail` | `/api/stacks/{id}` | one stack in detail (env, entrypoint, resource control) |\n\n## Compose stacks (read; docker or podman)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_compose_stacks` | `/containers/json?all=true` | Compose projects grouped by the `com.docker.compose.project` label, each with its services, per-state counts, and a health verdict (healthy = all running / degraded = some / down = none); ungrouped containers counted separately. Works on **docker and podman** (the label is set by both `docker compose` and `podman compose`). |\n\n## Pods — Podman (read; requires a podman target)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_pods` | `/{libpod}/pods/json` | Podman pods (id, name, status, created, infra id, member-container count + status rollup), bucketed by pod status. Pods are a Podman-only libpod concept — teaching-errors on docker/portainer. |\n\n## Podman platform notes\n\n- **Socket autodetection** (a `podman` target with no explicit `socket_path`): probe\n  `$XDG_RUNTIME_DIR/podman/podman.sock` (rootless) first, then `/run/podman/podman.sock`\n  (rootful); first existing wins, else fall back to the rootful path. An explicit\n  `socket_path` always overrides.\n- **Docker-compat reuse**: Podman serves the Docker-compatible API at the root\n  (unversioned), so every read/write/analysis above is reused wholesale — a `podman`\n  target behaves identically to `docker` for containers/images/volumes/networks/system\n  and all three flagship analyses and lifecycle/prune writes.\n- **libpod-native**: only pod reads use the libpod prefix; everything else stays on the\n  compat layer. A local Podman socket needs no secret.\n\n## Flagship analyses (read; injected or live)\n\n| Tool | Inputs | Returns |\n|------|--------|---------|\n| `restart_loop_rca` | container restart rows (+ optional log tails) or live pull | crash-looping containers ranked by restart count, each with cause+action from exit code (137 OOM/SIGKILL, 143 SIGTERM, 139 segfault, 127 bad entrypoint, …) + a log tail |\n| `resource_pressure_analysis` | CPU%/mem% samples or live pull | containers flagged near (≥80% of a threshold) / over, worst-first, with a recommendation |\n| `image_and_volume_bloat` | dangling images + volumes + system/df, or live pull | prune candidates with reclaimable bytes, largest first |\n\n## Writes (guarded)\n\n| Tool | Risk | Path | Notes |\n|------|:----:|------|-------|\n| `restart_container` | med | `POST /containers/{id}/restart` | captures prior state for audit; no meaningful inverse |\n| `stop_container` | med | `POST /containers/{id}/stop` | undo → `start_container` |\n| `start_container` | med | `POST /containers/{id}/start` | undo → `stop_container` |\n| `update_container` | med | `POST /containers/{id}/update` | captures prior CPU/memory limits; undo restores them |\n| `remove_container` | **high** | `DELETE /containers/{id}` | `dry_run` + double-confirm; captures full inspect BEFORE; no undo |\n| `prune_images` | **high** | `POST /images/prune` | `dry_run` LISTS candidates + reclaimable bytes first; no undo |\n| `prune_volumes` | **high** | `POST /volumes/prune` | anonymous unused volumes only unless `all_unused`; `dry_run` LISTS the candidates for that same scope + reclaimable bytes; no undo |\n| `recreate_stack` | **high** | `PUT /api/stacks/{id}/git/redeploy` | Portainer; captures prior stack; no undo |\n\n## Not in scope\n\n- Cluster orchestrators, hypervisors, storage appliances, backup products (separate AIops-tools)\n- Creating containers/images/networks from scratch, `docker build`, registry push/pull, exec-into-container\n- Swarm service scaling beyond a Portainer stack redeploy\n\nFile v0.11.1:references/cli-reference.md\n\n# container-host-aiops CLI reference\n\n> Covers the Docker Engine API (unix socket or TCP), Portainer (management API), and\n> Podman (rootful/rootless socket — Docker-compat + libpod). The Docker path has been\n> exercised against a live daemon; Portainer and Podman responses are mock-validated\n> only — see `docs/VERIFICATION.md`.\n\n## Setup\n\n```bash\ncontainer-host-aiops init                      # interactive wizard (Docker/Podman socket or Portainer)\ncontainer-host-aiops doctor                     # verify config, secrets, connectivity\n                                                #   Docker/Podman: GET /version · Portainer: GET /api/endpoints\ncontainer-host-aiops doctor --skip-auth         # config/secret checks only (no connectivity)\n```\n\n## Secrets (Portainer only)\n\n```bash\ncontainer-host-aiops secret set <target> [--value <token>]  # store a Portainer token (hidden prompt if no --value)\ncontainer-host-aiops secret list                            # list target names with a stored token\ncontainer-host-aiops secret rm <target>                     # delete a stored token\ncontainer-host-aiops secret migrate                         # import a legacy plaintext .env\ncontainer-host-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Overview\n\n```bash\ncontainer-host-aiops overview [--target <name>]   # one-shot host health\n```\n\n## Containers\n\n```bash\ncontainer-host-aiops container list [--running]            # all states, or only running\ncontainer-host-aiops container inspect <id>\ncontainer-host-aiops container logs <id> [--tail 200]\ncontainer-host-aiops container stats <id>                  # CPU% / memory%\ncontainer-host-aiops container top <id>                    # processes inside\ncontainer-host-aiops container restarts                    # restart-count + exit-code summary\n```\n\n## Images / Volumes / Networks\n\n```bash\ncontainer-host-aiops image list [--all]\ncontainer-host-aiops image inspect <id>                    # + build history\ncontainer-host-aiops image dangling\ncontainer-host-aiops image disk-usage\n\ncontainer-host-aiops volume list\ncontainer-host-aiops volume inspect <name>\ncontainer-host-aiops volume dangling\n\ncontainer-host-aiops network list\ncontainer-host-aiops network inspect <id>\n```\n\n## System\n\n```bash\ncontainer-host-aiops system info\ncontainer-host-aiops system version\ncontainer-host-aiops system df                             # disk-usage breakdown\ncontainer-host-aiops system events [--since 3600] [--type container]\n```\n\n## Stacks\n\n```bash\ncontainer-host-aiops stack endpoints          # Portainer target\ncontainer-host-aiops stack list               # Portainer target\ncontainer-host-aiops stack detail <stack_id>  # Portainer target\ncontainer-host-aiops stack compose            # Compose projects by label (docker OR podman) + health rollup\n```\n\n## Pods (Podman target)\n\n```bash\ncontainer-host-aiops pod list                 # Podman pods (libpod); errors on docker/portainer\n```\n\n## Analyses (flagship)\n\n```bash\ncontainer-host-aiops analyze restart-loop [--threshold 3]\ncontainer-host-aiops analyze resource-pressure [--cpu 80] [--mem 80]\ncontainer-host-aiops analyze bloat\n```\n\n## Manage (guarded writes — `--dry-run` + double confirmation)\n\n```bash\ncontainer-host-aiops manage restart <id> [--dry-run]\ncontainer-host-aiops manage stop <id> [--dry-run]          # undo: start\ncontainer-host-aiops manage start <id> [--dry-run]         # undo: stop\ncontainer-host-aiops manage update <id> '{\"Memory\":1073741824}' [--dry-run]   # undo restores prior limits\ncontainer-host-aiops manage remove <id> [--force] [--volumes] [--dry-run]     # high; captures full inspect first\ncontainer-host-aiops manage prune-images [--all] [--dry-run]                  # high; dry-run lists candidates\ncontainer-host-aiops manage prune-volumes [--all] [--dry-run]                 # high; anonymous only unless --all\ncontainer-host-aiops manage recreate-stack <stack_id> [--endpoint-id N] [--dry-run]   # high; Portainer\n```\n\n## MCP server\n\n```bash\ncontainer-host-aiops mcp          # stdio transport (or: container-host-aiops-mcp)\n```\n\n## Notes\n\n- Every command accepts `--target <name>` (`-t`) to pick a configured host; omit for the default (first) target.\n- The full 36-tool surface (all reads + writes) is exposed through the MCP server; the CLI is a convenient subset.\n- `stack endpoints`/`list`/`detail` and `recreate-stack` require a `portainer` target; `stack compose` works on docker or podman; `pod list` requires a `podman` target.\n\nFile v0.11.1:references/setup-guide.md\n\n# container-host-aiops setup & security guide\n\n> The Docker path has been exercised against a live daemon; the Portainer and Podman\n> paths are mock-validated only (see `docs/VERIFICATION.md`).\n> `container-host-aiops doctor` is the fastest live check on any platform.\n\n## 1. Install\n\n```bash\nuv tool install container-host-aiops     # or: pipx install container-host-aiops\n```\n\n## 2. What you need\n\n- **Docker (unix socket)** — read/write access to the Docker socket (default\n  `/var/run/docker.sock`). No secret is stored; the socket's file permissions are\n  the trust boundary. Treat socket access as **root-equivalent** on the host.\n- **Docker (TCP)** — a host + port (2375 plain, 2376 TLS). Enable TLS in\n  production; a plain TCP daemon is unauthenticated.\n- **Portainer** — the Portainer host + HTTPS port (default 9443), an **API token**\n  (Portainer → My account → Access tokens), and the **endpoint id** of the managed\n  Docker environment you want to read/manage (list them with `stack endpoints`).\n- **Podman (unix socket)** — a running Podman **service** socket (rootful\n  `/run/podman/podman.sock`, or rootless `$XDG_RUNTIME_DIR/podman/podman.sock` after\n  `systemctl --user enable --now podman.socket`). No secret; the socket's file\n  permissions are the trust boundary. Autodetection prefers the rootless socket,\n  then the rootful one.\n\n## 3. Onboard (interactive)\n\n```bash\ncontainer-host-aiops init\n```\n\nThe wizard asks, per target, for the **platform** (`docker` / `portainer` / `podman`):\n\n- **docker** — connect over a **unix socket** (path, default `/var/run/docker.sock`)\n  or a **TCP host** (host + optional TLS). No secret.\n- **portainer** — host, HTTPS port, managed **endpoint id**, TLS verification, and\n  the **API token** (stored encrypted). A master password (used to encrypt\n  `secrets.enc`) is prompted the first time a Portainer token is stored.\n- **podman** — connect over a **unix socket** (path defaults to the autodetected\n  rootless/rootful Podman socket) or a **TCP host**. No secret. Podman speaks the\n  Docker-compatible API (so all Docker reads/writes/analyses work) plus libpod-native\n  pod reads (`pod list`).\n\nNon-secret connection details go to `~/.container-host-aiops/config.yaml`; a\nPortainer token goes to `~/.container-host-aiops/secrets.enc` (encrypted).\n\n### Manual config (`~/.container-host-aiops/config.yaml`)\n\n```yaml\ntargets:\n  - name: local\n    platform: docker\n    socket_path: /var/run/docker.sock\n\n  - name: remote-tcp\n    platform: docker\n    host: 10.0.0.5\n    port: 2376\n    verify_ssl: true\n\n  - name: portainer1\n    platform: portainer\n    host: portainer.lan\n    port: 9443\n    endpoint_id: \"1\"\n    verify_ssl: false        # true in production\n\n  - name: podman-local\n    platform: podman\n    # socket_path omitted → autodetect rootless ($XDG_RUNTIME_DIR/podman/podman.sock)\n    # then rootful (/run/podman/podman.sock); set socket_path to pin one explicitly.\n```\n\nThen store the Portainer token (encrypted):\n\n```bash\ncontainer-host-aiops secret set portainer1\ncontainer-host-aiops doctor\n```\n\n## 4. Credentials & security\n\n- Only **Portainer** needs a secret; **Docker and Podman** sockets need none (file\n  permissions are the boundary). The Portainer API token is **never** written to disk\n  in plaintext — it lives encrypted in `~/.container-host-aiops/secrets.enc` (Fernet /\n  AES-128 + a scrypt-derived key; chmod 600). The master password is never stored.\n- The master password is resolved from `CONTAINER_HOST_AIOPS_MASTER_PASSWORD`\n  (non-interactive / MCP / CI) or an interactive prompt (CLI on a TTY).\n- A legacy plaintext env var `CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN` is honoured\n  as a fallback with a deprecation warning (migrate with `secret migrate`).\n- The token is sent in the `X-API-Key` header at request time and held only in\n  memory; secrets are never logged or echoed.\n- `verify_ssl` defaults to true; disable only for a self-signed Portainer / TLS\n  Docker daemon in a lab. A unix-socket Docker/Podman target does not use TLS.\n\n## 5. Governance\n\nEvery MCP tool runs through the bundled `@governed_tool` harness:\n\n- **Audit** — all calls logged to `~/.container-host-aiops/audit.db` (relocatable via\n  `CONTAINER_HOST_AIOPS_HOME`), agent-attributed, secret-redacted.\n- **Runaway guard** — a safety backstop (not authorization): a tight-loop breaker\n  plus optional call/time ceilings. Disable with `CONTAINER_HOST_RUNAWAY_MAX=0`.\n- **Risk tier** — a descriptive label on each audit row derived from `risk_level`;\n  it gates nothing. `CONTAINER_HOST_AUDIT_APPROVED_BY` / `CONTAINER_HOST_AUDIT_RATIONALE`\n  are optional annotations recorded on the row, never required.\n- **Undo recording** — reversible writes capture the before-state and record an\n  inverse (`stop`→`start`, `update_container`→restore prior limits).\n\n## 6. Verify\n\n```bash\ncontainer-host-aiops doctor            # Docker/Podman: GET /version · Portainer: GET /api/endpoints\ncontainer-host-aiops overview          # one-shot host health\n```\n\n## Missing a capability?\n\nCoverage is a curated subset of the Docker Engine + Portainer + Podman (libpod)\nAPIs. Missing a call or want another container host family? **Open an issue or PR**\n— contributions welcome.\n\nFile v0.11.1:skill-card.md\n\n## Description:\n\nContainer Host AIops helps an agent inspect and administer a single Docker, Portainer, or Podman container host with host overviews, container/image/volume/network/system reads, restart-loop and resource-pressure analysis, bloat analysis, and guarded lifecycle or prune actions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and operations engineers use this skill to triage and manage non-orchestrator container hosts, including crash-loop investigation, resource pressure review, disk cleanup planning, and guarded container or Portainer stack actions.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Write-capable Docker, Podman, or Portainer access can stop services, remove containers, prune images, or delete volumes without an enforced read-only or approval boundary in the skill.\n\nMitigation: Use a read-only Docker socket, a restricted Portainer account, or an isolated test host for diagnostics; enable write-capable access only for sessions where destructive actions are intended.\n\nRisk: Volume pruning and some remove or recreate actions are irreversible and may delete data or reproduce a broken stack definition.\n\nMitigation: Require dry-run review before high-risk actions, confirm backups for data-bearing volumes, and treat audit or undo records as operational records rather than guaranteed recovery.\n\nRisk: The reviewed artifact does not pin the runtime package installed by the agent.\n\nMitigation: Verify the exact installed package version before use and align it with the reviewed release version 0.11.1.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/zw008/skills/container-host-aiops)\n- [Container Host AIops source homepage](https://github.com/AIops-tools/Container-Host-AIops)\n- [Capabilities reference](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup and security guide](references/setup-guide.md)\n- [Agent guardrails](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands, configuration snippets, and structured tool-result summaries.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Outputs may include live container-host diagnostics, ranked analyses, dry-run previews, audit or undo guidance, and truncated log/event indicators.]\n\n## Skill Version(s):\n\n0.11.1 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.11.0: 7 files, 19591 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6870b), references/cli-reference.md (4534b), references/setup-guide.md (5258b), skill-card.md (2822b), SKILL.md (17695b), _meta.json (140b)\n\nFile v0.11.0:SKILL.md\n\n---\nname: container-host-aiops\nslug: container-host-aiops\ndisplayName: \"Container Host AIops\"\nsummary: \"Governed Docker + Portainer container-host ops: reads, RCA analyses, guarded writes. 38 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/Container-Host-AIops\ntags: [aiops, mcp, governance, container-host]\ndescription: >\n  Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list, inspect); system reads (info, version, df disk-usage, recent events); Portainer stacks + endpoints; Compose-project rollups (list_compose_stacks, docker+podman); Podman pods (list_pods, podman-only); three flagship analyses — restart-loop RCA (crash-looping containers + cause/action), resource-pressure analysis (CPU/memory vs limits), and image & volume bloat (prune candidates + reclaimable bytes); and eight guarded writes (restart/stop/start/remove a container, prune images/volumes, update resource limits, recreate a Portainer stack).\n  Always use this skill for \"Docker host overview\", \"which containers are crash-looping\", \"restart loop\", \"why does this container keep restarting\", \"container CPU/memory usage\", \"docker logs\", \"which containers are near their limits\", \"resource pressure\", \"dangling images/volumes\", \"reclaim disk\", \"prune images\", \"stop/start/restart a container\", \"update a container's memory limit\", \"Portainer stacks\", \"compose stacks\", \"Podman pods\" when the context is a Docker, Portainer, or Podman container host.\n  Do NOT use when the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment — route those to the appropriate other AIops-tools skill. This is for NON-orchestrator container hosts.\n  Governed Docker/Portainer/Podman container-host operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See docs/VERIFICATION.md.\ninstaller:\n  kind: uv\n  package: container-host-aiops\nargument-hint: \"[container/image/volume id or describe your container-host task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"container-host-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CONTAINER_HOST_AIOPS_CONFIG\",\"CONTAINER_HOST_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/Container-Host-AIops\",\"emoji\":\"🐳\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed Docker + Portainer + Podman container-host operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Multi-platform by construction (a platform registry); a per-target 'platform' field (docker / portainer / podman) selects the API shape.\n  All write operations are audited to a local SQLite DB under ~/.container-host-aiops/ (relocatable via CONTAINER_HOST_AIOPS_HOME).\n  Connection: a Docker target speaks the Docker Engine API over a local unix socket (httpx uds transport, default /var/run/docker.sock — treat socket access as root-equivalent) or a TCP host; a Portainer target speaks the Portainer management API over HTTPS with an X-API-Key token, and also proxies the Docker API of a managed endpoint at /api/endpoints/{id}/docker/...; a Podman target speaks over the rootful/rootless service socket (autodetected: $XDG_RUNTIME_DIR/podman/podman.sock, then /run/podman/podman.sock), reusing the Docker-compat paths at the root plus libpod-native endpoints (pods) under the libpod prefix.\n  Credentials: only Portainer needs a secret — its API token is stored ENCRYPTED in ~/.container-host-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. A local Docker or Podman socket needs no secret. Run 'container-host-aiops init' to onboard, or 'container-host-aiops secret set <target>' to add a Portainer token. The store is unlocked by a master password from CONTAINER_HOST_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN is still honoured as a fallback with a deprecation warning (migrate wi\n\nArchive v0.10.0: 7 files, 19615 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6870b), references/cli-reference.md (4534b), references/setup-guide.md (5258b), skill-card.md (2896b), SKILL.md (17786b), _meta.json (140b)\n\nArchive v0.9.0: 7 files, 19576 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6870b), references/cli-reference.md (4534b), references/setup-guide.md (5258b), skill-card.md (2713b), SKILL.md (17786b), _meta.json (139b)\n\nArchive v0.8.0: 7 files, 19443 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6801b), references/cli-reference.md (4531b), references/setup-guide.md (5258b), skill-card.md (2956b), SKILL.md (17590b), _meta.json (139b)\n\nArchive v0.7.0: 7 files, 19481 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6801b), references/cli-reference.md (4531b), references/setup-guide.md (5258b), skill-card.md (2986b), SKILL.md (17590b), _meta.json (139b)\n\nArchive v0.6.0: 7 files, 19565 bytes\n\nFiles: references/agent-guardrails.md (7711b), references/capabilities.md (6801b), references/cli-reference.md (4531b), references/setup-guide.md (5258b), skill-card.md (3164b), SKILL.md (17590b), _meta.json (139b)\n\nArchive v0.5.0: 7 files, 18900 bytes\n\nFiles: references/agent-guardrails.md (7088b), references/capabilities.md (6801b), references/cli-reference.md (4531b), references/setup-guide.md (5197b), skill-card.md (2901b), SKILL.md (17104b), _meta.json (139b)","readmeExcerpt":"Skill: container-host-aiops Owner: zw008 Summary: Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"uv tool install container-host-aiops\ncontainer-host-aiops init       # interactive wizard: Docker/Podman socket or Portainer target\ncontainer-host-aiops doctor"},{"language":"bash","snippet":"openclaw plugins install clawhub:@zw008/container-host-aiops\nopenclaw skills info container-host-aiops          # expect: Visible to model: yes"},{"language":"text","snippet":"You operate a Docker or Podman container host (optionally via Portainer)\nthrough the container-host-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current host, you MUST call a tool.\n  Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher tail instead of treating\n  the partial result as the container's complete log. A container that has been\n  restarting for hours has far more log history than the default tail shows.\n- A null field means Docker did not report that value. Report it as \"not\n  available\" — never infer it. A null id is not a container named \"None\".\n- Report values exactly as returned. Do not normalise, translate, or prettify\n  container states, exit codes, or image tags.\n- Exit code 0 with a high restart count is a container completing and being\n  restarted by policy, not a crash. Do not call it a failure.\n- \"oomKilled\": true is the memory limit being hit — cite it rather than\n  guessing at a memory problem from CPU numbers.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert that a container is failing for a particular reason unless the\n  log tail or exit-code classification in the result supports it.\n- Do not add generic Docker advice that does not follow from the tool output.\n- Do not confuse a container id with an image id, a short id with a full one, a\n  container name with its image name, or a compose stack with a container.\n- Volumes and images are not deleted with the container. Pruning is a separate,\n  destructive, and irreversible operation — never fol"},{"language":"bash","snippet":"# e.g. mount the Docker socket read-only for the container running this tool,\n# or use a Portainer account without write scope. Then:\ncontainer-host-aiops doctor"},{"language":"bash","snippet":"export CONTAINER_HOST_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport CONTAINER_HOST_AUDIT_RATIONALE=\"clearing disk on the build host\""},{"language":"bash","snippet":"container-host-aiops init                      # interactive wizard (Docker/Podman socket or Portainer)\ncontainer-host-aiops doctor                     # verify config, secrets, connectivity\n                                                #   Docker/Podman: GET /version · Portainer: GET /api/endpoints\ncontainer-host-aiops doctor --skip-auth         # config/secret checks only (no connectivity)"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: container-host-aiops\nslug: container-host-aiops\ndisplayName: \"Container Host AIops\"\nsummary: \"Governed Docker + Portainer container-host ops: reads, RCA analyses, guarded writes. 38 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/Container-Host-AIops\ntags: [aiops, mcp, governance, container-host]\ndescription: >\n  Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list, inspect); system reads (info, version, df disk-usage, recent events); Portainer stacks + endpoints; Compose-project rollups (list_compose_stacks, docker+podman); Podman pods (list_pods, podman-only); three flagship analyses — restart-loop RCA (crash-looping containers + cause/action), resource-pressure analysis (CPU/memory vs limits), and image & volume bloat (prune candidates + reclaimable bytes); and eight guarded writes (restart/stop/start/remove a container, prune images/volumes, update resource limits, recreate a Portainer stack).\n  Always use this skill for \"Docker host overview\", \"which containers are crash-looping\", \"restart loop\", \"why does this container keep restarting\", \"container CPU/memory usage\", \"docker logs\", \"which containers are near their limits\", \"resource pressure\", \"dangling images/volumes\", \"reclaim disk\", \"prune images\", \"stop/start/restart a container\", \"update a container's memory limit\", \"Portainer stacks\", \"compose stacks\", \"Podman pods\" when the context is a Docker, Portainer, or Podman container host.\n  Do NOT use when the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment — route those to the appropriate other AIops-tools skill. This is for NON-orchestrator container hosts.\n  Governed Docker/Portainer/Podman container-host operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Exercised against a live Docker Engine 27.5.1 daemon (doctor, overview, the three flagship analyses, and a governed stop_container with audit + undo recorded); the Portainer and Podman API paths are covered by the mock suite only. See docs/VERIFICATION.md.\ninstaller:\n  kind: uv\n  package: container-host-aiops\nargument-hint: \"[container/image/volume id or describe your container-host task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"container-host-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CONTAINER_HOST_AIOPS_CONFIG\",\"CONTAINER_HOST_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/Container-Host-AIops\",\"emoji\":\"🐳\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed Docker + Portainer + Podman container-host operations. The governance harness (audit, policy, token/r"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"container-host-aiops\",\n  \"version\": \"0.11.3\",\n  \"publishedAt\": 1789451605853\n}"},{"path":"references/agent-guardrails.md","content":"# Agent guardrails — running container-host-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Give it a Docker socket mounted read-only,\n  or a Portainer account without write scope. A write then fails at the server,\n  which is the only place the permission actually lives — no skill-side flag can\n  be argued around by a model, but a revoked permission cannot be.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Log everything you do, over both MCP and the CLI\" | Every operation is audited to `~/.container-host-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. Reversible writes also record an undo token capturing the *prior* state. |\n| \"Don't invent a value when a field is missing\" | The Docker Engine omits keys it has nothing to say about — a created-but-never-started container has no `Status`, a dangling image has no `RepoTags`. Those come back as `null`, never as `\"\"`. An id in particular is `null` when unknown, so a blank string is never mistaken for a real identifier. |\n| \"Tell me if the log was cut off\" | `container_logs` returns `{\"lines\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`, and `system_events` the same shape. Truncation is measured — one extra line is requested from Docker — not guessed from a length coincidence. |\n| \"Preserve the ordering / tell me what's most urgent\" | `restart_loop_rca` and `resource_pressure_analysis` rank worst-first and carry the measured number (restart count, exit code, CPU%, memory%) in each entry. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `remove_container`, `prune_images` and `prune_volumes` require a `--dry-run`-able preview plus double confirmation at the CLI. |\n| \"Don't get stuck retrying\" | The runaway guard trips "},{"path":"references/capabilities.md","content":"# container-host-aiops capabilities\n\n> **38 MCP tools** (29 read, 9 write) across the Docker\n> Engine API (unix socket or TCP), Portainer (management API + proxied Docker),\n> and Podman (rootful/rootless socket — Docker-compat layer + libpod-native\n> endpoints). Docker/Portainer/Podman API responses are mocked and need live\n> verification.\n\nEvery tool is wrapped with the bundled `@governed_tool` harness (audit, policy,\ntoken/runaway budget, undo, risk-tiers). All host-returned text is sanitized.\n\n## Overview (read)\n\n| Tool | Docker/Portainer path | Returns |\n|------|-----------------------|---------|\n| `overview` | `/info` + `/containers/json` + `/system/df` | host summary: platform, server version, container state rollup, disk headline |\n\n## Containers (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_containers` | `/containers/json?all=` | containers bucketed by state (running/exited/…), compact rows |\n| `inspect_container` | `/containers/{id}/json` | full inspect (config, state, mounts, network) |\n| `container_logs` | `/containers/{id}/logs?tail=N` | last N log lines (demuxed stdout+stderr) |\n| `container_stats` | `/containers/{id}/stats?stream=false` | CPU% + memory% snapshot (Docker's own delta formula) |\n| `container_top` | `/containers/{id}/top` | processes running inside the container |\n| `container_restart_summary` | `/containers/json` + per-container inspect | restart count + exit code + OOM, worst-first |\n\n## Images (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_images` | `/images/json` | images (tags, size, dangling), largest first |\n| `inspect_image` | `/images/{id}/json` + `/images/{id}/history` | inspect + build history (layers, sizes, commands) |\n| `dangling_images` | `/images/json?filters=dangling` | untagged images + reclaimable bytes |\n| `image_disk_usage` | `/system/df` (Images) | total, shared, reclaimable image bytes |\n\n## Volumes (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_volumes` | `/volumes` | named volumes (driver, mountpoint, scope) |\n| `inspect_volume` | `/volumes/{name}` | one volume in detail |\n| `dangling_volumes` | `/system/df` (Volumes, RefCount=0) | unreferenced volumes + reclaimable bytes |\n\n## Networks (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `list_networks` | `/networks` | networks bucketed by driver |\n| `inspect_network` | `/networks/{id}` | driver, IPAM subnet/gateway, attached containers |\n\n## System (read)\n\n| Tool | Path | Returns |\n|------|------|---------|\n| `system_info` | `/info` | container/image counts, storage driver, kernel, resources |\n| `system_version` | `/version` | version, API version, Go version, components |\n| `system_df` | `/system/df` | disk-usage breakdown: images, containers, volumes, build cache |\n| `system_events` | `/events?since=&until=` | recent daemon events, rolled up by type+action |\n\n## Stacks — Portainer (read; requires a portainer target)\n\n| Tool | Path | Returns |\n|------|------|---------|\n|"},{"path":"references/cli-reference.md","content":"# container-host-aiops CLI reference\n\n> Covers the Docker Engine API (unix socket or TCP), Portainer (management API), and\n> Podman (rootful/rootless socket — Docker-compat + libpod). The Docker path has been\n> exercised against a live daemon; Portainer and Podman responses are mock-validated\n> only — see `docs/VERIFICATION.md`.\n\n## Setup\n\n```bash\ncontainer-host-aiops init                      # interactive wizard (Docker/Podman socket or Portainer)\ncontainer-host-aiops doctor                     # verify config, secrets, connectivity\n                                                #   Docker/Podman: GET /version · Portainer: GET /api/endpoints\ncontainer-host-aiops doctor --skip-auth         # config/secret checks only (no connectivity)\n```\n\n## Secrets (Portainer only)\n\n```bash\ncontainer-host-aiops secret set <target> [--value <token>]  # store a Portainer token (hidden prompt if no --value)\ncontainer-host-aiops secret list                            # list target names with a stored token\ncontainer-host-aiops secret rm <target>                     # delete a stored token\ncontainer-host-aiops secret migrate                         # import a legacy plaintext .env\ncontainer-host-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Overview\n\n```bash\ncontainer-host-aiops overview [--target <name>]   # one-shot host health\n```\n\n## Containers\n\n```bash\ncontainer-host-aiops container list [--running]            # all states, or only running\ncontainer-host-aiops container inspect <id>\ncontainer-host-aiops container logs <id> [--tail 200]\ncontainer-host-aiops container stats <id>                  # CPU% / memory%\ncontainer-host-aiops container top <id>                    # processes inside\ncontainer-host-aiops container restarts                    # restart-count + exit-code summary\n```\n\n## Images / Volumes / Networks\n\n```bash\ncontainer-host-aiops image list [--all]\ncontainer-host-aiops image inspect <id>                    # + build history\ncontainer-host-aiops image dangling\ncontainer-host-aiops image disk-usage\n\ncontainer-host-aiops volume list\ncontainer-host-aiops volume inspect <name>\ncontainer-host-aiops volume dangling\n\ncontainer-host-aiops network list\ncontainer-host-aiops network inspect <id>\n```\n\n## System\n\n```bash\ncontainer-host-aiops system info\ncontainer-host-aiops system version\ncontainer-host-aiops system df                             # disk-usage breakdown\ncontainer-host-aiops system events [--since 3600] [--type container]\n```\n\n## Stacks\n\n```bash\ncontainer-host-aiops stack endpoints          # Portainer target\ncontainer-host-aiops stack list               # Portainer target\ncontainer-host-aiops stack detail <stack_id>  # Portainer target\ncontainer-host-aiops stack compose            # Compose projects by label (docker OR podman) + health rollup\n```\n\n## Pods (Podman target)\n\n```bash\ncontainer-host-aiops pod list                 # Podman pods (libpod); errors on docker/portainer\n```\n\n## Analyses (fl"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":2190,"uniquenessScore":37,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:19:49.871Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:19:49.871Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T15:52:46.944Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}