Skip to content

Pin ida-pro-mcp e2e image by digest - #6159

Merged
aponcedeleonch merged 2 commits into
mainfrom
fix-ida-pro-mcp-import
Jul 31, 2026
Merged

Pin ida-pro-mcp e2e image by digest#6159
aponcedeleonch merged 2 commits into
mainfrom
fix-ida-pro-mcp-import

Conversation

@aponcedeleonch

@aponcedeleonch aponcedeleonch commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

E2E Test Lifecycle is currently failing on every PR, on all three kind versions, regardless of the diff. The ida-pro-mcp backend in the optimizer multi-backend spec crashloops on startup:

File ".../site-packages/ida_pro_mcp/server.py", line 11, in <module>
    from mcp.server.fastmcp import FastMCP
ModuleNotFoundError: No module named 'mcp.server.fastmcp'

One unhealthy backend out of eleven makes the vMCP report Ready: False (Some backends are unhealthy), so the spec times out after 300s in BeforeAll. The optimizer path itself is fine: EmbeddingServerReady is True and the other ten backends reach Ready.

The cause is upstream drift in a mutable tag:

  • ida-pro-mcp 1.4.0 declares an unbounded mcp>=1.16.0 and imports mcp.server.fastmcp.
  • The mcp Python SDK removed that module in 2.0.0, uploaded to PyPI on 2026-07-28.
  • Dockyard rebuilt ghcr.io/stacklok/dockyard/uvx/ida-pro-mcp:1.4.0 on 2026-07-31 and resolved mcp 2.0.0. The previous build, 2026-07-27, has mcp 1.28.1 and works.

1.4.0 is the newest ida-pro-mcp release on PyPI, so there is no version to bump to. This pins the last build that resolved a 1.x mcp, which makes the reference immutable and the spec independent of future rebuilds.

  • Pin IDAProMCPServerImage to 1.4.0@sha256:5a596d96... in test/e2e/images/images.go, with a comment recording why.
  • Apply the same pin to the quickstart example, which the spec mirrors.
  • Add test/e2e/images/** to the E2E Tests Lifecycle trigger filter. See below.

The trigger gap, found while verifying this PR

The first push here went green on all 45 checks without ever running the test it fixes.

E2E Tests Lifecycle is the only job that runs the Ginkgo suite under test/e2e/thv-operator, which is where the optimizer multi-backend spec lives. (Operator CI / E2E Tests Operator looks like it would cover it, but it only runs the chainsaw suites under test/e2e/chainsaw/operator.) Its paths filter listed test/e2e/thv-operator/** but not test/e2e/images/**, even though that package supplies every backend image the suite deploys.

So a change to a test backend image could not trigger the tests that consume it. That is also why the original breakage looked like it came from unrelated PRs: the drift landed in an image, and nothing tied that to the suite.

Adding the path fixes it. Since the workflow file is itself in the filter, the second commit triggers the suite and verifies the pin on this PR.

Type of change

  • Bug fix

Test plan

  • E2E tests (task test-e2e)
  • Manual testing (describe below)

E2E: E2E Test Lifecycle now runs on this PR across all three kind versions, which is the suite that was failing. This is the actual verification of the fix, and it was only possible after the trigger-filter commit.

Manual: verified against linux/amd64, the arch CI runs, by pulling the per-arch manifest inside each index:

  • Current 1.4.0 (sha256:05691124, built 2026-07-31): mcp 2.0.0 installed, ida-pro-mcp exits with the ModuleNotFoundError above. Failure reproduced.
  • Pinned digest (sha256:5a596d96, built 2026-07-27): mcp 1.28.1 installed. Full stdio MCP handshake succeeds, initialize returns serverInfo ida-pro-mcp, and tools/list returns 48 tools.

Also confirmed the reference form is supported: MCPServerSpec.Image carries no pattern validation, pkg/runner/retriever already branches on nameref.Digest, and repo:tag@digest resolves through the registry.

Changes

File Change
test/e2e/images/images.go Pin IDAProMCPServerImage to the 2026-07-27 digest of tag 1.4.0
examples/operator/virtual-mcps/vmcp_optimizer_quickstart.yaml Same pin for the ida-pro-mcp backend
.github/workflows/test-e2e-lifecycle.yml Trigger the suite on test/e2e/images/** changes

Does this introduce a user-facing change?

No. Test fixtures, a CI trigger filter, and an example manifest.

Special notes for reviewers

The two approvals landed on the first commit, before the trigger-filter change. Worth a second look at .github/workflows/test-e2e-lifecycle.yml specifically.

This is distinct from #6026. That issue is the nondeterministic search-quality ranking assertion in the same spec file; this is a deterministic BeforeAll timeout from an unhealthy backend. Fixing this does not close that one.

Two follow-ups I did not fold in, to keep the scope contained:

  • test/e2e/images/images.go is not covered by any Renovate manager, despite the package doc saying it enables automated updates. That is why the tag drifted unnoticed in the first place.
  • Four other entries ride mutable tags and can break the same way at any time: mcp/puppeteer:latest, mcp/memory:latest, mcp/everything:latest, text-embeddings-inference:cpu-latest.

The pin should be revisited once upstream ida-pro-mcp either caps its mcp constraint or adopts the 2.x API. pagerduty-mcp, the only other dockyard uvx image in the spec, caps mcp[cli]~=1.8 and is not exposed.

Generated with Claude Code

Dockyard rebuilds the mutable 1.4.0 tag periodically and resolves Python
dependencies fresh on each build. ida-pro-mcp 1.4.0 declares an unbounded
"mcp>=1.16.0" and imports mcp.server.fastmcp, which the mcp Python SDK
removed in 2.0.0. The 2026-07-31 rebuild resolved mcp 2.0.0, so the
backend container now crashloops with ModuleNotFoundError. The vMCP
reports Ready: False and the optimizer multi-backend spec times out in
BeforeAll, failing E2E Test Lifecycle on every kind version regardless of
the PR diff.

1.4.0 is the newest ida-pro-mcp release on PyPI, so there is no version to
bump to. Pin the last build that resolved a 1.x mcp instead, which makes
the reference immutable and the spec independent of upstream rebuilds.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the size/XS Extra small PR: < 100 lines changed label Jul 31, 2026
JAORMX
JAORMX previously approved these changes Jul 31, 2026
amirejaz
amirejaz previously approved these changes Jul 31, 2026
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.62%. Comparing base (33e06f4) to head (07936e0).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6159      +/-   ##
==========================================
- Coverage   72.63%   72.62%   -0.02%     
==========================================
  Files         736      736              
  Lines       76331    76331              
==========================================
- Hits        55444    55436       -8     
- Misses      16949    16960      +11     
+ Partials     3938     3935       -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The E2E Tests Lifecycle workflow is the only job that runs the Ginkgo
suite under test/e2e/thv-operator, and that suite sources every backend
container image from test/e2e/images. That path was missing from the
trigger filter, so the ida-pro-mcp digest pin in the previous commit did
not run the tests it fixes, and no future change to a test image would
either.

Add test/e2e/images to the filter. Because the workflow file is itself in
the filter, this commit triggers the suite and verifies the pin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@aponcedeleonch
aponcedeleonch dismissed stale reviews from amirejaz and JAORMX via 07936e0 July 31, 2026 12:22
@github-actions github-actions Bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Jul 31, 2026
@aponcedeleonch

Copy link
Copy Markdown
Member Author

Heads up to @JAORMX and @amirejaz: I pushed a second commit after your approvals, so the diff grew by one file.

While verifying the pin I noticed the first push went green on all 45 checks without ever running the test it fixes. E2E Tests Lifecycle is the only job that runs the Ginkgo suite under test/e2e/thv-operator, and its paths filter didn't include test/e2e/images/**, the package that supplies every backend image that suite deploys. Operator CI / E2E Tests Operator looks like it would cover the spec, but it only runs the chainsaw suites.

So a change to a test backend image couldn't trigger the tests that consume it. That's also part of why the original breakage looked like it came from unrelated PRs.

07936e0 adds the path. Because the workflow file is itself in the filter, that commit triggers the suite here, which is what actually verifies the pin. Updated the description with the details.

@github-actions github-actions Bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Jul 31, 2026

@JAORMX JAORMX left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No hay pedorro

@aponcedeleonch

Copy link
Copy Markdown
Member Author

The red E2E Tests Core (proxy) check is not from this PR

It is the same upstream event as the bug this PR fixes, hitting a second image. Not fixable here, and it needs its own change in a different repo.

Three specs fail with timeout waiting for MCP server to be ready, all of them time-server specs. ghcr.io/stacklok/dockyard/uvx/mcp-server-time:2026.7.10 was rebuilt 2026-07-31 09:16 UTC, 2 minutes after the ida-pro-mcp rebuild, and resolved mcp 2.0.0. Reproduced locally on linux/amd64:

File ".../site-packages/mcp_server_time/server.py", line 12, in <module>
    from mcp.shared.exceptions import McpError
ImportError: cannot import name 'McpError' from 'mcp.shared.exceptions'. Did you mean: 'MCPError'?

Different symptom, same cause: McpError was renamed to MCPError in mcp 2.0.

Evidence it is independent of this diff:

For whoever picks it up: the last good build is sha256:5cca77dec3fefbacad35e3008ab1660f8725ef246213afb24231504fc73c999d (2026-07-27, mcp 1.28.1). I ran a stdio handshake against it, initialize and tools/list both fine. The fix belongs in toolhive-catalog rather than here, so it is not a digest pin in test/e2e/images.

Worth checking the blast radius: any dockyard uvx image whose package does not cap mcp<2 is exposed, and the whole catalog got rebuilt in that window. This PR's ida-pro-mcp and the catalog's time are the two we know about so far.

@aponcedeleonch

Copy link
Copy Markdown
Member Author

The red CI is independent of this fix. Will handle on a separate PR, merging this one as is

@aponcedeleonch
aponcedeleonch merged commit b7e824c into main Jul 31, 2026
48 of 49 checks passed
@aponcedeleonch
aponcedeleonch deleted the fix-ida-pro-mcp-import branch July 31, 2026 12:49
amirejaz added a commit that referenced this pull request Jul 31, 2026
The proxy e2e suites fail on every PR with "timeout waiting for MCP
server to be ready". Same root cause as #6159, a different image: tag
2026.7.10 of mcp-server-time is mutable, dockyard rebuilds it and
resolves Python dependencies fresh, and the 2026-07-31 rebuild picked up
the mcp Python SDK 2.0.0 released 2026-07-28. mcp-server-time imports
McpError from mcp.shared.exceptions, which 2.x moved, so the container
now exits on startup with "ImportError: cannot import name 'McpError'".

Pin the last build that resolved a 1.x mcp. Verified by driving both
builds over stdio: the pinned digest answers initialize, tag 2026.7.10
does not.

Point the two affected suites at the pinned constant instead of the
"time" registry entry, since the registry resolves to the moving tag and
is not fixable from this repo. Registry-name resolution stays covered by
the sibling cases that run "osv". stdio_proxy_over_streamable_http gains
an explicit --transport stdio, which the registry entry previously
supplied.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XS Extra small PR: < 100 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants