{
  "markdown": "# Dockerfile Security & Quality Audit\n\n> Hadolint-grade Dockerfile audit as an MCP server. 18+ checks across 5 categories, every finding ships with severity, line number, remediation text, and a copy-paste Dockerfile snippet.\n\n**Built by [Unbearable Labs](https://github.com/UnbearableDev).** Pay-per-event pricing — only billed when a tool is actually called.\n\n---\n\n## Available on\n\n- [Apify Actor Store](https://apify.com/unbearable_dev/dockerfile-audit) — primary, metered usage (PPE)\n- MCPize — *pending submission*\n- MCP.so — *pending submission*\n- PulseMCP — *pending submission*\n- Smithery — *pending submission*\n- Glama — *pending submission*\n\n**Newsletter:** [Unbearable TechTips Weekly](https://unbearabletechtips.com) · **All Actors:** [github.com/UnbearableDev](https://github.com/UnbearableDev)\n\n## What it does\n\nPoint any MCP-capable client (Claude Desktop, Cursor, n8n, Make, Zapier, custom agents) at this server, hand it a Dockerfile, get back a structured report:\n\n- **Severity** — high / medium / low / info\n- **Line number** — exact location in the file\n- **Description** — what's wrong and why it matters\n- **Remediation** — what to do about it\n- **Fix snippet** — Dockerfile syntax you can paste directly\n\n## Tools\n\n| Tool | Purpose |\n|------|---------|\n| `audit_dockerfile(dockerfile_content? \\| dockerfile_url?, min_severity='low')` | Run all checks |\n| `check_base_image(...)` | FROM/tag/digest/registry checks only |\n| `check_instructions(...)` | CMD form, ADD vs COPY, MAINTAINER, etc. |\n| `check_security(...)` | USER, sudo, chmod 777, curl\\|bash, hardcoded secrets, HEALTHCHECK |\n| `check_efficiency(...)` | apt cache hygiene, pip caching |\n| `check_secrets(...)` | ARG with secret-pattern names |\n| `list_checks(category?)` | Browse the full check catalog |\n\nProvide exactly one of `dockerfile_content` (paste the file) or `dockerfile_url` (HTTPS URL — e.g. GitHub raw).\n\n## Check catalog (v1: 18 checks across 5 categories)\n\n| ID | Category | Severity | Title |\n|----|----------|----------|-------|\n| DFA-001 | base_image | medium | Image uses :latest tag or no tag |\n| DFA-002 | base_image | info | No SHA256 digest pin on FROM |\n| DFA-003 | base_image | medium | Untrusted registry |\n| DFA-010 | instructions | low | CMD in shell form |\n| DFA-011 | instructions | low | ENTRYPOINT in shell form |\n| DFA-012 | instructions | info | MAINTAINER instruction is deprecated |\n| DFA-013 | instructions | medium | ADD used where COPY would suffice |\n| DFA-020 | security | medium | No USER directive (runs as root) |\n| DFA-021 | security | high | USER root set explicitly |\n| DFA-022 | security | high | sudo invoked in RUN |\n| DFA-023 | security | high | chmod 777 in RUN |\n| DFA-024 | security | medium | curl\\|bash pattern in RUN |\n| DFA-025 | security | high | Hardcoded secret in ENV |\n| DFA-027 | security | low | No HEALTHCHECK |\n| DFA-030 | efficiency | low | apt-get update without install |\n| DFA-031 | efficiency | low | apt-get install without --no-install-recommends |\n| DFA-032 | efficiency | low | pip install without --no-cache-dir |\n| DFA-040 | secrets | medium | ARG with secret-pattern name |\n\nUse `list_checks` to get the canonical, up-to-date catalog.\n\n## Pricing\n\n| Event | USD |\n|-------|-----|\n| Any audit / check_* tool call | $0.02 |\n| `list_checks` discovery | $0.005 |\n\n## Example response (truncated)\n\n```json\n{\n  \"summary\": {\n    \"total_findings\": 6,\n    \"by_severity\": {\"high\": 2, \"medium\": 2, \"low\": 2, \"info\": 0}\n  },\n  \"findings\": [\n    {\n      \"id\": \"DFA-021\",\n      \"category\": \"security\",\n      \"severity\": \"high\",\n      \"instruction\": \"USER\",\n      \"line_number\": 3,\n      \"title\": \"USER root set explicitly\",\n      \"description\": \"...\",\n      \"remediation\": \"Switch to a non-root UID after any root-required RUN steps.\",\n      \"fix_dockerfile_snippet\": \"USER 10001:10001\",\n      \"references\": [\"CIS-Docker-4.1\"]\n    }\n  ]\n}\n```\n\n## Connecting from Claude Desktop\n\n```json\n{\n  \"mcpServers\": {\n    \"dockerfile-audit\": {\n      \"transport\": \"streamable-http\",\n      \"url\": \"https://YOUR-ACTOR-URL.apify.actor/mcp\"\n    }\n  }\n}\n```\n\n## Limits\n\n- **Dockerfile size:** 200 KB cap per audit\n- **URL fetch:** 5s timeout, max 3 redirects, HTTPS only\n- **Session timeout:** 5 minutes of inactivity\n\n## What's NOT covered (yet)\n\n- Live image vulnerability scanning (use Trivy / Grype for that)\n- Multi-stage build optimization analysis (DFA-004 / DFA-005 — roadmapped)\n- Compose-file audit (separate MCP: [`docker-compose-audit`](https://apify.com/unbearable_dev/docker-compose-audit))\n\n## Sibling MCPs from Unbearable Labs\n\n- **[`docker-compose-audit`](https://apify.com/unbearable_dev/docker-compose-audit)** — same pattern for `docker-compose.yml`\n- **[`hu-postcode-validator`](https://apify.com/unbearable_dev/hu-postcode-validator)** — Hungarian postcode lookup\n\n## Source / contact\n\nIssues and ideas: `unbearabledev@gmail.com` or the GitHub org [`UnbearableDev`](https://github.com/UnbearableDev).\n",
  "bytes": 4955,
  "sha": "10040d07833fda5e26c646f03a454f73c8c44330f447c740327e7a8dbafcbed7",
  "repo_slug": "unbearabledev/dockerfile-audit",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_unbearabledev_dockerfile_audit_0068210f/readme"
}