Fix template CI: await ctx.error (lint) + clean bundle scan - #14
Merged
Conversation
Three pre-existing failures on main, all of which propagate to every server scaffolded from this template: - lint (ty): ctx.error() is async in FastMCP but was called without await in get_client/list_items/get_item, so the error notifications were never sent. Made get_client async and awaited all three call sites. - scan AI-05 (4x HIGH): tests-integration/ was packed into the bundle (unlisted in .mcpbignore) and flagged as unexpected executables. Excluded it. - scan CD-02 (2x HIGH): the code reads the EXAMPLE_API_KEY secret env var but the manifest declared no environment permission. Added the MTF permissions block (environment: read, network: outbound). Verified locally: ty + ruff clean, 25 tests pass, and a re-scan drops all 6 HIGH findings (risk HIGH -> MEDIUM), so the critical/high CI gate passes.
The scanner prints 'Scanning <bundle>...' to stdout before the JSON, so '--json > scan-results.json' produced a file json.load couldn't parse (Expecting value: line 1 column 1). This was latent — the scanner step used to exit 1 on HIGH findings before the parse step ran. With the HIGH findings cleared, the scanner exits 0 and the parse bug surfaced. Use the scanner's -o flag (its intended machine-readable output) so the file is clean JSON.
The server reads its bundled SKILL.md via importlib.resources at import time, so the MTF permissions block must declare filesystem access. With filesystem "none" the scanner raises CD-02 (undeclared filesystem permission, MEDIUM); declaring "read" makes the declaration accurate and drops the bundle's scan risk score to LOW.
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.
Green the template's CI
Three failures were red on
main(pre-existing, unrelated to any recent docs change). Each one propagates to every server scaffolded from this template, so fixing them at the source fixes the whole fleet.1. lint (
ty) —ctx.errornot awaitedFastMCP's
Context.error()is async (it sends an MCP log notification). It was called withoutawaitinget_client,list_items, andget_item, so the error notifications were silently never sent — a real runtime bug, not just a lint nit.get_clientwas sync, so it's nowasync(its only two callers are already async tools) and all three call sites are awaited.2. scan AI-05 (4× HIGH) — test files packed into the bundle
.mcpbignoreexcluded/tests/,/test/,/e2e/but not/tests-integration/, so those.pyfiles were packed and flagged as unexpected executables. Added/tests-integration/.3. scan CD-02 (2× HIGH) — undeclared secret env access
The code reads
EXAMPLE_API_KEYbut the manifest declared no environment permission. Added the MTF permissions block under_meta.org.mpaktrust(environment: read,network: outboundsince it's an API client).Verification (local)
ty check src/andruff check— clean (was 3tyerrors)pytest— 25 pass (the async change is transparent;patchauto-usesAsyncMockon the now-async target)HIGH → MEDIUM. The CI scan gate fails only on CRITICAL/HIGH, so it now passes.Not addressed (intentionally)
The remaining medium/low/info findings and the
Level: Nonetrust level don't gate CI and are out of scope here — a template scanned as a raw bundle won't earn a provenance level (no signed/attested build).