Skip to content

solution-server: cap fastmcp <2.13 to keep deps source-buildable in Hermeto#5

Open
fabianvf wants to merge 4 commits into
migtools:mainfrom
fabianvf:solution-server-pin-fastmcp-below-2.13
Open

solution-server: cap fastmcp <2.13 to keep deps source-buildable in Hermeto#5
fabianvf wants to merge 4 commits into
migtools:mainfrom
fabianvf:solution-server-pin-fastmcp-below-2.13

Conversation

@fabianvf

@fabianvf fabianvf commented Jun 17, 2026

Copy link
Copy Markdown

Problem

The downstream Hermeto/Konflux build of the solution server fails while building Python deps from source. Root cause: fastmcp 2.13 added a dependency on py-key-value-aio, whose build backend is uv_build — a Rust crate. Since Hermeto builds everything from source (no binary wheels, for reproducibility/auditability), pip must compile uv_build, which pulls in maturin and a full Rust crate graph:

  1. First failure (mta-8-2*.log): maturin needs cargo edition2024, but the base image shipped rust 1.84.1 (edition2024 was stabilized in 1.85).
  2. After bumping the base image to rust 1.92 (build.log), it still failed — uv_build 0.8.24's Cargo.lock mismatches the vendored crates: failed to select a version for the requirement anstream = "^0.6.15" (locked to 0.6.20).

None of this (uv_build/maturin/Rust) is used at runtime — it's pure build-time machinery introduced transitively by fastmcp 2.13+.

Fix

Cap fastmcp<2.13. 2.12.x predates py-key-value-aio and pulls none of the Rust build chain. The solution server only uses fastmcp's Context / FastMCP API, stable since well before 2.12, so the cap costs no functionality.

The pin is applied as a midstream-only constraints file (kai_mcp_solution_server/requirements-constraints.txt) fed to the uv pip compile step in scripts/post-sync.sh, rather than editing pyproject.toml (which is synced verbatim from konveyor/kai). This is sync-safe:

  • The constraints file does not exist upstream, so it never conflicts with the upstream → midstream merge.
  • post-sync.sh reapplies it on every sync, so the cap persists automatically.
  • Mirrors the existing requirements-build-constraints.txt pattern.

Result

Regenerated requirements.txt / requirements-build.txt:

  • fastmcp 2.14.3 → 2.12.5
  • uv-build fully removed from both files (the failing chain is gone)
  • Also drops py-key-value-aio, py-key-value-shared, beartype, pydocket, and the redis/opentelemetry/keyring subtrees (all fastmcp 2.13+ transitive deps)
  • maturin remains in requirements-build.txt only as the backend for legitimate Rust runtime wheels (pydantic-core, rpds-py, jiter…) that already build successfully on the bumped image

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Updated and regenerated pinned dependency versions for improved compatibility and stability, including version bumps for several core packages.
    • Added a runtime version constraint on fastmcp to address build backend and source build compatibility issues.
    • Updated build script to enforce constraint files during dependency resolution for more consistent builds.

…ermeto

fastmcp 2.13 added a dependency on py-key-value-aio, whose build backend is
uv_build -- a Rust crate. Hermeto builds every dependency from source (no
binary wheels), and uv_build 0.8.x pulls in maturin plus a Rust crate graph
that can't be vendored cleanly in the hermetic build: first maturin needed
cargo edition2024 (rust >=1.85), and after bumping the base image's rust, the
build still failed because uv_build's lockfile mismatches the vendored crates
(anstream 0.6.20 vs 0.6.21).

fastmcp 2.12.x predates py-key-value-aio and pulls none of it. The solution
server only uses fastmcp's Context / FastMCP API, stable since well before
2.12, so the cap costs no functionality.

The pin is applied as a midstream-only constraints file fed to the
`uv pip compile` step in post-sync.sh, rather than editing pyproject.toml
(which is synced verbatim from konveyor/kai). The constraints file does not
exist upstream, so it never conflicts with the upstream -> midstream merge,
and post-sync.sh reapplies it on every sync.

Removes py-key-value-aio, uv_build, beartype, pydocket, and the
redis/opentelemetry/keyring subtrees from the hash-locked requirements.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@fabianvf, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 26 minutes and 48 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fdab2d76-d614-44fb-a571-5952df160367

📥 Commits

Reviewing files that changed from the base of the PR and between a64365c and 2ef26bc.

📒 Files selected for processing (4)
  • kai_mcp_solution_server/requirements-build.txt
  • kai_mcp_solution_server/requirements-constraints.txt
  • kai_mcp_solution_server/requirements.txt
  • scripts/post-sync.sh
📝 Walkthrough

Wait, I used an invented range ID. Let me redo this correctly using only the provided range IDs.

I'm still accidentally inventing range IDs. Let me be very careful and only use the exact IDs from <all_range_ids>. The ID range_623_c does not exist. The range for diskcache removal is range_97a435911650. Let me recount.

From <all_range_ids>, the ranges for requirements.txt are:
range_24e9b04f3470, range_f559a96d0fa7, range_41551612bb18, range_4da02f8ea905, range_97a435911650, range_caddfbe47403, range_4afa6c7d0746, range_b780111f9117, range_28876d984f97, range_1c7b4fd91f9e, range_42224a77c179, range_1511d0480640, range_478c92772d4a, range_1e1c079c9e49, range_675525ae9358, range_a4252e43bab4, range_01d55cddd243, range_124947fae6ab, range_02e17f21c182, range_cf7cfc2b58ec, range_e3a5403093d6, range_4c702c40ab7c, range_01d0fe95c4f6, range_714ef333bfb0, range_b6be5048fc0f

That's 25 ranges for requirements.txt. Let me verify: the all_range_ids list has 43 total. constraints=1, post-sync=1, so build.txt + requirements.txt = 41. Build.txt has 16 ranges listed. 41-16=25. Good.

Walkthrough

Adds requirements-constraints.txt capping fastmcp below version 2.13 to avoid Rust build-backend issues, updates post-sync.sh to pass that constraint file to uv pip compile, and regenerates requirements.txt and requirements-build.txt with the resulting resolved dependency versions and provenance comments.

Changes

fastmcp Constraint and Lockfile Regeneration

Layer / File(s) Summary
Constraint rationale and compile script wiring
kai_mcp_solution_server/requirements-constraints.txt, scripts/post-sync.sh
Introduces requirements-constraints.txt with a fastmcp<2.13 pin and inline comments explaining the Rust crate build-backend/vendoring issue. Updates the uv pip compile call in post-sync.sh to pass --constraint requirements-constraints.txt.
Regenerated runtime lockfile
kai_mcp_solution_server/requirements.txt
Regenerated with the constraint applied: fastmcp downgraded 2.14.3→2.12.5, mcp 1.25.0→1.16.0, lupa replaced by lazy-object-proxy, jsonschema-path/pathable/referencing/openapi-* versions updated, werkzeug and rfc3339-validator added, and beartype/cachetools/diskcache/py-key-value-aio/pydocket/shellingham/sortedcontainers/typer removed.
Regenerated build lockfile
kai_mcp_solution_server/requirements-build.txt
Removes uv-build==0.8.24, bumps jaraco-context (6.1.0→6.1.2) and jaraco-functools (4.4.0→4.5.0), and updates # via attribution comment lists throughout to reflect the revised transitive dependency graph.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • migtools/mta-kai#4: Both PRs update kai_mcp_solution_server's Hermeto hash-locked requirements files (requirements-build.txt, requirements.txt) and the scripts/post-sync.sh regeneration pipeline.

Suggested reviewers

  • dymurray

Poem

🐇 A cap upon fastmcp was laid,
Below two-thirteen, constraints obeyed!
No Rust crates to vendoring stray,
The lockfiles regenerate today.
Hashes fresh and versions pinned tight —
All's well in dependency night! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: capping fastmcp to <2.13 to maintain source-buildability in Hermeto, which is the core objective of this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@kai_mcp_solution_server/requirements.txt`:
- Around line 652-657: The fastmcp package version 2.12.5 enforces an upper
bound on the mcp dependency that prevents using the patched version mcp>=1.23.0
which fixes the CVE-2025-66416 security vulnerability. Upgrade the fastmcp
version from 2.12.5 to a newer release that supports mcp>=1.23.0 or higher, then
update the dependency hash values in the requirements.txt entry for fastmcp to
match the new version being installed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 057a8868-b3ab-472d-8949-c47d8fab8363

📥 Commits

Reviewing files that changed from the base of the PR and between 19d65ce and a64365c.

📒 Files selected for processing (4)
  • kai_mcp_solution_server/requirements-build.txt
  • kai_mcp_solution_server/requirements-constraints.txt
  • kai_mcp_solution_server/requirements.txt
  • scripts/post-sync.sh

Comment on lines +652 to +657
fastmcp==2.12.5 \
--hash=sha256:2dfd02e255705a4afe43d26caddbc864563036e233dbc6870f389ee523b39a6a \
--hash=sha256:b1e542f9b83dbae7cecfdc9c73b062f77074785abda9f2306799116121344133
# via
# -c requirements-constraints.txt
# kai-mcp-solution-server (pyproject.toml)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -nP '^\s*(fastmcp|mcp)([<>=!~]=|==)' \
  kai_mcp_solution_server/requirements.txt \
  kai_mcp_solution_server/requirements-constraints.txt \
  kai_mcp_solution_server/pyproject.toml \
  scripts/post-sync.sh

Repository: migtools/mta-kai

Length of output: 183


🌐 Web query:

fastmcp 2.12.5 mcp dependency version requirements

💡 Result:

For FastMCP version 2.12.5, the mcp dependency is explicitly constrained to mcp>=1.12.4,<1.17.0 [1][2]. This specific version was released as a "safety pin" to prevent issues introduced in mcp version 1.17.0, which caused problems for users utilizing FastMCP auth providers or mounting servers within larger applications [3]. Key dependencies for FastMCP 2.12.5 include: - mcp: >=1.12.4, <1.17.0 [1][2] - pydantic: >=2.11.7 [1] - httpx: >=0.28.1 [1] - cyclopts: >=3.0.0 [1] - authlib: >=1.5.2 [1] - rich: >=13.9.4 [1] For production environments, it is recommended to pin fastmcp==2.12.5 to ensure consistent behavior [4][5].

Citations:


🌐 Web query:

mcp 1.16.0 DNS rebinding vulnerability CVE

💡 Result:

The Model Context Protocol (MCP) Python SDK, specifically the package mcp on PyPI, was affected by a DNS rebinding vulnerability tracked as CVE-2025-66416 [1][2][3]. In versions prior to 1.23.0, the SDK did not enable DNS rebinding protection by default for HTTP-based servers (such as those using SSE or Streamable HTTP transport) [1][4]. This allowed a malicious website, if a user were tricked into visiting it, to bypass same-origin policy restrictions and send unauthorized requests to an MCP server running on the user's localhost [1][4][5]. Key details regarding this vulnerability: - Affected Configurations: The vulnerability specifically affected HTTP-based MCP servers running on localhost without authentication, where no explicit TransportSecuritySettings were configured [1][4]. - Impact: Attackers could potentially invoke tools or access resources exposed by the MCP server on behalf of the user [1][4][5]. - Exclusions: Servers using stdio transport were not affected [1][4]. - Resolution: The issue was fixed in version 1.23.0 [1][4]. In this version and later, servers created via FastMCP() have DNS rebinding protection enabled by default when the host is set to 127.0.0.1, localhost, or ::1 [4]. Similar DNS rebinding vulnerabilities have been identified and patched in other MCP SDK implementations, including the TypeScript SDK (CVE-2025-66414, fixed in 1.24.0) [5][6], the Go SDK (fixed in 1.4.0) [7], and the Rust SDK (fixed in 1.4.0) [8]. Users of these SDKs are advised to ensure they are on the patched versions [4][8][5][7].

Citations:


🏁 Script executed:

#!/bin/bash
# Check if there are any comments or references to mcp versions in the repo
rg -i 'mcp.*version|vulnerable.*mcp|dns.*rebind' \
  kai_mcp_solution_server/ \
  scripts/ \
  --type md --type txt --type toml --type py

Repository: migtools/mta-kai

Length of output: 42


FastMCP 2.12.5 enforces an incompatible mcp version with a known security flaw.

fastmcp==2.12.5 pins mcp to the range >=1.12.4,<1.17.0, which locks in mcp==1.16.0. This version is vulnerable to CVE-2025-66416 (DNS rebinding protection missing in HTTP-based MCP servers on localhost). The fix is in mcp>=1.23.0, but that version violates the <1.17.0 upper bound enforced by fastmcp==2.12.5. Upgrading fastmcp to a newer version that supports mcp>=1.23.0 is required to resolve this security regression.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kai_mcp_solution_server/requirements.txt` around lines 652 - 657, The fastmcp
package version 2.12.5 enforces an upper bound on the mcp dependency that
prevents using the patched version mcp>=1.23.0 which fixes the CVE-2025-66416
security vulnerability. Upgrade the fastmcp version from 2.12.5 to a newer
release that supports mcp>=1.23.0 or higher, then update the dependency hash
values in the requirements.txt entry for fastmcp to match the new version being
installed.

Source: Linters/SAST tools

fabianvf and others added 3 commits June 17, 2026 12:22
…lag as temporary

- Suppress osv-scanner advisories on the generated requirements.txt via a
  `# trunk-ignore-all(osv-scanner)` header injected by post-sync.sh. The
  fastmcp<2.13 pin holds fastmcp/mcp at versions with known CVEs; we knowingly
  accept them until the Hermeto Rust build is fixed. Done in midstream-only /
  merge=ours files (post-sync.sh, requirements.txt) so it never conflicts with
  the upstream sync -- .trunk/trunk.yaml is left untouched.
- Fix the pre-existing verify-requirements crash: pybuild-deps 0.5.0 mkdirs
  ~/.cache/pybuild-deps without parents=True, so ensure ~/.cache exists first.
- Reformat post-sync.sh per shfmt.
- Add loud "REMOVE ASAP" notes cross-referencing the pin and the suppression so
  both are torn out together once fastmcp can be unpinned.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…CI/build

verify-requirements regenerates on Linux and compared against the committed,
macOS-generated files: uv resolves for the host platform by default, so the
committed manifests were missing Linux-only deps (notably greenlet, required by
SQLAlchemy's async engine). That drift is pre-existing -- upstream/main's file
is also macOS-generated -- and was previously masked by the pybuild-deps cache
crash.

Pin the resolution target with --python-platform x86_64-unknown-linux-gnu
--python-version 3.12 so post-sync.sh produces the image's Linux resolution
regardless of which host runs it, and regenerate. This adds greenlet (and other
Linux-conditional deps) to the hash-locked files, fixing both the CI drift and
a latent missing-dependency in the shipped image.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pybuild-deps has no platform-target flag (unlike uv pip compile), so it resolves
build deps for the host. Generated on macOS it dropped keyring's Linux-only
backend deps (secretstorage, jeepney, cryptography), drifting from CI's Linux
regeneration. Regenerated in a linux/x86_64 python:3.12 container with the same
uv to match CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fabianvf

Copy link
Copy Markdown
Author

🔧 Follow-up tracking: unpin fastmcp & remove CVE suppression (REMOVE ASAP)

Issues are disabled on this repo, so recording the tracking item here.

This PR caps fastmcp<2.13 to keep the solution-server deps source-buildable in Hermeto (2.13+ pulls py-key-value-aio → uv_build, a Rust crate that can't be vendored cleanly from source). That reintroduces known CVEs which are suppressed, not fixed — all fastmcp/mcp patches land in 2.13–2.14.2, exactly the Rust-pulling range:

Sev Package Advisory Fixed in
high fastmcp 2.12.5 OAuth Proxy token reuse (GHSA-5h2m-4q8j-pqpj) 2.14.2
high fastmcp 2.12.5 Auth confused-deputy takeover (GHSA-c2jp-c369-7pvx) 2.13.0
med fastmcp 2.12.5 Reflected XSS in OAuth callback (GHSA-mxxr-jv3v-6pgc) 2.13.0
high fastmcp 2.12.5 bundles mcp <1.23, CVE-2025-66416 (GHSA-rcfx-77hg-w2wv) 2.14.0
med fastmcp 2.12.5 Windows cmd injection in Cursor installer (GHSA-rj5c-58rq-j5g5) 2.13+
high mcp 1.16.0 DNS-rebinding protection off by default (GHSA-9h52-p55h-vw2f) (mcp bump)

4 of 6 (auth/OAuth/installer) aren't reachable in this server's config; the two mcp-SDK ones are relevant to an HTTP-exposed server.

When Hermeto can build the uv_build/maturin Rust chain from source, remove all of this together:

  1. Delete the pin in kai_mcp_solution_server/requirements-constraints.txt.
  2. Remove the # trunk-ignore-all(osv-scanner) injection in scripts/post-sync.sh.
  3. Regenerate requirements*.txt on Linux (pybuild-deps has no platform flag) and confirm osv-scanner is clean.
  4. Re-verify the server runs (its fastmcp surface — Context/FastMCP/@tool/run — is stable across 2.12→2.14).

Both files carry cross-referenced "REMOVE ASAP" comments. Blocked on hermetoproject/hermeto#983 / #984.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant