Skip to main content
Glama

zima-mcp

An MCP server that lets your AI assistant check on a ZimaBlade (or any Docker box) over plain SSH, and restart the containers you allow, with nothing installed on the box.

zima-mcp running against a real ZimaBlade: tool list, load, per-container stats, and a refused restart

Real output from a ZimaBlade running ZimaOS, captured 11 Oct 2026. The stats table is trimmed to the Immich and Homepage containers.

MIT licence Python 3.10+ Buy Me a Coffee

Contents

Related MCP server: MCP SSH SRE

What it does

  • Answers "is the box busy?" with load average and uptime (zima_load).

  • Finds the culprit with top processes by CPU (zima_top) and one snapshot of CPU and memory per container (zima_docker_stats).

  • Lists containers with status and image (zima_docker_ps) and shows disk usage (zima_disk).

  • Reads logs for one named container, up to 500 lines (zima_container_logs).

  • Restarts a container, but only one you have put on the allowlist (zima_restart_container). Everything else is refused.

  • Can't reboot the box, use sudo or kill root processes. None of the tools runs those commands, and the test suite checks that.

Quick start

You need Python 3.10+, an SSH key that logs in to the box without a password, and a user on the box that can run docker without sudo. On ZimaOS the normal user can, because it's in the docker group.

# 1. check SSH and docker work for that user
ssh you@your-zima docker ps

# 2. install
pipx install git+https://github.com/casareanderson/zima-mcp

# 3. try one tool
ZIMA_HOST=your-zima ZIMA_USER=you zima-mcp --call zima_load

Success looks like one uptime line, for example 10:09:19 up 16 days, 23:54, 0 users, load average: 0.81, 0.99, 0.94.

Then add it to your MCP client (next section). The full walkthrough, including every client and the common errors, is in docs/SETUP.md.

Usage

Claude Code:

claude mcp add zima -e ZIMA_HOST=your-zima -e ZIMA_USER=you -e ZIMA_RESTART_ALLOWLIST=immich-server -- zima-mcp

Claude Desktop, Cursor and most other clients take the same JSON shape (claude_desktop_config.json, ~/.cursor/mcp.json):

{
  "mcpServers": {
    "zima": {
      "command": "zima-mcp",
      "env": {
        "ZIMA_HOST": "your-zima",
        "ZIMA_USER": "you",
        "ZIMA_RESTART_ALLOWLIST": "immich-server,immich-machine-learning"
      }
    }
  }
}

Then ask things like "is the Zima busy?", "which container is eating the memory?" or "show me the last 100 lines of immich-server's logs".

Testing without a client:

zima-mcp --list-tools
zima-mcp --call zima_docker_stats
zima-mcp --call zima_container_logs --arg container=immich-server --arg lines=50

Configuration

All settings are environment variables. There's a copy-and-edit template in config.example.env.

Variable

Default

What it does

ZIMA_HOST

required

Hostname or IP of the box

ZIMA_USER

required

SSH user. Must be able to run docker without sudo

ZIMA_SSH_PORT

22

SSH port

ZIMA_SSH_KEY

your SSH default

Path to a private key, passed as ssh -i

ZIMA_SSH_TIMEOUT

20

Seconds before a command is given up on (60 for restarts)

ZIMA_RESTART_ALLOWLIST

empty

Comma-separated container names the agent may restart. Empty means every restart is refused

How it works

flowchart LR
    A[AI assistant] -- MCP over stdio --> B[zima-mcp]
    B -- "ssh -o BatchMode=yes user@box 'docker stats ...'" --> C[ZimaBlade]
    C -- text output --> B -- tool result --> A

Each tool is one fixed command run with ssh. SSH runs in BatchMode, so it never sits waiting for a password. A command that takes too long is stopped and reported as an error, not left hanging. Container names are checked against Docker's own naming rules before they go anywhere near a shell, so a name like --help or a;reboot is refused, and names are shell-quoted as well. Restarts also have to be on the allowlist.

zima_mcp/
  server.py      the tools, SSH runner, config and MCP wiring
  __main__.py    python -m zima_mcp
tests/
  test_server.py unit tests plus an in-memory MCP session
scripts/
  setup-check.sh what CI runs to prove docs/SETUP.md works

Status, limits and real results

  • Status: in use on one ZimaBlade (ZimaOS) as the "Zima ops" toolset of a self-hosted agent. This repo is the cleaned-up, configurable copy. The output above is from that box on 11 Oct 2026.

  • Tested: 19 unit tests, plus a CI job that follows docs/SETUP.md against a stand-in Docker host on the GitHub runner (SSH to localhost, a real nginx container, a real allowlisted restart).

  • Not a ZimaOS API client. It doesn't talk to the ZimaOS/CasaOS app store or settings, only to docker and standard Linux tools over SSH. That's also why it works on any Linux Docker host.

  • One box per server. To watch two boxes, add it twice under different names.

  • zima_top uses top -o %CPU. That works on ZimaOS. Some minimal BusyBox systems don't support -o, and the tool will return the error text.

  • Can't fix a sick host. No reboot, no sudo. If the box itself is wedged, it tells you and that's all.

Licence and credits

MIT, see LICENSE. Built on the Model Context Protocol Python SDK (MIT).

If zima-mcp is useful to you, buy me a coffee. More field notes at dev.to/iam-tech.

Available Tools

7 tools
zima_container_logsB

Tail recent logs for one named container.

ParametersJSON Schema
NameRequiredDescriptionDefault
linesNoLines to tail (default 80, max 500).
containerYesContainer name, e.g. immich-server.

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden, and it discloses very little: it does not say whether the call is read-only, whether it blocks or follows the stream, whether output is bounded, or what happens if the container is missing. 'Recent' is the only behavioral hint and it is undefined in the prose (the 80/500 bound lives in the schema).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the verb and resource, with zero filler. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter read tool with full schema coverage and no output schema, the description is minimally adequate. However, with no annotations and no output schema, it leaves open whether the result is a bounded string, whether the call streams/blocks, and what failure looks like.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both 'container' (name, example) and 'lines' (default 80, max 500) documented in the schema itself, so the baseline of 3 applies. The description only echoes the singular-container constraint and adds no format or syntax detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource pair ('tail logs') scoped to one named container, which is enough to distinguish it from zima_docker_ps (listing) and zima_restart_container (mutation). It stops short of naming or contrasting any sibling explicitly, so it is clear but not fully differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites (e.g. container must be running), and no mention of alternatives for viewing logs versus other container inspection tools. The agent must infer usage entirely from the name and purpose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

zima_diskB

Disk usage (df -h).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. Referencing 'df -h' implicitly conveys a read-only, human-readable inspection operation, which is genuine context beyond the empty schema, but there is no explicit statement of side-effect-free behavior, permissions, or output shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two words plus a parenthetical command reference; maximally front-loaded with zero waste for a trivial tool. It is arguably too terse to be called exemplary, but nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, no-output-schema read tool, the description is minimally adequate. The 'df -h' reference hints at the return format, but the agent gets no explicit statement of what fields or host scope to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the baseline there is nothing for the description to explain. It neither misleads nor needs to compensate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (disk usage) and pins it to a known command (df -h), which lets an agent tell it apart from siblings like zima_top, zima_docker_stats, and zima_load without opening a schema. It is not a bare tautology, though it does not explicitly contrast itself with any sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use, when-not-to-use, or alternative is stated. The agent must infer that this is the tool for checking host disk space rather than container or resource stats; nothing in the text guides that choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

zima_docker_psA

List running Docker containers with status and image.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It usefully implies a read-only listing and scopes results to running containers only (stopped/exited ones are excluded), but says nothing about permissions, pagination, or output format beyond two field names.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the action, scope, and return fields; every word earns its place and there is no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should indicate what comes back, and 'status and image' does so at a basic level. For a zero-parameter read-only listing this is nearly sufficient, though the exact shape/ordering of the listing is unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter semantics to document; the baseline for a 0-param tool is 4. The description correctly implies no arguments are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List running Docker containers') and clarifies the returned fields ('status and image'), which distinguishes it from log- or control-oriented siblings like zima_container_logs and zima_restart_container. It does not explicitly differentiate from zima_docker_stats, which likely overlaps in scope, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of when to prefer zima_docker_stats or zima_top instead, and no stated prerequisites. The agent must infer the tool's place in the sibling set on its own.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

zima_docker_statsA

One snapshot of CPU and memory per container. Best tool for finding the culprit.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses that this is a point-in-time snapshot rather than a live stream, but omits any statement about side effects, permissions, or return shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, no waste, with the core function front-loaded before the routing hint. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with no output schema, the description is serviceable but thin: it never indicates what the snapshot contains (per-container CPU/memory figures, units, ordering), which an agent would need to interpret results. Adequate but with a clear gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing to document and the baseline of 4 applies. The description adds no parameter detail because none is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (CPU and memory per container) and a clear scope ('one snapshot'), which distinguishes it from the streaming/monitoring siblings. It does not explicitly name how it differs from zima_top or zima_docker_ps, so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Best tool for finding the culprit' implies a use case (diagnosing a resource-hungry container), but no explicit when-to-use or when-not guidance and no named alternatives. Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

zima_loadA

Load average and uptime of the box. Quick check of whether it is busy.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full disclosure burden, but it does state the return content (load average and uptime), which is the main behavioral fact for a metric tool. It omits that the operation is read-only with no side effects and says nothing about output format, which is a modest gap for a zero-param probe.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the returned data before the usage hint, and no filler. It is appropriately sized for a trivial tool, though the second sentence is somewhat colloquial rather than informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-param, no-output-schema tool the description is nearly sufficient — it says what comes back. It stops short of situating the tool among its siblings (e.g. zima_top for per-process detail), so an agent lacks a complete basis for choosing this over the alternatives.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing to document and the baseline is 4. The description correctly implies no arguments are needed for a box-level metric read.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States exactly what the tool retrieves (load average and uptime) and its target (the box), so an agent knows the resource and scope. It does not explicitly distinguish itself from the closest sibling zima_top, which is also a system-level metric tool, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Quick check of whether it is busy" implies a lightweight triage use case, which is genuine guidance. However, it names no alternatives and gives no condition for preferring zima_load over zima_top or the docker-specific siblings, leaving the routing decision to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

zima_restart_containerA

Restart one named container. Only containers in ZIMA_RESTART_ALLOWLIST are allowed.

ParametersJSON Schema
NameRequiredDescriptionDefault
containerYesContainer name to restart.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full behavioral burden. It usefully discloses the allowlist eligibility constraint, but omits that a restart causes downtime/state loss, whether the call blocks until the container is back up, and how failures are surfaced.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the action front-loaded and the eligibility constraint second. No filler; every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Adequate for a simple one-parameter tool: it says what happens and the eligibility rule. But as an annotation-free mutation tool it leaves the operational consequences of a restart (downtime, blocking behavior, error mode) unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single 'container' parameter is already documented as 'Container name to restart.' The description reinforces the single-named-container constraint but adds no format, naming, or lookup details beyond the schema. Baseline 3 for full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Restart one named container') with unambiguous scope. Against the read-only siblings (zima_docker_ps, zima_top, zima_container_logs), the mutating 'restart' action is immediately distinguishable without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear precondition/exclusion: only containers in ZIMA_RESTART_ALLOWLIST are eligible, which tells the agent when the call will fail. It does not, however, point to any sibling (e.g., zima_container_logs) for diagnosing a container before or after restart.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

zima_topB

Top processes by CPU. Use it to find what is pegging the CPU.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNoHow many processes to show (default 12, max 40).

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden. It implies a read-only inspection but never states that it makes no changes, whether it requires host access, whether sampling is instantaneous vs. averaged, or how results behave under load.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero filler, and the resource definition is front-loaded before the use case. Nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, one-optional-parameter read tool with no output schema, the description is nearly sufficient — the agent knows what it returns conceptually (ranked processes). Only the behavioral/safety framing is thin.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single optional parameter's default (12) and max (40) are documented in the schema. The description adds no further meaning about the count parameter, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource and ordering (top processes by CPU), which is enough to distinguish it from siblings like zima_disk or zima_docker_stats. It does not explicitly differentiate itself from the Docker-oriented siblings, but the host-CPU focus is clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use it to find what is pegging the CPU" gives a concrete trigger scenario, so usage is implied rather than absent. However, it names no alternatives or exclusions (e.g. when to prefer zima_docker_stats for container-level CPU), leaving the agent to infer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updatesv0.1.0
    • First observedzima_container_logs
    • First observedzima_disk
    • First observedzima_docker_ps
    • First observedzima_docker_stats
    • First observedzima_load
    • First observedzima_restart_container
    • First observedzima_top

TDQS

A3.6/5.0

Scored across 7 tools

Disambiguation4/5

Each tool targets a distinct host or container concern (load, CPU, disk, container listing, stats, logs, restart), and descriptions explicitly differentiate the overlapping-looking ones (e.g. docker_ps vs docker_stats, top vs docker_stats). Minor residual overlap between host CPU tools and container CPU tools, but selection is generally clear.

Naming Consistency4/5

All tools share a zima_ prefix and consistent lowercase snake_case, so the set reads as a coherent family. The style is noun-oriented rather than strict verb_noun (load, top, disk, docker_ps), with only restart_container using a verb, but this is a minor deviation rather than confusion.

Tool Count5/5

Seven tools is well-scoped for a host-plus-Docker monitoring server: one per core observation (load, CPU, disk, container list, container stats, logs) plus a single guarded mutation. Nothing feels redundant or missing at the count level.

Completeness4/5

Covers the main diagnostic surface: host load/CPU/disk, container listing/stats/logs, and a safe restart. Gaps include host memory/network metrics and start/stop operations (only restart exists), but an agent can work around these for typical troubleshooting.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Enables AI assistants to manage homelab infrastructure through automated service installation (Jellyfin, Pi-hole, Ollama, Home Assistant, Frigate NVR), VM operations, AI accelerator support (MemryX, Coral TPU, Hailo-8), and Terraform state management with SSH-based discovery and deployment.
    58
    5
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Provides read-only server monitoring and diagnostic tools for AI assistants to manage Linux and Unraid systems via SSH. It enables natural language interactions for container management, storage health checks, and system log analysis while keeping credentials secure.
    17
    ISC
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to manage remote servers via SSH with agentless command execution, file operations, and service management.
    9
    19 PyPI
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to autonomously check, diagnose, and recover Dockerized services through safe, tool-based ops without direct host shell access.
    MIT