AP011: MCP server runs an unpinned package
| Severity | medium |
| Runs in | scan |
| One-line fix | Pin the package to an exact version (npx -y pkg@1.2.3, uvx pkg==1.2.3, image:1.2.3 or image@sha256:…) so the server only changes when you change the config. |
What it finds
Section titled “What it finds”An MCP server whose command installs a package each time it starts, with no exact version:
npx,npm exec,pnpm dlx,yarn dlxorbunxwith a package that has no@<version>, or only@latest, another tag or a range such as@^1.2.0;uvx,uv tool runorpipx runwith a package that has no==<version>(also through--fromor--spec);docker runorpodman runwith an image that has no tag, or thelatesttag, and no@sha256:digest, or a tag pulled again on every start with--pull=always;deno runwith annpm:package that has no version;- a git source with no commit, or a remote archive whose address names no version.
It reads every agent’s MCP config, and the MCP config that installed plugins and extensions carry. The print names the server and shows the pinned form to write instead.
Why it matters
Section titled “Why it matters”An unpinned server runs whatever version was published last, with your permissions, every time the agent starts. A hijacked maintainer account or a new malicious release reaches you without anything changing on your disk.
How to fix
Section titled “How to fix”Pin an exact version: npx -y pkg@1.2.3, uvx pkg==1.2.3 (or uvx --from pkg==1.2.3 cmd),
image:1.2.3 or image@sha256:<digest>. Choose the version you use now, after reading its
release notes. agentprint fix never changes the config: the version is your call.
Limits
Section titled “Limits”- Local programs and scripts are not packages:
node server.js,./bin/server,uv run, and a runner such asnpx tsx ./server.tsthat starts a local file are never printed. - A command built from variables (
${IMAGE}) is not read. - A pinned version can still be a bad one: pinning makes a change visible, it does not vouch for the code.