You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Docs: quickstart MCP configs use unpinned npx -y, contradicting the Local Server Security guide #3431
The beginner examples should follow the Local Server Security guide, which says to "Install a specific version rather than latest". For example "args": ["-y", "@modelcontextprotocol/server-filesystem@1.0.0", ...], plus one sentence linking to that guide.
What actually happens?
The pages people copy from start every server unpinned: docs/develop/connect-local-servers.mdx (lines 100, 116, 216, 220, 273), docs/examples.mdx (lines 43, 50, 66 to 78), docs/develop/build-client.mdx (961) and docs/tools/debugging.mdx (131), in both the 2026-07-28 and draft versions. Each launch can fetch whatever was published last.
The pattern is widespread. In a random sample of 2,999 public GitHub repositories that ship agent skills or MCP configs, 159 of the 346 repositories that configure a local MCP server (46.0%) start at least one with no pinned version, and 63 of 346 (18.2%) ask for latest outright. A hand check found 19 of 22 findings correct. Caveat: it is a sample of what GitHub code search surfaces, not a census. Data and method: https://github.com/basitalisandhu/agent-skills-state-2026
Anything else?
The registry already rejects latest and version ranges for server.json packages (internal/validators/validators.go), so these docs are the main place that still teaches the unpinned form. If maintainers agree, I am happy to open the docs PR.
AI disclosure: I used Claude Code to help prepare the analysis and draft this issue.
+1, and one addition for the docs PR. The same guide has a next bullet that I think should go with the fix, so readers don't assume a pinned version freezes everything:
"Pinning a package version with a launcher such as npx or uvx fixes only the top-level package; its transitive dependencies are typically resolved fresh at install time, which is exactly where a compromised dependency arrives. Pinning a container image by digest (image@sha256:...) freezes the entire dependency tree."
(https://modelcontextprotocol.io/docs/tutorials/security/local-server-security)
Also a small gotcha with the proposed example. On npm, @modelcontextprotocol/server-filesystem has latest = 1.0.0 (published 2026-10-11), but the package also has CalVer versions like 2026.8.31, which sort higher under semver. An exact pin is fine, but any range in the docs would resolve to the CalVer line, not 1.0.0. I have not tested that with npm; it is from semver ordering. May be worth a note so the example gets bumped when the version moves.
npm takes the latest tag when it satisfies the range, so the proposed @1.0.0 example is safe, and so is ^1.0.0.
The exposure is anyone who wrote a date-based range before 11 October. npm install prints a deprecation warning and exits 0, npm outdated shows Wanted 2026.8.31, Latest 1.0.0, and npm update leaves them on 2026.8.31.
For the PR: mcp-server-git, -fetch and -time are still date-based on PyPI (2026.10.10), so a pinning example needs both formats.
Thanks, both. Rechecked today (16 Oct): npm latest for @modelcontextprotocol/server-filesystem is still 1.0.0 (published 11 Oct), and mcp-server-git, mcp-server-fetch and mcp-server-time are at 2026.10.10 on PyPI.
So the docs change would use exact pins in both formats, for example @modelcontextprotocol/server-filesystem@1.0.0 with npx -y and mcp-server-git@2026.10.10 with uvx, no ranges, plus the guide's sentence that a launcher pin fixes only the top-level package, linking to the image digest option.
Activity
sattyamjjain commentedon Oct 13, 2026
+1, and one addition for the docs PR. The same guide has a next bullet that I think should go with the fix, so readers don't assume a pinned version freezes everything:
"Pinning a package version with a launcher such as
npxoruvxfixes only the top-level package; its transitive dependencies are typically resolved fresh at install time, which is exactly where a compromised dependency arrives. Pinning a container image by digest (image@sha256:...) freezes the entire dependency tree."(https://modelcontextprotocol.io/docs/tutorials/security/local-server-security)
Also a small gotcha with the proposed example. On npm, @modelcontextprotocol/server-filesystem has latest = 1.0.0 (published 2026-10-11), but the package also has CalVer versions like 2026.8.31, which sort higher under semver. An exact pin is fine, but any range in the docs would resolve to the CalVer line, not 1.0.0. I have not tested that with npm; it is from semver ordering. May be worth a note so the example gets bumped when the version moves.
imran-siddique commentedon Oct 15, 2026
On the range question, I tested it. npm 11.16.0 against the live registry,
server-filesystem:npm takes the
latesttag when it satisfies the range, so the proposed@1.0.0example is safe, and so is^1.0.0.The exposure is anyone who wrote a date-based range before 11 October.
npm installprints a deprecation warning and exits 0,npm outdatedshows Wanted 2026.8.31, Latest 1.0.0, andnpm updateleaves them on 2026.8.31.For the PR:
mcp-server-git,-fetchand-timeare still date-based on PyPI (2026.10.10), so a pinning example needs both formats.basitalisandhu commentedon Oct 16, 2026
Thanks, both. Rechecked today (16 Oct): npm
latestfor@modelcontextprotocol/server-filesystemis still 1.0.0 (published 11 Oct), andmcp-server-git,mcp-server-fetchandmcp-server-timeare at 2026.10.10 on PyPI.So the docs change would use exact pins in both formats, for example
@modelcontextprotocol/server-filesystem@1.0.0withnpx -yandmcp-server-git@2026.10.10withuvx, no ranges, plus the guide's sentence that a launcher pin fixes only the top-level package, linking to the image digest option.