Docs
Docs
Guides

Use Apexly from AI agents (MCP)

Connect Claude Code, Cursor or any MCP client to Apexly's hosted MCP server and let your coding agent add, check, diagnose and remove custom domains with your API key.

Apexly runs a hosted Model Context Protocol server, so an AI coding agent can manage your customers' domains while it builds the feature with you: add a hostname, hand the customer the DNS record or the connect link, check why a domain is stuck, and remove it.

The server is built into the Apexly API, but the mcp.apexly.dev hostname goes live with the next production deploy: until then the snippets below will not connect. You can run it locally today at http://localhost:4000/mcp (see Run it locally).

How it works

  • Endpoint: https://mcp.apexly.dev/mcp, Streamable HTTP transport (stateless: no session to keep alive).
  • Auth: your normal Apexly API key, sent as Authorization: Bearer sk_live_… or sk_test_…. Create one under Keys in the dashboard. There is no separate MCP login.
  • Scope: exactly the same as the REST API. The agent sees only the domains of the key's app; another app's domain is not_found. A test key sees and creates test domains only, so start with sk_test_… while you try it out.
  • Limits: every tool call counts against your app's API rate limits (60 writes and 600 reads per minute), plus 600 MCP requests per minute per app.
  • Errors come back as the same envelope as the API, { "error": { "code", "message", "fix", "docs" } }, so the agent can read the fix and act on it.

Claude Code

claude mcp add --transport http apexly https://mcp.apexly.dev/mcp \
  --header "Authorization: Bearer sk_test_…"

Then ask, for example: "Add careers.acme.com as a custom domain and tell me what DNS record Acme needs." Run claude mcp list to check the connection.

Keep the key out of the repository: claude mcp add stores it in your local Claude Code config by default. Use --scope project only with an environment variable, never a pasted key, in a shared .mcp.json:

{
  "mcpServers": {
    "apexly": {
      "type": "http",
      "url": "https://mcp.apexly.dev/mcp",
      "headers": { "Authorization": "Bearer ${APEXLY_API_KEY}" }
    }
  }
}

Cursor

Add the server to .cursor/mcp.json in your project (or ~/.cursor/mcp.json for every project):

{
  "mcpServers": {
    "apexly": {
      "url": "https://mcp.apexly.dev/mcp",
      "headers": { "Authorization": "Bearer ${env:APEXLY_API_KEY}" }
    }
  }
}

Set APEXLY_API_KEY in the environment Cursor starts from, and add .cursor/mcp.json to .gitignore if you paste a key into it instead.

Other MCP clients

Any client that supports remote servers over Streamable HTTP with custom headers works:

  • URL: https://mcp.apexly.dev/mcp
  • Transport: Streamable HTTP (POST only; GET and DELETE answer 405 because the server keeps no sessions)
  • Header: Authorization: Bearer <your API key>

A client that only speaks stdio can bridge with mcp-remote:

npx mcp-remote https://mcp.apexly.dev/mcp --header "Authorization: Bearer ${APEXLY_API_KEY}"

Tools

ToolWhat it doesWhat happens next
create_domainAdds the customer's hostname (idempotent: an existing one comes back as is). Optional metadata, apex_redirect, origin.The domain is pending_dns; the customer adds the record or opens the connect link.
get_domainThe domain object plus status_explained: one sentence on why it is in its status and the fix.Poll it until status is active.
list_domainsNewest first, filter by status or hostname prefix; pass next_cursor back as cursor.
get_dns_instructionsThe exact record(s) and steps for the customer's DNS provider, detected from its nameservers.Relay them to the customer.
get_connect_urlThe connect page link for the customer.Send it to the domain owner.
verify_domainQueues a DNS check now (one per 15 s per domain); on cert_failed, retries the certificate.Call get_domain a few seconds later.
diagnose_domainThe domain doctor, same as GET /v1/domains/{id}/diagnose: every check live (DNS at each resolver, other A and stale AAAA records, the Cloudflare proxy, CAA, the certificate, the origin, the www pair), each with what we saw and the fix, blocking_check_id (the one to fix first), plus status_explained and the expected record. 30 per minute per app.Tell the customer what to change.
delete_domainRemoves the domain; it stops being served within 5 seconds. Needs confirm: true.Agents are told to confirm with you first.

The tools return the same fields as the Domains API; they never return API keys or signing secrets.

Run it locally

With the API running (pnpm dev), point your client at http://localhost:4000/mcp with a key from your local dashboard:

claude mcp add --transport http apexly-local http://localhost:4000/mcp \
  --header "Authorization: Bearer sk_test_…"
Was this helpful?