Skip to main content
Glama

Docker MCP

PowerShell syntax Static analysis CodeQL License

A deliberately restricted Model Context Protocol (MCP) server for inspecting and maintaining a local Docker Desktop environment without giving the MCP client the raw Docker socket or a general host shell.

It is intended for an AI-assisted local infrastructure stack where the model should be able to answer questions such as:

  • Which containers are running?

  • Which image or Compose deployment is stale?

  • Does this container run as root?

  • Is a newer image available?

  • Which known repository checkout is behind its remote?

  • Can this one allowlisted service be safely restarted or redeployed?

The answer should not require handing the model arbitrary Docker administrator access.

Independent project. This repository is not a fork of docker/hub-mcp or docker/mcp-gateway. It can integrate with Docker MCP Toolkit/Gateway, but the restricted local maintenance layer in this repository is its own implementation.

Why this project exists

Mounting /var/run/docker.sock into a model-facing service is effectively equivalent to granting broad Docker administrator capability. From there, generic container creation or host mounts can become host compromise.

Docker MCP inserts explicit policy boundaries between the MCP client and that socket.

MCP client
   |
   v
Docker MCP server
   |
   v
restricted Docker API proxy
   |
   v
Docker Engine

Only the restricted socket proxy receives the Docker socket. The model-facing MCP container does not.

Windows host operations that cannot safely happen inside the container use a second, separate boundary:

MCP client
   |
   v
Docker MCP
   |
   v
host Maintenance Runner
   |
   +--> exact allowlisted repository alias
   +--> exact allowlisted Scheduled Task alias
   +--> exact allowlisted Compose project/service

The caller supplies an alias or a bounded operation — not an arbitrary path, branch, remote, command line or PowerShell expression.

Related MCP server: local-mcp-toolbox

What it can do

The tool surface has three main jobs.

Area

Examples

Inspection

containers, logs, stats, images, Compose state, deployment drift

Narrow maintenance

fast-forward an allowlisted repo, restart an allowlisted task/container, redeploy an allowlisted Compose target, clean known stale resources

Docker Scout

CVEs, recommendations, SBOM and image comparisons

The repository also includes a small host-side MCP port registry so local services can reserve stable ports instead of independently guessing from the same range.

For runtimes that genuinely require host-side recovery after Docker restarts — for example because credentials live only in tmpfs — an optional event-driven runtime supervisor can invoke preconfigured local recovery scripts. The supervisor itself is not exposed as a generic MCP command surface.

Proposed secure repository tests (not enabled)

A future fixed-profile regression-test tool must not become generic command execution. Its threat model, local-only default, sandbox requirements, source/commit allowlist and negative test gates are specified in the secure test-runner contract. The current server still has no repo_run_tests tool. The public MCP gateway must continue to reject any test-execution tool.

What it deliberately does not expose

The following are intentionally outside the MCP contract:

  • arbitrary docker exec.

  • arbitrary docker run.

  • a general shell or PowerShell runner.

  • raw Docker socket access.

  • arbitrary host filesystem paths.

  • arbitrary Git remotes or branches.

  • arbitrary Compose files/build contexts.

  • generic container deletion.

  • arbitrary Scheduled Task names.

  • arbitrary process arguments.

This is the core design constraint, not an accidental limitation.

Security model

The maintained deployment uses several layers rather than trusting one gateway:

  • the MCP server runs non-root.

  • the model-facing container never receives the raw Docker socket.

  • the restricted proxy exposes only the Docker API operations required by the reviewed tools;

  • container_inspect deliberately omits environment variables and command lines while still exposing fields needed for privilege audits;

  • repository maintenance is fail-closed: exact local root, clean checkout, expected HTTPS GitHub origin, explicitly allowlisted main or master branch, and fast-forward-only update; each branch is pinned in host-only configuration and must match the local checkout;

  • host maintenance resolves aliases from ignored local configuration.

  • public access, when enabled, is authenticated through Cloudflare Access and a reviewed gateway;

  • machine paths, identities, allowlists, Access configuration and credentials remain outside Git.

Local and remote architecture

Local use:

local MCP client
      |
      v
Docker MCP Toolkit / profile
      |
      v
Docker MCP server
      |
      v
restricted socket proxy
      |
      v
Docker Desktop Engine

Optional remote use:

ChatGPT / remote MCP client
      |
      v
Cloudflare Access
      |
      v
authenticated MCP gateway
      |
      v
Docker MCP server
      |
      v
restricted socket proxy
      |
      v
Docker Desktop Engine

The public edge does not replace the local policy boundary; it adds authentication in front of it.

Quick start

Requirements:

  • Windows with Docker Desktop.

  • Docker MCP Toolkit.

  • PowerShell.

  • Docker Engine running.

Install the local profile from the repository root:

Set-ExecutionPolicy -Scope Process Bypass
.\install.ps1
.\test.ps1

The default profile is dockerlocal.

Run the profile locally with Docker MCP Gateway:

docker mcp gateway run --profile dockerlocal

The detailed sections below document the exact tool surface, optional Cloudflare path, host maintenance runner, port registry and runtime supervisor.

Scope

Read-only inspection:

  • containers_list

  • container_inspect — includes the configured container user for privilege audits without exposing environment variables or command lines

  • container_logs

  • container_stats

  • compose_status

  • images_list

  • image_inspect

  • mcp_deployment_audit — checks every running Compose project for Compose files newer than its containers, and additionally compares docker compose config --hash plus desired image for allowlisted projects. This catches both broad file-level drift and exact desired-config drift without a background watcher.

  • image_usage_audit — reports container usage plus repository-level superseded hints; hints are not deletion-safe because unused images can still be Dockerfile build-stage inputs

  • maintenance_job_status

  • maintenance_runner_status

  • port_registry_status — persistent host MCP port reservations plus listeners in the managed range that are not registered

Narrow maintenance:

  • repo_status — HEAD/branch/clean/conflict/origin eligibility for one local allowlisted repository alias

  • repo_pull_ff — exact git pull --ff-only origin main semantics for a clean allowlisted main checkout

  • compose_redeploy(project, operation="sync_upstream") — generic script-backed only action for a separately allowlisted pinned-upstream sync; never calls Docker Compose, does not rebuild or restart anything. The operator must configure handler.operations.sync_upstream: ["-Action", "sync-upstream"] for that project in the host-only maintenance-projects.local.json. For Firecrawl the pre-existing fc.ps1 sync-upstream independently validates a clean checkout, official origin and exact reviewed tag/SHA from upstream/firecrawl.json. No client-supplied tag, branch, Git command, path or script is accepted.

One-time local opt-in for an existing Firecrawl script-backed project (no Git shell access or open-ended command parameters):

# From the Docker-MCP repository after the reviewed update is installed:
.\enable-project-upstream-sync.ps1 -Project firecrawl

This adds only sync_upstream: ["-Action", "sync-upstream"] to the host-only allowlist and refreshes the Maintenance Runner. The caller can then invoke compose_redeploy(project="firecrawl", operation="sync_upstream", services=[]); the existing Firecrawl launcher performs all pin, origin and dirty-tree checks. The operation never calls Compose or restarts Firecrawl. If the host project is not script-backed or its handler lacks a fixed sync action, the opt-in fails closed.

Recommended: one-command, service-only maintenance for Firecrawl

After the one-time local review/opt-in:

.\enable-project-staged-rollout.ps1 -Project firecrawl

ChatGPT can do a bounded, reusable build → Scout security check → stage → deploy → rollback-on-failure operation for a single stateless service in one call:

compose_redeploy(project="firecrawl", operation="update_stateless", services=["api"])

The same action accepts only mcp, playwright-service, browser-session-service, or playwright-public-proxy-service instead of api. Service lists of zero or multiple entries are rejected. The host runner checks a fixed allowlist, uses an exact reviewed fc.ps1 action, and gives image builds a bounded extended time window. Redis, RabbitMQ, PostgreSQL, SearXNG, and non-Firecrawl projects are never eligible. Version bumps still need to enter reviewed GitHub source, and data-bearing upgrades require verified backups and a separate migration plan. No new GitHub PR is needed to rerun this workflow for a newly approved version.

Opt-in isolated staged builds and deployment (script-backed projects only):

compose_redeploy(project="firecrawl", operation="build_only", services=[]) queues the reviewed fc.ps1 build-mcp action. It builds only the Firecrawl MCP image, verifies its immutable image ID and runs Docker Scout's critical/high vulnerability gate before writing a short-lived local receipt. Builds do not recreate containers.

compose_redeploy(project="firecrawl", operation="deploy_staged", services=[]) queues the reviewed fc.ps1 redeploy-mcp action, which fails closed unless the exact image has a fresh (24-hour) scan receipt, reviewed source file hashes still match, and a second critical/high scan passes. It preserves the previous image for rollback, recreates only the MCP service with --no-deps --no-build --force-recreate, verifies its image/running state, and attempts an MCP-only rollback if verification fails.

Neither new operation accepts caller-supplied service names, image references, shell commands, paths, branches or Compose files. No project receives these permissions by default. For the existing reviewed Firecrawl script-backed project, enable the exact two mappings once on Windows after refreshing the DockerLocal runtime and updating the Firecrawl wrapper:

cd C:\ClaudeCode\Docker-MCP
.\refresh-public-runtime.ps1 -Apply
.\enable-project-staged-rollout.ps1 -Project firecrawl

This updates the host-only allowlist and runner, but does not build or deploy a Firecrawl image. The old whole-stack rebuild_and_redeploy remains separate and is not used for a scoped MCP patch. Docker Scout must be available on the Windows host; a scan error, High/Critical CVE or missing receipt blocks release.

  • scheduled_task_status — state for one allowlisted Windows Scheduled Task alias

  • scheduled_task_control — start/stop/restart one allowlisted Windows Scheduled Task alias

  • image_pull

  • container_restart

  • image_prune_dangling

  • cleanup_stale_mcp_containers

  • cleanup_superseded_images — deletes only explicitly supplied local image refs after verifying that no running or stopped container uses the resolved image; multiple aliases must be supplied explicitly and are untagged one by one without force

  • compose_redeploy

Host disk capacity (read-only)

host_disk_usage queries the existing allowlisted Windows maintenance runner for local fixed-volume capacity and available space. The result includes volume letters, total/available/used bytes, used percent and an observation timestamp. It takes no user-controlled path or command, does not inspect file names or credentials, and cannot clean up or resize disks. The MCP gateway and runtime socket-proxy retain their existing restrictions.

Treat measurement_status=unknown or a runner timeout as UNKNOWN, not 0% utilization. The host drive measurement is not the same as Docker's internal WSL2 virtual-disk usage. The daily watch alerts at roughly 80% used only when valid host capacity and available bytes were measured.

Docker Scout:

  • scout_quickview

  • scout_cves

  • scout_recommendations

  • scout_sbom

  • scout_compare

The project intentionally does not expose arbitrary docker exec, docker run, shell access, generic container deletion, arbitrary Compose paths, arbitrary builds, or the raw Docker socket.

Requirements

  • Windows with Docker Desktop

  • Docker MCP Toolkit

  • PowerShell

  • Docker Engine running

Local installation

Clone or download the repository, open PowerShell in the repository root, and run:

Set-ExecutionPolicy -Scope Process Bypass
.\install.ps1

The default Docker MCP profile is dockerlocal. To use another profile:

.\install.ps1 -Profile my-profile

The installer:

  1. builds the restricted Docker API proxy and publishes it on 127.0.0.1:23750 (compose.proxy.toolkit.yaml), because Toolkit-started servers cannot join the proxy's Docker network;

  2. verifies the proxy on loopback;

  3. builds the Docker MCP server image;

  4. installs the local Docker MCP catalog entry, adding the Maintenance Runner control directory bind mount (%LOCALAPPDATA%\DockerLocalMCP\control → /control) to the installed copy only;

  5. adds the server to the selected Docker MCP profile;

  6. enables the server tools and performs tool discovery.

Verify the installation:

.\test.ps1

To run the Docker MCP Gateway locally with this profile:

docker mcp gateway run --profile dockerlocal

For supported local MCP clients, Docker MCP Toolkit can also connect a client to the profile:

docker mcp client connect <client-name> --profile dockerlocal

The exact client names supported by Docker MCP Toolkit depend on the installed Docker Desktop version.

Because of the control-directory mount, every process that runs the gateway for this profile must set MCP_GATEWAY_DOCKER_BIND_ALLOW_WRITABLE_PATHS to that directory; otherwise Docker MCP Gateway refuses to start the server. See docs/CONNECTING.md.

Host port trade-off. The proxy publishes no host port by default: a published port is reachable from every container through host.docker.internal, including containers that fetch untrusted web content. The stdio launcher and the public compose reach the proxy on the dockerlocal_default network instead. Only the Toolkit route above opts in to the port; prefer the stdio launcher when you do not need Docker MCP Toolkit.

Gateway-started containers get random Docker names. For stdio clients that should show up under an identifying name (dockerlocal-stdio-<client>-<pid>), use local-mcp/stdio-launcher.mjs instead; see docs/CONNECTING.md.

Remote connection through Cloudflare Access

The remote path is optional. It is intended for an MCP client that cannot directly reach the local Docker MCP profile.

Use placeholders such as:

Public hostname: docker-mcp.example.com
MCP endpoint:    https://docker-mcp.example.com/mcp
Access team:     team-name.cloudflareaccess.com
Origin target:   http://dockerlocal-gateway:8080

No real hostname, tunnel identifier, account identifier, email address, audience tag, token, or credential belongs in this repository.

1. Start the remote stack

Run:

Set-ExecutionPolicy -Scope Process Bypass
.\install-public.ps1

The installer prompts at runtime for:

  • Cloudflare Access team domain.

  • Access application audience tag.

  • allowed identity email.

Those values are written only to the ignored local file:

public/gateway.env

2. Create the Cloudflare side

In Cloudflare:

  1. create a Tunnel or use an existing Tunnel;

  2. create a public hostname such as docker-mcp.example.com;

  3. point the origin to http://dockerlocal-gateway:8080;

  4. protect the hostname with a Cloudflare Access self-hosted application;

  5. configure the Access policy for the identity that is allowed to use the MCP endpoint.

If cloudflared runs as a Docker container, attach it to the Docker MCP edge network:

docker network connect dockerlocal-public_edge <cloudflared-container>

The public MCP client should then connect to:

https://docker-mcp.example.com/mcp

The included gateway verifies the Cloudflare Access JWT, the configured audience, and the configured identity before forwarding MCP traffic.

See docs/CONNECTING.md for the full local and remote connection flow.

Host-side Compose maintenance runner

The Docker MCP container deliberately does not receive arbitrary host filesystem access. Narrow Compose redeploy operations are therefore delegated to a small Windows runner.

Install it with:

.\install-maintenance-runner.ps1

The runner accepts only:

  • an allowlisted project.

  • an allowlisted service for direct Compose projects.

  • redeploy_current.

  • rebuild_and_redeploy.

By default only this project's own Compose services are allowlisted.

Additional host projects can be configured locally in:

%LOCALAPPDATA%\DockerLocalMCP\maintenance-projects.local.json

Start from maintenance-projects.example.json. The local file is ignored by Git and should not contain secrets. The example includes an avanza-mcp-public entry; replace its placeholder with the local Avanza checkout path to allow safe gateway-only redeploys.

The allowlist is the source of truth for exact desired-Compose hash checks and write maintenance. Separately, the audit performs a read-only file-age check for every running Compose project using Docker's existing Compose labels and the host filesystem. This broad check does not grant redeploy rights. mcp_deployment_audit only performs these checks when called; there is no background reconciliation loop.

Two execution modes are supported:

  • Compose mode: the runner executes only the configured Compose files and allowlisted services.

  • Script-backed mode: the runner invokes one absolute, allowlisted PowerShell .ps1 wrapper with a fixed argument array for the requested operation. This is intended for projects whose wrapper owns required runtime setup such as DPAPI-backed or tmpfs secret injection.

Script-backed projects are whole-project operations: callers must omit the services argument. The local config contains the script path and fixed arguments only; credentials and secret values must remain in the project-specific secret store and must not be copied into the maintenance config. An operation may use an empty argument array when the allowlisted wrapper itself requires no parameters.

Reviewed source-to-runtime promotions (GitHub MCP, Cloudflared, DockerLocal)

The original Compose maintenance tool recreates containers from the installed Compose files. Some locally installed runtimes are copies of the source repo, so a successful repo_pull_ff alone does not update the running image.

One-time host-only registration, under the normal logged-in Windows user:

& 'C:\ClaudeCode\Docker-MCP\enable-runtime-promotions.ps1' -DryRun
& 'C:\ClaudeCode\Docker-MCP\enable-runtime-promotions.ps1'

This extends three exact existing aliases; it preserves all other project allowlists and the built-in DockerLocal project. It does not deploy anything. Stop if an active maintenance job is reported. After registration, ChatGPT can use existing compose_redeploy with operation="redeploy_current" and without services for these script-backed actions:

  • github-mcp-local — runs the already reviewed github-mcp-server/deploy/local-gateway/deploy-runtime.ps1, syncing tracked runtime files and reimporting DPAPI-backed secrets, with backup/rollback.

  • mcp-edge — promotes only the pinned cloudflared tag in dependency-watch/edge-images/Dockerfile, keeps the existing tunnel secret holder and edge network mapping, and calls the secret-aware mcp-edge-runtime.ps1 Up.

  • dockerlocal-runtime-promotion — promotes only the installed DockerLocal public gateway's Node image and tracked JavaScript; never rebuilds or restarts the MCP backend or socket-proxy. Also refreshes the host Maintenance Runner when its trusted source files have changed, without requiring another local installer command.

To update the resident Maintenance Runner after a reviewed source change: fast-forward the clean Docker-MCP checkout with repo_pull_ff, then invoke compose_redeploy with project="dockerlocal-runtime-promotion", operation="redeploy_current", and no service list. This uses the existing local allowlist entry; it does not create a new remote permission. The script skips gateway recreation if its image and JavaScript already match. It requires exactly its own active dispatched maintenance job and no queued or concurrent processing jobs, backs up the currently installed runner files, checks PowerShell syntax, invokes the existing host-only installer, then verifies a new resident runner PID and exact installed source file hashes. The new runner adopts the still-active dispatched worker and retains its result receipt. If installation fails, old runner files are restored and the existing Windows host launcher is invoked. Do not start a second update while the first is running; check its job receipt and runner heartbeat first.

The client cannot provide a path, a version, or a shell command. The host wrapper rejects an unexpected source origin, dirty checkout or non-main branch. The local-only allowlist is backed up before registration, while deployment backups live under %LOCALAPPDATA%\DockerLocalMCP\runtime-promotion-backups. Data-bearing Firecrawl services remain excluded.

Allowlisted Windows host maintenance

The same host-side Maintenance Runner can expose a small Windows maintenance surface without exposing PowerShell or a generic process runner.

The MCP client supplies only an alias. Repository paths, the exact origin URL, the fixed main branch, Scheduled Task names and Task Scheduler paths are resolved from the local-only file:

%LOCALAPPDATA%\DockerLocalMCP\host-maintenance.local.json

Start from host-maintenance.example.json. The real file is covered by *.local.json in .gitignore and must not be committed.

Example shape:

{
  "repositories": {
    "example-repo": {
      "path": "<absolute-path-to-repository>",
      "origin_url": "https://github.com/example/example-repo.git",
      "branch": "main"
    }
  },
  "scheduled_tasks": {
    "example-service": {
      "task_name": "ExampleScheduledTask",
      "task_path": "\\"
    }
  }
}

Repository pulls fail closed unless all of these are true:

  • the configured path is the exact Git repository root.

  • the current branch is main.

  • tracked and untracked status is clean.

  • there are no unresolved index conflicts.

  • the current origin URL exactly matches the local allowlist.

  • the update can complete with --ff-only.

The runner also disables Git hooks and recursive submodule updates for maintenance Git calls, and disables interactive credential prompts. The MCP schema has no path, remote, branch, argument or command-string field.

Scheduled Task lookup is exact after local alias resolution. The remote MCP caller cannot choose a Task Scheduler name/path or PowerShell argument.

The four host-maintenance tools return compact structured JSON. If a bounded synchronous call times out, it returns a job_id that can be inspected with maintenance_job_status.

For the initial activation on an already-installed DockerLocal stack, enable-host-maintenance.ps1 validates one repository and one Scheduled Task, merges them into the local allowlist, preserves the existing Cloudflare gateway configuration, rebuilds the MCP image and restarts the Maintenance Runner. Re-run it with another pair of aliases to extend the local allowlist later.

.\enable-host-maintenance.ps1 `
  -RepositoryAlias example-repo `
  -RepositoryPath C:\path\to\example-repo `
  -ScheduledTaskAlias example-service `
  -ScheduledTaskName ExampleScheduledTask

To allowlist an additional repository without creating a Scheduled Task mapping, use the repo-only helper:

.\add-host-maintenance-repository.ps1 `
  -RepositoryAlias another-repo `
  -RepositoryPath C:\path\to\another-repo

The helper performs the same exact-root, main, and HTTPS GitHub-origin validation, preserves the existing task allowlist, and restarts only the local Maintenance Runner so it reloads the updated configuration.

Host MCP port registry

Local MCP services should not independently guess static ports. Docker MCP installs a small host-side registry at:

%LOCALAPPDATA%\DockerLocalMCP\port-registry.json

The default managed range is 8760–8799. A service reserves a port once through port-registry.ps1 and then reuses that reservation on every normal start. Allocation is protected by a named Windows mutex and an atomic JSON write.

The intended lifecycle is:

first install
  -> request preferred port (optional)
  -> skip ports reserved by another service
  -> skip ports with an unrelated live listener
  -> reserve first safe port
  -> persist mapping

normal start / restart
  -> read the existing service reservation
  -> use exactly that port
  -> if another process owns it, fail closed

Do not automatically move to another port at runtime. Cloudflare ingress, health checks and MCP clients rely on stable local endpoints. Dynamic allocation happens only when a service has no reservation yet.

For migration of an already-running service, the helper can adopt a listening port only when the installer supplies an expected command-line fragment and the listener owner matches it. This is for local installer use; the remote Docker MCP surface exposes only port_registry_status, never an arbitrary process/command matching primitive.

The allocator also inspects Docker's configured host-port bindings, including stopped containers. A Docker-backed service therefore keeps its host port protected even while its container is down; another MCP cannot claim the port during that outage.

The read-only status tool reports both Docker-configured host ports and live listeners inside 8760–8799 that are not yet in the registry. This makes legacy/manual allocations visible before they create another collision.

Existing non-Docker services can be seeded once with the local-only helper:

.\reserve-mcp-port.ps1 -Service example-http -PreferredPort 8765 -AdoptIfCommandContains "expected-process-fragment"

The command-line fragment is checked only on the host during migration and is not exposed through the remote MCP surface.

Event-driven local runtime supervisor

Some local MCP runtimes intentionally keep credentials only in ephemeral container storage such as tmpfs. Those credentials disappear when Docker Desktop or the container is restarted. Requiring a user to rerun a bootstrap script after every Docker restart defeats the purpose of a resilient local runtime.

Docker MCP therefore includes an optional host-side runtime supervisor. It is event-driven rather than a fixed polling watchdog:

Windows logon
  -> Runtime Supervisor
  -> Docker events
  -> relevant container start / restart / health change
  -> runtime health check
  -> allowlisted local recovery script

When Docker Engine itself disappears, the supervisor waits. When Docker becomes available again it subscribes to the Docker event stream before the initial reconciliation pass, so container events that occur during a longer recovery are buffered rather than lost. While idle it refreshes only its local heartbeat state; it does not query healthy containers every few minutes.

The supervisor contains no credentials and is not exposed as an MCP tool. It only invokes PowerShell scripts explicitly listed in the trusted local configuration file:

%LOCALAPPDATA%\DockerLocalMCP\runtime-supervisor.local.json

The configuration can define one or more container health checks per runtime: whether each named container is running, whether Docker reports it as healthy, and whether expected ephemeral files still exist inside it.

Recovery is restricted to an absolute local .ps1 file plus an argument array. There is no inline shell-command field. Recovery scripts are launched as isolated child PowerShell processes so Docker/Compose progress written to stderr cannot be mistaken for a supervisor failure. recovery_wait_seconds controls the bounded post-recovery health wait for runtimes that need a few seconds to become healthy.

Start with:

Copy-Item .\runtime-supervisor.example.json "$env:LOCALAPPDATA\DockerLocalMCP\runtime-supervisor.local.json"

Edit only the local copy to point at runtimes that genuinely need post-restart recovery, then install:

.\install-runtime-supervisor.ps1

The installer registers DockerLocalRuntimeSupervisor at Windows logon. By default it uses a tiny Windows Script Host wrapper so the long-running supervisor stays completely backgrounded even when Windows Terminal is the system's default console host. Pass -Visible only for foreground troubleshooting. The process remains attached to docker events; polling is used only while Docker Engine is unavailable so it can reconnect. Start/restart events use a short startup grace period for health-only runtimes, while tmpfs-file checks remain fast. Healthy healthcheck events are ignored so normal startup cannot create a recovery feedback loop.

Do not add a runtime merely because it is Dockerized. Persistent .env configuration and ordinary Docker restart policies do not need this supervisor. It is intended for runtimes with a real host-side recovery step, especially ephemeral secret rehydration.

Secret handling

Do not commit:

  • public/gateway.env.

  • .env files.

  • API keys, tokens, passwords, Access audience values, or identity allowlists.

  • maintenance-projects.local.json.

  • runtime logs, heartbeats, or maintenance job files.

Dependency and security automation

This repository includes:

  • Dependabot version updates for Python, Dockerfiles, Docker Compose and GitHub Actions.

  • CodeQL analysis for Python, JavaScript/TypeScript and GitHub Actions.

  • GitHub Dependabot vulnerability alerts through the repository's security settings.

License

MIT. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables AI assistants to interact with Docker containers through safe, permission-controlled access to inspect, manage, and diagnose containers, images, and compose services with built-in timeouts and AI-powered analysis.
    -
  • A
    license
    A
    quality
    A
    maintenance
    A secure, local-first MCP server for read-only inspection and troubleshooting of development environments, exposing narrow, typed, auditable capabilities for repository inspection, log summarization, Docker review, and security scanning without granting unrestricted machine access.
    8
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to inspect and operate Docker environments managed by DockHand via a security-first, profile-gated subset of DockHand's REST API, with redacted output and human approval for destructive actions.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables local LLM agents to inspect Docker containers and optionally perform guarded restarts through MCP, with read-only defaults, credential redaction, canonical ID checks, denylists, and bounded daemon timeouts. It provides secure, zero-trust Docker daemon access for MCP clients.
    109
    MIT