Skip to main content
Glama
tyler-rich

dockhand-mcp

by tyler-rich

dockhand-mcp

License: Apache-2.0 Latest release

A security-first Model Context Protocol server for DockHand. It lets MCP clients (Claude Code, Claude Desktop, the MCP Inspector, any client that can send a header) inspect and operate the Docker environments DockHand manages, through DockHand's REST API only, and never through the Docker socket.

Why: an AI client that can manage containers is useful, and dangerous if it can do everything DockHand can. dockhand-mcp exposes a curated, profile-gated subset of DockHand's API: the whole server is designed around what a prompt-injected model must not be able to do.

Status: early (v0.1.x). Built and tested against DockHand's API 1.0.46. Before 1.0, tool names, arguments, results and configuration can change in a minor release; each release's notes list what changed, so pin the image by digest and read them before upgrading. Tools whose DockHand response shape is not documented are marked experimental in docs/TOOLS.md. OAuth, which Claude.ai custom connectors need, is not available yet (CLIENTS §4).

Security posture

  • Profiles. read-only (the server's default), operator (plus reversible writes: start, stop, deploy, compose and .env edits verified by reading them back) and admin (plus destructive tools). Tools above the profile are never registered, so no client can list or call them. The profile is set by the server's configuration, never by the client.

  • Excluded tier. Whole API families are out in every profile, permanently: credentials and tokens, users and roles, in-container exec and file access, the DockHand host filesystem, secret providers, image export, self-update, webhooks (SECURITY §4).

  • Human-approved destructive actions. Every remove, prune, stack down and delete needs a human approval: an elicitation form bound to the exact call where the client supports it, otherwise an explicit confirm (weaker: see Confirm mode and approvals). Destructive calls are also rate-limited per client.

  • Output redaction. DockHand's answers pass one redactor before they reach the model: credential-shaped keys, tokens and URL credentials, and each stack's own variable values in its operation output (SECURITY §2).

  • Guardrails on compose writes. Privileged containers, host-namespace modes, dangerous capabilities and bind mounts of /, the Docker socket, /etc and similar are refused before anything is written.

  • No socket, no shell, no host mounts. The server is a plain HTTP client of DockHand. It runs as a non-root, read-only, capability-free container.

  • Authenticated before anything. Bearer-token auth on every MCP request, including tool listing, with rate limits and DNS-rebinding protection.

  • Scanned and signed image. Each release image is scanned with OSV-Scanner for both platforms before it is pushed, signed keylessly with cosign, and published with a CycloneDX SBOM; the published image is rescanned weekly.

  • Fail-closed startup. An invalid or insecure configuration, or a missing DockHand token when DockHand requires one, stops the server with a one-line reason instead of starting it.

Design and threat model: docs/SECURITY.md. Locked decisions: plan.md.

Related MCP server: Docker-MCPilotS

Quick start (Docker Compose)

You need a DockHand API token first: docs/DOCKHAND-SETUP.md walks through the dedicated user, the Enterprise role or the Free-edition warning, and the token.

  1. Copy deploy/docker-compose.yml into a new directory. Its image: line is a placeholder, ghcr.io/tyler-rich/dockhand-mcp:X.Y.Z@sha256:<digest>: replace it with the exact pinned image: line from the latest GitHub release notes, and set DOCKHAND_URL and DOCKHAND_MCP_ALLOWED_HOSTS.

  2. Create the two token files. The DockHand token file is required: without it the server won't start (unless DockHand runs with authentication off).

    mkdir -p secrets && chmod 700 secrets
    $EDITOR secrets/dockhand_token        # paste the dh_ token
    python -c "import secrets;print(secrets.token_urlsafe(48))" > secrets/mcp_token
    chmod 600 secrets/* && sudo chown 10001:10001 secrets/*   # the container runs as UID 10001
  3. Check, then start:

    docker compose run --rm dockhand-mcp check
    docker compose up -d
    docker compose ps          # dockhand-mcp should become "healthy"
  4. Connect a client with the token in secrets/mcp_token: docs/CLIENTS.md.

The reference compose runs profile operator: switch to admin only while you need destructive tools. If the container keeps restarting, its last log line says why: troubleshooting. Other ways to run it: deploy/docker-run.md (plain Docker), deploy/dockhand-stack.yml (DockHand or Portainer stack editors), stdio for Claude Desktop (CLIENTS §3).

Verify the image signature before you deploy it; each release's notes carry the exact cosign verify line.

WARNING

Keep secrets out of compose files. dockhand_get_stack_compose returns compose files as they are, so that they can be edited; a literal password in a compose file reaches the model. Keep secrets in the stack's environment or DockHand's secret variables and reference them as ${NAME}. More.

WARNING

Never point two DockHand environments at one Docker daemon. Each would list the other's stacks, duplicates become possible, and compose down through one removes the other's containers. The server guards what it can, and dockhand-mcp check warns when it detects a shared daemon. More.

Configuration

Every setting is an environment variable; *_FILE reads the value from a file, for example a Docker secret. deploy/.env.example lists them all with their defaults.

Variable

Default

Notes

DOCKHAND_URL

(required)

e.g. https://dockhand.example.test. Must be absolute; scheme https unless DOCKHAND_ALLOW_HTTP=true.

DOCKHAND_ALLOW_HTTP

false

Boolean (true/false, 1/0, yes/no, on/off). When not true, an http:// DOCKHAND_URL fails startup.

DOCKHAND_TOKEN / DOCKHAND_TOKEN_FILE

(required unless DockHand auth is disabled — see SECURITY §6)

dh_ API token of a dedicated DockHand user.

DOCKHAND_CA_BUNDLE

—

PEM path for private CAs.

DOCKHAND_TLS_INSECURE

false

Disables verification. WARN at startup.

DOCKHAND_DEFAULT_ENVIRONMENT_ID

—

Makes environment_id optional in tools.

DOCKHAND_MCP_PROFILE

read-only

read-only / operator / admin.

DOCKHAND_MCP_DISABLE_TOOLS

—

Comma list of tool names to remove.

DOCKHAND_MCP_TRANSPORT

http

http / stdio.

DOCKHAND_MCP_BIND / DOCKHAND_MCP_PORT

127.0.0.1 / 8080

Compose sets bind to 0.0.0.0 inside the container.

DOCKHAND_MCP_PATH

/mcp

DOCKHAND_MCP_AUTH_MODE

bearer

bearer / oauth (Phase 5) / none.

DOCKHAND_MCP_TOKEN / DOCKHAND_MCP_TOKEN_FILE

(required in bearer mode)

≥ 32 bytes of entropy enforced (min length 43 base64url chars).

DOCKHAND_MCP_ALLOW_UNAUTHENTICATED

false

Required to be true for AUTH_MODE=none over HTTP; additionally bind must be loopback.

DOCKHAND_MCP_ALLOWED_HOSTS

localhost,127.0.0.1

Host-header allow-list (DNS rebinding). Add your public hostname.

DOCKHAND_MCP_ALLOWED_ORIGINS

(empty = no browser origins)

Origin allow-list.

DOCKHAND_MCP_TRUST_PROXY

false

Honour X-Forwarded-For for rate limiting.

DOCKHAND_MCP_RATE_LIMIT_PER_MIN

120

Per client IP.

DOCKHAND_MCP_DEFAULT_TIMEOUT / _MAX_TIMEOUT

60 / 300

Seconds, for wait=true.

DOCKHAND_MCP_LOG_LEVEL / _LOG_FORMAT

info / json

DOCKHAND_MCP_GUARDRAILS

strict

strict / warn (findings returned but not blocking) — off does not exist.

DOCKHAND_MCP_GUARDRAIL_ALLOW_BIND

—

Comma list of extra bind-mount source prefixes to allow (SECURITY §5). The non-configurable deny set can never be allowed. Implemented in S3a; parsed and validated from S0.

DOCKHAND_MCP_CONFIRM_MODE

auto

auto / elicitation / param (D-006, auth/approval.py). auto: elicitation when the request declares form elicitation on MCP 2026-07-28, else confirm; elicitation: refuse destructive calls otherwise; param: always confirm. 2025-11-25 requests never elicit (§7).

DOCKHAND_MCP_CHALLENGE_KEY / _FILE

(random per process)

HMAC key for elicitation challenges. Optional: if unset, a random 32-byte key is generated at startup (challenges then don't survive a restart, which is fine at a 120 s lifetime). If set, ≥ 32 bytes.

DOCKHAND_MCP_DESTRUCTIVE_PER_MIN

10

Per-principal destructive-call rate limit (S-11). Every destructive tools/call counts, the approval round included, and is checked before the preview. Over the limit: not_available.

DOCKHAND_MCP_I_UNDERSTAND_ADMIN_OVER_INSECURE_TLS

false

Deliberately ugly escape hatch; see SECURITY §6.

DOCKHAND_MCP_RESOURCE_URL and DOCKHAND_MCP_OAUTH_*

—

Phase 5 only. Not parsed before the OAuth implementation session; listed so the names are reserved.

Tools

96 tools in three tiers, each registered only in the profiles that include its tier:

Tier

Profiles

Tools

Examples

read

read-only, operator, admin

50

environments, containers (list, inspect, logs, stats), stacks (list, compose, .env, deploy runs), images, volumes, networks, jobs, host and system, activity, audit (Enterprise), schedules, updates, vulnerabilities, registries, git

operator

operator, admin

36

container and stack lifecycle, compose and .env edits with read-back verification, create stack with guardrails, image pull, tag and scan, volumes, networks, schedules, git sync and deploy, batch start/stop/restart

destructive

admin

10

remove container, image, volume or network; stack down and delete; prune; batch remove; run image prune now; clear activity log

The full catalogue, with each tool's DockHand endpoints and permissions: docs/TOOLS.md. dockhand-mcp tools prints the catalogue of the running version (names, descriptions, schema hashes) so you can diff it between upgrades.

License

Licensed under the Apache License, Version 2.0. See LICENSE and NOTICE. Some third-party dependencies carry their own licenses; each release's SBOM lists them.

Contributing

Contributions are welcome under the same license: per Section 5 of the Apache License 2.0, any contribution you intentionally submit is licensed under its terms, with no additional terms or conditions. How to propose a change: CONTRIBUTING.md. Report security issues privately: SECURITY.md.


Not affiliated with or endorsed by DockHand. DockHand is a trademark of its respective owner.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables secure Docker command execution from isolated environments like containers through MCP protocol. Provides tools for managing Docker containers, images, and Docker Compose services with security validation and async operation support.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to manage Docker containers through a secure MCP interface, supporting container lifecycle operations, log inspection, resource monitoring, and system diagnostics with role-based access control.
    3
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Governed Docker + Portainer container-host operations (non-Kubernetes) — restart-loop, resource-pressure, and image/volume-bloat RCA, with guarded lifecycle writes, unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.
    38
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    Read-only MCP adapter for the Dockhand REST API, enabling secure querying of container environments, networks, stacks, and runtime status via STDIO or authenticated HTTP.
    8
    -