MCP Registryの認証方式3種(GitHub/DNS/HTTP)を比較する
MCP Registryへの公開に必要なGitHub OAuth・DNS TXTレコード・HTTP .well-knownファイルの3方式を、命名ルールと手順の違いで比較します。
認証方式がサーバー名の名前空間を決める
MCPの公式サーバーカタログであるMCP Registryへ公開する前には、認証が必要です。単なるログイン確認ではありません。どの方式を選ぶかが、server.json に書くサーバー名の形を決めます。
GitHub認証なら io.github.username/*(Organizationなら io.github.orgname/*)です。ドメイン認証(DNS・HTTP)なら、所有ドメインを逆順にした com.example.*/* の形になります。公開済みのバージョンは変更できないため、公開前に選び切ることになります。なお、MCP Registryはプレビュー段階にあり、一般提供の前に破壊的変更やデータのリセットが入りえます。
| 認証方式 | 名前空間の形式 | 名前の例 |
|---|---|---|
| GitHub認証 | 名前空間の形式io.github.username/* または io.github.orgname/* | 名前の例io.github.alice/weather-server |
| ドメイン認証(DNS・HTTP) | 名前空間の形式com.example.*/*(com.example は自分のドメインの逆順) | 名前の例io.modelcontextprotocol/everything(modelcontextprotocol.io の逆順) |
3方式の違いは「どこに証明を置くか」
3方式とも、操作は mcp-publisher というCLIから行います。違いは、名前空間の持ち主であることを何で示すかです。
証明を置く場所の違い
GitHub認証
mcp-publisher login github でOAuthのデバイスフローが始まります。鍵もDNSも使いません。名前空間は自分のGitHubアカウント名か所属Organization名に固定されます。
DNS認証
鍵ペアを作り、公開鍵から組み立てた1行をドメインのTXTレコードに登録します。DNSプロバイダーの管理画面を触れる権限が要り、反映には数分かかることがあります。
HTTP認証
同じ鍵ペアから作った1行を、/.well-known/mcp-registry-auth というファイルとしてドメイン上に置きます。必要なのは、そのパスにファイルを配信できる権限です。
DNS認証とHTTP認証は、どちらもEd25519またはECDSA P-384の鍵ペアを使います。組織が複数のMCPサーバーを公開する一方で、利用側では許可リストで使えるサーバーを絞り込む運用をしている場合、公開側の認証と利用側の許可は別々に管理することになります。
GitHub認証 — 鍵もDNSも使わない最短経路
サーバーのプロジェクトディレクトリで、次のコマンドを実行します。
mcp-publisher login githubデバイスコードとGitHubの認証URLが表示されます。
Logging in with github...
To authenticate, please:
1. Go to: https://github.com/login/device
2. Enter code: ABCD-1234
3. Authorize this application
Waiting for authorization...URLをブラウザで開いてコードを入力し、認可します。ターミナルに戻ると、次の2行が出れば完了です。
Successfully authenticated!
✓ Successfully logged in引き換えに、名前空間は自分のGitHubアカウント名(または所属Organization名)に固定されます。独自ドメインでサーバー名を揃えたいチームには向きません。
DNS認証 — TXTレコードを1行足す
自社ドメインを名前空間にするなら、DNS認証かHTTP認証です。DNS認証ではまず鍵ペアを作り、TXTレコードの文面を出力します。
MY_DOMAIN="example.com"
openssl genpkey -algorithm Ed25519 -out key.pem
PUBLIC_KEY="$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)"
echo "${MY_DOMAIN}. IN TXT \"v=MCPv1; k=ed25519; p=${PUBLIC_KEY}\""出力された1行を、使っているDNSプロバイダーの管理画面でTXTレコードとして追加します。反映を待ってから、秘密鍵を渡してログインします。
PRIVATE_KEY="$(openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n')"
mcp-publisher login dns --domain "${MY_DOMAIN}" --private-key "${PRIVATE_KEY}"ECDSA P-384を使うときは、鍵の生成が openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:secp384r1 になり、TXTレコードの鍵種別も k=ecdsap384 に変わります。公開鍵の取り出し方も別のコマンドになるため、Ed25519の行をそのまま流用しないでください。
DNSの変更フローがすでに整っている組織なら、この方式が自然です。DNSの権限が別部門にあって変更に申請が要る場合は、待ち時間がそのまま公開の遅れになります。
HTTP認証 — .well-knownにファイルを置く
DNSには触れないが、ドメイン配下にファイルは置ける。そういう組織にはHTTP認証が合います。鍵の作り方はDNS認証と同じで、出力先がTXTレコードからファイルに変わります。
openssl genpkey -algorithm Ed25519 -out key.pem
PUBLIC_KEY="$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)"
echo "v=MCPv1; k=ed25519; p=${PUBLIC_KEY}" > mcp-registry-authできた mcp-registry-auth を、https://example.com/.well-known/mcp-registry-auth で取得できる状態にします。そのうえで、DNS認証と同じ形でログインします。
MY_DOMAIN="example.com"
PRIVATE_KEY="$(openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n')"
mcp-publisher login http --domain "${MY_DOMAIN}" --private-key "${PRIVATE_KEY}"DNSのTXTレコードと違い、認証ページにはHTTP認証の反映待ちの記載がありません。ただし、.well-known 配下のパスにファイルを配信できるホスティングであることが前提です。SaaS型のホスティングでパス単位の制御ができない場合は、ここで手間が出ます。マーケティングサイトとAPIドメインの管理組織が別なら、開発チームが管理するドメインの .well-known に置くという運用もあり得ます。
鍵ペアの中身を手元で確かめる
手順は、鍵ペアを生成して公開鍵を1行にし、秘密鍵を16進文字列としてコマンドに渡す、という流れです。何が作られているかは、OpenSSL 3.2.1で同じコマンドを実行したときの出力に表れます。
openssl genpkey -algorithm Ed25519 -out key.pem
PUBLIC_KEY="$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)"
echo "example.com. IN TXT \"v=MCPv1; k=ed25519; p=${PUBLIC_KEY}\""example.com. IN TXT "v=MCPv1; k=ed25519; p=4ZzCu+I6El7u349oUJIADW8ZFNCgSwzZZohLq1FLf3g="OpenSSL 3.2.1 の出力での鍵のサイズ
Ed25519 公開鍵
32バイト
Base64で44文字。TXTレコードの p= に入る
Ed25519 秘密鍵
16進64文字
--private-key に渡す文字列
mcp-registry-auth
1行67バイト
末尾の改行を含む
ECDSA P-384
49バイト / 96文字
圧縮公開鍵 / 秘密鍵の16進表記
秘密鍵はコマンド引数として渡る形です。シェルの履歴やCIのログに残さないよう、扱う場所は決めておく必要があります。引数に渡さない選択肢が、次のクラウドの鍵管理サービスです。
鍵ファイルを手元に置きたくない場合
秘密鍵を key.pem として保存したくない組織向けに、Google Cloud KMSとAzure Key Vaultで鍵を保持したまま署名する経路が用意されています。Google Cloud KMSの場合、流れは次のとおりです。
Google Cloud KMSでDNS認証を通す
- 1
鍵を作る
キーリングを作り、Ed25519の署名鍵を作成します。
- 2
Application Default Credentialsを有効にする
gcloud auth application-default loginで、mcp-publisherが署名できる状態にします。 - 3
ログインを一度試して、証明用のレコードを表示させる
手順のコメントは、この段階のログインで公開鍵を表示させ、「Expected proof record」をコピーするよう指示しています。
- 4
レコードを登録して、再度ログインする
DNS認証ならTXTレコードに、HTTP認証なら
./mcp-registry-authに書き写します。
gcloud kms keyrings create "mykeyring" --location global
gcloud kms keys create "mykey" --default-algorithm=ec-sign-ed25519 \
--purpose=asymmetric-signing --keyring="mykeyring" --location=global
gcloud auth application-default login
mcp-publisher login dns google-kms --domain="example.com" \
--resource="projects/myproject/locations/global/keyRings/mykeyring/cryptoKeys/mykey/cryptoKeyVersions/1"最後のコマンドは、レコードを登録する前に1回、登録したあとにもう1回実行します。HTTP認証なら login dns を login http に置き換えます。
Azure Key Vaultも同じ流れで、鍵の種類だけが違います。手順はECDSA P-384(az keyvault key create --curve P-384)で、ログインは mcp-publisher login dns azure-key-vault --domain=... --vault=... --key=... です。表示されるレコードの鍵種別は k=ecdsap384 になります。鍵管理を情報システム部門やセキュリティチームに集約している組織向けの選択肢で、個人で公開するなら、ここまで組む必要はありません。
自動公開で使える認証は何か
CI/CDから公開するときは、方式ごとに必要なものが変わります。GitHub Actionsのドキュメントにある例は、次の3通りです。
| 認証方式 | CIでのログイン | 用意するもの |
|---|---|---|
| GitHub OIDC(推奨) | CIでのログインmcp-publisher login github-oidc | 用意するものワークフローに id-token: write 権限。専用のシークレットは不要 |
| GitHub PAT | CIでのログインmcp-publisher login github --token <トークン> | 用意するものread:org と read:user を持つPATを MCP_GITHUB_TOKEN シークレットに |
| DNS | CIでのログインmcp-publisher login dns --domain example.com --private-key <秘密鍵> | 用意するものEd25519の秘密鍵を MCP_PRIVATE_KEY シークレットに |
HTTP認証のワークフロー例は、同じドキュメントにありません。OIDCは長期の秘密鍵もPATも保管せずに済むため、CIとの相性が最も良い選択肢です。DNS認証を自動化する場合は、秘密鍵そのものをシークレットとして預ける形になります。
認証のあとに待つ、もう一つの名前照合
認証が通っても、公開の段階では別の所有確認が走ります。パッケージ側に、server.json と同じサーバー名を書いておく照合です。npmなら package.json の mcpName、PyPIならREADMEの mcp-name: が、server.json の名前と一致している必要があります。
{
"name": "@username/email-integration-mcp",
"version": "1.0.0",
"mcpName": "io.github.username/email-integration-mcp"
}PyPIの mcp-name: はコメントの中に隠してもかまいません。ただし、名前の部分は server.json と一致させます。認証方式を変えて名前空間が変わったときは、この表記も新しい名前に書き換え、パッケージを出し直すことになります。リモートサーバーを公開する場合は、パッケージではなく remotes のURLが、公開アクセスできる状態である必要があります。
バージョン文字列にも規則があります。公開のたびに一意でなければならず、^1.2.3 や 1.x のような範囲指定は禁止です。セマンティックバージョニングが推奨されていて、2025.06.18 のような非セマンティックの日付は許容されるものの注意が必要とされています。
認証が通らないときの切り分け
認証まわりの失敗は、メッセージによって原因の場所が違います。クイックスタートとGitHub Actionsのページに載っているメッセージは、次のとおりです。
| エラーメッセージ | 見る場所 |
|---|---|
| Invalid or expired Registry JWT token | 見る場所認証の期限切れです。mcp-publisher login github などでログインし直します |
| You do not have permission to publish this server | 見る場所認証方式と名前空間が合っていません。GitHub認証なら、サーバー名が io.github.<自分のユーザー名>/ で始まっている必要があります |
| Authentication failed(GitHub Actions) | 見る場所OIDCなら id-token: write 権限、PATやDNSならシークレットの設定を確認します |
| Registry validation failed for package | 見る場所認証ではなくパッケージ側の検証です。たとえばnpmなら package.json に mcpName が必要です |
最後の行だけは、認証を通したあとの段階の失敗です。ログインが成功しているのに公開で止まるときは、認証ではなくパッケージの所有確認を疑う、という切り分けになります。
認証方式はサーバーの安全性を保証しない
3方式のどれでも、MCP Registryが確かめるのは名前空間の持ち主が公開操作をした、という一点だけです。コードが安全かどうかは審査されません。Registry自身はセキュリティスキャンを行わず、npmやPyPIといったパッケージレジストリ側の検査と、下流のアグリゲーターの追加チェックに任せる設計です。
モデレーションの方針も同じ方向です。削除の対象は違法なコンテンツ、マルウェア、スパム、動作しないサーバーで、それ以外は取り除かれません。モデレーションポリシーのページは、利用側がモデレーションをほぼ無いものとして扱うよう求めています。認証を選ぶ作業は「誰が公開したか」を証明する作業であり、「何を公開したか」の審査ではありません。
認証方式を後から変えると何が起きるか
公開済みのバージョン文字列とメタデータは変更できません。更新するときは、新しいバージョン文字列を付けた server.json を公開し直します。名前空間は認証方式で決まるため、方式を変えることは、実質的に別の名前でサーバーを登録し直すことになります。
組織の正規サーバーとして長く運用するケースでは、特定の担当者のGitHubアカウントに紐づく名前よりも、組織のドメインに紐づく名前にする運用もあり得ます。PostgreSQL MCPサーバーのように、インフラチームが継続的に面倒を見るサーバーが想定される例です。DNSの変更に申請が必要で、Webサーバーへのファイル配置は開発チームの裁量でできる組織なら、HTTP認証が現実的です。
状況別の選び方
| 状況 | 向く方式 | 理由 |
|---|---|---|
| 個人開発・検証で早く公開したい | 向く方式GitHub認証 | 理由鍵の生成もDNS操作も要らない |
| 自社ドメインを使い、DNSを自分たちで触れる | 向く方式DNS認証 | 理由TXTレコードを足すだけで済む |
| 自社ドメインを使うが、DNS変更に申請が要る | 向く方式HTTP認証 | 理由.well-known にファイルを置くだけで済む |
| 秘密鍵をファイルで持ちたくない | 向く方式DNSまたはHTTP + KMS | 理由鍵管理サービスに秘密鍵を預けたまま署名できる |
| CIから自動で公開したい | 向く方式GitHub OIDC | 理由長期の秘密鍵もPATも不要 |
ログアウトで認証情報を消す
mcp-publisher には logout コマンドがあります。クイックスタートのヘルプ表示では「Clear saved authentication」と説明されていて、保存済みの認証情報を消します。
まとめ
認証方式は、名前空間を何にするかと、DNSを誰が握っているかで決まります。個人ならGitHub認証、自社ドメインならDNSかHTTP、CIで回すならOIDCが出発点です。
どの方式を通しても、証明されるのは公開した人であって、公開物の安全性ではありません。認証を終えたら、server.json を仕上げてmcp-publisher publishで公開します。