charter fix --rule AE-MCP-001
AE-MCP-001 is partially auto-fixable. Charter can bump unpinned or behind-stable packages to the catalog’s stable version. Deprecated or archived packages require manual migration — Charter provides the successor package name in the finding evidence, but will not rewrite the entry automatically.
Why this rule
An MCP server at@latest can change behavior between runs without any change to the repo. A package can be deprecated, archived, or found to contain a known vulnerability after a repo first passed Charter. Pinning to an exact version ties the tool definition to a reviewable artifact — every tool-call behavior is deterministic across machines and runs.
What triggers it
Charter scans MCP configuration files for server entries launched by package runners and checks whether each entry pins an exact version. Scanned files:.mcp.json, mcp.json, .cursor/mcp.json, .vscode/mcp.json, .gemini/settings.json
Scanned runners: npx, bunx, uvx, pnpm dlx
The finding ladder based on signal type:
| Signal | Severity | Example |
|---|---|---|
| Deprecated or archived package | High | @modelcontextprotocol/server-github |
| Known CVE / GHSA advisory on pinned version | High | mcp-server-git@2025.8.0 |
Unpinned reference (@latest, semver range, missing version) | High | mcp-server-git@latest |
| Behind catalog stable, no advisory | Informational | Old exact pin, no known issues |
@latest, a missing version suffix, semver ranges (^1.0.0, ~1.0.0, >=1.0.0), floating git refs, or dynamic values like pkg@${VERSION}.
Examples
- Failing
- Passing
.mcp.json (floating tag)
.mcp.json (archived package)
How to fix
Score impact
Deprecated, unpinned, or advisory-covered findings areHigh (−10 each). The behind-stable-only nudge is Informational (0). No hard cap applies to MCP findings — caps are reserved for raw-secret findings.
Edge cases
Package specs are resolved only for direct runners (npx, bunx, uvx) and the dlx subcommand of pnpm/yarn. Local path arguments (./, /, ../) and exec/run forms launch local binaries and are not treated as registry packages. Scoped packages (@scope/name@1.2.3) are pinned only when the trailing version is exact. A dynamic pkg@${VERSION} reference is treated as unpinned.
Related rules
- AE-MCP-002 — remote MCP server origins must be trusted
- AE-MCP-003 — remote MCP servers must declare auth
- AE-SEC-002 — no raw secrets in MCP config files