Feature request: re-check published entries periodically (more than 1 in 8 have a problem the registry doesn't catch)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 28/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- github, go
- 領域
- backend, data, infrastructure
調査の方向性
Start with internal/validators/registries/npm.go, pypi.go, and ValidateUpdateRequest, then trace ValidatePackage to understand the existing publish-time checks. Identify the registry’s job or background-worker entry point and the storage used for registry metadata, noting the overlap with issues #93, #1579, and #1484. Done requires a maintainer to choose the validation cadence and failure-status policy, implement and test periodic rechecks, and record results without automatically deleting entries.
索引モデルが issue の本文から書いたものです。
説明
Summary
I measured every latest entry in the registry (38,977 entries from 23,016 publisher namespaces, registry snapshot 2026-10-04) against what npm, PyPI and GitHub reported on 2026-10-06. 5,435 entries (13.9%; 3,169 publisher namespaces, 13.8%) have at least one problem the registry doesn't catch — most commonly a repository link that isn't publicly reachable, or a listed package version that is withdrawn upstream or can't be installed. Part of that count is a design choice rather than a problem (see the websiteUrl note below); setting that part aside, the figure is still at least 5,192 entries (13.3%).
This is not a security report, and it isn't a criticism of publishers: things change upstream after an entry is published, and some checks were never part of publishing. The registry's validation is good at publish time; it just has no timer that runs it again. Below are the numbers, what the code does, and some small proposals.
The registry has changed since my snapshot, so exact counts today will differ. I have not re-pulled it for this issue.
Disclosure: I built ProtocolProbe, a free directory that reads the registry's public data. This issue is about the registry, not about my project.
Related, already open (I found these after measuring): #93 (remove entries that reference invalid packages, with a check "at least ~daily"), #1579 (active entries with neither remotes nor packages), #1484 (repository URLs that point at renamed or transferred repositories). Discussions #1547 and #1591 measured remote endpoints; this covers package and repository records instead, so the counts are not comparable. This issue adds whole-registry numbers across several kinds of drift and a way to record them without deleting anything.
What the registry checks (read from source at c384c4b, re-read at HEAD 11b7b0e, 2026-10-11)
- At publish, it checks the exact listed version.
internal/validators/registries/npm.gofetches/{identifier}/{version}and requires a 200 plus a matchingmcpName;pypi.gofetches/pypi/{identifier}/{version}/jsonand requires themcp-name:token. This has been the case since the validators were added in September 2025. It runs only whenENABLE_REGISTRY_VALIDATIONis on (defaulttrue; I can't see production's setting). - It runs again only when a publisher edits an entry.
UpdateServercallsValidateUpdateRequest, which repeats the package ownership check (skipped for deleted entries). I found no timer, cron or background job that validates entries on a schedule. An entry nobody edits is checked once. repository.urlis checked for format only (IsValidRepositoryURL, a regular expression), never fetched.- The schema requires
name,descriptionandversion— neitherpackagesnorremotes. The docs describe entries with only awebsiteUrlas a supported "custom installation path".
What I found (whole registry, no sampling)
Every percentage below uses the same base — all 38,977 entries, or all 23,016 publisher namespaces — so no row can exceed the total. Each row's own subset is given in the fourth column for context.
| Finding | % of all entries | % of all publisher namespaces | Within its own subset | Cause |
|---|---|---|---|---|
| Any of the below | 5,435 (13.9%) | 3,169 (13.8%) | ||
| Repository link not publicly reachable (404 — missing or private) | 4,298 (11.0%) | 11.3% | 15.0% of 28,743 entries with a GitHub link | never checked |
| Listed package version is deprecated (npm) or yanked (PyPI) | 663 (1.7%) | 1.0% | 4.6% of 14,431 npm/PyPI entries | never checked |
active, but declares no packages and no remotes |
459 (1.2%) | 1.3% | 243 have a websiteUrl, 216 do not |
allowed by schema |
| Linked GitHub repository is archived | 309 (0.8%) | 0.6% | 1.3% of 24,256 entries with a reachable repo | never checked |
| Listed package or version doesn't exist on npm/PyPI | 157 (0.4%) | 0.5% | 1.1% of 14,431 npm/PyPI entries | checked at publish (by default); not again unless the publisher edits |
The 243 entries that have a websiteUrl follow the documented custom-installation pattern, so they may be intended. The 216 that have neither a way to run nor a page to read are the ones a client can do nothing with. The "any of the below" row counts all 459; without the 243 it is at least 5,192 (13.3%), because removing 243 entries cannot lower the total by more than 243.
All 157 entries whose listed version doesn't exist were published after the existence check was introduced — so, if validation was enabled (it is by default), they existed at submission and were removed afterwards. For withdrawn versions and archived repositories I can't tell when the change happened: npm/PyPI don't record when a version was deprecated or yanked, and GitHub doesn't expose when a repository was archived. The registry doesn't check either, at publish or later.
Publisher-supplied deprecation messages for the 663 withdrawn versions, grouped by publisher namespace: renamed to another package (89), backing service shut down (16), npm staff "no longer supported" notice (24), publisher-declared security issue (12), plus discontinued / upgrade-advised / moved distribution.
Proposals
- Re-run the existing package validation on a schedule (e.g. weekly; #93 suggests daily), reusing
ValidatePackage. On failure, don't silently delete — record it, e.g. a_metafield such aslastVerifiedAt+verificationStatus: ok | version-missing | package-missing, so clients can choose what to do. - Surface upstream withdrawal state. When the listed npm version is deprecated or the PyPI release is yanked, expose that (with the upstream message) in
_meta. Registry-driven clients currently install a withdrawn version with no signal, becauseversionmust be exact. - Optionally check
repository.urlreachability at publish and during re-validation, or mark it as unverified. - Treat "no packages, no remotes, no
websiteUrl" as incomplete (216 active entries in my snapshot) — a distinct status or a publish-time warning — and leave the documentedwebsiteUrl-only pattern alone.
Happy to share the full dataset and method (one record per entry; npm/PyPI/GitHub/OSV sources, every field marked declared / undeclared / not-applicable with a reason), and to help with an implementation. The dataset is archived with a DOI under CC BY 4.0: https://doi.org/10.5281/zenodo.23386799. The report with each figure's source and date is at https://protocolprobe.com/mcp/reports/registry-vs-reality.
Method notes
- Registry snapshot 2026-10-04 (full pagination, 131,427 version rows, one latest row per name); npm, PyPI and GitHub lookups on 2026-10-06.
- npm/PyPI checks use the exact version the registry lists, parsed with semver / PEP 440.
- A 404 on a repository link means missing or private; I don't distinguish the two, and I haven't separated renamed repositories from missing ones (see #1484).
- Rate-limited lookups were retried and are never counted as missing data.
- Counts are given per entry and per publisher namespace, because a few namespaces publish hundreds of entries and would otherwise dominate.
- I did not run or call any MCP server for any of this; everything comes from the registry and public package records.
Drafted with help from Claude (AI); the data, method and checks are mine and I've reviewed every number.
- 主要言語
- Go
- スター
- 7.4k
- フォーク
- 1k
- 平均マージ
- 1日 9時間
- マージ済み PR(30日)
- 29
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
modelcontextprotocol/registry のほかの issue
-
3 registry records that cannot resolve for any client, and a caution about single-pass dead countsオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
modelcontextprotocol/registry#1692 ·
メンテナーはふだん 1 日以内に返信
-
IsValidRemoteURL only blocks literal localhost/127.0.0.1 — misses [::1], 127.0.0.0/8, 0.0.0.0, and private/link-local addresses対応中かも @amitvijapur が 97 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
modelcontextprotocol/registry#1465 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 56/100
modelcontextprotocol/registry#1719 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 8/100
modelcontextprotocol/registry#1708 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
modelcontextprotocol/registry#1706 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
modelcontextprotocol/registry の issue をすべて見る
似ている issue
-
[flaky test] TestValidatorCommitterDropsEmptyStatusBatch: submits to the mock VC before its stream is registered対応中かも @liran-funaro が今日担当しました。 オープンcoordinator flaky-test race-condition testing
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
hyperledger/fabric-x-committer#876 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
garethgeorge/backrest#1426 ·
メンテナーはふだん 1 日以内に返信
-
enhancement nav-pilot
難易度 2/5 半日 初心者へのやさしさ 62/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
valkey-io/valkey-operator#549 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
-
kind/features
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
TencentBlueKing/bk-nodemgr#3804 ·
メンテナーはふだん 1 日以内に返信