Skip to content

cli: flag unpinned npx/uvx package specs in mcp list - #275

Open
raymondginger2018-sudo wants to merge 2 commits into
HKUDS:mainfrom
raymondginger2018-sudo:pr/mcp-list-supply-chain-concern
Open

raymondginger2018-sudo wants to merge 2 commits into
HKUDS:mainfrom
raymondginger2018-sudo:pr/mcp-list-supply-chain-concern

Conversation

@raymondginger2018-sudo

Copy link
Copy Markdown
Contributor

Responds to the closing invitation on #269: "a small PR that adds a concern to
mcp list itself, for example an unpinned package (npx/uvx with @latest
or no version) or a server that receives credential environment variables."

Of those two examples the credential-env concern already exists on main
(cred -> sends-credential, merged via #241 / 2fafe40), so this PR adds the
remaining one: unpinned-package. It replaces #269's separate mcp audit
command with a concern on mcp list itself, as suggested.

What it does

mcp list now reports unpinned-package on a stdio server row when it is
launched through npx/uvx and its package argument floats -- no version at
all (npx -y left-pad) or a floating tag (npx -y left-pad@latest,
pkg@next). Those resolve whatever the registry serves at each start, so the
effective code was never chosen by the operator.

Recognition rules

command line reading
npx -y left-pad unpinned-package
npx -y left-pad@latest unpinned-package
npx -y left-pad@next unpinned-package
uvx mcp-server-time unpinned-package
npx -y left-pad@1.2.3 pinned
uvx mcp-server-time==0.3.0 pinned (PEP 508)
npx @modelcontextprotocol/server-filesystem unpinned (scoped name; the @ delimiter is only searched past position 0)
npx --index-url https://... pkg flag/URL skipped; pkg is the package token
npx ./server.js, npx C:\x.js local file -- no version to pin, not scanned
npx --version (flags only) nothing to scan
python3 server.py not a launcher, not scanned
  • Windows launcher suffixes (.cmd/.exe/.bat/.ps1) are stripped before
    matching, so C:\Program Files\nodejs\npx.cmd -y left-pad is caught.
  • Only the first package token decides; later positional arguments are the
    server's own operands (npx -y pkg /data).
  • An optional leading v in the version (pkg@v1.2.3) counts as pinned.

Scope

  • Reads only the existing command/args keys of mcp_server_view -- no
    serializer, McpServerInfo, or JSON-output change (consistent with how the
    existing concerns are table-only).
  • Files: cli/mcp_cli.py (+65), tests/test_mcp_cli.py (+88); pure additions.

Testing

  • New test_mcp_list_flags_unpinned_launcher_packages covers the rows above.
  • tests/test_mcp_cli.py: 8 passed; pinned ruff 0.15.21 check + format clean;
    local CI preflight KNOWN-RED | new=0 (the 2 known reds are the documented
    Windows environment baselines: job-windows-lifecycle:group2_rc,
    job-desktop-quality:test_rc).

The posture line counts only servers whose configuration resolves, and
launcher availability differs by host (Windows path / uvx missing on CI),
so a hardcoded 9 failed upstream while passing locally. Derive the count
from the CONFIG column instead; the concerns map assertion is unchanged.

This branch has not been deployed

No deployments
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