Skip to content

feat(dockhand): support transitive dependency overrides/constraints in spec.yaml #668

Description

@JAORMX

Problem

Renovate version bumps for MCP servers fail the build-containers Grype gate (--fail-on high --only-fixed) when the bumped package pins or caps a transitive dependency to a vulnerable version, and we have no way to override that pin from within dockyard. Three open PRs are blocked on exactly this:

PR Package Vulnerable transitive dep Why we can't fix it Worst
#469 @brightdata/mcp 2.9.5 @modelcontextprotocol/sdk hard-pinned 1.21.2 package pins exact version; fixes are ≥1.24 3× HIGH
#527 mcp-clickhouse 0.3.0 fastmcp capped <3.0.0 CRITICAL fix is fastmcp 3.2.0, excluded by cap CVE-2026-32871 (Critical)
#528 mcp-neo4j-cypher 0.6.0 fastmcp capped <2.14 all fixes (2.14.x / 3.2.0) excluded by cap Critical + 3 HIGH

(Note #527 and #528 are also regressions vs. what main currently ships — see those PRs.)

Proposal

Add an optional dependency-override mechanism to the spec.yaml schema, plumbed into the generated Dockerfile:

spec:
  package: "@brightdata/mcp"
  version: "2.9.5"
  overrides:                                  # npx → npm "overrides"
    "@modelcontextprotocol/sdk": "1.26.0"
spec:
  package: "mcp-clickhouse"
  version: "0.3.0"
  constraints:                                # uvx → uv "--override" / constraints file
    - "fastmcp>=3.2.0"

Implementation sketch

  • Extend MCPServerPackageSpec (cmd/dockhand/main.go:43) with Overrides map[string]string (npx) and/or Constraints []string (uvx).
  • generateDockerfile (cmd/dockhand/main.go:354) already receives the Dockerfile as a string from toolhive's BuildFromProtocolSchemeWithName(..., dryRun=true). Post-process that string to inject the override:
    • npx: emit a package.json containing an overrides block before the npm install --save <pkg> step (npm honors overrides only from package.json).
    • uvx: add --override <constraints-file> (or per-spec --override pkg>=ver) to the uv tool install step.
  • Require every override entry to carry a short justification (mirroring security.allowed_issues) so the why is auditable in-repo.

Verification (already done manually)

A throwaway test of each override was run against the exact build recipe + the same Grype gate:

Acceptance

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions