Repository navigation
@genclass/mcp: the plugin ships the launcher's lockfile for the Anthropic directory - #125
Merged
Merged
Conversation
…ge.json, package-lock.json) Anthropic's directory validator warned "Launcher lock missing" for mcpServers.genclass in .mcp.json (2026-10-28, genclass-dev/genclass-plugin main @ e911b25): a package-lock.json next to the manifest that declares the server, with exact versions, registry sources and hashes, is required for the Verified badge, and its hold on pinned npx launchers prefers a package that ships a lockfile. - plugin/package.json: private, one dependency, @genclass/mcp at package.json's version. - plugin/package-lock.json: lockfileVersion 3, from `npm install --package-lock-only --ignore-scripts` in the plugin folder (the version, its registry tarball, its sha512 integrity; 659 bytes). No node_modules committed; the root package-lock.json is untouched. The daily sync carries both to genclass-plugin. - test/manifests.test.ts: package.json is a JSON pin; the lock is a lock pin (lockfileVersion 3, the root dependency and the entry at the version, resolved to the registry tarball, every entry with an exact version, a registry source and a sha512 integrity; a missing integrity fails, never rewrites). Only npm writes the lock, and only once npm serves the version, while release-mcp.yml runs the tests at the tag before publishing: between a bump and its release the lock may stay at the previous release, consistent at its own version, while npm does not serve the new one (npm view, in that state only); once npm serves it the test fails until the lock is regenerated. The sync regenerates it with the npm command. - Claude Code 2.1.311 installs a plugin's lockfile when it installs the plugin (npm ci --ignore-scripts --workspaces=false --no-audit --no-fund in the plugin's cache folder); the launchers still run npx. - CHANGELOG (Unreleased), docs/adoption/listings/mcp.md section 3, one sentence in the plugin README. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
MeharPro
force-pushed
the
claude/busy-hawking-abb88b
branch
from
October 28, 2026 17:01
5208c73 to
14c2cf0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The Claude Code plugin folder (
packages/mcp/plugin/) now shipspackage.json(private; its one dependency is@genclass/mcpat the package's version) andpackage-lock.json(lockfileVersion 3;@genclass/mcp@0.2.1with its registry tarball and sha512 integrity, 659 bytes), generated withnpm install --package-lock-only --ignore-scriptsin that folder. Nonode_modulesis committed and the rootpackage-lock.jsonis untouched. The daily sync carries both files to genclass-dev/genclass-plugin (the generator test, byte-identical copy within 256 KiB per file and 512 files, passes with them).Anthropic's directory validator said on 2026-10-28 (genclass-dev/genclass-plugin,
main@ e911b25): warning "Launcher lock missing · .mcp.json · mcpServers.genclass: Ship a package-lock.json (npm ci) or uv.lock next to the manifest that declares this server; exact versions, registry sources and hashes are required for the Verified badge", and a policy hold "Runs a pinned npx or uvx package (2 findings): Prefer a package that ships a lockfile, or vendor the package's readable source into the plugin and run it from ${CLAUDE_PLUGIN_ROOT}".Expected to clear, and what it cannot
package.jsonandpackage-lock.jsonsit next to.mcp.jsonat the plugin root, with the exact version, the registry source and the integrity, which is what the warning asks for..mcp.jsonandhooks/hooks.json). Its text prefers "a package that ships a lockfile", which the plugin now does, but a hold is a reviewer's decision, and the launchers still runnpx -y @genclass/mcp@0.2.1. The certain way around it remains vendoringdist/cli.jsinto the plugin and running it from${CLAUDE_PLUGIN_ROOT}(a committed build output; left to the owner, asdocs/adoption/listings/mcp.mdsays).Local validator
claude plugin validate --profile directory(Claude Code 2.1.311) on the assembled tree (node packages/mcp/scripts/plugin-repo.mjs <out>) says "These checks found nothing to report", with and without the lock, also with--strict: the lockfile check runs in the portal only. CI's pinned@anthropic-ai/claude-code@2.1.296 plugin validate ... --strictpasses on the plugin folder and the repository root.What the lock does at install time (verified)
Claude Code 2.1.311 installs a plugin's dependencies when it installs the plugin if
package.jsonand a v2/v3package-lock.json(ornpm-shrinkwrap.json,bun.lock) are at the plugin root:npm ci --ignore-scripts --workspaces=false --no-audit --no-fundin the plugin's cache folder. Installing the assembled plugin into an isolatedCLAUDE_CONFIG_DIRputnode_modules/@genclass/mcp0.2.1 (1.3 MB unpacked) underplugins/cache/genclass/genclass/0.2.1/. The launchers are unchanged, so that copy is not what runs..mcp.jsoncould later point at${CLAUDE_PLUGIN_ROOT}/node_modules/@genclass/mcp/bin/genclass-mcp.mjs, but a Claude Code without the installer would then have no server, so that is not done here.npm packalso putsplugin/package.jsonandplugin/package-lock.jsoninto the@genclass/mcptarball (thepluginfolder is infiles); harmless.The test (
packages/mcp/test/manifests.test.ts)plugin/package.jsonis a JSON pin: its dependency equalspackage.json's version; the sync rewrites it.plugin/package-lock.jsonis a lock pin: lockfileVersion 3, the root dependency on@genclass/mcpat the version, that entry resolved to the registry tarball of that version, every entry with an exact version, a registry source and a sha512 integrity. A missing integrity fails and is never rewritten: only npm writes the lock.release-mcp.ymlruns these tests at the tag before publishing andmcp.ymlruns them on the bump commit. So between a bump and its release the lock may stay at the previous release, consistent at its own version, while npm does not serve the new version (asked withnpm viewin that state only: E404 means not served; an unreachable npm counts as unknown and passes with a note that--silent=falseshows). Once npm serves it, the test fails until the lock is regenerated. In the steady state no npm call is made.npm run sync -w @genclass/mcp(GENCLASS_SYNC=1) regenerates the lock withnpm install --package-lock-only --ignore-scriptswhen it is not at the version; while npm does not serve the version (ETARGET) the lock stays. A release is therefore: bump, sync, tag; after the publish, sync again and commit the lock. In that window the daily sync carries a lock one release behind to the plugin repository.Docs
packages/mcp/CHANGELOG.md(Unreleased),docs/adoption/listings/mcp.mdsection 3 ("What the checks will say"), one sentence in the plugin README.Checks run
npm run typecheck -w @genclass/mcp,npm run build -w @genclass/mcp,cd packages/mcp && npx vitest run: 12 files, 149 tests pass. Not run: the e2e (race.e2e.mjs) and the bundle. Nothing published; nothing pushed besides this branch.🤖 Generated with Claude Code