From 01ca59caeefa0af39e1aa31e2c38c30d6ad9b88d Mon Sep 17 00:00:00 2001 From: Uzair Ahmed Date: Tue, 3 Nov 2026 11:25:49 +0500 Subject: [PATCH 1/5] docs: correct MCP distribution facts (Smithery, registry limits, Glama, awesome-mcp-servers, plugin directory) --- CHANGELOG.md | 3 ++ README.md | 2 +- skills/github-seo/SKILL.md | 6 ++-- .../references/claude-plugin-directory.md | 34 +++++++++++++++--- .../references/mcp-install-and-metadata.md | 25 +++++++++---- .../references/mcp-registry-checklist.md | 36 +++++++++++++++++-- 6 files changed, 89 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2abf192..2d30eed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes are listed here. The format follows [Keep a Changelog](https ## [Unreleased] +### Changed +- MCP distribution facts (2026-11-02): Smithery is now a passive registry, Official MCP Registry `_meta` 4 KB limit and npm version timing, Glama listing claim, awesome-mcp-servers requirements, Claude plugin directory rules. + ## [0.2.0] - 2026-11-02 ### Added diff --git a/README.md b/README.md index 81fba51..3ec168b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ GitHub SEO Skill is an Agent Skill for Claude Code that gets open-source GitHub repos found on Google and GitHub search. It audits a repo's name, description, topics and README, writes a search-ready README, runs a pre-publish secret and client-data check, and walks MCP servers -through registry submissions such as the Official MCP Registry, Smithery, Glama and mcp.so. +through registry submissions such as the Official MCP Registry, Glama and mcp.so. It works with any tool that supports the [Agent Skills](https://agentskills.io) format. diff --git a/skills/github-seo/SKILL.md b/skills/github-seo/SKILL.md index 542046d..13d4461 100644 --- a/skills/github-seo/SKILL.md +++ b/skills/github-seo/SKILL.md @@ -1,6 +1,6 @@ --- name: github-seo -description: Makes an open-source GitHub repo discoverable and safe to publish. Audits the repo name, description, topics and README for search, writes a search-ready README, runs a pre-publish secret and client-data check, and guides the launch sequence. Covers MCP server registry submissions (Official MCP Registry, Smithery, Glama, mcp.so). Use when the user wants more stars, traffic or search visibility for a repo, is about to open-source a project, asks for GitHub SEO or repo SEO, or wants to publish an MCP server. Not for general website SEO. +description: Makes an open-source GitHub repo discoverable and safe to publish. Audits the repo name, description, topics and README for search, writes a search-ready README, runs a pre-publish secret and client-data check, and guides the launch sequence. Covers MCP server registry submissions (Official MCP Registry, Glama, mcp.so) and existing Smithery listings. Use when the user wants more stars, traffic or search visibility for a repo, is about to open-source a project, asks for GitHub SEO or repo SEO, or wants to publish an MCP server. Not for general website SEO. license: MIT --- @@ -87,10 +87,12 @@ Fix failures first, then warnings. Start with `references/mcp-install-and-metadata.md`: choose the package type (npm, PyPI, OCI and others each have their own ownership check), complete `server.json` including `websiteUrl`, and lay out the README install routes per client. Then use `references/mcp-registry-checklist.md`. It covers the Official MCP Registry (`server.json` -plus the `mcp-publisher` CLI), Smithery, Glama, mcp.so, mcpservers.org, Cursor Directory, which +plus the `mcp-publisher` CLI), Glama, mcp.so, mcpservers.org, Cursor Directory, which registries auto-ingest from the Official one, and common gotchas (stale listings under a personal account, publish order, domain presence). Pitfalls from real runs (org namespace 403, OCI build and label, leaked-history scrub) are in the install reference. +Smithery shut down its hosted services on 31 Oct 2026 and is now a passive registry. Do not +publish to Smithery, and skip deploy or `smithery.yaml` work [verified, 2026-11-02, smithery.ai/future]. ## What not to do diff --git a/skills/github-seo/references/claude-plugin-directory.md b/skills/github-seo/references/claude-plugin-directory.md index 193027b..9498050 100644 --- a/skills/github-seo/references/claude-plugin-directory.md +++ b/skills/github-seo/references/claude-plugin-directory.md @@ -6,15 +6,23 @@ repeating this. Anything not seen during the run is marked [unverified]. ## Prerequisites -- A paid claude.ai plan [observed, 2026-11-02]. -- A public GitHub repo with `.claude-plugin/plugin.json` [observed, 2026-11-02]. -- A GitHub account with push access to the repo, used by the submitter [observed, 2026-11-02]. +- A paid claude.ai plan [observed, 2026-11-02]. On Team and Enterprise, the submitter needs the + Owner role or, on Enterprise, a custom role with the Directory permission [verified, 2026-11-02, + claude.com/docs/directory/publish.md]. +- A GitHub repo with `.claude-plugin/plugin.json` [observed, 2026-11-02]. The repo can stay + private while you validate and submit, but must be public before the listing goes live + [verified, 2026-11-02, claude.com/docs/plugins/submit.md]. +- A GitHub account with push access to the repo, used by the submitter [observed, 2026-11-02], + and connected on claude.ai in the submitting organisation [verified, 2026-11-02, same page]. +- The listing belongs to the organisation you submit from. Submit from the organisation that + should own it long term [verified, 2026-11-02, claude.com/docs/directory/publish.md]. - Limits: at most 10 submissions per organisation per 24 hours (drafts and withdrawn submissions count), and one submission per repo and folder [observed, 2026-11-02]. ## The five steps -1. **Source.** Point the portal at the repo and folder. +1. **Source.** In the portal, select Submit new, then Plugin bundle [verified, 2026-11-02, + claude.com/docs/plugins/submit.md]. Point the portal at the repo and folder. 2. **Listing details.** Name, description, icon and related listing fields. 3. **Data handling.** Questions on personal data, whether the plugin sends data to other services (declare this in the README), retention, and users under 18 [observed, 2026-11-02]. @@ -39,6 +47,19 @@ touches a fix [observed, 2026-11-02]. All rows [observed, 2026-11-02]. +### Documented rules for packages and files + +From claude.com/docs/plugins/pre-submission-checklist.md [verified, 2026-11-02]: + +| Rule | Result if broken | +|---|---| +| Pin every package a launcher runs to an exact version, such as `npx @1.2.3` | Blocks, "Unpinned npx launcher" | +| A launcher with an exact pin | Still held for a reviewer, "Runs a pinned npx or uvx package" | +| `.npmrc` or another file that sets a registry or package source, in a plugin with a launcher | Blocks | +| `package.json` beside `package-lock.json`, `npm-shrinkwrap.json`, `bun.lock` or `bun.lockb` in the plugin folder root | Held for a reviewer, "Dependencies install from a lockfile". `yarn.lock` is not on the list | +| Keep every file that is not an image or font under 256 KiB | Held for a reviewer | +| Keep the plugin to 512 files or fewer | Held for a reviewer | + ### Scanner false positives (second submission, 2026-11-02) Two more plugins went through Validate on 2026-11-02. The scanner reads text in skills and @@ -73,3 +94,8 @@ The review step offers an auto-publish toggle. Two update modes were shown [obse - `anthropics/claude-plugins-official` is by partner contact only [observed, 2026-11-02]. - Your own `marketplace.json` lets users run `/plugin marketplace add /` [general]. - A skills.sh listing is automatic, built from `npx skills add` telemetry [observed, 2026-11-02]. +- `/plugin install --marketplace /` adds the marketplace and installs in one + step. It needs Claude Code v2.1.275 or later [verified, 2026-11-02, + code.claude.com/docs/en/plugins/publish.md]. +- The directory no longer accepts desktop extension (MCPB) listings. Ship a local MCP server + inside a plugin bundle instead [verified, 2026-11-02, claude.com/docs/directory/publish.md]. diff --git a/skills/github-seo/references/mcp-install-and-metadata.md b/skills/github-seo/references/mcp-install-and-metadata.md index d85fbb7..d9326b3 100644 --- a/skills/github-seo/references/mcp-install-and-metadata.md +++ b/skills/github-seo/references/mcp-install-and-metadata.md @@ -20,6 +20,13 @@ mismatch is the most common publish failure. | Docker/OCI | `oci` | Image label `io.modelcontextprotocol.server.name` equals the `server.json` `name` | | MCPB bundle | `mcpb` | URL contains "mcp", and `fileSha256` is set (clients check the hash) | +npm timing: the registry checks that the exact version exists on npm. Right after `npm publish` +it can reject the version with "NPM package '...' exists, but version 'X' was not found (status: +404). A newly published release can take a moment to appear..." [verified, 2026-11-02, registry +`internal/validators/registries/npm.go`]. Publish to the registry only after +`npm view @` returns the version. The version became visible about one minute +after publish [observed on a Devkind npm MCP server, 2026-11-02]. + OCI details [verified]: supported hosts are Docker Hub, `ghcr.io`, Google Artifact Registry, `*.azurecr.io` and `mcr.microsoft.com`. The `identifier` is `registry/namespace/repository:tag` (a digest also works). Pin a version tag, not `latest`. Put the `LABEL` in the Dockerfile and @@ -71,11 +78,18 @@ Schema `2025-12-11` [verified]: | `repository` | `url` and `source` | Source link for inspection. | | `icons` | Optional | PNG or JPEG for UI display. | | `packages` | Array | One entry per install route (see section 1). | -| `_meta` | Vendor extension | Free-form. Put author, tool list and website here as a bonus, not instead of `websiteUrl`. | +| `_meta` | Vendor extension | Only `io.modelcontextprotocol.registry/publisher-provided` is kept, max 4096 bytes of JSON. Put author and website here as a bonus, not instead of `websiteUrl`. | Observed gap: a live entry that put the website only under `_meta` and left `websiteUrl` empty [observed, 2026-10-31]. Whether downstream directories display `_meta` is unknown, so fill both. +`_meta` limit [verified, 2026-11-02, registry `internal/validators/validators.go` +`validatePublisherExtensions` and `docs/reference/server-json/official-registry-requirements.md`]: +the registry drops every other `_meta` key, and fails the publish when the publisher-provided +object exceeds 4 KB, with "publisher-provided extension exceeds 4KB limit (N bytes)". A full +tool-name list can pass that limit. A 125-tool server failed at 4474 bytes [observed on a Devkind +npm MCP server, 2026-11-02]. Keep the tool list out of `_meta` for a large server. + Environment variables go in `packages[].environmentVariables` with `name`, `description`, `isRequired` and `isSecret`. Names only, never values. @@ -125,20 +139,17 @@ server needs them. | File | Feeds | Notes | |---|---|---| | `server.json` | Official MCP Registry | Section 3. Commit it to the repo root. | -| `smithery.yaml` | Smithery | `name`, `description`, `vendor`, `homepage`, `license`, `startCommand` with a config schema [observed]. | +| `smithery.yaml` | Nothing now | Smithery stopped hosted deploys on 31 Oct 2026. Do not add or update this file [verified, 2026-11-02, smithery.ai/future]. | | `manifest.json` | MCPB bundle, desktop installs | Carries `author` with name and URL, `repository`, and `user_config` prompts for credentials [observed]. | | README badges | Humans | "Built by " badge linking to the homepage. | -`smithery.yaml` with a docker `commandFunction` was copied from another published server README and is -[unverified] against Smithery's current docs. Check them before reusing it. - Keep one source of truth for the description, tool list and homepage, and copy it into each file. A version drift between `package.json`, `server.json` and `manifest.json` is easy to introduce [observed: one repo had `1.1.0` in two files and `1.0.9` in the third]. ## 6. Make the org visible in every listing -- Same organisation name and the same homepage URL in `server.json` (`websiteUrl`), `smithery.yaml`, +- Same organisation name and the same homepage URL in `server.json` (`websiteUrl`), `manifest.json`, the README byline and the repo About box. - Link to a page on a domain you own that is specific to the server or its category, not only the home page. @@ -190,4 +201,4 @@ directory that renders the README. Keep it specific to the server's audience, no - One link to a specific page on a domain you own (a services, consulting or product page, not only the home page) plus a contact address. - Request each linked URL first and confirm it returns 200. -- Use the same organisation name and homepage as in `server.json`, `smithery.yaml` and the About box. +- Use the same organisation name and homepage as in `server.json` and the About box. diff --git a/skills/github-seo/references/mcp-registry-checklist.md b/skills/github-seo/references/mcp-registry-checklist.md index 2125fee..71a5361 100644 --- a/skills/github-seo/references/mcp-registry-checklist.md +++ b/skills/github-seo/references/mcp-registry-checklist.md @@ -32,10 +32,10 @@ Write the fields every listing asks for, then reuse them verbatim so listings st |---|---|---| | **Official MCP Registry** | A `server.json` in your project, published with the `mcp-publisher` CLI. Names take the form `io.github./` and you must authenticate with access to that namespace [verified, 2026-10-29, registry README]. For an org namespace the device flow is not enough, see `mcp-install-and-metadata.md` section 2 [verified, 2026-11-02]. A pull request to the registry repo does not publish a server [verified, 2026-10-29]. | Direct. Do this first, because other registries ingest from it. | | **Docker MCP Registry** | PR adding `servers//server.yaml`, Docker team review [verified, 2026-11-02]. | Optional second route, see `mcp-install-and-metadata.md` section 8. | -| **Smithery** | Listed under an organisation namespace. Shows a quality score that depends on the live tool surface [observed]. | Direct. Check for stale listings under a personal account. | +| **Smithery** | On 31 Oct 2026 its hosted server URLs, API, Connect and Toolbox, accounts and API keys, and CLI and SDKs stop working (current versions marked deprecated). It remains a public, non-proxied MCP registry powered by Arcade.dev [verified, 2026-11-02, smithery.ai/future]. | None. Do not publish to Smithery, and skip deploy or `smithery.yaml` work. An existing listing stays as a passive registry entry. | | **PulseMCP** | Ingests from the Official Registry [observed]. | None once the Official entry is live. | | **mcpbench.ai** | Indexes from the Official Registry, can lag [observed]. | Verify it appears. | -| **Glama** | Manual submission, goes to review [observed]. | Direct, then wait. | +| **Glama** | Manual submission, goes to review [observed]. A listing can exist before you submit [observed, 2026-11-02]. | Search Glama first. Claim an existing listing (see Gotchas), else submit and wait. | | **mcp.so** | Manual submission with name, icon and server config, human approval [observed]. | Direct, then wait. | | **mcpservers.org** | Free manual listing, category required, email approval [observed]. | Direct, then wait. | | **Cursor Directory** | Manual submission with an icon upload [observed]. | Direct. | @@ -49,7 +49,21 @@ Write the fields every listing asks for, then reuse them verbatim so listings st - **Version drift.** Keep `package.json`, `server.json` and `manifest.json` on the same version. - **Stale listings under a personal account.** If the server was ever published from a personal GitHub account before the org account existed, that listing can persist on registries such as - Smithery. Find it and have it removed, through the registry's support if there is no self-service delete. + Smithery. Find it and have it removed, through the registry's support if there is no self-service delete, though Smithery, now a passive registry, may no longer remove listings. +- **Unclaimed Glama listing.** An npm-published server with a private repo already had an + unclaimed Glama page with an older README [observed on a Devkind npm MCP server, 2026-11-02]. + The claim box on a Glama server page says access comes from the repo, with no form + [observed, 2026-11-03, Glama server page claim box]: + - The owner of a personal repo signs in as that GitHub account. The page becomes theirs at once. + - For an org-owned repo, add `glama.json` at the repo root with your GitHub username under + `maintainers`, then sign in. Glama recognises you on the next sync. + + ```json + {"$schema": "https://glama.ai/mcp/schemas/server.json", "maintainers": ["github-username"]} + ``` + + After you change `glama.json`, do the Claim flow again [verified, 2026-11-02, + https://glama.ai/blog/2025-07-08-what-is-glamajson]. - **Publish order.** Merge pull requests that change the tool surface before publishing to the Official Registry. The `server.json` tool list must match what ships, and some registries recompute a quality score from the live tool count. @@ -57,6 +71,22 @@ Write the fields every listing asks for, then reuse them verbatim so listings st likely a stronger signal than one domain repeating. If you control more than one property, mention the server on each. +## 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 +[verified, 2026-11-02, commit 29f2d49]: + +- A public GitHub repo. A remote-only server goes to `punkpeye/awesome-remote-mcp-servers`. +- The entry name in `owner/repo` form, linked to the GitHub repo. The CI message: "The entry + name must use the full `owner/repo` format (not just the repo name)." +- A Glama score badge in the entry. Without it, CI adds the label `missing-glama`: + `[![owner/repo MCP server](https://glama.ai/mcp/servers/owner/repo/badges/score.svg)](https://glama.ai/mcp/servers/owner/repo)` +- At least one permitted emoji and no other emoji. 🎖️ marks an official implementation only. +- Alphabetical order within the category. + +Order: make the repo public, get the Glama listing, then open the awesome-list PR. + ## After submission Most manual registries have a review queue and no way to speed it up. Track pending reviews in a From 2962efb434b290f2b7f576f4ba0cddb1d8dbd50b Mon Sep 17 00:00:00 2001 From: Uzair Ahmed Date: Tue, 3 Nov 2026 14:28:39 +0500 Subject: [PATCH 2/5] docs: add plugin folder choice and listing fields to plugin directory reference --- CHANGELOG.md | 1 + .../references/claude-plugin-directory.md | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d30eed..70cf754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes are listed here. The format follows [Keep a Changelog](https ### Changed - MCP distribution facts (2026-11-02): Smithery is now a passive registry, Official MCP Registry `_meta` 4 KB limit and npm version timing, Glama listing claim, awesome-mcp-servers requirements, Claude plugin directory rules. +- Claude plugin directory (2026-11-03): listing fields in `plugin.json` (`icon` and URL fields), local `claude plugin validate`, how to choose the plugin folder. ## [0.2.0] - 2026-11-02 diff --git a/skills/github-seo/references/claude-plugin-directory.md b/skills/github-seo/references/claude-plugin-directory.md index 9498050..a8f2e9a 100644 --- a/skills/github-seo/references/claude-plugin-directory.md +++ b/skills/github-seo/references/claude-plugin-directory.md @@ -47,6 +47,33 @@ touches a fix [observed, 2026-11-02]. All rows [observed, 2026-11-02]. +The documented listing fields go in `plugin.json` only, not in a marketplace entry: `icon` (a +path to an image inside the plugin, such as `./assets/icon.png`), `documentationUrl`, +`supportUrl`, `privacyPolicyUrl` and `termsOfServiceUrl` (each `https://`). Claude Code ignores +them at load time [verified, 2026-11-03, code.claude.com/docs/en/plugins-reference]. + +Before you push, run `claude plugin validate .` in the plugin folder. It checks syntax and +schema only, not the directory rules, so the portal's Validate still runs [verified, 2026-11-03, +claude.com/docs/plugins/pre-submission-checklist.md]. + +### Choose the plugin folder + +The plugin folder is the folder that holds `.claude-plugin/plugin.json`, and installers get +that whole folder [verified, 2026-11-03, claude.com/docs/plugins/pre-submission-checklist.md]. +Claude Code copies it into its plugin cache at install [verified, 2026-11-03, +code.claude.com/docs/en/plugins/loading]. You cannot submit `.claude-plugin/` alone: it holds +only the manifests, and every other plugin file sits beside it. + +- **Plugin at the root of a repo that also holds server code:** works, but every install + copies the source, scripts and lockfile, and the scan reads all of it. A lockfile near 256 KiB + can cross the limit after a dependency update and cause a reviewer hold [general]. +- **Plugin-only repo or a subfolder such as `plugin/`:** the common layout when the server + ships from npm or a container registry. In `anthropics/claude-plugins-official`, 159 entries + use a whole repo and 99 use a `git-subdir` path. A sample of 14 whole-repo entries had 12 + with no code at the root [observed, 2026-11-03]. +- In a subfolder, keep `marketplace.json` at the repo root with `"source": "./plugin"`, so the + install command does not change [general]. + ### Documented rules for packages and files From claude.com/docs/plugins/pre-submission-checklist.md [verified, 2026-11-02]: From 2e81bf99e289f899474db94ebbc592559ed2c056 Mon Sep 17 00:00:00 2001 From: Uzair Ahmed Date: Tue, 3 Nov 2026 14:35:47 +0500 Subject: [PATCH 3/5] revert: remove plugin folder and listing field notes from plugin directory reference --- CHANGELOG.md | 1 - .../references/claude-plugin-directory.md | 27 ------------------- 2 files changed, 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70cf754..2d30eed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,6 @@ All notable changes are listed here. The format follows [Keep a Changelog](https ### Changed - MCP distribution facts (2026-11-02): Smithery is now a passive registry, Official MCP Registry `_meta` 4 KB limit and npm version timing, Glama listing claim, awesome-mcp-servers requirements, Claude plugin directory rules. -- Claude plugin directory (2026-11-03): listing fields in `plugin.json` (`icon` and URL fields), local `claude plugin validate`, how to choose the plugin folder. ## [0.2.0] - 2026-11-02 diff --git a/skills/github-seo/references/claude-plugin-directory.md b/skills/github-seo/references/claude-plugin-directory.md index a8f2e9a..9498050 100644 --- a/skills/github-seo/references/claude-plugin-directory.md +++ b/skills/github-seo/references/claude-plugin-directory.md @@ -47,33 +47,6 @@ touches a fix [observed, 2026-11-02]. All rows [observed, 2026-11-02]. -The documented listing fields go in `plugin.json` only, not in a marketplace entry: `icon` (a -path to an image inside the plugin, such as `./assets/icon.png`), `documentationUrl`, -`supportUrl`, `privacyPolicyUrl` and `termsOfServiceUrl` (each `https://`). Claude Code ignores -them at load time [verified, 2026-11-03, code.claude.com/docs/en/plugins-reference]. - -Before you push, run `claude plugin validate .` in the plugin folder. It checks syntax and -schema only, not the directory rules, so the portal's Validate still runs [verified, 2026-11-03, -claude.com/docs/plugins/pre-submission-checklist.md]. - -### Choose the plugin folder - -The plugin folder is the folder that holds `.claude-plugin/plugin.json`, and installers get -that whole folder [verified, 2026-11-03, claude.com/docs/plugins/pre-submission-checklist.md]. -Claude Code copies it into its plugin cache at install [verified, 2026-11-03, -code.claude.com/docs/en/plugins/loading]. You cannot submit `.claude-plugin/` alone: it holds -only the manifests, and every other plugin file sits beside it. - -- **Plugin at the root of a repo that also holds server code:** works, but every install - copies the source, scripts and lockfile, and the scan reads all of it. A lockfile near 256 KiB - can cross the limit after a dependency update and cause a reviewer hold [general]. -- **Plugin-only repo or a subfolder such as `plugin/`:** the common layout when the server - ships from npm or a container registry. In `anthropics/claude-plugins-official`, 159 entries - use a whole repo and 99 use a `git-subdir` path. A sample of 14 whole-repo entries had 12 - with no code at the root [observed, 2026-11-03]. -- In a subfolder, keep `marketplace.json` at the repo root with `"source": "./plugin"`, so the - install command does not change [general]. - ### Documented rules for packages and files From claude.com/docs/plugins/pre-submission-checklist.md [verified, 2026-11-02]: From f598093eb2f1bffc7cae8e1c38e002c422d11c9f Mon Sep 17 00:00:00 2001 From: Uzair Ahmed Date: Tue, 3 Nov 2026 22:56:20 +0500 Subject: [PATCH 4/5] docs: add Glama build, awesome-mcp-servers and plugin preparation notes --- CHANGELOG.md | 1 + skills/github-seo/SKILL.md | 2 +- .../references/claude-plugin-directory.md | 18 +++++++++++ .../references/mcp-registry-checklist.md | 31 +++++++++++++++++-- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d30eed..89e7a05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes are listed here. The format follows [Keep a Changelog](https ### Changed - MCP distribution facts (2026-11-02): Smithery is now a passive registry, Official MCP Registry `_meta` 4 KB limit and npm version timing, Glama listing claim, awesome-mcp-servers requirements, Claude plugin directory rules. +- MCP distribution facts (2026-11-03): Glama build config and stale listings, awesome-mcp-servers bot and entry rules, Claude plugin preparation. ## [0.2.0] - 2026-11-02 diff --git a/skills/github-seo/SKILL.md b/skills/github-seo/SKILL.md index 13d4461..aa7c8cf 100644 --- a/skills/github-seo/SKILL.md +++ b/skills/github-seo/SKILL.md @@ -89,7 +89,7 @@ others each have their own ownership check), complete `server.json` including `w lay out the README install routes per client. Then use `references/mcp-registry-checklist.md`. It covers the Official MCP Registry (`server.json` plus the `mcp-publisher` CLI), Glama, mcp.so, mcpservers.org, Cursor Directory, which registries auto-ingest from the Official one, and common gotchas (stale listings under a personal -account, publish order, domain presence). Pitfalls from real runs (org namespace 403, OCI +account, the Glama build config, publish order, domain presence). Pitfalls from real runs (org namespace 403, OCI build and label, leaked-history scrub) are in the install reference. Smithery shut down its hosted services on 31 Oct 2026 and is now a passive registry. Do not publish to Smithery, and skip deploy or `smithery.yaml` work [verified, 2026-11-02, smithery.ai/future]. diff --git a/skills/github-seo/references/claude-plugin-directory.md b/skills/github-seo/references/claude-plugin-directory.md index 9498050..002999f 100644 --- a/skills/github-seo/references/claude-plugin-directory.md +++ b/skills/github-seo/references/claude-plugin-directory.md @@ -32,6 +32,24 @@ repeating this. Anything not seen during the run is marked [unverified]. 5. **Review and submit.** An automated scan runs first. Held items go to a human reviewer. Approval is not guaranteed, and no review-time estimate was shown [observed, 2026-11-02]. +## Prepare the plugin + +- The plugin folder is the folder that holds `.claude-plugin/plugin.json`, and installers get that + whole folder [verified, 2026-11-03, claude.com/docs/plugins/pre-submission-checklist.md]. If it + is the root of a repo that also holds the server's `package.json` and `yarn.lock`, every install + 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 + directory reads `icon`, `documentationUrl`, `supportUrl`, `privacyPolicyUrl` and + `termsOfServiceUrl` from `plugin.json` only [verified, 2026-11-03, + code.claude.com/docs/en/plugins-reference]. +- Add a README "Network access and data" section: what the plugin downloads, which hosts it calls, + what each request carries and what it stores. The checklist asks the README to describe + everything the plugin runs, sends or fetches [verified, 2026-11-03, pre-submission checklist]. +- Run `claude plugin validate .` in the plugin folder before you push. It checks syntax and schema + only, so the portal's Validate still runs [verified, 2026-11-03, pre-submission checklist]. + ## Validate Validate runs 7 checks and reports three kinds of result: Blocking findings, policy holds and diff --git a/skills/github-seo/references/mcp-registry-checklist.md b/skills/github-seo/references/mcp-registry-checklist.md index 71a5361..153d75c 100644 --- a/skills/github-seo/references/mcp-registry-checklist.md +++ b/skills/github-seo/references/mcp-registry-checklist.md @@ -35,7 +35,7 @@ Write the fields every listing asks for, then reuse them verbatim so listings st | **Smithery** | On 31 Oct 2026 its hosted server URLs, API, Connect and Toolbox, accounts and API keys, and CLI and SDKs stop working (current versions marked deprecated). It remains a public, non-proxied MCP registry powered by Arcade.dev [verified, 2026-11-02, smithery.ai/future]. | None. Do not publish to Smithery, and skip deploy or `smithery.yaml` work. An existing listing stays as a passive registry entry. | | **PulseMCP** | Ingests from the Official Registry [observed]. | None once the Official entry is live. | | **mcpbench.ai** | Indexes from the Official Registry, can lag [observed]. | Verify it appears. | -| **Glama** | Manual submission, goes to review [observed]. A listing can exist before you submit [observed, 2026-11-02]. | Search Glama first. Claim an existing listing (see Gotchas), else submit and wait. | +| **Glama** | Manual submission, goes to review [observed]. A listing can exist before you submit [observed, 2026-11-02]. Approval comes by email [observed, 2026-11-03]. The listing gets tools and a score only after a Glama build passes [observed, 2026-11-03]. | Search Glama first. Claim an existing listing (see Gotchas), else submit with Add Server and wait for the email. Then set the build (see Gotchas). | | **mcp.so** | Manual submission with name, icon and server config, human approval [observed]. | Direct, then wait. | | **mcpservers.org** | Free manual listing, category required, email approval [observed]. | Direct, then wait. | | **Cursor Directory** | Manual submission with an icon upload [observed]. | Direct. | @@ -64,8 +64,22 @@ Write the fields every listing asks for, then reuse them verbatim so listings st After you change `glama.json`, do the Claim flow again [verified, 2026-11-02, https://glama.ai/blog/2025-07-08-what-is-glamajson]. +- **Glama build config.** Glama builds its own image from the settings on the server page under + Admin, Dockerfile. The repo needs no Dockerfile for this [observed, 2026-11-03]. Glama generated + `pnpm install` build steps for a repo that pins `"packageManager": "yarn@1.22.22"`, and the build + failed with "This project is configured to use yarn" [observed, 2026-11-03]. Set the build steps + for the repo's own package manager, for example + `["npm install -g yarn@1.22.22", "yarn install --frozen-lockfile", "yarn build"]`, and the CMD + to the stdio entry point, for example `["mcp-proxy", "--", "node", "dist/index.js"]`. Check the + generated environment schema as well: one set `TRANSPORT` to `http` for a server whose default + is stdio [observed, 2026-11-03]. Use placeholder values only, never real keys. +- **Stale Glama listing.** The summary, tool list and score come from the latest Glama release, + not from the repo [observed, 2026-11-03]. An old README or tool count after a sync usually means + the build fails. Fix the build, then run Build & Release. Auto-Release then builds on every + GitHub release [observed, 2026-11-03]. Glama numbers its releases on its own, so they do not + match npm versions [observed, 2026-11-03]. - **Publish order.** Merge pull requests that change the tool surface before publishing to the - Official Registry. The `server.json` tool list must match what ships, and some registries + Official Registry. If `server.json` lists tools, that list must match what ships, and some registries recompute a quality score from the live tool count. - **Domain presence compounds** [general]. Several distinct root domains linking to the project is likely a stronger signal than one domain repeating. If you control more than one property, @@ -85,6 +99,19 @@ Write the fields every listing asks for, then reuse them verbatim so listings st - At least one permitted emoji and no other emoji. 🎖️ marks an official implementation only. - Alphabetical order within the category. +The list's bot and recent merges add these rules: + +- The Glama listing must pass Glama's checks, not only show a badge. The bot asks that the server + "passes all checks" and that it "start and respond to introspection requests", which is the Glama + build above [verified, 2026-11-03, bot comment on a closed PR]. +- One server per PR. Nearly every merged PR adds one line [observed, 2026-11-03]. +- The scope emoji follows the note under the README legend: ☁️ "when MCP server is talking to + 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 + [verified, 2026-11-03, CONTRIBUTING.md]. + Order: make the repo public, get the Glama listing, then open the awesome-list PR. ## After submission From c9d19ab2f8e42aaf1b962f17953e2810240e3aa7 Mon Sep 17 00:00:00 2001 From: Uzair Ahmed Date: Thu, 5 Nov 2026 11:21:32 +0500 Subject: [PATCH 5/5] feat: add retired platforms, plugin submit decision and listing check Smithery guidance is removed; one retired-platforms row remains, which the audit reads to flag leftover files. --- CHANGELOG.md | 8 +- skills/github-seo/SKILL.md | 14 +-- skills/github-seo/evals/evals.json | 2 +- .../references/claude-plugin-directory.md | 31 ++++- .../references/mcp-install-and-metadata.md | 1 - .../references/mcp-registry-checklist.md | 27 ++++- skills/github-seo/scripts/check_listings.py | 108 ++++++++++++++++++ skills/github-seo/scripts/check_repo_seo.py | 21 ++++ 8 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 skills/github-seo/scripts/check_listings.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 89e7a05..c27775a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,14 @@ All notable changes are listed here. The format follows [Keep a Changelog](https ## [Unreleased] ### Changed -- MCP distribution facts (2026-11-02): Smithery is now a passive registry, Official MCP Registry `_meta` 4 KB limit and npm version timing, Glama listing claim, awesome-mcp-servers requirements, Claude plugin directory rules. +- MCP distribution facts (2026-11-02): Official MCP Registry `_meta` 4 KB limit and npm version timing, Glama listing claim, awesome-mcp-servers requirements, Claude plugin directory rules. - MCP distribution facts (2026-11-03): Glama build config and stale listings, awesome-mcp-servers bot and entry rules, Claude plugin preparation. +- Retired platforms (2026-11-05): one table in `references/mcp-registry-checklist.md`; guidance for retired platforms removed. +- Claude plugin directory (2026-11-05): a "Decide first" check for plugins that return third-party personal data, keep plugin files when not submitting, and two more documented holds (brand name, `docker run`). + +### Added +- `scripts/check_repo_seo.py` flags files and README lines that name a retired platform. +- `scripts/check_listings.py`: read-only check of the Official MCP Registry entry, its npm or Docker Hub package, Glama and awesome-mcp-servers. ## [0.2.0] - 2026-11-02 diff --git a/skills/github-seo/SKILL.md b/skills/github-seo/SKILL.md index aa7c8cf..e186e7f 100644 --- a/skills/github-seo/SKILL.md +++ b/skills/github-seo/SKILL.md @@ -1,6 +1,6 @@ --- name: github-seo -description: Makes an open-source GitHub repo discoverable and safe to publish. Audits the repo name, description, topics and README for search, writes a search-ready README, runs a pre-publish secret and client-data check, and guides the launch sequence. Covers MCP server registry submissions (Official MCP Registry, Glama, mcp.so) and existing Smithery listings. Use when the user wants more stars, traffic or search visibility for a repo, is about to open-source a project, asks for GitHub SEO or repo SEO, or wants to publish an MCP server. Not for general website SEO. +description: Makes an open-source GitHub repo discoverable and safe to publish. Audits the repo name, description, topics and README for search, writes a search-ready README, runs a pre-publish secret and client-data check, and guides the launch sequence. Covers MCP server registry submissions (Official MCP Registry, Glama, mcp.so) and the Claude plugin directory. Use when the user wants more stars, traffic or search visibility for a repo, is about to open-source a project, asks for GitHub SEO or repo SEO, or wants to publish an MCP server. Not for general website SEO. license: MIT --- @@ -51,7 +51,7 @@ python3 scripts/check_repo_seo.py owner/repo ``` It reports pass, warn or fail for the description, topics, homepage, license, README shape, -and community files, and prints the one lever it cannot check (the social preview image). +community files and retired-platform leftovers, and prints the one lever it cannot check (the social preview image). Fix failures first, then warnings. ## Step A: plain repo checklist @@ -78,9 +78,9 @@ Fix failures first, then warnings. produces the artifact the next needs. 9. **Upstream galleries and awesome-lists** only once the repo is complete and has real stars. Maintainers reject cold, thin submissions. -10. **Claude plugin directory.** If the repo ships a Claude plugin, follow - `references/claude-plugin-directory.md` for the submission portal, Validate findings and - the other plugin distribution routes. +10. **Claude plugin directory.** If the repo ships or could ship a Claude plugin, start with + "Decide first" in `references/claude-plugin-directory.md`. It says whether to submit, then + covers the submission portal, Validate findings and the other plugin distribution routes. ## Step B: MCP server checklist (after Step A) @@ -91,8 +91,8 @@ plus the `mcp-publisher` CLI), Glama, mcp.so, mcpservers.org, Cursor Directory, registries auto-ingest from the Official one, and common gotchas (stale listings under a personal account, the Glama build config, publish order, domain presence). Pitfalls from real runs (org namespace 403, OCI build and label, leaked-history scrub) are in the install reference. -Smithery shut down its hosted services on 31 Oct 2026 and is now a passive registry. Do not -publish to Smithery, and skip deploy or `smithery.yaml` work [verified, 2026-11-02, smithery.ai/future]. +Submit only to the registries in that checklist, never to one in its "Retired platforms" table. +After you submit, confirm each listing with `python3 scripts/check_listings.py owner/repo`. ## What not to do diff --git a/skills/github-seo/evals/evals.json b/skills/github-seo/evals/evals.json index 574f8bd..81f40e1 100644 --- a/skills/github-seo/evals/evals.json +++ b/skills/github-seo/evals/evals.json @@ -9,7 +9,7 @@ { "type": "should_trigger", "prompt": "what topics and description should I put on this repo so people find it" }, { "type": "should_trigger", "prompt": "plan the launch for our new open source tool, reddit, hn, the lot" }, { "type": "should_trigger", "prompt": "is it safe to make this private repo public" }, - { "type": "should_trigger", "prompt": "submit my mcp server to smithery and glama" }, + { "type": "should_trigger", "prompt": "submit my mcp server to glama and mcp.so" }, { "type": "should_trigger", "prompt": "audit the discoverability of github.com/acme/widget-cli" }, { "type": "should_not_trigger", "prompt": "improve the SEO of my marketing website" }, { "type": "should_not_trigger", "prompt": "write a blog post about our product" }, diff --git a/skills/github-seo/references/claude-plugin-directory.md b/skills/github-seo/references/claude-plugin-directory.md index 002999f..f6d9f9e 100644 --- a/skills/github-seo/references/claude-plugin-directory.md +++ b/skills/github-seo/references/claude-plugin-directory.md @@ -4,6 +4,31 @@ Generalised from one real submission at `claude.ai/directory/manage` on 2026-11- [observed, 2026-11-02]. The portal and its checks change, so re-check each step before repeating this. Anything not seen during the run is marked [unverified]. +## Decide first + +Answer two questions before any plugin work [verified, 2026-11-05, Anthropic Software Directory +Policy 1D and 3A]: + +1. Does the plugin collect user data or connect to a remote service? Then it needs "a clear, + accessible privacy policy link". Without one, do not submit yet. +2. Does it collect or return personal data about people other than the user, such as emails or + profiles? Then tell the owner it may be refused even with a privacy policy, because software + must protect "the privacy interests of third parties". + +Submit or skip is the owner's call. + +If the answer is skip, change no files: the directory reads only what you submit. The plugin files +(`.claude-plugin/`, `.mcp.json`, plugin skills) still serve everyone who installs from the repo, +through its own `marketplace.json` or `/plugin marketplace add owner/repo`. Keep them unless the +owner wants the plugin gone everywhere. To find other marketplaces that list the repo: + +```bash +gh search code "owner/repo" --filename marketplace.json +``` + +The search finds only marketplaces in repos you can read, so zero results do not prove that +nothing depends on the files. + ## Prerequisites - A paid claude.ai plan [observed, 2026-11-02]. On Team and Enterprise, the submitter needs the @@ -67,7 +92,9 @@ All rows [observed, 2026-11-02]. ### Documented rules for packages and files -From claude.com/docs/plugins/pre-submission-checklist.md [verified, 2026-11-02]: +From claude.com/docs/plugins/pre-submission-checklist.md [verified, 2026-11-02; the brand and +`docker run` rows 2026-11-05]. The launcher rule lists `npx`, `bunx`, `pnpm dlx`, `yarn dlx`, +`uvx`, `pipx run` and `uv run` only. | Rule | Result if broken | |---|---| @@ -75,6 +102,8 @@ From claude.com/docs/plugins/pre-submission-checklist.md [verified, 2026-11-02]: | A launcher with an exact pin | Still held for a reviewer, "Runs a pinned npx or uvx package" | | `.npmrc` or another file that sets a registry or package source, in a plugin with a launcher | Blocks | | `package.json` beside `package-lock.json`, `npm-shrinkwrap.json`, `bun.lock` or `bun.lockb` in the plugin folder root | Held for a reviewer, "Dependencies install from a lockfile". `yarn.lock` is not on the list | +| `name`, `displayName` or `author.name` could be mistaken for a well-known brand that is not yours | Held for a reviewer, "Name matches a known brand" | +| A local MCP server starts with something other than a file in the plugin, such as `docker run` | Held for a reviewer, "MCP server command wasn't read" | | Keep every file that is not an image or font under 256 KiB | Held for a reviewer | | Keep the plugin to 512 files or fewer | Held for a reviewer | diff --git a/skills/github-seo/references/mcp-install-and-metadata.md b/skills/github-seo/references/mcp-install-and-metadata.md index d9326b3..25eb1ed 100644 --- a/skills/github-seo/references/mcp-install-and-metadata.md +++ b/skills/github-seo/references/mcp-install-and-metadata.md @@ -139,7 +139,6 @@ server needs them. | File | Feeds | Notes | |---|---|---| | `server.json` | Official MCP Registry | Section 3. Commit it to the repo root. | -| `smithery.yaml` | Nothing now | Smithery stopped hosted deploys on 31 Oct 2026. Do not add or update this file [verified, 2026-11-02, smithery.ai/future]. | | `manifest.json` | MCPB bundle, desktop installs | Carries `author` with name and URL, `repository`, and `user_config` prompts for credentials [observed]. | | README badges | Humans | "Built by " badge linking to the homepage. | diff --git a/skills/github-seo/references/mcp-registry-checklist.md b/skills/github-seo/references/mcp-registry-checklist.md index 153d75c..a05eb95 100644 --- a/skills/github-seo/references/mcp-registry-checklist.md +++ b/skills/github-seo/references/mcp-registry-checklist.md @@ -32,7 +32,6 @@ Write the fields every listing asks for, then reuse them verbatim so listings st |---|---|---| | **Official MCP Registry** | A `server.json` in your project, published with the `mcp-publisher` CLI. Names take the form `io.github./` and you must authenticate with access to that namespace [verified, 2026-10-29, registry README]. For an org namespace the device flow is not enough, see `mcp-install-and-metadata.md` section 2 [verified, 2026-11-02]. A pull request to the registry repo does not publish a server [verified, 2026-10-29]. | Direct. Do this first, because other registries ingest from it. | | **Docker MCP Registry** | PR adding `servers//server.yaml`, Docker team review [verified, 2026-11-02]. | Optional second route, see `mcp-install-and-metadata.md` section 8. | -| **Smithery** | On 31 Oct 2026 its hosted server URLs, API, Connect and Toolbox, accounts and API keys, and CLI and SDKs stop working (current versions marked deprecated). It remains a public, non-proxied MCP registry powered by Arcade.dev [verified, 2026-11-02, smithery.ai/future]. | None. Do not publish to Smithery, and skip deploy or `smithery.yaml` work. An existing listing stays as a passive registry entry. | | **PulseMCP** | Ingests from the Official Registry [observed]. | None once the Official entry is live. | | **mcpbench.ai** | Indexes from the Official Registry, can lag [observed]. | Verify it appears. | | **Glama** | Manual submission, goes to review [observed]. A listing can exist before you submit [observed, 2026-11-02]. Approval comes by email [observed, 2026-11-03]. The listing gets tools and a score only after a Glama build passes [observed, 2026-11-03]. | Search Glama first. Claim an existing listing (see Gotchas), else submit with Add Server and wait for the email. Then set the build (see Gotchas). | @@ -42,14 +41,25 @@ Write the fields every listing asks for, then reuse them verbatim so listings st | **MCPMarket** | Observed to index without a submission form [observed]. | Verify the listing and description. | | **Community lists** (selective, unclear criteria) | Small subsets of servers, links may be nofollow [observed]. | Low priority. | +## Retired platforms + +Do not submit to these. Remove their config files, scripts and doc mentions, but keep released +changelog entries. The Step 2 audit +(`scripts/check_repo_seo.py`) reads this table and flags any file path or README line that names +a platform here. To retire a platform, add a row. + +| Platform | Status | +|---|---| +| **Smithery** | Out of service. Its hosting, API, accounts, CLI and SDKs shut down on 31 Oct 2026. Only a read-only directory remains, with nothing to publish [verified, 2026-11-05, smithery.ai/future]. | + ## Gotchas - **Empty `websiteUrl`.** Put the homepage in the official `websiteUrl` field, not only under `_meta`. See `mcp-install-and-metadata.md`. - **Version drift.** Keep `package.json`, `server.json` and `manifest.json` on the same version. - **Stale listings under a personal account.** If the server was ever published from a personal - GitHub account before the org account existed, that listing can persist on registries such as - Smithery. Find it and have it removed, through the registry's support if there is no self-service delete, though Smithery, now a passive registry, may no longer remove listings. + GitHub account before the org account existed, that listing can persist on other registries. Find it + and have it removed, through the registry's support if there is no self-service delete. - **Unclaimed Glama listing.** An npm-published server with a private repo already had an unclaimed Glama page with an older README [observed on a Devkind npm MCP server, 2026-11-02]. The claim box on a Glama server page says access comes from the repo, with no form @@ -118,3 +128,14 @@ Order: make the repo public, get the Glama listing, then open the awesome-list P Most manual registries have a review queue and no way to speed it up. Track pending reviews in a note and check back, rather than resubmitting. + +Check the listings with one command. It needs `gh` logged in and reads `server.json` from the repo: + +```bash +python3 scripts/check_listings.py owner/repo +``` + +It finds the latest Official MCP Registry entry and checks the package it names: the npm version +matches, or the OCI image tag exists on Docker Hub. It also checks that the Glama page exists, and +whether awesome-mcp-servers lists the repo or has a pull request for it. Directories that need a login, such as the Claude plugin +directory, stay a manual check. diff --git a/skills/github-seo/scripts/check_listings.py b/skills/github-seo/scripts/check_listings.py new file mode 100644 index 0000000..ce73874 --- /dev/null +++ b/skills/github-seo/scripts/check_listings.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +"""Read-only check of an MCP server's public listings. Usage: check_listings.py owner/repo + +Reads the server name from server.json in the repo with the GitHub CLI (`gh`), then checks the +Official MCP Registry, the package it points at (npm or Docker Hub), Glama and awesome-mcp-servers. +Makes no changes. Exits 1 if any check fails. +""" +import base64 +import json +import subprocess +import sys +import urllib.error +import urllib.parse +import urllib.request + +if len(sys.argv) != 2 or "/" not in sys.argv[1]: + sys.exit(__doc__) +slug = sys.argv[1] +results = [] + + +def gh(*args, required=False): + out = subprocess.run(["gh", *args], capture_output=True, text=True) + if out.returncode == 0: + return out.stdout + if required: + sys.exit(f"gh {' '.join(args)} failed: {out.stderr.strip()}") + return None + + +def get(url): + """Return (status, body). A 404 is a result, not an error; status 0 means no response.""" + req = urllib.request.Request(url, headers={"User-Agent": "github-seo-skill"}) + try: + with urllib.request.urlopen(req, timeout=20) as r: + return r.status, r.read().decode() + except urllib.error.HTTPError as e: + return e.code, "" + except urllib.error.URLError as e: + return 0, str(e.reason) + + +def record(level, name, detail): + results.append((level, name, detail)) + + +gh("repo", "view", slug, "--json", "name", required=True) +raw = gh("api", f"repos/{slug}/contents/server.json", "--jq", ".content") +if not raw: + sys.exit(f"{slug} has no server.json in the default branch, so there is no MCP listing to check.") +try: + name = json.loads(base64.b64decode(raw))["name"] +except (ValueError, KeyError): + sys.exit(f"{slug}: server.json is not valid JSON or has no name") + +# Official MCP Registry. Search results are paged, so ask for the latest version directly. +status, body = get( + f"https://registry.modelcontextprotocol.io/v0/servers/{urllib.parse.quote(name, safe='')}/versions/latest" +) +live = json.loads(body)["server"] if status == 200 else {} +if live: + record("PASS", "Official MCP Registry", f"{name} {live['version']}") +else: + record("FAIL", "Official MCP Registry", f"{name} not found (HTTP {status})") + +# Packages in the live registry entry, so the check matches what clients install +for pkg in live.get("packages", []): + kind, ident = pkg.get("registryType"), pkg.get("identifier", "") + if kind == "npm": + status, body = get(f"https://registry.npmjs.org/{urllib.parse.quote(ident, safe='@')}/latest") + if status != 200: + record("FAIL", "npm", f"{ident} not found (HTTP {status})") + else: + npm_v = json.loads(body)["version"] + want = pkg.get("version") or live["version"] + record("PASS" if npm_v == want else "WARN", "npm", f"{ident} {npm_v}, registry {want}") + elif kind == "oci": + image, _, tag = ident.removeprefix("docker.io/").partition(":") + if "/" not in image: + image = f"library/{image}" + if "." in image.split("/")[0]: + record("WARN", "OCI image", f"{ident} is not on Docker Hub. Check it by hand.") + continue + status, _ = get(f"https://hub.docker.com/v2/repositories/{image}/tags/{tag or 'latest'}") + record("PASS" if status == 200 else "FAIL", "Docker Hub tag", f"{ident} (HTTP {status})") + +# Glama +status, _ = get(f"https://glama.ai/mcp/servers/{slug}") +record("PASS" if status == 200 else "FAIL", "Glama", f"https://glama.ai/mcp/servers/{slug} (HTTP {status})") + +# awesome-mcp-servers: listed in the README, or a pull request for the repo +listed = gh("api", "repos/punkpeye/awesome-mcp-servers/contents/README.md", "-H", "Accept: application/vnd.github.raw") +if listed and f"[{slug}]".lower() in listed.lower(): + record("PASS", "awesome-mcp-servers", "listed in README") +else: + prs = gh("pr", "list", "--repo", "punkpeye/awesome-mcp-servers", "--state", "all", "--search", slug, + "--json", "number,state") + if prs is None: + detail = "pull request search failed" + else: + detail = ", ".join(f"#{p['number']} {p['state']}" for p in json.loads(prs)) or "no pull request found" + record("WARN", "awesome-mcp-servers", f"not listed; {detail}") + +width = max(len(n) for _, n, _ in results) +for level, n, d in results: + print(f"{level:<5} {n:<{width}} {d}") +print("\nMANUAL Claude plugin directory, mcp.so, mcpservers.org and Cursor Directory need a login or have no API.") +sys.exit(1 if any(level == "FAIL" for level, _, _ in results) else 0) diff --git a/skills/github-seo/scripts/check_repo_seo.py b/skills/github-seo/scripts/check_repo_seo.py index e65178d..07bf67e 100644 --- a/skills/github-seo/scripts/check_repo_seo.py +++ b/skills/github-seo/scripts/check_repo_seo.py @@ -8,6 +8,7 @@ import re import subprocess import sys +from pathlib import Path results = [] @@ -109,6 +110,26 @@ def record(level, name, detail): ok = bool(files & candidates) record("PASS" if ok else "WARN", label, "present" if ok else "missing in repo root") +# Retired platforms: the table in the registry checklist is the single source of names. +checklist = Path(__file__).resolve().parent.parent / "references" / "mcp-registry-checklist.md" +text = checklist.read_text() +if "## Retired platforms" not in text: + sys.exit(f"{checklist} has no '## Retired platforms' section") +section = text.split("## Retired platforms", 1)[1].split("\n## ", 1)[0] +paths = [ + e["path"] + for e in json.loads(gh("api", f"repos/{slug}/git/trees/HEAD?recursive=1"))["tree"] + if e["type"] == "blob" +] +for platform in re.findall(r"^\| \*\*(.+?)\*\* \|", section, flags=re.M): + key = platform.lower() + hits = [p for p in paths if key in p.lower()] + hits += [f"README.md:{n}" for n, line in enumerate(readme.splitlines(), 1) if key in line.lower()] + if hits: + record("FAIL", f"retired: {platform}", f"remove {', '.join(hits)}. Also run: git grep -n -i {key}") + else: + record("PASS", f"retired: {platform}", "no files or README lines") + # MCP server metadata (only when a server.json is present) if "server.json" in files: try: