v1.4.1 - Failure hints and the mcp<2 compatibility pin
Failure hints and the mcp<2 compatibility pin
A terminally failed activation usually surfaces as something generic — "readiness
timed out", "bridge exited rc=1" — while the real cause sits in the log backlog. 1.4.1
teaches the supervisor to recognize known failure signatures and say what to do about
them, and ships the first fix it recommends: a per-server toggle that holds a uvx
server to the Python mcp 1.x SDK line.
Also in this release: the open Trivy code-scanning alerts are cleared, cryptography
is bumped, and the screenshot pipeline is repaired.
Failure-signature hints (#115)
New app/supervisor/hints.py maps log signatures to actionable operator
recommendations. The unit appends the first match to last_error, so the hint reaches
the API and the UI through the existing field with no schema change.
- Only the final attempt's lines count as evidence. An earlier retry may have
failed on the signature while the terminal failure was something else; the hint has
to describe what actually killed the activation. - Phase-aware. The setup script runs in its own shell with the child env, where a
launch-argv remedy can't reach — so setup-phase and launch-phase log sections are
scored separately, and a setup script that merely prints a traceback can't put
launch advice on an unrelated later failure. - Signatures carry real evidence. The first entry matches the mcp 2.0 SDK import
break by known removed-symbol pairs, not anyImportErrorundermcp.*— a loose
pattern would recommend a downgrade to servers where a downgrade can't help. - Recommendations are only ever actions the operator can take on that server. The
hint sees the runner, the launch shape and the current pin state, so it never
suggests a toggle that's already on, or one the service would refuse to save; a
dockerrow is told to use or rebuild an image instead, since only the image selects
what's installed inside the container.
"Pin mcp SDK < 2" toggle for uvx servers (#115)
uvx re-resolves a package's own (often unbounded) mcp>=… constraint on every cold
start, so a server that predates the SDK's 2.x line dies at import. The new per-server
pin_mcp1 toggle launches it as uvx --with "mcp<2" … until upstream ships a fix.
- The pin lives in the launch argv, not in your stored arguments — it's injected at
spec-build time. The UI mirrors the same placement rule, so the form preview and the
server-detail Configuration card show the command that actually runs (with the<
quoted the way a shell needs it). - Placement is only ever applied where it's certain.
uvxtakes--withleading;
auvlauncher takes it only after a leadingtool run/runsubcommand. For any
other shape the save is refused with the workable alternatives named, rather than
silently launching the original unpinned argv — a toggle that quietly no-ops sends
the operator in circles. - uvx-only, and forced off elsewhere, including on conversion away from the uvx
runner, so a runner change can't carry a pin that no longer means anything. - Part of the launch spec (
config_hash), so toggling it restarts the bridge.
A pre-column row (NULL) hashes identically to off, so upgrading bounces nothing. - Imported configs launched via
uvx.exe/uv.exenow classify as the uvx runner, so
a Claude-Desktop-on-Windows config gets the toggle too.
API: pin_mcp1 on create, PATCH /api/servers/<id>, and the detail response;
carried through clone. UI: a toggle in the server form's uvx section (Edit server).
Fixes and maintenance
- Cleared the open Trivy code-scanning alerts (#118). npm is bumped to 11.19.0, and
two dependencies bundled inside npm that no published release has re-vendored yet
(checked 11.19.0 and 12.0.2) are overlaid with their patched versions in the image:
brace-expansion5.0.9 (CVE-2026-14257, CVE-2026-69152) andip-address10.3.1
(CVE-2026-69192) — semver-patch swaps with identical dependency sets, so the
replacement is drop-in and folds into the next npm bump. Two remaining alerts are for
packages vendored insidepipin thepython:3.14-slimbase image (msgpack
GHSA-6v7p-g79w-8964,setuptoolsCVE-2025-47273); neither is reachable from the
control plane, and no published pip vendors a fixed version, so they're recorded in a
new.trivyignore.yamlwith written justifications and an expiry of 2026-10-13
that forces re-triage rather than letting the suppression become permanent. cryptography49.0.0 → 50.0.0 (#116), a transitive dependency, via the lockfile.- Screenshot pipeline repaired (#114, #117). The uvx Time demo seed pins
mcp<2so
it actually starts, and the capture waits for the seeded HF.co server rather than the
removed Upstream Weather entry. UI screenshots indocs/screenshots/are refreshed.
Upgrade notes
- No migration and no new environment variables.
pin_mcp1is added via the
existing forward-onlyADD COLUMNpath and is nullable; NULL reads as off and hashes
as off, so no bridge restarts on upgrade. - Nothing changes until you opt in. The pin is off by default and applies only to
uvxservers; hints are additive text appended tolast_erroron a terminal
failure. - The pin is a stopgap, not a fix. It holds the 1.x line so a server keeps working
while its maintainer catches up with the mcp 2.x SDK; drop the toggle once upstream
ships a compatible release.
Full Changelog: v1.4.0...v1.4.1
License
MIT © pacnpal