Repository navigation
docs: correct MCP distribution facts and fit the plugin to the directory rules - #7
Uzair-Ahmed-Dahraj wants to merge 7 commits into
Conversation
…a, awesome-mcp-servers, plugin directory)
There was a problem hiding this comment.
devkind-code-review: devkindhq/github-seo-skill #7
Mode: comment-only · Scope: docs-only PR (137+/19-, 6 markdown files). No lint/test surface in this repo; reviewed for factual consistency with the repo's own verified-claims convention.
Fact-checking the Smithery-shutdown correction surfaced two internal-consistency misses (rename-miss class):
Findings (2)
warning
- skills/github-seo/SKILL.md:3 — [consistency] The frontmatter
descriptionstill lists Smithery as an active registry: "…registry submissions (Official MCP Registry, Smithery, Glama, mcp.so)." The PR's own correction states Smithery shut down hosted services 31 Oct 2026 and must not be published to — a skill consumer matching on the description will be pointed at a dead publish route. The body text was updated (SKILL.md:89-90 area) but the frontmatter line was missed. Fix: drop Smithery or reword to "…Glama, mcp.so, and existing Smithery listings" to match README.md's new wording.
warning
- README.md:13 — [consistency] Same class: README still says "…registry submissions such as the Official MCP Registry, Smithery, Glama and mcp.so." Line 10 of the same file was corrected in this PR; line 13 wasn't. Fix: mirror the corrected line 10.
Verified good
- The Smithery table row,
smithery.yamlfile-matrix row, section 6 homepage list, and closing checklist line were ALL updated consistently — the correction is thorough everywhere else. _meta4 KB limit, npm-visibility timing, Glama build config, and awesome-mcp-servers sections follow the repo's [observed]/[verified]/[general] evidence convention with dates and sources. No secrets, no client data, no unverified claims presented as fact.
Both misses are in lines that consumers (skill-matching description; repo visitors) actually read, so they're worth a follow-up commit rather than a silent merge.
There was a problem hiding this comment.
devkind-code-review: re-review (verify-fixes) + adversarial pass @ f598093
Mode: comment-only · Scope: docs-only. Re-verified both prior findings, then ran a hostile source-by-source fact-check battery over every new claim.
Prior findings (2) — both CLOSED
| Finding | Verdict | Evidence at head f598093 |
|---|---|---|
| SKILL.md:3 frontmatter description still lists Smithery as active | ✅ CLOSED | Description now reads "…(Official MCP Registry, Glama, mcp.so) and existing Smithery listings" — matches the corrected body text. |
| README.md:13 still lists Smithery in registry list | ✅ CLOSED | Line 13 now reads "…such as the Official MCP Registry, Glama and mcp.so" — mirrors the corrected line 10. |
Whole-tree grep at head: no other stale Smithery publish guidance. evals.json still carries the "submit to smithery" trigger — intentional per PR body (the skill must still catch and redirect that request); agreed, not a finding. python3 scripts/validate_skill.py → ok at head.
Adversarial fact-check battery — sources re-pulled live today
| # | Claim in PR | Live source check | Verdict |
|---|---|---|---|
| 1 | Smithery shutdown: hosted URLs/API/Connect/Toolbox, accounts+keys, CLI+SDKs dead 31 Oct 2026; remains public non-proxied registry powered by Arcade.dev | smithery.ai/future fetched: matches word for word, including "now powered by Arcade.dev" | ✅ accurate |
| 2 | _meta 4 KB limit, error text "publisher-provided extension exceeds 4KB limit (N bytes)" |
modelcontextprotocol/registry validators.go @ main: maxExtensionSize = 4 * 1024, exact error string present in validatePublisherExtensions |
✅ accurate |
| 3 | "Only io.modelcontextprotocol.registry/publisher-provided is kept; registry drops every other _meta key" |
Same source: ServerJSON._meta only contains PublisherProvided data comment |
✅ accurate |
| 4 | npm timing: registry 404s version until npm serves it; error text quoted | registries/npm.go @ main: npmVersion404Error message matches verbatim ("A newly published release can take a moment to appear") |
✅ accurate |
| 5 | awesome-mcp-servers: owner/repo entry name (exact CI message), missing-glama label, Glama score badge format, permitted-emoji list, alphabetical order |
check-glama.yml @ main fetched and read: all five verified, including the verbatim CI comment "The entry name must use the full owner/repo format (not just the repo name)." |
✅ accurate |
| 6 | Badge "right after the repo link" vs bot's "after the server description" | Pulled the live README (5095 lines): every sampled entry is - [owner/repo](…) [![badge]…] 🐍 ☁️ - description. The bot's wording is looser than the list's actual format; the skill follows the list, which is what CI+reviewers enforce |
✅ accurate (skill correct; bot wording is the imprecise one) |
| 7 | Scope-emoji legend quotes (☁️ remote APIs / 🏠 locally installed software) | README.md legend note @ main: verbatim match | ✅ accurate |
| 8 | CONTRIBUTING.md sets no star minimum | Fetched @ main: confirmed, no star threshold; scope section routes remote-only servers to awesome-remote-mcp-servers exactly as stated | ✅ accurate |
| 9 | Cited awesome-list commit 29f2d49 (2026-11-02) |
Commit exists, dated 2026-11-02, and its PR (#18312) merge comment shows the glama-check bot in action | ✅ exists |
| 10 | Plugin directory: Owner/Directory-permission roles, private-until-live repo, org ownership of listing, 10-per-24h limit, MCPB deprecation | claude.com/docs/directory/publish.md + plugins/submit.md fetched: all match, including "first organization to submit a given repository folder holds that listing" | ✅ accurate |
| 11 | Lockfile hold list: package-lock/npm-shrinkwrap/bun.lock/bun.lockb, "yarn.lock is not on the list" | Pre-submission checklist @ claude.com: list matches exactly; the yarn.lock carve-out is correct and is a sharp, non-obvious catch | ✅ accurate |
| 12 | plugin.json directory fields (icon, documentationUrl, supportUrl, privacyPolicyUrl, termsOfServiceUrl) read from plugin.json only |
code.claude.com plugins-reference @ live: "Anthropic's directory reads the icon, documentationUrl, supportUrl, privacyPolicyUrl, and termsOfServiceUrl fields from plugin.json" — verbatim |
✅ accurate |
| 13 | /plugin install <name> --marketplace <owner>/<repo> needs v2.1.275+ |
code.claude.com plugins/publish.md @ live: in-session form "Requires Claude Code v2.1.275 or later" | ✅ accurate |
| 14 | Glama claim: personal-repo sign-in vs org glama.json maintainers + re-run Claim flow |
glama.ai blog post fetched: matches, including the org carve-out note ("This does not work for servers that are hosted under an organization") | ✅ accurate |
| 15 | Glama release numbering ≠ npm versions; releases drive summary/tools/score | [observed] label only — not verifiable without a Glama login; correctly labelled | ✅ properly labelled |
Findings (1)
low — claude-plugin-directory.md:77 ("Documented rules for packages and files" table)
- [consistency] The section header says
From claude.com/docs/plugins/pre-submission-checklist.md [verified, 2026-11-02], but three of the six rows document rules that live in a different part of the checklist than the table's context suggests — specifically the "A launcher with an exact pin → still held" row and the.npmrcrow. The current live docs split these between the "Review what the plugin runs and connects to" table and the "Choices a reviewer always checks" list, and the.npmrcrule's result there is two-tier ("Blocks with a launcher. Held for a reviewer with a package install") while this table records only "Blocks". A reader following this table into the docs will not find the rows verbatim in one place and may miss the two-tier.npmrcresult. Fix: either cite the doc section(s) per row, or add the package-install half of the.npmrcrule to the Result cell. Low severity: direction of every rule is correct; only the citation granularity and one result tier are imprecise.
Verified good (adversarial angle)
- Trigger coverage survives the Smithery removal — the skill still triggers on "submit to smithery" and now redirects instead of walking a dead flow. This was the biggest regression risk of the rename class and it is handled.
- No client names, domains, or repo identifiers leak into the new Glama/observed claims ("a Devkind npm MCP server" is the only self-reference, matching repo convention). Grepped at head.
- Every dated [observed] claim carries its own date and source label; the unverifiable-without-login Glama build claims are all [observed], none promoted to [verified]. Label discipline held under a hostile read.
- Internal cross-references: the conditional "Publish order" line now agrees with the 4 KB
_metarule; the checklist's "Then set the build (see Gotchas)" pointer resolves to a Gotcha that exists. No dangling references.
Verdict: both review findings properly closed in f598093; adversarial battery found no factual errors — one low-severity citation-granularity imprecision (finding above). From my side this is merge-ready once you decide whether finding L-1 is worth a follow-up line or a merge-as-is.
Smithery guidance is removed; one retired-platforms row remains, which the audit reads to flag leftover files.
devkind-code-review: delta re-review @
|
| Claim | Verdict |
|---|---|
Brand-name hold row ("Name matches a known brand", displayName/author.name scope) — verified against live claude.com/docs/plugins/pre-submission-checklist.md |
✅ matches source verbatim (Manifest table row: "Choose a name, displayName, and author.name that can't be mistaken for … well-known brand that isn't yours → Held for a reviewer") |
docker run / MCP-server-command hold ("MCP server command wasn't read") |
✅ matches source row: "Start each local MCP server by running a file in the plugin with plain arguments … not through a shell … or a package-manager script" — same title. Note: source generalizes to any non-file start (shell, -c, npm run), the doc row lists docker run as the instance — acceptable compression, the launcher enumeration (npx, bunx, pnpm dlx, yarn dlx, uvx, pipx run, uv run) matches the source exactly |
| "Decide first" privacy-policy / third-party-data guidance [Anthropic Software Directory Policy 1D/3A] | ✅ consistent with the source's policy link and the security-scan section (undisclosed data sends rejected); not independently fetched past the paywall-free policy article — labelled verified in-doc, spot-checked |
| Smithery retired-platform row ("shut down 31 Oct 2026, read-only directory remains") | ✅ smithery.ai/future fetched live this run — hosting/API/accounts/CLI/SDK all stop, registry remains public non-proxied, powered by Arcade.dev. Row is accurate |
| CHANGELOG: Smithery dropped from the 2026-11-02 entry | ✅ consistent — history moved to the retired table rather than deleted |
New scripts — execution results (run at head, with gh auth)
scripts/check_listings.py — ran on two real Devkind MCP servers:
-
devkindhq/whatweb-mcp→ PASS registry 1.0.0, PASS Docker Hub tag, PASS Glama, WARN awesome-mcp-servers, rc=0 -
devkindhq/theharvester-mcp→ same shape, rc=0 -
✅ Exit-code contract honored (1 on any FAIL), README/docs usage line matches behavior, read-only throughout (GET/HEAD only,
ghreads only). -
🟡 MEDIUM — Glama check can false-FAIL when Glama's slug ≠ GitHub slug. The check hardcodes
https://glama.ai/mcp/servers/<owner>/<repo>. Probe this run:punkpeye/awesome-mcp-servers→ 200,devkindhq/whatweb-mcp→ 200,modelcontextprotocol/server-filesystem→ 404 (that server IS on Glama under a different slug), random nonexistent → 404. So the check is sound for Devkind's own naming convention but will report FAIL for any repo whose Glama slug differs. Consider a fallback (Glama search endpoint) or downgrading a Glama 404 to WARN with a "verify slug by hand" note. -
LOW:
check_listings.pyrequiresghauth but the failure mode is a cleanrequired=Trueexit with a helpful message — fine; just note in SKILL.md that it needsgh(the checklist doc does say "It needsghlogged in" ✅).
scripts/check_repo_seo.py retired-platform guard — mutation-tested:
- ✅ Positive control: injecting a
deploy/smithery.yamlpath fires FAIL; live run ondevkindhq/whatweb-mcpcorrectly FAILs on the repo's realsmithery.yaml+README.md:168— the guard works against a real offender, not just fixtures. - ✅ Negative control: unrelated paths pass. Table parsing (
## Retired platforms→ platform names) verified; missing-section guard hard-exits as documented. - LOW: scoping is correct — the guard flags file paths and
README.mdlines only, and the retired-platforms doc says "keep released changelog entries", so a CHANGELOG.md mention is deliberately not flagged. Consistent. - LOW (pre-existing class, now load-bearing): guard reads file paths + README lines only; a Smithery mention in e.g.
docs/markdown isn't caught (the FAIL message's owngit grep -n -i smitheryhint covers this — acceptable manual follow-through).
Disposition of prior findings
No open findings from the first review / re-review remain unaddressed in this delta — the Smithery-facts correction series is now coherent (facts table → retired table → enforcement script), and the enforcement is real (verified above).
Checks: no test suite in repo (docs+scripts only); both scripts ast.parse clean; check_listings.py rc contract verified.
Verdict: ✅ ship. One MEDIUM (Glama slug false-FAIL) worth a follow-up commit, not a hold.
There was a problem hiding this comment.
devkind-code-review: devkindhq/github-seo-skill #7 — delta re-review (retired platforms + check_listings.py)
Mode: comment-only · Head: c9d19ab2f8e42aaf1b962f17953e2810240e3aa7 · Follow-up on review 5758167832 (commit f598093e).
Reviewed the new commit c9d19ab2f8 only (retired-platforms table, check_listings.py, Decide-first section, 2 new validation rows).
Execution-verified ✅
Ran both scripts against live targets at the head:
check_repo_seo.py devkindhq/github-seo-skill → 10 PASS, 1 FAIL: retired: Smithery — README.md:13
check_listings.py devkindhq/whatweb-mcp → Official Registry PASS 1.0.0, Docker Hub tag PASS, Glama PASS, awesome-mcp-servers WARN
check_listings.py is genuinely read-only (GET-only, gh read calls), exits 1 only on FAIL — good. The npm version-match check comparing against pkg.version or live.version is the right drift check.
Findings
1. 🟡 MEDIUM — check_repo_seo.py flags your own README at head: FAIL retired: Smithery — remove README.md:13.
README.md:13 still reads "…Official MCP Registry, Smithery, Glama and mcp.so". The new retired-platform check catches the PR's own repo — the dogfood is nice proof the guard works, but it means the skill's repo ships with a failing Step-2 audit. Remove Smithery from the README line (or link it as the retired-platforms note) and merge.
2. 🟡 MEDIUM — claude-plugin-directory.md:106 cites a rule the live checklist does not state.
New row: "A local MCP server starts with something other than a file in the plugin, such as docker run | Held". Live source (pre-submission-checklist.md, fetched today) says: "Start each local MCP server by running a file in the plugin with plain arguments … not through a shell or a package-manager script such as npm run". docker run never appears in the live checklist (grep: 0 hits). The rule class (start from a file in the plugin) is real and your row's result/title match verbatim; the docker run example is a plausible-but-uncited addition presented under a [verified, 2026-11-05] banner that only the brand row earned. Per this skill's own citation discipline, either attribute the docker run example as [observed] or swap the example to the source's npm run.
3. ✅ Verified correct — the "Decide first" claims. Live Anthropic Software Directory Policy says verbatim: "Developers of Software that collects user data or connects to a remote service must provide a clear, accessible privacy policy link…" and "Software must prioritize protecting user privacy and the privacy interests of third parties". Both quoted accurately. The brand-name row ("Name matches a known brand", Held) also matches the live checklist exactly.
4. ✅ Nit-level — check_listings.py Glama check is a bare 200 on glama.ai/mcp/servers/<slug>; Glama serves a 200 soft-page for unknown servers in some cases. The awesome-mcp-servers WARN (not FAIL) is the right severity choice.
Non-blocking otherwise. The single-source-of-truth retired table driving the audit script is a good pattern — adding a row retires a platform everywhere.
— posted by the nightly PR audit (superbro-dev)
The checklist does not name docker run. Glama can list a server under another name, so a 404 is not proof it is missing.
There was a problem hiding this comment.
devkind-code-review: verify-fixes delta pass at 5769b244 — APPROVED
Per-finding disposition of review 5819251062 (Nov 8, c9d19ab2):
| Finding | Status | Evidence at head |
|---|---|---|
| M1 README.md:13 still names Smithery | ✅ FIXED | grep -ci smithery README.md → 0; the only Smithery mention left is the deliberate retired-platforms table row (mcp-registry-checklist.md:53), which the check treats as its source-of-truth |
M2 docker run example under a [verified] banner |
✅ FIXED | claude-plugin-directory.md row now quotes the checklist verbatim ("running a file in the plugin … not through a shell or a package-manager script such as npm run"); the docker run extrapolation moved to a separate note labelled [inference, 2026-11-09] — exactly the citation-discipline fix requested |
| Nit: Glama check was a bare 200 | ✅ FIXED | check_listings.py now records WARN on 404 ("Glama can list a server under another name"), doc text updated to match |
Checks run at head 5769b244 in a fresh clone:
python3 scripts/validate_skill.py→okpython3 -m py_compileon both check scripts → ok- Full delta
c9d19ab2..5769b244read: 4 files, +18/−9, all changes map to the two findings; no drive-by edits, CHANGELOG row updated honestly (docker run→MCP server command)
One pass per the standing arrangement — not re-reviewing this PR again. Merge is yours.
— nightly PR audit (superbro-dev)
…e not Verified The Claude plugin directory refused v0.2.0 for files outside the allowed types. The audit and listing scripts become written checks in references/audit-checks.md, the validator runs inline in CI, and the SVG assets go. The plugin directory reference gains the rules for an organisation that is not Verified.
There was a problem hiding this comment.
Review of head d073451 (diffed against its parent 5769b24, plus the full PR against merge-base 15c2e9d). The earlier approval predates this commit, so I re-reviewed it standalone: it deletes check_repo_seo.py, check_listings.py, validate_skill.py and the SVG assets, inlines the CI validator, and adds references/audit-checks.md plus the "Organisations that are not Verified" section.
What I executed / verified live (2026-11-11):
- Extracted the heredoc Python from
.github/workflows/ci.ymland ran it against the checkout: printsok, exit 0. CI on this commit:validateandskills-shboth green. - Ran the doc's own refusal-listing commands (
git ls-files | grep -v ..., shebang awk) on this repo: clean — the commit achieves its stated goal. - Diffed quoted strings against live sources. Verbatim matches confirmed: registry
validatePublisherExtensions4KB error string andnpm.go404 message (mcp-install-and-metadata.md); plugin checklist lockfile/launcher/MCP-command/256KiB/512-file rows and the new bundled-image rule;submit.md"reads and scans only that folder"; 10-submissions/24h limit;icon/documentationUrl/supportUrl/privacyPolicyUrl/termsOfServiceUrlread fromplugin.jsononly (manifest reference "Directory listing fields"); awesome-mcp-serverscheck-glama.ymlowner/repo-format message, badge format,missing-glamalabel, "passes all checks" / "start and respond to introspection requests" bot text, permitted-emoji list, README legend ☁️/🏠 note; Smitherysmithery.ai/futureshutdown (31 Oct 2026); Glamaglama.jsonclaim flow (blog 2025-07-08);anthropics/claude-plugins-official#7024exists, open, title matches.
Verdict: COMMENT — three factual corrections should land before merge (findings 1–3 below; inline). Not approving with those open.
Findings:
mcp-registry-checklist.md:100-101— the rules are attributed to "check-glama.ymlandCONTRIBUTING.md[verified, 2026-11-02, commit 29f2d49]". I fetchedCONTRIBUTING.mdboth at the pinned commit29f2d490(2026-11-02) and on current main: it contains none of the listed rules — no Glama mention, no badge requirement, no emoji rules. Every quoted rule actually comes from the CI workflow and the bot comments. The "andCONTRIBUTING.md" attribution is wrong and undermines the label system this skill is built on.mcp-registry-checklist.md:122— "The Glama checks are the gate for this list [verified, 2026-11-03, CONTRIBUTING.md]": same problem,CONTRIBUTING.mdnever mentions Glama, so it cannot be the source for that claim. Cite the workflow/bot instead.claude-plugin-directory.md:41-47+:62— SVG/ICO is left internally tense: the portal list (observed) permits ICO and not SVG, while the live public checklist (which I re-pulled today) says "Include only text files, SVG included, complete PNG, JPEG, GIF, and WebP images, and font files. Any other binary file, such as an.ico… is held." The doc states both halves in different bullets but never says they conflict; and thegit ls-filesrefusal-listing command whitelists.ico, which the public checklist holds. Add one explicit sentence: portal list and public checklist disagree on SVG and ICO — treat.icoas risky and re-check at Validate.- (Pre-existing, not introduced here, but in scope for a claims PR)
mcp-install-and-metadata.md:30-31— "supported hosts are Docker Hub,ghcr.io, Google Artifact Registry,*.azurecr.ioandmcr.microsoft.com" drops Quay.io (quay.io), which the liveofficial-registry-requirements.mdlists as supported. A user following this would wrongly avoid quay.io. claude-plugin-directory.md:111vs the repo's own.claude-plugin/plugin.json— the reference says "SetdisplayName, and seticonto a path inside the plugin", and the manifest reference confirms the directory readsiconfromplugin.jsononly; this repo setsdisplayNamebut noiconfield. If Devkind submits this plugin, the listing icon won't come from the existing.claude-plugin/icon.png.README.md:65— "The listing checks read public pages of the Official MCP Registry, npm, Docker Hub and Glama" omits awesome-mcp-servers, whichaudit-checks.mdalso reads (viagh api). Internal inconsistency between the two files this PR touches.
Suggestions (gaps worth a follow-up):
audit-checks.mdlisting table: the checklist says PulseMCP and mcpbench.ai ingest from the Official Registry ("Verify it appears"), but the listing checks stop at registry/npm/Docker Hub/Glama/awesome. Both are public pages — cheap rows to add, and they close the loop the checklist opens.audit-checks.mdnpm row: note that a scoped identifier (@scope/pkg) needs the slash URL-encoded in the registry path (/@scope%2Fpkg/latest); the deleted script handled this, the doc silently drops it.claude-plugin-directory.mdPrerequisites: the livesubmit.mdadds a private-repo requirement the reference misses — the Claude GitHub App must be installed on the repository and connected to the Claude org, plus explicit consent to source upload. That's a real submission blocker worth a bullet.CONTRIBUTING.mdnow says only "CI checks … on each pull request", so a contributor must push to discover a validation failure. Paste the same heredoc one-liner into CONTRIBUTING (or amake validate) so it runs locally.- The changelog "Removed" line paraphrases the portal rule as "accepts only Markdown, text, JSON, YAML and PNG, JPEG, GIF, WebP or ICO files" — it drops the portal's UTF-8/
#!/package-manager conditions the reference correctly carries; fine as a summary, but consider "see the reference for the full rule".
Everything else checked out: evals updated to the new flow, SKILL.md description matches the registry checklist, repo tree matches the documented layout, no stale references to the deleted scripts outside the changelog history entries (correct to keep those), and the inline CI validator is behaviorally equivalent to the deleted validate_skill.py on this repo.
| ## awesome-mcp-servers | ||
|
|
||
| `punkpeye/awesome-mcp-servers` needs a Glama listing first. Its CI | ||
| (`.github/workflows/check-glama.yml`) and `CONTRIBUTING.md` require the following |
There was a problem hiding this comment.
Fact-check (live, 2026-11-11): I fetched CONTRIBUTING.md from punkpeye/awesome-mcp-servers both at the pinned commit 29f2d490cc02 (2026-11-02, the commit this cites) and on current main — it contains none of the rules listed below: no Glama mention, no badge requirement, no owner/repo entry-name rule, no emoji rules. Every one of those rules lives in .github/workflows/check-glama.yml and the bot comments (those strings I did verify verbatim: "The entry name must use the full owner/repo format (not just the repo name).", the badge template, missing-glama, the permitted-emoji array). Please drop "and CONTRIBUTING.md" from the attribution (and from the citation) — as written, a [verified] label points at a source that doesn't contain the claim.
| remote APIs", 🏠 "when MCP server is talking to a locally installed software" [verified, | ||
| 2026-11-03, README legend note]. | ||
| - Put the badge right after the repo link, as the existing entries do [observed, 2026-11-03]. | ||
| - `CONTRIBUTING.md` sets no star minimum. The Glama checks are the gate for this list |
There was a problem hiding this comment.
"CONTRIBUTING.md sets no star minimum" is true, but the citation "[verified, 2026-11-03, CONTRIBUTING.md]" can't also cover "The Glama checks are the gate for this list": CONTRIBUTING.md (both at commit 29f2d49 and on main today) never mentions Glama at all. The gate claim is enforced by check-glama.yml (badge + passes all checks bot message) — cite that instead.
| a package manager configuration file, and a text file that is not UTF-8 or has NUL bytes. A | ||
| license, a readme, `.gitignore` and the icon can stay if they are UTF-8 text or an allowed | ||
| image and do not start with `#!`. | ||
| - SVG is not on the portal's list. The public checklist permits SVG [verified, 2026-11-11, |
There was a problem hiding this comment.
This SVG bullet and the "Refused now" bullet above it are both plausible, but the doc never states that they conflict with the public checklist in the opposite direction the reader expects. Live claude.com/docs/plugins/pre-submission-checklist.md (re-pulled today) says: "Include only text files, SVG included, complete PNG, JPEG, GIF, and WebP images, and font files. Any other binary file, such as an .ico, .pdf, or .zip file or a compiled executable, is held." So the public checklist permits SVG but holds .ico, while the portal's non-Verified list (observed) permits ICO and not SVG — the two disagree on exactly the two formats this section is deciding between. Suggest one explicit sentence: the portal list and the public checklist conflict on SVG and ICO, so a non-Verified org should treat both as risky and let Validate decide. Also note the public checklist additionally allows font files, which the portal list here doesn't mention either.
| List the files the directory is likely to refuse. Run this in the plugin folder: | ||
|
|
||
| ```bash | ||
| git ls-files | grep -v -i -E '\.(md|txt|json|ya?ml|png|jpe?g|gif|webp|ico)$' | grep -v -E '(^|/)(LICENSE|\.gitignore)$' |
There was a problem hiding this comment.
Nit on the refusal-listing command: it whitelists .ico (consistent with the portal list, but the public checklist holds .ico — see my note above), and it doesn't whitelist other text files the portal bullet says can stay (a readme is already .md, fine). More useful: also print files that are not valid UTF-8, since that's a stated refusal reason — e.g. git ls-files -z | xargs -0 file or a small iconv -f utf-8 pass — or at least mention in the prose that encoding/NUL checking is deliberately out of scope for both commands (the prose below covers the #! gap but attributes encoding only to the second command's limits).
| shows a note that the listed packages were not installed, because plugin installs do not support | ||
| yarn or pnpm lockfiles [observed, 2026-11-03, `claude plugin list`]. A server that runs from | ||
| npm through `npx` never uses those packages, so the note does not affect it [general]. | ||
| - Set `displayName`, and set `icon` to a path inside the plugin, such as ./assets/icon.png. The |
There was a problem hiding this comment.
Docs-vs-repo contradiction: this line says to set icon in the plugin (and the manifest reference confirms the directory reads icon from plugin.json only), but this repo's own .claude-plugin/plugin.json sets displayName and has no icon field — the existing .claude-plugin/icon.png won't be picked up as the listing icon. Since this PR's whole purpose is fitting this plugin to the directory, add "icon": "./.claude-plugin/icon.png" (or move the PNG and point at it) before submitting.
| you have logged in, using read-only requests. When the skill guides an MCP server submission, it | ||
| This repo collects no data and runs no server. The audit only calls the GitHub CLI (`gh`) | ||
| you have logged in, using read-only requests. The listing checks read public pages of the Official | ||
| MCP Registry, npm, Docker Hub and Glama. When the skill guides an MCP server submission, it |
There was a problem hiding this comment.
"The listing checks read public pages of the Official MCP Registry, npm, Docker Hub and Glama" — audit-checks.md's listing checks also read punkpeye/awesome-mcp-servers (README via gh api + PR search). Add it so the README matches the reference this PR introduces.
| ```bash | ||
| gh api repos/punkpeye/awesome-mcp-servers/contents/README.md -H "Accept: application/vnd.github.raw" | grep -i -c "\[owner/repo\]" | ||
| gh pr list --repo punkpeye/awesome-mcp-servers --state all --search "owner/repo" --json number,state | ||
| ``` |
There was a problem hiding this comment.
Suggestion: the registry checklist says PulseMCP and mcpbench.ai ingest from the Official Registry ("Verify it appears"), but the listing checks stop at registry/npm/Docker Hub/Glama/awesome — the verification loop the checklist opens is never closed. Both are public pages with predictable URLs; one row each would finish the job.
| | Listing | URL | Pass | Otherwise | | ||
| |---|---|---|---| | ||
| | Official MCP Registry | `https://registry.modelcontextprotocol.io/v0/servers/<name, URL-encoded>/versions/latest` | 200. Note `server.version` and `server.packages`. | Fail: not found. | | ||
| | npm package (for each npm entry in `server.packages`) | `https://registry.npmjs.org/<identifier>/latest` | 200, and `version` equals the version of that package entry, or `server.version` when the entry has none. | Warn: the versions differ. Fail: not found. | |
There was a problem hiding this comment.
Nit: for a scoped npm identifier the registry path needs the slash encoded — https://registry.npmjs.org/@scope%2Fpkg/latest (/@scope/pkg/latest also resolves via redirect today, but the encoded form is what the API documents and what the deleted script used). One clarifying word, "URL-encoded" (as the registry row already does for the server name), would keep the deleted script's behavior.
| run: python3 scripts/validate_skill.py | ||
| - name: Compile the audit script | ||
| run: python3 -m py_compile skills/github-seo/scripts/check_repo_seo.py | ||
| # Inline, because the plugin directory refuses script files from this repo. |
There was a problem hiding this comment.
Verified the inlined validator: I extracted the heredoc body and ran it against the checkout — prints ok, exit 0 — and it is behaviorally equivalent to the deleted validate_skill.py on this repo (only the nicer relative_to(ROOT) error paths are lost). One gap: CONTRIBUTING.md now says only "CI checks … on each pull request", so contributors must push to discover a failure. Consider pasting the same python3 - <<'EOF' … block into CONTRIBUTING as a local pre-push step — YAML/markdown files are allowed by the portal list, so no conflict with the reason this was inlined.
Problem
The skill's MCP distribution guidance is out of date or missing in nine places (items 1 to 9), and the plugin does not pass the Claude plugin directory (items 10 and 11):
_metapublisher-provided data. A server that lists all its tools there fails to publish.owner/repoentry name.plugin.jsonfields the directory reads, or how to check the plugin locally.#!. The repo holds three Python scripts and two SVG files, and this PR added one more script.Fix
SKILL.md, the Smithery reference rows, README: Smithery is now a passive registry, so the skill drops Smithery publish, deploy andsmithery.yamlsteps. An existing listing stays.mcp-install-and-metadata.md:_metalimit, with the exact error text;npm view <pkg>@<version>returns the version.mcp-registry-checklist.md:glama.json;owner/repo, the Glama badge, permitted emojis and alphabetical order;server.jsonlists tools, so it agrees with the new 4 KB rule.claude-plugin-directory.md:displayNameandicon, the README data section, andclaude plugin validate.CHANGELOG.md: a new Unreleased entry.check_repo_seo.py,check_listings.py,scripts/validate_skill.py,assets/icon.svg,assets/social-preview.svg.references/audit-checks.md: the repo audit and the listing checks as read-onlyghcommands and tables, with the same thresholds as the scripts..github/workflows/ci.yml: the validator checks run inline. Thepy_compilestep is gone with its file.SKILL.md,mcp-registry-checklist.md,evals.json, README, CONTRIBUTING, SECURITY and both templates point to the new reference.claude-plugin-directory.md:Verification
Sources, with each claim labelled as
SKILL.mdrequires:_metalimit: modelcontextprotocol/registryinternal/validators/validators.go(maxExtensionSize = 4 * 1024, "exceeds 4KB limit (%d bytes)"), anddocs/reference/server-json/official-registry-requirements.md. [verified] Also observed on a Devkind npm MCP server with 125 tools: 4474 bytes. [observed, 2026-11-02]internal/validators/registries/npm.go: "exists, but version '%s' was not found (status: 404). A newly published release can take a moment to appear". [verified] The version appeared about one minute afternpm publish. [observed, 2026-11-02]CONTRIBUTING.md, and.github/workflows/check-glama.yml(themissing-glamalabel,permittedEmojis, and "The entry name must use the fullowner/repoformat"). [verified]glama-checkbot comment on Add ciperx/battle-training-mcp (battle.training arena) 🤖🤖🤖 punkpeye/awesome-mcp-servers#18398, the README legend note, andCONTRIBUTING.md(no star minimum). [verified] One line per merged PR: 100 of the last 100 merged PRs add one line. [observed, 2026-11-03]displayName,iconand the listing URL fields. [verified] The install note on a yarn repo comes fromclaude plugin list. [observed, 2026-11-03]Checklist:
python3 scripts/validate_skill.pyprintsokCHANGELOG.mdupdatedgit ls-filesscan: the only files outside the accepted types areLICENSEand.gitignore, which the portal permits. No tracked file starts with#!.ok, and exits 1 on a broken link added on purpose.claude plugin validate .:✔ Validation passed.npx -y skills@1.7.4 add . --list:Found 1 skill.Review Notes
docker.io/prefix, the default tag, which version to compare). They are in.SECURITY.mdand the bug report template still named the audit script. Both are corrected.npx skills add ...still gives a "download-and-run" warning in the directory. The portal says that documentation needs no change.