CustomDomain™ docs
Getting started

MCP: drive it from an agent

Let an AI agent discover providers, start domain connections and read their status through the hosted MCP server, with API key or scoped agent token access.

Use the MCP server when an agent (Claude, Cursor, a custom MCP client) should discover providers, start connections and read status on a user's behalf. It is the same control plane behind a tool interface.

Connect

  • Endpoint: https://mcp.customdomain.ai/mcp (Streamable HTTP).
  • API key: a cd_live_… key from the console's API & SDK page (an older sk_ key keeps working), sent as Authorization: Bearer <key>. It works for every tool except create-domain-order. It carries your whole workspace's authority, so give it only to agents you trust.
  • Agent token: the scoped option. A person approves exactly which scopes the agent gets (domains:read, domains:connect, domains:disconnect, domains:purchase) and can revoke it at any time. See Agent access.
  • Purchases through MCP are off on the hosted service. Buy a domain in the console instead.
  • The console's MCP server page (switch it on in Settings → Features) has ready made setup for each client (with a key) and a connection test.

Set up an agent from the welcome

On the welcome's first question, tick Also let an AI agent connect and manage domains for me and it has one more step, Give your agent access. It is optional, and Not now always works. Pick your agent (Claude Code, Claude Desktop, Codex, Cursor, VS Code, ChatGPT or Other) and the step shows what to add to it: a command, or a few fields to fill in.

  • Most agents sign in, so there is no key. A browser opens, you approve what the agent may do, and the step says connected, with the agent's name, only once it signed in and you approved it. A grant you revoked or that expired does not count. The same grant is what Overview shows on its Connect your agent row, and you can end it under Agents (in the sidebar under More).
  • Cursor cannot sign in to a new server by itself yet, so it gets the key setup, with your default key from API & SDK (every workspace has one from the start).
  • An agent that connects with a key leaves nothing to see, so the step says it cannot watch for it and the checklist does not claim it. Carry on once you have added it.
  • A prompt to paste into the agent tells it to read the agent skill, to show you what it plans before anything changes, and what to do first for what you told the welcome: connect your domain, add the widget to your product, or list the domains you added. It never holds a key.

The flow an agent should follow

  1. discover-provider { domain } is read only. It says where the domain's DNS lives and which rails can run: rails, recommendedRail and blockedReason (the same truth as rails on POST /v1/domains:check). Do this before promising anything.
  2. connect-domain { domain } creates the connection and returns a link for the human to complete (sign in with the provider, one click, or the records to add) plus a connectionId. The agent never writes DNS itself.
  3. check-connection-status { connectionId } returns a status of pending, propagating, live or failed. Stop when connected is true. A failed connection says why in errorCode. pending has no deadline; a failed connection can be retried by calling connect-domain again for the same domain, which revives it.
  4. A domain that is not live yet: diagnose-connection says record by record what public DNS shows and what is missing. Once the person has fixed it, recheck-connection runs the check now. check-certificate-status reads the HTTPS certificate; certificates renew on their own.
  5. list-connections { status?, limit?, cursor? } lists the connected domains with their status (every application in the workspace when you use an API key). A page that was cut says truncated: true; call again with nextCursor as cursor.

When a connect fails with billing_required, check-billing-status says why and where an owner fixes it.

Buying: search-domain-availability and generate-domain-suggestions work as read tools. create-domain-order exists, but ordering is off on the hosted service. check-order-status and list-domain-orders read orders. Email and forwarding: add-email, forward-domain.

Re-apply and disconnect

  • reapply-connection re-pushes the stored records of a managed connection. A connection with no stored grant answers 409 (conflict), so read managed on list-connections or check-connection-status first. See Managed connections.
  • disconnect-domain { connectionId, confirm } removes any connection of the application, managed or not. The domain stops being served and its certificate and monitoring go away. DNS records are removed only where a kept grant wrote them; anywhere else they stay at the provider and the user deletes them. It answers 409 removal_in_progress while another removal of the same connection is running. The domain goes offline, so ask the person first and send the domain they confirmed as confirm.
  • Disconnecting needs the domains:disconnect scope, which is separate from connecting. A grant approved before that scope existed does not carry it until the person approves the agent again. See Removing a domain.

When a call fails

A failed call is an isError result with success: false, an error code and details. Branch on the code. A token without the tool's scope gets insufficient_scope, and an account over its limit (5 calls a second, bursts of 20) gets rate_limited with retryAfterSeconds. See What a call answers.

Agent authorization

Delegated agent access is live. An agent registers as an OAuth client, a person approves it on the consent page, and the agent gets a 15 minute token limited to the scopes that person approved. Review and revoke agents under Agents, which switches on after your first approval (see Managing access). Full tool reference: MCP server.

On this page