# Set up DoDomain for this project

These are official instructions from DoDomain to set up an AI development environment for custom domains for SaaS: an API, hosted flow and widget that get a customer's domain pointed at your product, verified against authoritative DNS, and monitored for drift. All commands are validated by DoDomain. Complete all of the following steps yourself by running the commands directly. Do not ask the user to run any of these commands, except where a step needs the user in a browser (the OAuth consent) or needs a secret only the user has.

Checklist:

- [ ] 1. Get credentials only if the project's own backend needs a secret key.
- [ ] 2. Connect this agent to the DoDomain MCP server (use the section for your agent).
- [ ] 3. If integrating a backend, install its SDK and wire in the secret key.
- [ ] 4. Verify the MCP connection and any backend secret key.
- [ ] 5. Tell the user what was installed and what is left for them.

## 1. Get credentials

DoDomain has two kinds of credentials. For MCP-only work, skip the backend secret-key and SDK steps:

- The MCP server signs the user in with OAuth in the browser, so MCP-only work needs no key. An app's secret key is also accepted there, acting as that app.
- The REST API and the server SDKs use a secret key that starts with `dd_sk_`, read from the `DODOMAIN_SECRET_KEY` environment variable. It is created per app and shown once.

Only if the project's own backend needs a secret key, check whether `DODOMAIN_SECRET_KEY` is already set in the environment or in the project's env file. If it is not, ask the user for it ONCE, with these instructions: sign in at https://app.dodomain.io/signin, open the app at https://app.dodomain.io/dashboard, and rotate its secret key from the API keys card to reveal a new key once. App creation itself can be done through MCP with create_app. Then write it to the project's local env file (for example `.env.local` or `.env`) and confirm that file is ignored by git. Never commit the key, never print it back, never put it in client-side code, and never pass it to the MCP server.

If the project receives webhooks, it also needs `DODOMAIN_WEBHOOK_SECRET`: the `whsec_` signing secret shown once when a webhook endpoint is added on the same app page. Ask for it only if the project handles DoDomain webhooks. The browser widget uses the app's publishable key (`dd_pk_`), which is safe to expose.

## 2. Connect your agent to the DoDomain MCP server

The remote MCP server is `https://app.dodomain.io/api/mcp` over Streamable HTTP. Auth: OAuth 2.1 with PKCE and dynamic client registration. The client discovers everything from the URL, the user signs in and approves scopes on DoDomain's consent page, and no API key is involved. An app's dd_sk_ secret key is also accepted as a Bearer token and acts as that app, within the permissions chosen when the key was created.

Tools: `accept_team_invitation`, `add_webhook_endpoint`, `billing_status`, `check_domain`, `convert_guest_account`, `create_api_key`, `create_app`, `create_connect_session`, `create_shared_setup_link`, `create_support_ticket`, `create_team`, `decline_team_ownership`, `delete_account`, `delete_app`, `delete_team`, `delete_webhook_endpoint`, `detect_connect_session`, `disconnect`, `disconnect_sign_in_method`, `export_data`, `get_connect_links`, `get_connect_session`, `get_connection`, `get_notification_inbox_session`, `get_profile`, `get_referral`, `get_webhook_delivery`, `invite_member`, `leave_team`, `list_api_keys`, `list_apps`, `list_connected_apps`, `list_connections`, `list_granted_scopes`, `list_invites`, `list_members`, `list_plans`, `list_sessions`, `list_sign_in_methods`, `list_support_tickets`, `list_teams`, `list_vercel_connections`, `list_webhook_deliveries`, `list_webhook_endpoints`, `manage_subscription`, `redrive_webhook_delivery`, `remove_member`, `rename_app`, `request_scopes`, `resume_webhook_endpoint`, `reverify_connection`, `revoke_api_key`, `revoke_connected_app`, `revoke_invite`, `rotate_api_key`, `rotate_webhook_secret`, `run_dns_tool`, `send_test_webhook_event`, `switch_active_team`, `update_app_allowed_origins`, `update_app_branding`, `update_app_tls_issuer`, `update_member_role`, `update_notification_prefs`, `update_profile`, `update_webhook_endpoint`, `upgrade_plan`, `verify_connect_session`. A tool that deletes or cancels something asks for a confirmation token first.
For a fresh team, call create_app with a name, then pass its returned id as appId to create_connect_session. No other step is needed for this flow. App creation requires an Admin or Owner role and refuses the plan app limit. Ask the user which permissions the app's key gets.

### How to use DoDomain from here

What DoDomain is: end-user DNS connection for SaaS apps (a hosted connect flow, verification against authoritative DNS, signed webhooks, drift monitoring), plus this account's apps, API keys, plan, team and billing. Everything the dashboard does is a tool.

Connect: the MCP server is https://app.dodomain.io/api/mcp (Streamable HTTP, OAuth 2.1). The person signs in and picks the permission tiers; a tool outside the granted tiers is not listed, and calling it answers SCOPE_MISSING with request_scopes as the way to widen.

What you can do, by family:
- Domains: check_domain, create_connect_session, verify_connect_session, reverify_connection.
- Apps: list_apps, create_app, rename_app, delete_app, update_app_branding.
- Keys: list_api_keys, create_api_key, rotate_api_key, revoke_api_key.
- Webhooks: add_webhook_endpoint, list_webhook_deliveries, redrive_webhook_delivery.
- Connections: list_connections, get_connect_links, disconnect.
- Billing: billing_status, list_plans, upgrade_plan, manage_subscription.
- Team: list_members, invite_member, update_member_role, remove_member.
- Support: create_support_ticket, list_support_tickets.

Confirmations: a tool that deletes, cancels or removes something answers CONFIRMATION_REQUIRED with a confirmToken in next.args. Tell the person exactly what will happen, then repeat the same call with the token. A token works once, for the same arguments, for ten minutes.

Links: some steps are the person's own to finish (card entry, a Cloudflare or Vercel sign-in, an export download, widening a grant). Those tools return a dashboard link whose path starts with /go/. Give it to the person as it is. It expires in 15 minutes.

Choices: never choose for them. The plan and billing interval, the permissions of a new key, key rotation overlap, a teammate's role and the exact app name or account email typed to confirm a deletion are the person's decisions. Ask, then pass their answer.

Upgrade and cancel: upgrade_plan returns a checkout link. manage_subscription cancels or refunds only with the person's say-so, and a plan bought through Apple or Google is cancelled with that store.

Errors: every refusal carries a code and a next. Follow next.tool with next.args, and ask the person for any value that begins with ask the user.

Use the section for the agent you are (Claude Code, Codex, Cursor, OpenCode, GitHub Copilot (VS Code), or any other MCP client).

### Claude Code

1. Register the DoDomain MCP server.

```bash
claude mcp add --transport http dodomain https://app.dodomain.io/api/mcp
```

Sign-in: Start a new Claude Code session so it loads the server, run /mcp, pick dodomain and choose Authenticate. The browser opens the DoDomain sign-in and consent page.

Reference: https://code.claude.com/docs/en/mcp

### Codex

1. Register the DoDomain MCP server.

```bash
codex mcp add dodomain --url https://app.dodomain.io/api/mcp
```

2. Sign in to DoDomain (opens the browser for the OAuth consent).

```bash
codex mcp login dodomain
```

Sign-in: codex mcp login dodomain opens the DoDomain sign-in and consent page in the browser and stores the token for later sessions.

Reference: https://developers.openai.com/codex/mcp

### Cursor

1. Add the server to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (this project only). If the file exists, merge the dodomain entry into its mcpServers object. File: `~/.cursor/mcp.json`.

```json
{
  "mcpServers": {
    "dodomain": {
      "url": "https://app.dodomain.io/api/mcp"
    }
  }
}
```

Sign-in: Cursor discovers the OAuth endpoints from the URL. When dodomain shows as needing login in Cursor Settings under MCP, click it to open the DoDomain sign-in and consent page.

Reference: https://cursor.com/docs/context/mcp

### OpenCode

1. Add the server to opencode.json in the project root (or ~/.config/opencode/opencode.json for every project). If the file exists, merge the dodomain entry into its mcp object. File: `opencode.json`.

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "dodomain": {
      "type": "remote",
      "url": "https://app.dodomain.io/api/mcp",
      "enabled": true
    }
  }
}
```

2. Sign in to DoDomain (opens the browser for the OAuth consent).

```bash
opencode mcp auth dodomain
```

Sign-in: opencode mcp auth dodomain opens the DoDomain sign-in and consent page in the browser. OpenCode also starts this flow by itself the first time the server answers 401.

Reference: https://opencode.ai/docs/mcp-servers/

### GitHub Copilot (VS Code)

1. Add the server to .vscode/mcp.json in the workspace. If the file exists, merge the dodomain entry into its servers object. File: `.vscode/mcp.json`.

```json
{
  "servers": {
    "dodomain": {
      "type": "http",
      "url": "https://app.dodomain.io/api/mcp"
    }
  }
}
```

Sign-in: Start the server from the MCP: List Servers command (or the Start link VS Code shows above the entry in mcp.json). VS Code asks to sign in and opens the DoDomain consent page in the browser.

Reference: https://code.visualstudio.com/docs/copilot/customization/mcp-servers

### Any other MCP client

Add a remote (Streamable HTTP) MCP server named `dodomain` with the URL `https://app.dodomain.io/api/mcp` and no headers. The URL is the only configuration: the client finds the OAuth metadata, registers itself and opens the browser for sign-in. Full guide: https://dodomain.io/docs/connecting-ai-assistants

## 3. Install the SDK

Skip this step for MCP-only work. Otherwise pick the package that matches this project's stack. Server code gets a server SDK and the secret key from `DODOMAIN_SECRET_KEY`; browser code gets the widget and the publishable key. A plain HTTPS client against the REST API is fully supported too: every endpoint, with its base URL and auth, is in the reference at https://dodomain.io/docs/api.

### @dodomain/node (Node.js 20+ server)

Create connect sessions, manage connections, verify signed webhooks.

```bash
npm install @dodomain/node
```

```ts
import { DoDomain } from "@dodomain/node";

const dodomain = new DoDomain({ secretKey: process.env.DODOMAIN_SECRET_KEY! });

const { apps } = await dodomain.apps.list();
```

Guide: https://dodomain.io/docs/node-sdk

### dodomain-sdk (Python 3.10+ server)

The same server surface as @dodomain/node, sync and async.

```bash
pip install dodomain-sdk
```

```python
import os
from dodomain import DoDomain

client = DoDomain(secret_key=os.environ["DODOMAIN_SECRET_KEY"])

apps = client.apps.list()
```

Guide: https://dodomain.io/docs/python-sdk

### @dodomain/connect (Browser)

Opens the hosted connect flow as a sheet inside your own UI, driven by a session token your server minted.

```bash
npm install @dodomain/connect
```

```ts
import { showDoDomain } from "@dodomain/connect";
```

Guide: https://dodomain.io/docs/widget

### @dodomain/react (React)

The widget as a useDoDomainConnect hook.

```bash
npm install @dodomain/react
```

```tsx
import { useDoDomainConnect } from "@dodomain/react";
```

Guide: https://dodomain.io/docs/react-sdk

Webhooks: verify every delivery with `verifyWebhook(process.env.DODOMAIN_WEBHOOK_SECRET!, rawBody, signatureHeader)` from @dodomain/node (the Python SDK has the same verifier) before trusting it. Guide: https://dodomain.io/docs/webhooks

## 4. Verify

- MCP: once the user has signed in, call the `list_apps` tool. Success is a list of the apps on the user's team.
- Backend secret key, if needed: run the request below. Success is HTTP 200 with a JSON body of the form {"apps": [...]}: a secret key sees exactly its own app, with its id, name and publishable key. A 401 means the key is wrong or rotated.

```bash
curl -s https://app.dodomain.io/api/v1/apps -H "Authorization: Bearer $DODOMAIN_SECRET_KEY"
```

## 5. Report to the user

When you are done, tell the user in this shape, filling in what you actually did:

```text
DoDomain is set up.

- MCP server: added to [agent] as dodomain. [Signed in / Still needs sign-in: how to trigger it in this agent].
- Credentials: DODOMAIN_SECRET_KEY is [set in which file / still missing].
- SDK: [package] installed, client created in [file].
- Verified: [list_apps result / curl result].

Next: [anything left for the user, for example restarting the agent or approving the OAuth consent].
```

## Resources

- Documentation: https://dodomain.io/docs
- FAQ: https://dodomain.io/docs/faq
- Getting started: https://dodomain.io/docs/getting-started
- REST API reference: https://dodomain.io/docs/api
- OpenAPI 3.1 document: https://dodomain.io/docs/openapi.json
- MCP server guide: https://dodomain.io/docs/connecting-ai-assistants
- Site index for agents (llms.txt): https://dodomain.io/llms.txt
- Agent setup guides: https://dodomain.io/agent-setup
- Pricing: https://dodomain.io/pricing
- Status: https://status.dodomain.io
- Support: support@dodomain.io
