Add buildx, scout, and Hub rate-limit handling#8
Merged
Conversation
Extends the MCP surface with two new CLI-backed modules and hardens the existing registry HTTPS path against Hub throttling. tools/buildx.py (11 tools): - buildx_build, buildx_bake — modern BuildKit builds with multi-platform, cache import/export, SBOM/provenance attestations - buildx_imagetools_inspect, buildx_imagetools_create — supersede docker manifest inspect/create/push; docstrings call out the migration - buildx_ls, buildx_inspect, buildx_du, buildx_prune — builder + cache management - buildx_create, buildx_use, buildx_rm — builder admin tools/scout.py (5 tools): - scout_cves, scout_quickview, scout_recommendations, scout_compare, scout_sbom — vulnerability scanning, CVE delta, base-image recommendations, SBOM generation. Docstrings note that most data requires `docker login`. Hub rate-limit handling (tools/registry.py): - Hybrid retry: transparently retry once when Retry-After <= 10s, otherwise raise a descriptive RuntimeError mentioning the cap and how to authenticate. Applied to both the OCI v2 path and the Hub UI API. Prompts (tools/prompts.py): - plan_multiarch_build, audit_image_cves, compare_image_versions, recommend_base_image — walk-throughs for the new tools - inspect_multiarch_manifest, create_multiarch_manifest, migrate_from_docker_manifest — guide users from "docker manifest" thinking to buildx imagetools Resources, README, CLAUDE.md updated to match. New CI job runs the integration suite on every push, gated on the unit-test job, with optional Hub auth via repo secrets. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Extends docker-mcp with new CLI-backed MCP tools for Docker Buildx and Docker Scout, adds multi-arch / security-focused prompts, and hardens the HTTPS registry/Hub tooling with a 429 retry policy to better handle Docker Hub throttling.
Changes:
- Add new CLI-backed tool modules:
tools/buildx.py(BuildKit/buildx workflows) andtools/scout.py(CVE/SBOM/recommendations/compare). - Add new prompts for multi-arch builds, manifest inspection/creation, and Scout-based security auditing/comparison.
- Add Hub/registry 429 handling plus new CI integration test job and accompanying unit/integration tests and docs updates.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
tools/buildx.py |
New buildx CLI tool wrappers (build/bake/imagetools/builder management). |
tools/scout.py |
New scout CLI tool wrappers (cves/quickview/recommendations/compare/sbom). |
tools/registry.py |
Adds Retry-After parsing + one-retry policy for HTTP 429 on registry/Hub calls. |
tools/prompts.py |
Adds buildx/scout workflow prompts + manifest-to-imagetools migration prompts. |
tools/resources.py |
Extends docs resource allow-list with buildx/scout sections. |
tools/__init__.py |
Re-exports the new tool modules. |
tests/test_buildx.py |
Unit tests for buildx argument construction and parsing behavior. |
tests/test_scout.py |
Unit tests for scout argument construction and JSON parsing behavior. |
tests/test_registry.py |
Unit tests for new 429 policy and Retry-After parsing. |
tests/test_prompts.py |
Unit tests validating new prompt outputs reference the right tools. |
tests/integration/test_buildx.py |
Integration smoke tests for buildx plugin + daemon wiring. |
tests/integration/test_scout.py |
Integration smoke test for scout (skips cleanly if plugin absent/offline). |
README.md |
Documents new tool groups, prompt examples, and destructive-operation notes. |
CLAUDE.md |
Updates architecture/tooling table with buildx/scout modules. |
.github/workflows/premerge.yaml |
Adds a new integration-tests job for pytest -m integration. |
- buildx.py: enforce mutual-exclusion the docstrings claimed but the
code didn't: push/load (build), raw/format (imagetools_inspect),
name/all_inactive (rm). Each pair now raises ValueError with a
message explaining why and how to pick one.
- scout.py: clarify scout_sbom returns docstring — JSON parsing
happens for spdx/cyclonedx/json formats (all JSON serializations),
not only when format='json'.
- registry.py: 429 error message is now registry-agnostic. Hub-specific
guidance ("anonymous pulls capped at ~100 / 6h") only appears when the
URL is on registry-1.docker.io / index.docker.io / hub.docker.com;
other registries (GHCR, ECR, GAR, …) get neutral advice about
authenticating to raise per-registry limits.
- premerge.yaml: the Hub-login step's `if:` referenced env.DOCKERHUB_TOKEN
before the step's own env block had been applied, so the step would
run even with an empty secret. Gate on `secrets.DOCKERHUB_TOKEN` (and
DOCKERHUB_USER) directly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- buildx_build: reject context='-' explicitly. The tool doesn't forward stdin to run_docker, so `-` would block on the MCP server's own stdin rather than reading a tarball. The docstring is updated to call out the limitation and suggest an HTTP URL as the workaround. - _parse_retry_after: treat naive datetimes returned by email.utils.parsedate_to_datetime (when the source HTTP-date used the `-0000` form) as UTC, per RFC 7231/9110. Without this, .timestamp() re-interpreted the value in the host's local timezone and could produce a wildly wrong delay. Test added for the -0000 vs +0000 equivalence. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- buildx_build / buildx_imagetools_create / buildx_create: emit one `--platform` with a comma-joined value instead of one flag per entry. Both forms work functionally (the underlying CLI flag is stringArray and buildx parses commas inside each entry too — verified locally), but comma-joined is the documented convention across upstream docs and avoids ambiguity for review tools. Tests updated. - migrate_from_docker_manifest prompt: switch to keyword args (`buildx_imagetools_create(target=…, sources=[…])`) so the mapping is unambiguous and consistent with the other prompts in the file. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The buildx_build docstring noted no shell expansion of `~`, but the `secret` example used `src=~/.npmrc` — which neither this tool nor buildx itself would expand. Updated to show an absolute path plus an `env=` alternative, and called out the `~` non-expansion explicitly in the secret parameter doc. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous fix gated the Hub-login step on `secrets.DOCKERHUB_TOKEN`
in its `if:`, but GitHub Actions blocks the `secrets` context inside
step-level `if:` conditions (security policy — secrets would leak into
expression-evaluation logs). Workflow validation now fails outright:
Unrecognized named-value: 'secrets'
Hoist the secrets to job-level `env:` instead. Job-level env IS
resolved before step `if:` is evaluated, so gating on
`env.DOCKERHUB_TOKEN` works correctly. The Hub-login step no longer
needs its own `env:` block — it inherits from the job.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous comment claimed GitHub Actions "blocks the `secrets` context inside step-level `if:`", which is more assertive than the authoritative GitHub docs (the policy is somewhat ambiguous and may have evolved). Replace with a description of the observed empirical behaviour — the workflow validator rejects `secrets.*` in step `if:` with "Unrecognized named-value: 'secrets'" — without claiming why. The hoist to job-level env remains correct. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous docstring listed only "spdx"/"cyclonedx"/"list" under args.format, but the parsing logic and returns description also reference "json". docker scout sbom accepts all four (json is in fact the CLI's own default). Enumerate every supported value explicitly so the args, returns, and implementation agree. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
_parse_json_lines now accepts an explicit `truncated` flag and a label. When truncated=True the final non-blank line is dropped before parsing (it's almost certainly a partial record from the MAX_CLI_OUTPUT_BYTES cap in run_docker). Any remaining JSONDecodeError is converted into a descriptive RuntimeError that includes the line number, the truncated flag, and a snippet — so a malformed-but-not-truncated response no longer surfaces as a bare json.JSONDecodeError. buildx_ls and buildx_du forward the truncation flag from CliResult and provide a human-readable label. Tests cover: partial-record drop, descriptive raise on garbage, and the buildx_ls truncated path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… ref - prompts.py: realign three new prompts (plan_multiarch_build, compare_image_versions, create_multiarch_manifest) to the project's one-`args:`-per-line docstring convention. The block style I'd used was inconsistent with every other prompt in this file. - recommend_base_image: the candidate-verification step pointed at `registry_inspect_manifest(image=<candidate>, reference=<tag>)`, but `registry_inspect_manifest` strips `:tag`/`@digest` from `image` — so passing a full ref like `python:3.13-slim` would need to be split, and the prompt didn't explain how. Switch to `buildx_imagetools_inspect(image=<candidate>, raw=True)`, which accepts a full ref. Added a brief note steering callers away from `registry_inspect_manifest` for this use case. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the MCP surface with two new CLI-backed modules and hardens the existing registry HTTPS path against Hub throttling.
tools/buildx.py(11 tools)buildx_build,buildx_bake— modern BuildKit builds with multi-platform, cache import/export, SBOM/provenance attestations, build secrets, and SSH forwarding.buildx_imagetools_inspect,buildx_imagetools_create— supersededocker manifest inspect/create/push. The standalonedocker manifestcommand is in maintenance mode and lacks support for OCI image indexes and attestations; the docstrings and three new prompts (`inspect_multiarch_manifest`, `create_multiarch_manifest`, `migrate_from_docker_manifest`) point users to the buildx equivalents.buildx_ls,buildx_inspect,buildx_du,buildx_prune— builder + cache management.buildx_prunealways runs with--force(no interactive TTY available) and is documented as destructive in the README security section.buildx_create,buildx_use,buildx_rm— builder admin.tools/scout.py(5 tools)scout_cves— list CVEs, filter by severity (`only_severity` accepts a list and is joined for the CLI), skip base-image issues with `ignore_base`.scout_quickview— compact per-severity summary.scout_recommendations— base-image upgrade suggestions.scout_compare— CVE delta between two image refs; validates exactly one of `to`, `to_env`, or `to_latest` is supplied.scout_sbom— SPDX, CycloneDX, or list-format SBOMs. SPDX and CycloneDX outputs are parsed; `list` is returned as text.Each docstring notes that Scout's richest data requires `docker login` on the host running this MCP server.
Hub rate-limit handling (`tools/registry.py`)
Hybrid retry policy: when a 429 has `Retry-After ≤ 10s`, sleep + retry once transparently. Otherwise raise a descriptive RuntimeError that mentions the anonymous-pull cap and how to authenticate. Applied to both the OCI v2 code path (`_registry_get`) and the Hub UI API loops (`hub_list_tags`, `hub_repo_info`).
Prompts
Buildx / Scout walkthroughs: `plan_multiarch_build`, `audit_image_cves`, `compare_image_versions`, `recommend_base_image`.
Manifest-redirect prompts (the bridge from `docker manifest` thinking):
CI: integration tests
New `integration-tests` job in `.github/workflows/premerge.yaml`:
Resources / docs
Toolchain
Test plan
🤖 Generated with Claude Code