MCP Registryのバージョニングルール — 公開後は変更不可
MCP Registryに公開したサーバーのバージョンはなぜ書き換えられないのか。文字列の書式ルールと、アグリゲーター側の並び替えロジックまで押さえます。
MCP Registryに公開したサーバーのバージョンは、一度公開すると書き換えられません。FAQではこの扱いが「npmと同様」と説明されており、メタデータを直したいときも既存バージョンの上書きではなく、新しいバージョン文字列での再公開になります。文字列の形式は自由ですが、semver(セマンティックバージョニング)として読めない文字列を公開すると、そのバージョンは常に「latest」になります。
「バージョン」が指すものを先に区別する
MCP RegistryのversionとMCPプロトコルのバージョンは別物です。違いは次のとおりです。
server.jsonのversionとプロトコルバージョン
server.jsonのversion
個々のサーバー実装のリリースを指すラベルです。公開ごとに一意で、公開後は変えられません。
プロトコルバージョン
クライアントとサーバーがやり取りの規格を合わせるための識別子です。server.jsonのversionとは別の値です。
バージョン文字列の書式ルール
MCP Registryはsemverを推奨しますが、文字列の形式そのものは自由です。公開時にsemverとして解釈を試み、解釈できれば並び順の判定に使います。解釈できなければ、そのバージョンは常に「latest」になります。
| 例 | 種別 | 扱い |
|---|---|---|
1.0.0 | 種別セマンティックバージョン | 扱い推奨 |
2.1.3-alpha 1.0.0-beta.1 3.0.0-rc.2 | 種別セマンティックプレリリース | 扱い推奨 |
2025.11.25 2025.6.18 | 種別日付形式(semver互換) | 扱い推奨(2025.6.18は注意付き) |
2025.06.18 | 種別日付形式(非semver) | 扱い許可(注意付き) |
2025-06-18 | 種別日付形式(非semver) | 扱い許可 |
v1.0 | 種別プレフィックス付き | 扱い許可 |
^1.2.3 ~1.2.3 >=1.2.3 <1.2.3 1.x 1.2.* 1 - 2 | 種別バージョン範囲指定 | 扱い禁止 |
範囲指定は、バージョン文字列が複数の公開を束ねる表現に見えるため、誤りを防ぐ仕組みとして禁止されています。^1.2.3のような構文を許すと、どの公開を指すのか定まらなくなるからです。npmのpackage.jsonが依存関係の宣言に範囲構文を使うのとは役割が異なり、MCP Registryのversionは1回の公開を指すラベルです。禁止の対象には、1 - 2のようなハイフン区切りの範囲や、1.2 || 1.3のような論理和の書き方も含まれます。
一度semverを使ったサーバーが途中で非semver形式に切り替えると、挙動が変わります。新しく公開したバージョンが本来の並び順では前に来るはずでも、semverでないと判定された時点で「latest」になります。古い番号を新しい番号として見せてしまう典型パターンです。
公開後の不変性が公開ワークフローに与える影響
一度公開したバージョンの中身(パッケージ識別子・説明文・環境変数の定義など)は、あとから直接編集できません。誤字を直したいだけでも、新しいバージョン文字列でserver.jsonを出し直します。
パッケージの実体を変えずにメタデータだけを更新したい場面は珍しくありません。説明文を整えた、環境変数の説明を追記した、といったケースです。この用途向けに公式が案内しているのが、セマンティックプレリリースを使う方法です。
{
"version": "1.2.3-1",
"packages": [
{
"registryType": "npm",
"identifier": "@my-username/my-server",
"version": "1.2.3",
"transport": { "type": "stdio" }
}
]
}1.2.3-1のようなプレリリース表記であれば、実体のnpmパッケージは1.2.3のまま、MCP Registry側のメタデータだけを複数回公開し直せます。ただしプレリリース版は正規のバージョンより前にソートされます。正規版1.2.3を先に公開してから1.2.3-1を後追いで公開すると、そのプレリリース版は「latest」になりません。メタデータ更新用のプレリリース公開は、正規版を公開する前に済ませる順序が安全です。
メタデータには独自の付加情報を持たせることもできます。置き場所は_meta.io.modelcontextprotocol.registry/publisher-provided以下で、サイズ上限は4KB(JSONで4096バイト)です。上限を超えると公開自体が失敗します。ログや設定サンプルをまるごと詰め込む使い方には向きません。
公開したサーバーを消す・非公開にする方法はあるか
FAQでは、公開者が自分のサーバーを削除・非公開にできるかという問いに「現時点ではできない」と答えています。FAQが参照しているGitHubのIssue #104は2026年4月にクローズされていますが、FAQの記述は今もこのとおりです。
一方で、レジストリのデータそのものが完全に固定というわけではありません。
公開者にできることと、レジストリ側で変わりうること
公開者の操作
公開済みバージョンの上書きも削除もできません。
status フィールド
アグリゲーター向けのページでは、メタデータは原則不変でstatusだけが更新されうるとされています。値は"deprecated"や"deleted"です。"deleted"は、モデレーションポリシー違反(スパム・マルウェア・違法な内容の疑い)を典型とする状態です。アグリゲーターには、手元のstatusを最新に保ち、deletedのサーバーを索引から外す選択肢があります。
公開者側からは削除できないため、本番のnamespaceへテスト目的で気軽に公開すると、消せない記録が積み上がります。動作確認は別の名前空間に切り分ける選択肢があります。
MCP Registryはpreview段階で、versioning・FAQ・アグリゲーターの各ページの冒頭には「General Availability前に破壊的変更やデータリセットが起きうる」という注意書きがあります。ここまでの「公開後は変更不可・公開者は削除不可」というルールも、この前提の上にあります。
実際のレジストリで確かめる
公式レジストリは認証なしの読み取り専用REST APIを公開しており、あるサーバーの全バージョンをGETで取れます。ここではGitHubのMCPサーバーを例にします。
curl -s "https://registry.modelcontextprotocol.io/v0.1/servers/io.github.github%2Fgithub-mcp-server/versions"返ってくるJSONはservers配列とmetadataで、配列の先頭は新しいバージョンから並んでいます。この例では58件のバージョンが返り、先頭の1.13.0の_metaに"isLatest": true、"status": "active"、publishedAtが付いていました。その1つ下の1.12.2は"isLatest": falseです。パスのサーバー名にある/は%2FにURLエンコードする必要があります。
_metaのio.modelcontextprotocol.registry/officialには、status・statusChangedAt・publishedAt・updatedAt・isLatestの5つのキーが並びます。バージョンごとに「latest」かどうかをisLatestで持つので、先ほどの並び替えの結果はこのフラグを見れば分かります。
1つのバージョンだけを見るときは、パスの末尾にlatestかバージョン文字列を置きます。次は最新版の例です。
curl -s "https://registry.modelcontextprotocol.io/v0.1/servers/io.github.github%2Fgithub-mcp-server/versions/latest"このレスポンスのトップレベルはserverと_metaで、serverの中にserver.jsonで書いたname・description・version・packagesなどが入っています。remotesを持つサーバーなら、そのURLもここに載ります。
アグリゲーター側の取り込み方にも指針があります。取得は定期的だが低頻度(例として1時間に1回)で行い、取得したデータは自前のデータストアに保存します。MCP Registryは稼働率もデータの耐久性も保証しないためです。更新分だけ拾いたいときは、GET /v0.1/serversにupdated_sinceをRFC 3339形式の日時で渡します。
サーバーバージョンと配下パッケージバージョンの揃え方
サーバーのversionと、packages配列内の各パッケージのversionは別のフィールドです。公式のベストプラクティスは、混乱を避けるために揃えることです。
パッケージが1つだけなら、サーバーのバージョンと完全に一致させます。パッケージが複数(npm版とNuGet版を同時提供する等)なら、サーバーのバージョンは全体のリリース番号として扱います。公式の例では、サーバーが1.3.0でnpmが1.3.0、NuGetが1.0.0という組み合わせです。パッケージ種別ごとの識別子の違いを踏まえると、複数形式を並行提供するサーバーほど、この「サーバー版」と「パッケージ版」の使い分けが重要になります。
リモートサーバーでAPIのバージョンがあるなら、サーバーのversionをそれに合わせます。https://api.myservice.com/mcp/v2.1というURLなら、versionは2.1.0です。リモートサーバーの公開手順で扱ったremotesプロパティと組み合わせて設計する項目です。
揃えを崩すと、サーバーのversionだけ独自に進み、配下パッケージのversionは据え置きという状態が起きます。利用者は「MCP Registry上は3.0.0なのに、npmで見えるパッケージは1.2.0のまま」に遭遇し、どちらの番号を指すのか確認し直す場面が出てきます。
アグリゲーター側の並び替えロジックを知っておく
MCP Registryのメタデータを取り込むダウンストリームのアグリゲーター(マーケットプレイス等)には、バージョン比較の推奨ルールが示されています。まずsemverとして解釈を試み、2つのバージョンを次の順で比べます。
2つのバージョンの新旧を決める順番
- 1
「latest」の付いた側を新しいとみなす
どちらかに「latest」が付いていれば、そちらが後のバージョンです。
- 2
両方がsemverなら、semverの規則で比べる
通常のバージョン比較です。
- 3
両方がsemverでなければ、公開時刻で比べる
公開されたタイムスタンプの新しい方が後です。
- 4
片方だけsemverなら、semver側を新しいとみなす
「latest」が付いていない場合、非semverの文字列はsemverのバージョンより古い側として扱われます。
非semver形式の選択そのものは禁止されていません。ただ、複数のアグリゲーターをまたいだ挙動を読みやすいのはsemverです。タイムスタンプ比較に落ちる経路は、semverの規則ほど読み筋が単純ではありません。
日付ベースの番号では、ゼロ埋めの有無が分かれ目になります。公式の表では2025.6.18がsemver互換の日付形式、2025.06.18が非semverの日付形式で、どちらにも注意マークが付いています。ゼロ埋めするとsemverとして読めなくなり、latest判定のロジックが変わるためです。日付を使うなら、ゼロ埋めの有無を最初に決めて、公開のたびに揺らさないようにします。
混同しやすい別のバージョニング概念
「バージョニング」という言葉は、Claude関連のエコシステムだけでも複数の文脈で使われます。たとえばAnthropic APIのツール定義には、日付形式の名前でバージョンを表す独自の慣習があります。MCP Registryのサーバーバージョンとは更新の単位が別物です。詳しくはClaude APIツールのバージョン管理で扱っています。
まとめ
MCP Registryのバージョンは、公開ごとに一意で、公開後は変えられない前提で設計されています。公開前に決めておくのは、番号体系(semverか日付か)とゼロ埋めの有無です。公開後は直せないので、メタデータだけ直したくなったときの逃げ道は、正規版より先に出すプレリリース表記しかありません。