Skip to main content
Glama

dockerlint-mcp

An MCP server that lets an AI lint and explain Dockerfiles and docker-compose files statically: rule IDs, severities, line numbers and a concrete fix for every finding. It never builds or runs anything, needs no Docker daemon and no external binary.

How it differs from what exists. The Dockerfile-lint MCP servers I could find (Docker CI Lint MCP, and hosted linters on Apify) wrap a single linter or a hosted service, and Hadolint-based setups need the hadolint binary. This server is pure Python (mcp + pyyaml), runs fully offline, and covers the whole build context in one place: Dockerfile rules, compose rules, .dockerignore matching that follows Docker's real rules (and checks it against what your COPY lines need), layer/cache-order analysis, multi-stage rewrite proposals, and a unified-diff preview of the safe automatic fixes. Secret values are never echoed back to the model, and file access is sandboxed to one directory.

Install

Claude Code:

claude mcp add dockerlint -- uvx dockerlint-mcp --dir .

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "dockerlint": {
      "command": "uvx",
      "args": ["dockerlint-mcp", "--dir", "C:\\path\\to\\your\\project"]
    }
  }
}

Without uv: pip install dockerlint-mcp, then run dockerlint-mcp --dir /path/to/project.

Flag

Meaning

--dir PATH

Only files inside this directory can be read (default: the current directory).

--disable IDS

Comma-separated rule ids to turn off, e.g. --disable DL1013,DC2008. Repeatable.

You can also silence a single finding in the file itself with a comment on the line above:

# dockerlint-ignore: DL1003, DL1005
RUN apt-get update

In compose files, put the comment above a line, or above a service name to cover the whole service. In a .dockerignore, # dockerlint-ignore: DI3002 anywhere turns that rule off for the file.

Related MCP server: mcp-zen-of-languages

Tools

Tool

What it does

dockerfile_overview(path)

Stages with base image tag/digest, layer count, exposed ports, final user, workdir, ENTRYPOINT/CMD (exec vs shell form), COPY --from edges.

lint_dockerfile(path)

28 rules (DL1001-DL1028). Each finding: rule id, severity, instruction line, explanation, concrete fix.

explain_layers(path)

Which instructions create layers, heuristic size hints, and ORDER problems that bust the cache or bloat the image.

lint_compose(path)

13 compose rules (DC2001-DC2014) with line numbers.

check_dockerignore(path)

Missing file, patterns that do not exclude .git / node_modules / .env, nested directories the root-anchored patterns miss, and patterns that exclude files your COPY needs.

suggest_multistage(path)

A multi-stage rewrite as text for common Python, Node, Go and Rust patterns. Never writes a file.

fix_preview(path)

Unified diff of the safe automatic fixes. Never writes a file; lists what needs a manual change.

path is a file (or a directory containing a Dockerfile), relative to --dir or absolute inside it. The line number of a Dockerfile finding is the first line of the instruction.

Try asking

  • "Lint the Dockerfile and fix everything that is safe, then show me what is left."

  • "Why does my Docker build re-install dependencies on every code change?" (explain_layers)

  • "Is my .dockerignore protecting me? Does it exclude anything my COPY lines need?"

  • "Review docker-compose.yml for anything dangerous before I deploy it."

  • "Turn this single-stage Python Dockerfile into a multi-stage one."

  • "Which layers make my image big?"

Rules

ID

Severity

Rule

DL1001

warning

base image has no version tag or digest

DL1002

warning

base image uses the :latest tag

DL1003

warning

apt-get update without install in the same RUN

DL1004

warning

apt-get install without --no-install-recommends

DL1005

warning

apt package lists are left in the layer

DL1006

warning

pip install without --no-cache-dir

DL1007

warning

container runs as root

DL1008

warning

ADD used where COPY would do

DL1009

warning

COPY . before installing dependencies busts the build cache

DL1010

error

secret stored in ENV or ARG

DL1011

error

secret in a RUN / COPY / other instruction

DL1012

warning

piping curl/wget into a shell

DL1013

info

no HEALTHCHECK

DL1014

warning

shell-form ENTRYPOINT/CMD (signals are not forwarded)

DL1015

warning

multiple CMD / ENTRYPOINT / HEALTHCHECK in one stage

DL1016

warning

WORKDIR is not an absolute path

DL1017

warning

cd inside RUN

DL1018

warning

sudo inside a Dockerfile

DL1019

warning

world-writable permissions (chmod 777)

DL1020

warning

package manager cache is left in the layer (apk, yum, dnf)

DL1021

warning

COPY would send node_modules or .git into the image

DL1022

error

COPY --from refers to an unknown or later stage

DL1023

error

duplicate stage name

DL1024

error

package install without a non-interactive flag (-y)

DL1025

warning

apt-get upgrade makes the build non-reproducible

DL1026

warning

apt CLI used in a script; use apt-get

DL1027

info

MAINTAINER is deprecated

DL1028

error

Dockerfile syntax problem

DC2001

warning

compose image has no version tag

DC2002

warning

compose image uses :latest

DC2003

error

privileged container

DC2004

warning

host network mode

DC2005

error

docker.sock mounted into a container

DC2006

error

secret in environment

DC2007

info / warning

published port binds all interfaces (warning for databases and caches)

DC2008

info

no restart policy

DC2009

info

no healthcheck

DC2010

info

depends_on without a health condition

DC2012

warning / error

broad host directory bind mount (/ is an error)

DC2013

info

obsolete top-level version: key

DC2014

error

env_file does not exist

DI3001

warning

no .dockerignore

DI3002

warning

.dockerignore does not exclude .git

DI3003

warning

.dockerignore does not exclude node_modules

DI3004

warning

.dockerignore does not exclude .env files

DI3005

error

.dockerignore excludes a file the Dockerfile copies

DI3006

info

node_modules/.git in a subdirectory is not excluded

How it works and what it cannot know

  • The Dockerfile parser is hand-written: parser directives, line continuations (with comments and blank lines inside), heredocs, JSON vs shell form, --mount/--chown/--from flags, ONBUILD, multi-stage names, and ARG/ENV expansion in FROM/WORKDIR.

  • Rules look at parsed commands, not raw text, so echo "apt-get update" is not a finding.

  • The build context is assumed to be the Dockerfile's directory. If you build with a different context (docker build -f docker/Dockerfile .) the context-dependent checks (DL1021, check_dockerignore) are looking at the wrong directory.

  • Sizes in explain_layers are heuristics from the commands, not measurements.

  • A base image that already runs unprivileged (for example a custom image) looks like root to DL1007; silence it with # dockerlint-ignore: DL1007.

  • Compose findings are located by scanning the YAML text; if a key cannot be found the finding points at the service line. Only a single file is read (no extends, include, or -f merging, no .env interpolation).

Security

  • Read-only and static. Nothing is built, run, pulled or written. suggest_multistage and fix_preview return text; applying it is up to you.

  • Directory sandbox. Every path is resolved (symlinks included) and must stay inside --dir; .. traversal, absolute paths outside it and symlink escapes are refused. env_file paths that point outside it are reported without being probed.

  • Secrets are never echoed. Findings name the variable (DB_PASSWORD) or the kind of secret ("GitHub token"), not its value. Instruction text shown by dockerfile_overview, explain_layers and fix_preview is redacted the same way. (The file on disk is of course unchanged.)

  • Safe parsing. Compose files are loaded with yaml.safe_load only; files over 2 MB are refused; nested or alias-heavy YAML cannot make the server expand data without bound.

  • The server makes no network requests.

Development

uv sync --extra test
uv run --python 3.12 pytest
uv run ruff check src tests
uv run mypy --strict src

The tests use real files in temporary directories and launch the installed server over stdio. The corpus in tests/corpus/good holds 16 realistic Dockerfiles that must produce zero findings.

There is a build-it-yourself tutorial in dockerlint-mcp-the-hard-way.

MIT licensed.

Available Tools

7 tools
check_dockerignoreA

Check the .dockerignore for a Dockerfile (or a directory): missing file, patterns that do not exclude .git, node_modules or .env files, nested node_modules the root-anchored patterns miss, and patterns that exclude files the Dockerfile COPYs (the build would fail or silently omit them). Uses Docker's matching rules (root-anchored, last match wins, ** crosses dirs).

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations supplied, the description carries the full burden and largely succeeds: it names the matching semantics used (root-anchored, last match wins, ** crosses dirs) and explains the real consequence of a bad ignore file ("the build would fail or silently omit them"). What it does not state is whether the tool is purely read-only and whether a missing path is reported as a finding or an error.

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?

One dense sentence front-loads the resource and the failure modes, then a second sentence supplies the matching rules. Every clause carries information, though the parenthetical list is long enough that a reader must parse carefully; a short bulleted breakdown would scan faster.

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

Completeness5/5

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

An output schema exists, so return values need no explanation, and the description covers the check surface, the matching semantics, and the stakes of a bad result. For a single-parameter read-check tool this is effectively complete.

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 0% — the only parameter is titled "Path" with no description. The description partly compensates by clarifying that the path may be a Dockerfile or a directory, which is genuinely useful disambiguation, but it does not say whether relative paths are resolved from cwd or how a directory is located/disambiguated.

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 ("Check the .dockerignore") and enumerates exactly the four classes of problem it detects: missing file, missing .git/node_modules/.env exclusions, nested node_modules missed by root-anchored patterns, and patterns that exclude COPY'd files. This is clearly distinct from siblings like lint_dockerfile or dockerfile_overview, which operate on the Dockerfile itself.

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?

The description implies the context of use ("for a Dockerfile (or a directory)") and hints at the build-failure consequence that motivates running it, but it never states when to prefer this tool over lint_dockerfile or fix_preview, nor any prerequisites. Usage is inferable rather than directed.

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

dockerfile_overviewA

Summarize a Dockerfile: stages with base images (tag/digest), layer count, exposed ports, final user, workdir, and ENTRYPOINT/CMD (exec vs shell form). Start here to understand a file before linting it. path is a Dockerfile or a directory containing one.

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

No annotations are supplied, so the description carries the full burden; it discloses that the operation is a read-only summarization over a local file and lists the specific artifacts returned, including the exec-vs-shell-form distinction. It does not discuss failure modes (e.g., path not found, file that is not a Dockerfile) or permission expectations, which is a modest gap for an inspection tool.

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?

Three sentences with a clean progression: what is produced, when to reach for it, then how to call it. The field enumeration is dense but every item listed is a distinct output the agent would otherwise have to discover, and nothing is redundant with the schema or annotations.

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?

An output schema exists, so the description is not required to document return values, yet it usefully summarizes them anyway; the sole parameter is fully explained. The remaining gap is that it does not clarify how this differs from explain_layers, the closest sibling, which an agent would have to infer.

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?

Schema coverage is 0% — the schema only declares `path` as a string with no description — so the sentence "`path` is a Dockerfile or a directory containing one" is genuinely load-bearing, telling the agent that a directory is acceptable and that discovery happens internally. It does not cover relative-vs-absolute resolution or symlink behavior, so not a perfect 5.

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?

The description opens with a specific verb and resource ("Summarize a Dockerfile") and then enumerates exactly what is extracted: stages with base images, layer count, exposed ports, final user, workdir, and ENTRYPOINT/CMD with exec vs shell form. This is enough to distinguish it from lint_dockerfile, explain_layers, and suggest_multistage without opening any 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?

It gives explicit sequencing guidance: "Start here to understand a file before linting it," which positions it relative to lint_dockerfile as a prerequisite step. It does not explicitly say when to prefer explain_layers or suggest_multistage instead, so sibling differentiation is only partially covered.

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

explain_layersA

Explain which Dockerfile instructions create image layers, with heuristic size hints (small/large and why), and list ORDER problems that invalidate the build cache or bloat the image (COPY . before dependency install, cleanup in a later layer, recursive chown after COPY, volatile build args before expensive steps). Sizes are estimates; nothing is built.

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does meaningful work: 'Sizes are estimates' sets accuracy expectations and 'nothing is built' discloses that the tool is a safe, side-effect-free static analysis. It also enumerates the specific defect classes it reports, so the agent knows what the output covers; it does not discuss error behavior for a missing/invalid path.

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?

One dense sentence, front-loaded with the core purpose before the heuristic and order-problem details. The four-item parenthetical is long but each example earns its place by concretizing what 'ORDER problems' means; a brief split into two sentences would read slightly better.

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?

An output schema exists, so return values need not be described, and the description adequately covers scope, accuracy caveats, and defect classes for a single-input analysis tool. The remaining gap is practical: no indication of what 'path' should contain or what happens when it does not resolve to a Dockerfile.

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

Parameters2/5

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

Schema description coverage is 0% for the single required parameter 'path', and the description never mentions it or says whether it points to a Dockerfile, a directory, or a build context. The one parameter the agent must supply is left entirely to inference, which is the opposite of compensating for the schema gap.

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 opens with a specific verb and resource: 'Explain which Dockerfile instructions create image layers,' and adds two concrete outputs (heuristic size hints and ORDER problems). That is clearly distinct from dockerfile_overview or lint_dockerfile in framing, but it never explicitly names an alternative, and 'list ORDER problems' overlaps enough with lint_dockerfile that an agent might hesitate between the two.

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?

Usage is only implied: the listed pathologies (COPY . before dependency install, cleanup in a later layer, recursive chown after COPY, volatile build args) suggest when the tool is valuable, and 'nothing is built' signals a static-analysis context. There is no explicit when-to-use/when-not statement and no routing away from lint_dockerfile or fix_preview, so the agent must infer the choice.

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

fix_previewA

Show a unified diff of the safe automatic fixes for a Dockerfile (add -y and --no-install-recommends to apt-get install, --no-cache-dir to pip, --no-cache to apk, apt -> apt-get, ADD -> COPY, shell-form CMD -> exec form, MAINTAINER -> LABEL, apt lists cleanup). Never writes the file: apply the diff yourself. Lists the findings that need manual changes.

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations supplied, the description carries the full burden and mostly succeeds: it explicitly declares the tool is non-mutating ('Never writes the file') and describes exactly which transformations will appear in the diff. It also discloses a secondary output (findings that need manual changes), though it does not cover failure behavior, e.g. what happens if path does not exist or is not a Dockerfile.

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?

The non-mutation guarantee is stated up front and the fix list is compactly parenthesized. The enumeration is long but each item earns its place by telling the agent what the diff will contain; only slight tightening would improve it.

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 single-argument tool with an output schema, the description covers purpose, mutation safety, and output nature (diff plus manual findings) adequately. The one material hole is the ambiguity of 'path', which is unaddressed in both schema and description.

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?

Only one parameter exists, 'path', and the schema gives it zero description coverage. The description never clarifies whether it is a path to a Dockerfile, to a directory, or to a compose/Dockerfile pair, so it adds no meaning beyond the bare schema field.

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: it shows a unified diff of safe automatic fixes for a Dockerfile, and enumerates the exact fix categories (apt-get flags, ADD->COPY, MAINTAINER->LABEL, etc.). The scope is unmistakable, but it never names or contrasts itself with the closest sibling, lint_dockerfile, which also reports Dockerfile problems.

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?

The description implies the workflow ('Never writes the file: apply the diff yourself') and hints at a two-stage process by saying it also lists findings needing manual changes. However, it gives no explicit when-to-use versus lint_dockerfile or when-not guidance, leaving the agent to infer that lint_dockerfile diagnoses and fix_preview produces a patch.

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

lint_composeA

Lint a docker-compose / compose.yaml file (rule IDs DC2001-DC2014): unpinned or :latest images, privileged, host network, docker.sock mounts, secrets in environment (values never echoed), ports published on all interfaces, missing restart/healthcheck, depends_on without a condition, broad bind mounts (/, home), obsolete version: key, and env_file paths that do not exist. Uses yaml.safe_load only. Suppress with # dockerlint-ignore: DC2008 above a line or service.

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does meaningful work: it states that secret values are never echoed, that parsing uses yaml.safe_load only (no execution risk), and that findings can be suppressed via a '# dockerlint-ignore: DCxxxx' comment. It does not describe failure behavior for a missing or unreadable path, which is the remaining gap.

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?

The verb and resource are front-loaded, and the long rule enumeration is genuinely scoping information rather than filler, followed by a compact suppression hint. It is dense but every clause carries content; only the rule list could arguably be trimmed.

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?

An output schema exists, so return values need not be explained, and the description covers safety posture, rule coverage, and suppression. What is missing is the meaning of the required 'path' argument and any error-handling note, which matters for a single-required-param tool.

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

Parameters2/5

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

Schema description coverage is 0% — the single 'path' parameter has no description in the schema — and the tool description never clarifies it either. An agent cannot tell whether 'path' means the compose file itself or a directory to scan, nor whether relative or absolute paths are accepted, so the description fails to compensate for the coverage gap.

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?

The description opens with a specific verb and resource ('Lint a docker-compose / compose.yaml file') and then enumerates the exact rule set (DC2001-DC2014) it applies. This makes it immediately distinguishable from the sibling 'lint_dockerfile', which targets a different artifact.

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?

The scope is clearly bounded to compose.yaml files and the enumerated checks tell an agent what situations the tool covers, so the choice versus lint_dockerfile is inferable from the resource named. It stops short of explicitly stating when not to use it or naming alternatives, which keeps it out of 5 territory.

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

lint_dockerfileA

Lint a Dockerfile with 28 rules (IDs DL1001-DL1028). Each finding has a rule ID, severity (error/warning/info), the line of the instruction, an explanation, and a concrete fix. Covers unpinned/latest tags, apt/pip/apk/yum hygiene, root user, ADD vs COPY, COPY-before-install cache busting, secrets in ENV/ARG/RUN (values are never echoed), curl|sh, HEALTHCHECK, shell-form CMD/ENTRYPOINT, WORKDIR, sudo, chmod 777 and COPY of node_modules/.git. Suppress with # dockerlint-ignore: DL1003 above an instruction. Never builds anything.

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations supplied, the description carries the full burden and does well: it discloses 'Never builds anything' (a clear safety/read-only signal), that secret values are never echoed, and that findings include severity and a concrete fix. It stops short of stating failure modes, e.g. behavior on a missing/non-Dockerfile path.

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?

Front-loaded with purpose and scale, then a dense rule summary and the suppression mechanism. The long rule enumeration earns its place by telling the agent exactly what classes of findings to expect, though it could be trimmed slightly.

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

Completeness5/5

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

An output schema exists, so return values need not be re-explained, and the description still summarizes finding structure (rule ID, severity, line, explanation, fix). Combined with the safety note and suppression syntax, an agent has everything needed except explicit `path` semantics.

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 0% and the single `path` parameter is never described — it is ambiguous whether it expects a Dockerfile file path or a directory containing one. The verb 'Lint a Dockerfile' weakly implies a file path, so some meaning leaks through but not enough to compensate for the coverage gap.

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 ('Lint a Dockerfile') plus concrete scope ('28 rules, DL1001-DL1028'), which cleanly separates it from the sibling lint_compose. An agent can identify this as the Dockerfile-specific linter 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 Guidelines3/5

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

Usage is implied by the resource name, and the description usefully documents the in-file suppression syntax (`# dockerlint-ignore: DL1003`). However, it never states when to prefer this over siblings like fix_preview or suggest_multistage, nor any prerequisites or exclusions.

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

suggest_multistageA

Propose a multi-stage rewrite of a single-stage Dockerfile as TEXT (never writes a file). Recognizes common Python, Node, Go and Rust patterns and reuses your base image version, workdir, ports and CMD/ENTRYPOINT. Explains what moves to the build stage and why the final image shrinks.

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations, the description carries the full load and does well: it declares a non-mutating contract ('never writes a file'), describes what is preserved from the original (base image version, workdir, ports, CMD/ENTRYPOINT), and says it explains what moves to the build stage. It omits failure behavior for already-multi-stage or unrecognized files.

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?

Three sentences, front-loaded with the output contract, then capability, then value. Every sentence carries information; the ecosystem list is slightly padded but genuinely useful for deciding applicability.

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?

An output schema exists, so return values need no explanation. For a one-parameter read-only tool the description covers scope, output form, and preserved settings; only edge-case behavior and the exact meaning of 'path' are missing.

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?

The single 'path' parameter has 0% schema description coverage, so the description should say it points to the Dockerfile to analyze. 'A single-stage Dockerfile' only weakly implies that; an agent could plausibly pass a directory path instead.

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 ('Propose a multi-stage rewrite of a single-stage Dockerfile') and pins down the output form ('as TEXT, never writes a file'). It does not name a sibling to contrast with, so the agent must infer the boundary against fix_preview or lint_dockerfile on its own.

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?

The input constraint ('single-stage Dockerfile') implies when the tool applies, but there is no explicit when-not guidance, no prerequisite statement (e.g. file must exist and be readable), and no named alternative for already-multi-stage or non-Python/Node/Go/Rust files.

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 observedcheck_dockerignore
    • First observeddockerfile_overview
    • First observedexplain_layers
    • First observedfix_preview
    • First observedlint_compose
    • First observedlint_dockerfile
    • First observedsuggest_multistage

TDQS

A3.9/5.0

Scored across 7 tools

Disambiguation4/5

Each tool has a fairly distinct role: overview summarizes, lint_dockerfile reports rule findings, explain_layers focuses on layer/cache heuristics, fix_preview shows diffs. There is minor overlap between explain_layers' order/cache problems and lint_dockerfile's cache-busting rule, but descriptions clarify the split.

Naming Consistency4/5

All tools use snake_case, which is consistent, but the ordering is mostly verb_noun (lint_dockerfile, check_dockerignore, fix_preview) with one noun_verb outlier (dockerfile_overview). Readable and predictable overall with a single minor deviation.

Tool Count5/5

Seven tools is well-scoped for a Dockerfile/compose linting server, each covering a distinct artifact (Dockerfile, compose, dockerignore) or function (summarize, lint, explain, suggest, fix). No tool feels redundant or like padding.

Completeness4/5

The surface covers the full lint lifecycle for Dockerfiles plus compose and .dockerignore, with suggestions and fix previews but no write/apply by design. Minor gaps exist, such as no automatic fix suggestions for compose or dockerignore, but core workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

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
    Enables AI assistants and developers to analyze code for language-specific best practices and idiomatic patterns across programming languages, CI automation, and configuration formats.
    16
    2
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables agents to validate Dockerfiles for build-breaking syntax errors, risky patterns like root users and secrets in ENV/ARG, and cache-order problems, returning every finding with its line and a fix. It also verifies referenced container images against public registries, reporting tag existence, digests to pin, supported platforms, last rebuild time, and end-of-life status with an upgrade tag.
    2
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Exposes a Dockerfile auditing engine to AI assistants, letting them scan a Dockerfile for the 32 deterministic layer-aware rules, print a stage/layer map showing what each layer adds or deletes, explain any rule's rationale and fix, and list available rules. Findings include file:line evidence so agents can surface and triage image-safety issues directly in Claude Code, Cursor, or Cline.
    MIT