Rightshold™ Sign up

Answers · MCP security

How do I pin MCP server versions and review what changed before upgrading?

Short answer: Run every local MCP server at an exact version, make each upgrade a deliberate change, and review the published package and its tool list, not just the changelog, before you switch. In practice: replace npx some-server or @latest with some-server@1.4.2 (uvx some-server@1.4.2 for Python, or a container image by digest); add a release-age delay so brand-new versions aren't installed the day they appear; when an update is offered, read the release notes, diff the two published versions with npm diff, run the new version in a sandbox and compare its tools/list with the one you approved; then change the pin. The changelog alone is not enough: in September 2025 the npm package postmark-mcp, which impersonated Postmark, shipped 15 working versions and then a 1.0.16 whose one added line BCC'd every email to the attacker. Nothing in a version number tells you that; a diff of the published code does.

Checklist

  1. Pin exactly in your client config: an exact version in the args ("some-server@1.4.2", never @latest or a bare package name), uvx some-server@1.4.2, or a Docker image referenced by @sha256 digest. For servers you install as dependencies, commit the lockfile.
  2. Add a release-age delay: npm's min-release-age (days), pnpm's minimumReleaseAge (minutes; 1440, one day, by default in current pnpm), and uv's exclude-newer (accepts durations such as "7 days") refuse versions newer than the window, which gives the registry and researchers time to catch a malicious release.
  3. Let a bot open the upgrade, not your agent: Dependabot or Renovate turns a new version into a pull request you review. Dependabot applies a 3-day cooldown to version updates by default and lets you set your own with cooldown; security updates skip the cooldown.
  4. Read the release notes and the compare view between the two tags, and look for new tools, new network destinations, new environment variables or credentials, and new install scripts.
  5. Diff what is actually published: npm diff --diff=some-server@1.4.2 --diff=some-server@1.5.0 compares the two registry tarballs. The source repository can look clean while the published package differs, and the package is what runs.
  6. Check provenance: npm audit signatures verifies registry signatures and provenance attestations of installed packages; a package that suddenly loses provenance or changes publisher deserves a closer look.
  7. Diff the tool list before you switch: start the new version in a sandbox with no real credentials, fetch tools/list (the MCP Inspector can do this), and compare names, descriptions and schemas with the hash you stored at approval. A new or changed tool needs a fresh approval.
  8. Change the pin in one reviewed commit, keep the old version one line away for rollback, and log which version each environment runs.

What pinning does and doesn't cover

Why a delay window helps

Ask Rightshold (free, no key)

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “This MCP server just released a new version. Has its tool list changed since it was recorded, and what exactly changed?”

One-click setup

{
  "tool": "check_tool_integrity",
  "arguments": {
    "server": "<the server's Rightshold slug or id>"
  }
}

Rightshold compares remote servers' tool definitions with recorded fingerprints. It does not diff npm or PyPI packages, review changelogs, or certify that a version is safe.

Sources

Related

Not legal advice. Updated 2026-10-29. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'