CustomDomain™ について
CustomDomain™は、ドメインの検索、接続、診断、管理をエージェントから行うホスト型MCPサーバーです。エージェント開発チームや顧客独自ドメインが必要なSaaS向けに、任意のDNSレコード値を受け付けず、制約付きツールでDNS、メールレコード、HTTPS状態を扱います。
主な機能
- 01ドメイン検索と価格確認
- 02ドメイン接続とDNSプロバイダー検出
- 03レコード診断と接続状態の確認
- 04メールレコードと転送の設定
- 05証明書、ドメイン一覧、ネームサーバーの管理
活用シーン
- 01公開したアプリへの顧客ドメイン接続
- 02SaaSの企業顧客向けドメイン設定
- 03メール用のMX、SPF、DKIM、DMARC設定
- 04未稼働のドメイン接続の診断や修復
MCP 対応
Streamable HTTP経由で20種類のドメイン管理ツールを提供するホスト型MCPサーバーで、OAuthとスコープ別認可に対応します。必要なDNSレコードを返して接続確認などを行い、任意のレコード値をエージェントが指定することはできません。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://mcp.customdomain.ai/mcpclaude mcp add --transport http ai-customdomain https://mcp.customdomain.ai/mcp{"mcpServers":{"ai-customdomain":{"type":"http","url":"https://mcp.customdomain.ai/mcp"}}}Cursor で開く{"servers":{"ai-customdomain":{"type":"http","url":"https://mcp.customdomain.ai/mcp"}}}VS Code で開く{"mcpServers":{"ai-customdomain":{"type":"http","url":"https://mcp.customdomain.ai/mcp"}}}{"mcpServers":{"ai-customdomain":{"serverUrl":"https://mcp.customdomain.ai/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
CustomDomain™ MCP サーバー:AI エージェント向けのカスタムドメイン
これは CustomDomain™ 製品の公式 MCP サーバーです。エンドポイントは https://mcp.customdomain.ai/mcp のみで、公式 MCP レジストリには ai.customdomain/mcp として登録されています。OAuth スコープは domains:read、
domains:connect、domains:disconnect、domains:purchase です。これを提供しているホストはほかにないため、別のアドレスで CustomDomain™ を名乗るサーバーは、このサーバーではありません。
カスタムドメイン向けの MCP サーバーです。Claude などの AI エージェントが、ドメインの検索、接続、診断、管理を行えます。
ステータス: 本番稼働中 · サーバー 0.6.0 · リリース v0.6.0
ウェブサイト · ドキュメント · コンソール · 製品ページ · MCP ドキュメント · ツールリファレンス · プロバイダーの対応状況 · 料金
インストール:
· Claude Code、Claude Desktop、Cursor: クイックスタート · GitHub Copilot cloud agent: 設定
GitHub でほかの開発者がこのサーバーを見つけるきっかけになるのがスターです。役に立ったら、リポジトリにスターを付けてください。
| 概要 | AI エージェントにドメイン関連の 20 個のツールを提供するホスト型 MCP サーバー |
| 対象ユーザー | 顧客に独自ドメインを持たせたいエージェント開発者、SaaS プラットフォーム、コーディングエージェントのユーザー |
| 稼働先 | customdomain.ai/mcp-server · エンドポイント https://mcp.customdomain.ai/mcp |
| スタック | Go 1.26 · ストリーミング可能な HTTP 上の JSON-RPC 2.0 · ホスト型、サーバー内にデータストアなし |
| ステータス | 本番稼働中 · 公式 MCP レジストリに 0.6.0 を登録 · 20 個のツール · カタログ登録済みの DNS プロバイダー 178 社、そのうち 62 社は自動対応 |
CustomDomain™ MCP は、AI エージェントがユーザーに独自ドメインを持たせるためのホスト型 Model Context Protocol サーバーです。すでに所有しているドメインを接続し、メールレコードを設定し、HTTPS で利用可能になるまで監視し、利用できない理由を調べられます。DNS コントロールパネルで通常は人が手作業で行う作業を代行します。インストールも、稼働させ続ける必要もありません。MCP クライアントを上記のエンドポイントに接続してください。
flowchart LR
A["Agent<br/>Claude · Cursor · ChatGPT"] -->|"JSON-RPC over HTTPS"| M["mcp.customdomain.ai<br/>20 tools"]
M -->|"credential forwarded"| C["Control plane<br/>api.customdomain.ai"]
C --> R["Registrars<br/>search · price"]
C --> D["DNS providers<br/>178 catalogued · 62 automatic"]
C --> E["Edge<br/>TLS issued"]
課題
どの SaaS 製品も、いずれは顧客独自のドメインに対応する必要があります。ホワイトラベルアプリのホスト、独自のリンク、メールの送信ドメインなどです。必要な作業は少なく、いつも同じです。顧客の DNS を管理している事業者を特定し、適切な形式で正しいレコードを設定して、反映を待ち、証明書を取得します。手作業ならサポートチケットになり、コードで実現するなら、結局は自分たちで面倒を見る気のなかった DNS プロバイダー連携が 60 件も必要になります。
エージェントは、改善する前に状況を悪化させます。エージェントにこの作業を任せるわかりやすい方法は、DNS 認証情報とレコードを書き込む手段を渡すことです。そうすると、エージェントが一度判断を誤ったり、悪意あるウェブページを読み込んだりするだけで、顧客のゾーンを編集できてしまいます。本番ドメインに対する SetRecords 呼び出しを言語モデルに渡したい人はいません。一方、手順を読み上げてユーザーにどこかで入力するよう求めるエージェントは、余計な手順が増えただけで、結局またサポートチケットになります。これはプロンプトで解決できる権限の問題ではありません。引数リストの問題であり、エージェントが実行できる操作を変えることで解決します。
対象ユーザー
- 実際に何かを提供するエージェントを構築するチーム。 コーディングエージェント、サイトビルダー、デプロイボットなど、実行可能なアプリを出力し、人が実際に入力するアドレスを必要とするものが対象です。エージェントはドメインを接続し、
liveになるまでポーリングするため、DNS の手順を説明するだけで最後の一歩を残すことはありません。 - テナントドメインを扱う SaaS プラットフォーム。 顧客が自社のドメインを製品に接続できるようにしている場合、これは CustomDomain™ ウィジェットと REST API が利用するものと同じエンジンです。エージェントがすでに使用しているプロトコルを通じて利用できます。
- メールおよびメッセージングプラットフォーム。 送信ドメインの認証(MX、SPF、DKIM、DMARC を顧客のプロバイダーで適切な形式に設定する作業)は、ドキュメントのページやサポート窓口の代わりに、ここでの 1 回の呼び出しで完了します。
- 維持管理が必要なドメインポートフォリオを持つ方。 接続状態は変化し、証明書には引き続き名前解決できるレコードが必要です。ドメインの一覧表示、診断、再確認、再適用を行えるエージェントを使えば、四半期ごとに人が作業するよりもコストを抑えられます。
できること
20 個のツールを、1 つの認証情報で利用できます。どの引数にも DNS レコードは含まれません。以下はすべて個別のツール呼び出しであり、組み立てが必要なワークフローではありません。
- ドメインを登録できるか確認する。購入時と更新時の最新料金も確認できます:
search-domain-availability - 実際に空いている名前を提案する。キーワードのセットから決定論的に提案します:
generate-domain-suggestions - ドメインを登録する。解決済みのレジストラを通じて、フェイルクローズの認可ゲートを設けています。現在、ホスト型サービスでは無効です:
create-domain-order - 顧客がすでに所有しているドメインを接続する。必要なレコードを正確に返します:
connect-domain - 何かを依頼する前に DNS プロバイダーを検出する。レールごとの判定に加え、競合と CAA の事前チェックも行います:
discover-provider - 接続が完了するまでポーリングする。レコードの書き込みから証明書の発行まで確認します:
check-connection-status - ドメインが公開されていない理由を説明する。レコードごとに確認します:
diagnose-connection - 担当者が修正した後、DNS チェックを今すぐ再実行する:
recheck-connection - HTTPS 証明書を確認する(有効期限、更新の失敗):
check-certificate-status - どちらの台帳が該当するか推測せず、2 種類の台帳をまたいで登録注文をポーリングする:
check-order-status - アカウントを通じて行った購入を一覧表示する:
list-domain-orders - 1 回の呼び出しでメールを設定する(サーバー側のテンプレートから MX、SPF、DKIM、DMARC を設定):
add-email - ドメインを別の場所に恒久的に転送する(301):
forward-domain live状態から外れたドメインを、保存済みの許可情報を使って修復する:reapply-connection- 担当者が対象ドメインを確認した後、そのドメインを停止する:
disconnect-domain - アカウント全体のインベントリをページごとに取得する。エージェントは、開始したジョブだけでなくポートフォリオ全体を照合できます:
list-connections - バッチ処理の前、または
billing_requiredによる拒否の後に、ワークスペースが新しいドメインを接続できるか確認する:check-billing-status - ドメインのネームサーバーをアプリケーションの DNS ホストに移行する。先にレコードをコピーし、メール設定も含めて、以後もレコードが正しく保たれるようにします:
migrate-nameservers - 移行を最後まで追跡し、担当者が行う必要のある手順を伝える:
check-nameserver-status - ネームサーバーを元に戻す。以前のネームサーバー、またはレジストラ独自の DNS に戻せます:
rollback-nameservers
引数、スコープ、レスポンス形式の詳細は、TOOLS.md をご覧ください。
外部からすべて検証できる実績:このサーバーは公式 MCP レジストリに ai.customdomain/mcp として 0.6.0 で公開され、プロトコルリビジョン 2025-06-18 に対応しています。認証なしで /.well-known/agent/mcp.json にバージョンとツールの一覧を公開し、未認証の呼び出しには、単なる 401 ではなく、自身のメタデータ文書を示す RFC 9728 チャレンジを返します。自動セットアップは、カタログに登録された 178 のプロバイダーのうち 62 のプロバイダーに対応しています(スコープ付き API トークンで 55、プロバイダーの OAuth で 6、Domain Connect で 1)。残りの 116 も利用でき、適用するレコードとリンクを返します。最新の内訳は /v1/providers/census で確認できます。
これらのツールはすべて、同じ教訓を踏まえて作られています。コンソールへのリンクを返して終わるエージェントは、仕事を完了したとは言えません。ツールは正式なレコード一式そのものを返すため、エージェントは担当者に追加すべき内容を正確に伝えられます。また、完了のシグナルには、インテグレーションが誤読するおそれのあるステータス文字列ではなく、ブール値を使用しています。
ユースケース
- サイドプロジェクトを公開するコーディングエージェント。「このアプリにドメインを向けてください。」
discover-provider、connect-domainの順に実行し、connectedがtrueになるまでcheck-connection-statusを呼び出します。人が行う手順は、DNS プロバイダーで認証するか、返されたレコードを追加することだけです。 - **エンタープライズ顧客をオンボーディングする SaaS。**エージェントは最初に
discover-providerを呼び出し、顧客がルートドメインのエイリアスを設定できないプロバイダーを使っていると確認した場合、誰かが認証する前に警告します。 - メールプラットフォーム。
add-emailはテンプレートから MX、SPF、DKIM、DMARC を書き込みます。エージェントが指定するのは、ドメインごとの DKIM セレクターだけです。 - 1,000 個のテナントドメインを管理するプラットフォーム。
status=failedを指定してlist-connectionsを呼び出し(一覧が揃うまでnextCursorをたどります)、managed: trueの行を残して、それらにreapply-connectionを実行し、残りにはdiagnose-connectionを実行して人に引き継ぎます。これはエージェントが定期的に実行できる調整ループであり、インベントリツールが存在する理由そのものです。 - 「ドメインがまだ機能しないのはなぜですか」という問い合わせに答えるサポートエージェント。
diagnose-connectionは、欠落または誤っているレコードとその理由(Name フィールドにホスト名が入力されている、前段にプロキシがあるなど)を示し、recheck-connectionは次回の定期チェックを待たずに修正を確認します。 - **ユーザーのドメインを正常に保つプラットフォーム。**アプリケーションがドメインを管理している場合、エージェントはユーザーに確認し、
confirm: trueを指定してmigrate-nameserversを呼び出し、doneになるまでcheck-nameserver-statusをポーリングします。ユーザーがレジストラで操作する必要がある場合は、その都度nextStepを伝えます。rollback-nameserversで変更を取り消せます。
MCP 経由でドメインを購入する機能は実装済みですが、ホステッドサービスでは利用できません。購入には認証が必要ですが、そこで購入認証コールバックが設定されていないため、create-domain-order は rejected を返します。コンソールでドメインを購入してから、ここで接続してください。
REST API ではなく MCP サーバーを使う理由
REST API は存在し、このサーバーが呼び出すのもそれです。違いは、エージェントに何を許可するかです。REST API は DNS レコードを受け取りますが、MCP ツールは受け取りません。すべてのレコード値は、検証済みのテンプレートに基づいてコントロールプレーンが計算するため、プロンプトインジェクションを受けたエージェントがここで起こせる最悪の事態は、誤ったドメインを接続することであり、顧客のゾーンに任意の MX レコードを書き込むことではありません。セキュリティモデルは引数リストにあります。さらに、委任されたエージェントトークンが持つのはユーザーが承認したスコープだけであり、ドメインの削除には専用のスコープが必要で、confirm にドメイン名を再度指定する必要があります。有料のドメイン登録は別途制限されています。create-domain-order では confirm_domain にドメインを再度指定する必要があり、インテグレーターの購入認証コールバックが承認した場合にのみ注文が作成されます。コールバックが未設定の場合、すべての購入が拒否されます。ネームサーバーの移行には confirm: true が必要で、エージェントトークンから移行先のネームサーバーを選ぶことはできません。移行先はアプリケーションの設定によって決まります。
2 つ目の理由はディスカバリーです。この製品について何も知らないエージェントでも見つけられます。サーバーは公式 MCP レジストリに登録され、所定のパスでエージェントマニフェストと OAuth 保護リソースドキュメントを公開しています。また、未認証の呼び出しに対して、単なる 401 ではなく、保護リソースドキュメントを示すチャレンジを返します。OAuth 対応クライアントは、そのドキュメントに従って認可サーバーにアクセスし、ユーザーをサインインさせ、コピーするキーが不要なスコープ付きトークンを取得します。REST API ではこのような形で自己紹介することはできません。
クイックスタート
ほとんどのクライアントは OAuth でサインインするため、コピーするキーはありません。ブラウザーが開き、ユーザーがエージェントに許可する操作を承認すると、エージェントはスコープが制限されたトークンを取得します。サインインできないクライアントでは、コンソールの app.customdomain.ai(API & SDK)で取得した API キーを使用します。キーは cd_live_... または cd_test_... の形式です(以前の sk_live_.../sk_test_... キーも引き続き使用できます)。キーは環境変数に保存し、コミットするファイルには決して保存しないでください。
Claude Code で OAuth を使ってサインインする場合:
claude mcp add --transport http customdomain https://mcp.customdomain.ai/mcp
# then run /mcp inside Claude Code and sign in
または、環境変数に設定した API キーを使う場合:
claude mcp add --transport http customdomain https://mcp.customdomain.ai/mcp \
--header "Authorization: Bearer $CUSTOMDOMAIN_API_KEY"
Claude Desktop:Settings → Connectors → Add custom connector を選択します。URL
https://mcp.customdomain.ai/mcp を入力して追加し、Connect を選んでサインインします(OAuth)。
Cursor はまだ新しいサーバーに直接サインインできないため、キーを使用します。ユーザーレベルの
~/.cursor/mcp.json に設定してください。コミットされるプロジェクトの .cursor/mcp.json には設定しないでください。また、Cursor の起動元の環境で CUSTOMDOMAIN_API_KEY を設定してください。
{
"mcpServers": {
"customdomain": {
"url": "https://mcp.customdomain.ai/mcp",
"headers": { "Authorization": "Bearer ${env:CUSTOMDOMAIN_API_KEY}" }
}
}
}
任意の HTTP クライアント:エンドポイントは標準の JSON-RPC 2.0 なので、curl でツールを呼び出せます。
curl -X POST https://mcp.customdomain.ai/mcp \
-H "Authorization: Bearer $CUSTOMDOMAIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"discover-provider","arguments":{"domain":"example.com"}}}'
コンソールの MCP server ページには、これらのクライアントや Codex、VS Code、ChatGPT などのセットアップ手順をコピーして貼り付けられる形式で用意しており、接続テストも実行できます。
VS Code
ページ上部のインストールバッジから、このエントリを追加できます。または、自分で .vscode/mcp.json に追加するか、MCP: Add Server を実行します。
{
"servers": {
"customdomain": { "type": "http", "url": "https://mcp.customdomain.ai/mcp" }
}
}
このエントリにはキーは含まれません。サーバーは最初のリクエストに 401 で応答し、その WWW-Authenticate ヘッダーに保護リソースメタデータの URL を示します。そのドキュメントには、認可サーバーとして https://api.customdomain.ai が記載されています(PKCE を使う認可コードフローと、動的クライアント登録に対応)。VS Code のドキュメントに記載されているように、このチャレンジに従うクライアントでは、ユーザーがサインインしてスコープを承認するためのブラウザーが開きます。代わりに API キーを使うには、VS Code が一度だけ入力を求め、シークレットとして保存するヘッダーを追加します。
{
"servers": {
"customdomain": {
"type": "http",
"url": "https://mcp.customdomain.ai/mcp",
"headers": { "Authorization": "Bearer ${input:customdomain-key}" }
}
},
"inputs": [
{ "type": "promptString", "id": "customdomain-key", "description": "CustomDomain™ API key", "password": true }
]
}
GitHub Copilot クラウドエージェント
Copilot クラウドエージェント(イシューやプルリクエストに対応するコーディングエージェント)は、OAuth でサインインするリモート MCP サーバーに対応していないため、認証情報をヘッダーとして送信します。リポジトリで Settings → Copilot → MCP servers を開き、この設定を貼り付けて保存します。
{
"mcpServers": {
"customdomain": {
"type": "http",
"url": "https://mcp.customdomain.ai/mcp",
"headers": { "Authorization": "$COPILOT_MCP_CUSTOMDOMAIN_AUTH" },
"tools": ["*"]
}
}
}
次に、COPILOT_MCP_CUSTOMDOMAIN_AUTH という名前の Agents シークレットを追加します(Copilot が渡すのは、名前が COPILOT_MCP_ で始まるシークレットのみです)。値には、ヘッダー全体の値である Bearer に続けて、次のいずれかを設定します。
- コンソールの API & SDK ページで取得した API キー(
cd_live_...)。ワークスペース全体で使用できます。 POST /v1/applicationsで作成したアプリケーションのAPPLICATION_ID:CLIENT_SECRET。この API はシークレットを一度だけ返します。サーバーはリクエストごとにこのペアを 15 分間有効なトークンと交換します。これはPOST https://mcp.customdomain.ai/tokenがclient_credentialsグラントで行う交換と同じで、エージェントはそのアプリケーションのみを対象に操作します。コンソールで作成したアプリケーションのシークレットは再表示されないため、その場合は API キーを使用してください。
"tools": ["*"] を設定すると、エージェントは確認なしですべてのツールを呼び出せるようになります。これにはドメインをオフラインにする disconnect-domain も含まれます。エージェントの操作を読み取りと診断に限定するには、代わりにツールを列挙します。例:["discover-provider", "check-connection-status", "diagnose-connection", "list-connections", "check-certificate-status"]。
クライアントのサポート
| クライアント | 接続方法 | 備考 |
|---|---|---|
| Claude Code | ネイティブのストリーム可能な HTTP | claude mcp add --transport http を実行します。/mcp でサインインするか、キーをヘッダーに渡します |
| Claude Desktop | カスタムコネクタ | 「設定」→「コネクタ」→「カスタムコネクタを追加」を選択します。OAuth でサインインします |
| Cursor | ヘッダー付きのネイティブ HTTP | 環境変数から取得したキーを使って ~/.cursor/mcp.json を設定します。現時点ではサインインできません |
| ChatGPT | 開発者モードのアプリ | OAuth でサインインします。API キーは送信できません |
| その他すべて | POST /mcp、JSON-RPC 2.0 | 401 の案内に従ってサインインするか、Authorization ヘッダーに Bearer を指定します |
ツールと3つの規則
すべてのツールに共通する規則が3つあります。インテグレーターが間違えやすいのはこの点です。
どのツールも DNS レコードを受け取りません。 add-email はメール設定(MX ホスト、DKIM セレクター)を受け取り、テンプレートがそれらをレコードに変換します。forward-domain はリダイレクト先を受け取ります。どちらもレコードは受け取りません。
connected: true が完了の合図です。 ステータス文字列は参考情報です。分岐の条件にはブール値を使ってください。ステータスの列挙型が将来拡張されても、この値は変わりません。
取り消せない呼び出しには、本人の承認が必要です。 disconnect-domain は connectionId と confirm(本人が確認したドメイン)を受け取ります。create-domain-order ではドメインを confirm_domain に再度指定します。migrate-nameservers と rollback-nameservers は confirm: true を受け取ります。これらがなければ、何も実行される前に呼び出しは拒否されます。
所有権を証明するチャレンジの手順もありません。TXT 検証レコードを要求したり、確認したりするツールはありません。ドメインの管理権限は、レコードを書き込む手段(プロバイダーでの OAuth 認可、ワンクリックでの適用、またはスコープを限定した API トークン)によって証明されます。手動の場合、コントロールプレーンはレコードがパブリック DNS に現れるのを待つだけです。
認証
POST /mcp は、4 種類のベアラー認証情報を受け付けます。
| 認証情報 | 発行元 | 対象 |
|---|---|---|
API キー cd_live_ / cd_test_(旧形式 sk_live_ / sk_test_) | コンソールの API & SDK。各ワークスペースにはデフォルトのキーがあり、作成したキーは一度だけ表示されます。 | ワークスペース全体 |
POST /token で取得した JWT | application_id + client_secret を使用した client_credentials 交換。15 分で期限切れになります。 | 1 つのアプリケーション |
CLIENT_ID:CLIENT_SECRET | トークン交換を実行できないホスト向けのショートカット。サーバーがリクエストごとに交換します。 | 1 つのアプリケーション |
| 委任エージェントトークン | https://api.customdomain.ai での OAuth:動的クライアント登録、PKCE(S256)を使用した認可コードフロー、ユーザーによるスコープの承認 | 承認されたスコープのみを持つ 1 つのアプリケーション |
curl -X POST https://mcp.customdomain.ai/token \
-u "<APPLICATION_ID>:<CLIENT_SECRET>" \
-d "grant_type=client_credentials"
# -> { "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 900 }
APPLICATION_ID と CLIENT_ID は、名前が異なるだけで同じ値です。
インテグレーター認証情報(API キー、/token の JWT、CLIENT_ID:CLIENT_SECRET 形式)は、サーバー自体では検証されません。サーバーはこれらをコントロールプレーンに転送し、コントロールプレーンが各呼び出しで REST API と同じ権限を適用します。これらにスコープはありません。コンソールでキーを取り消すと、次の呼び出しからエージェントは利用できなくなります。現時点では、その呼び出しは HTTP 401 ではなく、error: "unauthorized" を含むツールエラーを返します。
委任エージェントトークンは、オーディエンス https://mcp.customdomain.ai/mcp 向けに発行された ES256 トークンです。サーバーはコントロールプレーンの JWKS を使用してローカルでトークンを検証し、別のオーディエンス向けに発行されたトークンは 401 invalid_token で拒否します。また、各呼び出しでツールのスコープを確認します。
| スコープ | ツール |
|---|---|
domains:read | search-domain-availability、generate-domain-suggestions、check-connection-status、check-order-status、discover-provider、list-connections、check-certificate-status、diagnose-connection、check-billing-status、list-domain-orders、check-nameserver-status |
domains:connect | connect-domain、reapply-connection、forward-domain、add-email、recheck-connection、migrate-nameservers、rollback-nameservers |
domains:disconnect | disconnect-domain |
domains:purchase | create-domain-order |
ツールに必要なスコープがないトークンを使用すると、必要なスコープ名を示す JSON-RPC エラー -32003(insufficient_scope)が返されます。エージェントアクセスと認証を参照してください。
エージェントが使用するものには、エージェントトークンまたはアプリケーションスコープの JWT を使用してください。cd_live_ キーが漏えいすると、ワークスペース全体へのアクセスが可能になります。
レート制限
ツール呼び出しは、呼び出し元ごとに毎秒 5 回、バースト時は 20 回に制限されます。呼び出し元は、委任エージェントトークンの場合はワークスペース(同じワークスペース内のすべてのエージェントで 1 つのバケットを共有します)、API キーまたは /token の JWT の場合は認証情報自体(キーが 3 つあるワークスペースには 3 つのバケットがあります)、CLIENT_ID:CLIENT_SECRET 形式の場合はアプリケーションです。制限を超えると、呼び出しは error: "rate_limited" と retryAfterSeconds を含むツールエラーを返し、コントロールプレーンには到達しません。コントロールプレーンでも、各クライアントアドレスに対して制限が適用されます。
ライフサイクル、ポーリング、エラー
接続は pending → propagating → live と遷移します。failed は診断結果であり、終了状態ではありません。
| ステータス | 意味 |
|---|---|
pending | 作成済みです。レコードがまだ書き込まれていないか、パブリック DNS でまだ確認されていません。手動接続は自動的に失敗することはありません。72 時間経過後も pending のまま errorCode: "setup_incomplete" となり、6 時間ごとに再確認されます。 |
propagating | レールがレコードを書き込みました。ポーラーが値を基にパブリック DNS と照合しています。 |
live | すべての目的のレコードが意図した値に解決され、エッジがそのホストに対して TLS を提供しています。 |
failed | レールが書き込んだレコードが 24 時間以内に解決されなかった場合(errorCode: "propagation_timeout")、またはレールが書き込みを拒否した場合の状態です。接続が後で再検証されると解除されます。 |
バックグラウンドポーラーは約 1 分ごとに再確認するため、30〜60 秒より短い間隔でポーリングしても効果はありません。failed は回復可能な状態であり、ユーザーに最初からやり直すよう伝える理由にはなりません。diagnose-connection で問題の内容を確認でき、修正後に recheck-connection を実行すると確認をやり直せます。ライフサイクルの詳細については、Connections をご覧ください。
エラーには 2 つの形式があります。不正な呼び出しは JSON-RPC 層で失敗します。無効または不足している引数は -32602、不明なツールは -32601、解析できない JSON は -32700、スコープがない場合は -32003 です。これらは呼び出し元のバグです。コントロールプレーンが拒否した呼び出しは、どのツールでも同じ形式で、isError: true が設定されたツール結果として返されます。
{ "success": false, "error": "billing_required", "message": "A card is needed to connect more domains.", "details": "..." }
error は、コントロールプレーンがエラーコードを送信した場合はそのコード、それ以外の場合はツールのフォールバックコード(connect_failed、status_failed、list_failed など)です。error に基づいて分岐し、message を表示してください。一覧については、TOOLS.md をご覧ください。
仕組み
このリポジトリは、ホスト型サービスの公開インターフェースです。サーバーを掲載するレジストリーマニフェスト、ツールの仕様、そしてこのページで構成されています。サーバー本体は小規模な Go プロセスです。JSON-RPC を終端し、委任されたエージェントトークンとそのスコープを検証し、呼び出し元ごとのレートを制限して、各ツール呼び出しを CustomDomain™ のコントロールプレーンに転送します。コントロールプレーンはプロバイダーの検出、レコードテンプレート、レジストラーレール、伝播ポーラー、証明書の発行を担います。この分離により、ツールのインターフェースをこれほど絞り込めます。すべての状態と判断は、1 ホップ先に集約されています。
リポジトリの構成
.
├── README.md # this file: what the server is, how to point a client at it, how it is built
├── TOOLS.md # the tool contract: every argument, scope, response field, status value and error code
├── CHANGELOG.md # one entry per server version, matching the tags and GitHub releases
├── server.json # MCP registry manifest: name ai.customdomain/mcp, version 0.6.0, remote endpoint, tools and scopes
├── glama.json # Glama directory ownership claim
└── LICENSE # MIT
サービスモジュール
サーバーのソースは、呼び出し先のコントロールプレーンとともに、非公開の CustomDomain™ モノレポ内の services/mcp にあります。境界が分かりやすいようにここに記載していますが、リポジトリは非公開のためリンクしていません。
| モジュール | 目的 | 通信先 |
|---|---|---|
server.go | initialize、tools/list、tools/call をルーティングし、20 個のツールを固定順で登録します。ツールの実行前にスコープとレートを確認します | tools.go、usage.go |
tools.go | ツール定義、JSON スキーマ、注釈、ハンドラー、および単一の失敗形式 | client.go |
nameservers.go | 3 つのネームサーバーツールのハンドラーです。confirm: true を必須とし、エージェントトークンからの target または nameservers は受け付けません | client.go |
scopes.go | ツールとスコープの対応表、およびすべてのツールがスコープを 1 つだけ宣言していることを確認する構築時チェック | server.go |
ratelimit.go | 呼び出し元ごとのトークンバケット(デフォルトでは毎秒 5 件、バースト 20 件) | server.go |
jsonrpc.go | JSON-RPC 2.0 のフレーミングとエラーコード | transport.go |
transport.go | stdio およびストリーム可能な HTTP トランスポート | server.go |
client.go | ControlPlane ポートです。すべてのツールハンドラーが呼び出すインターフェースです | httpclient.go によって実装 |
httpclient.go | コントロールプレーンの REST API に接続する HTTP アダプター | api.customdomain.ai |
clientinfo.go | 呼び出し元のアドレスを引き継ぎ、コントロールプレーンのアドレスごとの制限が各ユーザーを認識できるようにします | コントロールプレーン |
origin.go | /mcp の Origin チェック(ブラウザーのオリジンはサーバー自身、または運用者が指定したものに限ります。それ以外は 403)と CORS プリフライト応答 | なし |
auth.go | Bearer の抽出、POST /token、および RFC 9728 の WWW-Authenticate チャレンジ | コントロールプレーン |
agenttoken.go | 委任されたエージェントトークンのローカル ES256 検証(署名、有効期限、オーディエンス) | コントロールプレーンの JWKS |
purchaseauth.go | フェイルクローズ方式の購入認可コールバック。有料注文の前に確認します | インテグレーターのコールバック |
registrar.go | レジストラの解決と優先レジストラの順序付け | コントロールプレーン |
untrusted.go | サードパーティーのテキスト(DNS 値、プロバイダーエラー)がエージェントに渡る前に長さを制限します | なし |
wellknown.go | 保護対象リソースと認可サーバーのメタデータ、および /.well-known/agent/mcp.json を提供します | なし |
usage.go | バッチ処理を行う使用状況記録機能です。容量がいっぱいの場合は破棄し、ツール呼び出しをブロックしません | コントロールプレーンのインジェスト |
cmd/mcp/main.go | プロセスのエントリーポイントです。フラグ、環境、Sentry、OpenTelemetry を扱います | 上記すべて |
エントリーポイント:services/mcp/cmd/mcp/main.go。
重要なフロー
すでに所有しているドメインを接続するフローを軸に、ほかのすべてが設計されています。
sequenceDiagram
participant A as Agent
participant M as mcp.customdomain.ai
participant C as Control plane
participant D as Customer's DNS
participant E as Edge
A->>M: tools/call connect-domain {domain}
M->>C: POST /v1/connections (credential forwarded)
C->>C: detect provider, choose rail, compute records
C-->>M: connectionId, records[], link, managed
M-->>A: same payload as structuredContent
Note over A,D: automatic rail: user authorizes once<br/>manual rail: user adds the returned records
C->>D: poll public DNS by value (~60s)
C->>E: request certificate once records resolve
A->>M: tools/call check-connection-status {connectionId}
M-->>A: status live, connected true
不変条件
- DNS レコードを入力として受け取るツールはありません。 レコード値は、検証済みテンプレートからサーバー側で計算されます。 これはセキュリティモデルであり、機能の欠落ではありません。
- サーバーにデータベースはありません。
go.modが取り込むのは Sentry と OpenTelemetry だけです。ツールが返す情報はすべて、そのリクエスト中にコントロールプレーンから取得されます。レートリミッターのバケットはメモリ上にあります。 - すべてのツールはスコープを 1 つだけ宣言します。 宣言されていない場合、サーバーは起動を拒否します。
- 所有権を確認する手順はありません。 TXT 検証レコードを要求したり確認したりするツールはありません。
- このリポジトリ内のものは何もデプロイされません。 ビルドも CI もサーバーのソースもありません。ここにあるファイルは MCP レジストリと人が読むものであり、エンドポイントは別の場所から提供されます。
POST /v1/connectionsはアプリケーションとドメインの組み合わせごとに冪等です。 そのため、connect-domainを繰り返すと既存の接続を再開し、2 つ目の接続を作成する代わりにalready_connected: trueを返します。
設定
クライアント側で設定する項目です。 このリポジトリで設定が必要な環境変数はありません。
| 設定項目 | 必須 | デフォルト | 用途 |
|---|---|---|---|
| エンドポイント URL | はい | なし | https://mcp.customdomain.ai/mcp |
Authorization ヘッダー | クライアントがサインインする場合を除く | なし | Bearer cd_live_...、/token から取得した JWT、または CLIENT_ID:CLIENT_SECRET。サインインするクライアントはエージェントトークンを取得し、自身で送信します。 |
| トークン URL | /token の JWT を使用する場合のみ | なし | https://mcp.customdomain.ai/token |
クライアントがサポートしている場合は、キーを設定ファイルに含めないでください。シークレットマネージャーに保存している場合は、起動時に注入してください。リポジトリ、コミットする .cursor/mcp.json、Issue に、キーをそのまま貼り付けないでください。
ホスト型サービスの設定項目です。 これらのいくつかはツールの動作を変えるため、インテグレーターから購入が拒否された理由を尋ねられることがあります。シークレット値はデプロイ時に注入され、リポジトリには保存されません。
| 変数 | 必須 | デフォルト | 用途 |
|---|---|---|---|
MCP_ADDR | いいえ | :8080 | HTTP のリッスンアドレス |
MCP_API_BASE | いいえ | https://api.customdomain.ai | コントロールプレーンのベース URL |
MCP_PUBLIC_BASE | いいえ | https://mcp.customdomain.ai | ディスカバリードキュメントに設定される公開オリジン、およびエージェントトークンのオーディエンスのベース |
MCP_AUTH_SERVER | いいえ | https://api.customdomain.ai | エージェントトークンを発行するコントロールプレーンの公開オリジン。保護されたリソースのメタデータで最初に指定されます |
MCP_AGENT_JWKS_URL | いいえ | 未設定 | 委任されたエージェントトークン用の JWKS。未設定の場合、エージェントトークンの経路は無効になります。 ホスト型サービスでは設定されています。 |
MCP_ALLOWED_ORIGINS | いいえ | 未設定 | サーバー独自のオリジン以外に、/mcp の呼び出しを許可するブラウザーオリジン(scheme://host[:port]、カンマ区切り)。それ以外の Origin は 403 になります。Origin のないリクエスト(すべての非ブラウザークライアント)は影響を受けません。ワイルドカードは使用できません。ホスト型サービスでは未設定です。 |
MCP_TENANT_RPS | いいえ | 5 | 呼び出し元ごとの 1 秒あたりのツール呼び出し回数。0 にすると制限が無効になります。 |
MCP_TENANT_BURST | いいえ | 20 | 1 回のバーストで呼び出し元ごとに許可されるツール呼び出し回数 |
MCP_LINK_BASE | いいえ | コンソール URL | エージェントに返される、ガイド付き DNS のフォールバックリンクのプレフィックス |
MCP_PURCHASE_AUTHZ_URL | 購入時 | 未設定 | 認可コールバック。未設定の場合、有料注文はすべて拒否されます。現在、ホスト型サービスはこの設定で稼働しています。 |
MCP_PURCHASE_AUTHZ_USER | URL 設定時 | 未設定 | そのコールバック用の Basic 認証ユーザー |
MCP_PURCHASE_AUTHZ_PASSWORD | URL 設定時 | 未設定 | そのコールバック用の Basic 認証パスワード(注入され、保存されることはありません) |
MCP_PREFERRED_REGISTRAR | いいえ | 未設定 | 注文の解決時に最初に試すレジストラー |
JUSTEASY_MCP_USAGE_KEY | いいえ | 未設定 | 使用状況の記録を有効にします。未設定の場合、レコーダーは何もしません。CUSTOMDOMAIN_MCP_USAGE_KEY が最初に読み込まれ、フォールバックとして MCP_USAGE_INGEST_KEY が使われます。 |
MCP_USAGE_INGEST_URL | いいえ | MCP_API_BASE から導出 | 使用状況のバッチの送信先 |
CUSTOMDOMAIN_API_TOKEN | stdio のみ | 未設定 | ローカル stdio トランスポート用の静的なコントロールプレーンベアラートークン(旧名称は JUSTEASY_API_TOKEN) |
MCP_INSECURE | いいえ | 未設定 | ある開発者のマシン用に、ベアラーチェックなしで /mcp を提供します。サーバーがループバックアドレスをリッスンしていない場合は起動を拒否し、本番ホストでの起動も拒否します。 |
SENTRY_ENVIRONMENT | いいえ | 未設定 | 環境タグ。プロダクションガードが参照する値でもあります |
OTEL_EXPORTER_OTLP_ENDPOINT | いいえ | 未設定 | オプトインのトレーシング。未設定の場合は何もしません |
開発とテスト
ここにはビルドはありません。このリポジトリに含まれているのは、2 つの JSON マニフェストと 3 つの Markdown ドキュメントだけなので、チェックもそれに見合ったものです。
git clone https://github.com/CUSTOM-DOMAIN-APP/customdomain-mcp.git
cd customdomain-mcp
jq -e . server.json glama.json > /dev/null && echo "manifests parse"
server.json は、宣言されている MCP レジストリスキーマ(https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json。description の文字数制限は 100 文字です)に照らして検証する必要があり、version はレジストリに公開されているバージョンと一致している必要があります。TOOLS.md が仕様書です。ツールの引数やレスポンスフィールドが上流で変更された場合、そこに反映するまでは変更完了とはなりません。
サービス自体は Go 1.26 で、プロトコル、トランスポート、コントロールプレーンアダプター、購入ゲートとその確認、スコープの適用、エージェントトークンの検証、レートリミッター、Origin チェック、ネームサーバーツール、ディスカバリードキュメントの整合性を網羅する、26 個のテストファイルにわたる 196 件のテスト(2026-10-21、0.6.0 のコミット時点で集計)を備えています。エンドポイントに反映する前に、モノレポで go build ./... && go test ./... を実行し、さらに -race によるテストも行います。
エージェントのマニフェストは公開されているため、ライブチェックには何も必要ありません。
curl -s https://mcp.customdomain.ai/.well-known/agent/mcp.json | jq '{version, tools: (.tools | length)}'
# -> { "version": "0.6.0", "tools": 20 }
バージョニングとリリース
サーバーのバージョン番号は 1 つです。serverInfo、/.well-known/agent/mcp.json、レジストリエントリー、そしてこのリポジトリの server.json に記載されています。各バージョンには vX.Y.Z タグ、GitHub リリース、および CHANGELOG.md のエントリーがあります。現在のバージョンは 0.6.0 です。
2 つのものが異なるリリース経路で提供されるため、それらを混同するとバージョン文字列が古いままになります。
このリポジトリはディレクトリに公開されます。server.json は公式 MCP レジストリが ai.customdomain/mcp 向けに読み取るマニフェストで、glama.json は Glama ディレクトリの所有権を示す申告です。変更を公開するには、server.json の version を更新し、マニフェストをレジストリに再公開(公開済みのレジストリバージョンは変更できません)し、CHANGELOG のエントリーを追加してタグを付けます。ロールバックするには、コミットをリバートして以前のバージョンを再公開します。このリポジトリ内のものはリクエスト経路にないため、ここで問題のあるコミットがあってもエンドポイントが停止することはありません。
レジストリは、customdomain.ai の DNS TXT レコード(v=MCPv1; k=ed25519; p=...)から ai.customdomain の名前空間を認識します。そのため公開には、これに対応する Ed25519 秘密鍵(メンテナーが保持し、このリポジトリには決して置かれません)と、レジストリの mcp-publisher CLI が必要です。
mcp-publisher login dns --domain customdomain.ai --private-key "$REGISTRY_PRIVATE_KEY_HEX"
mcp-publisher publish server.json
エンドポイントは、プライベートモノレポから、バイナリに /healthz プローブを組み込んだ distroless コンテナとしてリリースされます(イメージにシェルがないため、-probe を使用します)。クライアントは常にデプロイ済みのビルドに接続します。上流で追加されたツールは、お客様側で変更しなくても利用でき、ロールバックも以前のイメージを再デプロイするだけで、クライアント側の操作は一切不要です。インテグレーションでは、バージョン文字列ではなく、ツール名と connected ブール値を基準にしてください。
運用上の対処は、実施する順に次のとおりです。問題のあるエージェントを停止するには、コンソールでキーまたはエージェントへの許可を取り消します。MCP_TENANT_RPS を下げます。すべての購入を拒否するには MCP_PURCHASE_AUTHZ_URL を未設定にします。サービスとコントロールプレーンのエラー報告を確認します。ツールに影響する変更は、ドキュメントの変更履歴に記録されます。
既知の制限事項
- カタログに掲載されている178のDNSプロバイダーのうち、116には自動連携機能がありません。 ツールは引き続き動作し(レコードとリンクを返します)が、人が追加する必要があります。まず
discover-providerを呼び出して、該当するケースを確認してください。内訳は プロバイダー で公開されています。 - エージェントだけでは手動接続を完了できません。 意図的にリンクを介する設計になっています。エージェントがリンクを返してポーリングし、人が支払い手続きを行い、自動連携機能がない場合はDNSの設定も行います。
- ホスト型サービスでは購入できません。
create-domain-orderは認可が必要ですが、購入認可コールバックが設定されていないため、rejectedを返します。コンソールで購入してください。 confirmとドメインの照合は、エージェントトークンの場合にのみ行われます。disconnect-domainはすべての呼び出し元にconfirmを要求しますが、現在、コントロールプレーンがそれを接続先のドメイン名と照合するのは、委任されたエージェントトークンの場合のみです。API キーまたはクライアント認証情報トークンを使用する場合は、呼び出す前にご自身で確認してください。- Cursor ではまだサインインできません。 ワークスペース全体へのアクセス権を持つ API キーを使用します。
- ブラウザー経由のクライアントは拒否されます。 Web ページからのリクエストには
Originが含まれますが、ホスト型サービスが受け付けるのは自身のオリジンのみです(そこでMCP_ALLOWED_ORIGINSは未設定)。そのため、このようなクライアントには403が返されます。プロセスまたはサーバーとして実行され、Originを送信しないクライアントには影響しません。 - エージェントトークンでは、ドメインのネームサーバーの移行先を指定できません。
migrate-nameserversはネームサーバーをアプリケーションの DNS ホストに移行します。targetまたはnameserversを指定するには、プラットフォーム独自の認証情報が必要です。 - 任意のDNSレコードを書き込むことはできません。 ご自身で用意したレコードを書き込む必要がある場合、このサーバーは適していません。REST API またはプロバイダー独自のものを使用してください。
- API キーのレート制限は認証情報ごとに適用されます。 複数のキーにまたがって呼び出しを分散するワークスペースには、キーごとに個別の枠が割り当てられます。エージェントトークンは、ワークスペースごとに1つの枠を共有します。また、接続数はプランの上限に基づき、UTC の暦月ごとに計測されます。
- サーバーのソースコードはこのリポジトリにありません。 ここにあるのはマニフェストと仕様であり、サーバーはホストされています。
セキュリティ
このリポジトリに認証情報を含めてはいけません。実際、ここには含まれていません。MCP サーバーは独自のキーを保持しません。お客様のキーをコントロールプレーンに転送し、エージェントトークンは保存せずに検証します。エージェントが扱うものには、ワークスペース全体にアクセスできる cd_live_ キーではなく、委任されたエージェントトークン(スコープ制限付き、取り消し可能、有効期間15分)またはアプリケーションスコープの JWT を使用してください。脆弱性は、公開 issue ではなく、「サポート」に記載された方法で報告してください。
関連項目
- connect-domain-for-ai-agents:エージェントスタック向けのフィールドガイド
- customdomain-sdk:公式 JS/TS クライアント、
customdomain-jsおよび@customdomain/react - awesome-custom-domains:代替手段を含む、分野全体の一覧
- docs:docs.customdomain.ai のソース
コントリビューション
ドキュメントやマニフェストに関する issue とプルリクエストを歓迎します。ツールの動作変更は、上流のプライベートモノレポで行われます。必要な動作を説明する issue を作成してください。担当者に転送されます。TOOLS.md と公開中のツールスキーマの内容が一致するようにしてください。一方だけを変更するプルリクエストには、もう一方の変更も求められます。
サポート
- ドキュメント: docs.customdomain.ai
- 質問やアイデア: GitHub Discussions
- バグや修正点: このリポジトリでイシューを作成してください
- サービスのステータス: status.customdomain.ai
- アカウントと請求: [email protected]
- セキュリティ: [email protected] に非公開で報告してください。公開イシューには絶対に投稿しないでください。ポリシー:app.customdomain.ai/security
ライセンス
MIT。CustomDomain™ は EverJust Company の製品です。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。