diff --git a/.agents/skills/gddy/README.md b/.agents/skills/gddy/README.md new file mode 100644 index 0000000..e09b720 --- /dev/null +++ b/.agents/skills/gddy/README.md @@ -0,0 +1,24 @@ +# gddy skill + +Teaches an AI coding agent how to drive `gddy`, GoDaddy's beta CLI for domain search, registration, and DNS management. It covers install/auth, the two-step quote-then-purchase flow for buying a domain, DNS record semantics (`add` vs `set` vs `delete`), and how to use the CLI's own self-documentation (`--help`, `--search`, `tree`, `guide`) to stay current as `gddy` evolves. + +See [SKILL.md](./SKILL.md) for the full instructions given to the agent. + +## Installation + +### Claude Code + +```bash +claude plugin marketplace add godaddy/cli +claude plugin install gddy@godaddy +``` + +### Any other AI coding agent + +This repo is also compatible with [skills](https://github.com/vercel-labs/skills), a package-manager-style installer for agent skills that isn't tied to Claude Code — it supports Cursor, Codex, Windsurf, opencode, and 70+ other agents in addition to Claude Code: + +```bash +npx skills add godaddy/cli --skill gddy --agent +``` + +Swap `` for whichever agent you use (`claude-code`, `cursor`, `codex`, `windsurf`, `opencode`, ...). Run `npx skills add --help` for the full list of supported agents. diff --git a/.agents/skills/gddy/SKILL.md b/.agents/skills/gddy/SKILL.md new file mode 100644 index 0000000..5d9cb97 --- /dev/null +++ b/.agents/skills/gddy/SKILL.md @@ -0,0 +1,70 @@ +--- +name: gddy +description: Use GoDaddy's beta CLI (`gddy`) to search, register, and manage domains and DNS records. Load this skill whenever a task involves running `gddy` commands, parsing their JSON output, finding or buying a domain, or editing DNS records (A, CNAME, MX, TXT, etc.) for a domain hosted at GoDaddy. `gddy` is a separate tool from GoDaddy's older `godaddy` CLI (applications, deployments, webhooks) — do not use this skill for that tool, and don't trigger for other registrars or DNS providers (Cloudflare, Route 53, Namecheap, etc.) unless GoDaddy is explicitly involved. +version: 0.1.0 +author: GoDaddy +tags: [godaddy, gddy, cli, domains, dns] +--- + +# gddy — GoDaddy domains & DNS CLI + +`gddy` is GoDaddy's beta CLI for domain search, registration, and DNS management. It's separate from GoDaddy's older `godaddy` CLI, which covers applications, deployments, and webhooks. + +Both tools exist side by side because `gddy` is the newer of the two, under active development, and ships new features frequently. Run `gddy --help` against your installed release for the authoritative, current command list. + +## Setup + +Install: + +```bash +# macOS / Linux / Git Bash / MSYS2 / Cygwin +curl -fsSL https://github.com/godaddy/cli/releases/latest/download/install.sh | bash + +# PowerShell +irm https://github.com/godaddy/cli/releases/latest/download/install.ps1 | iex +``` + +Verify that installation works by running `gddy --version`. + +Authenticate with `gddy auth login` (opens a browser for OAuth). Check state with `gddy auth status`, sign out with `gddy auth logout`. For non-interactive use (CI, scripts), use a Personal Access Token instead — manage one with `gddy pat add/list/remove`, or set the `GDDY_PAT`/`GDDY_PAT_` env var directly (checked before OAuth). Note PATs can't do everything: domain purchase specifically requires a customer-scoped OAuth login (see `gddy guide domain-purchase`). + +Every command accepts `--env ` to pick environment (default `prod`) and `--debug` for verbose output. + +## Documentation + +The `gddy` CLI is self-documenting. Use the following to get more information about its capabilities: + +- The `--help` flag will give you detailed documentation on any command. +- `gddy --search ` will help you find a command. +- The `gddy tree` command will give you a full listing of all commands. +- The `gddy guide` command lets you view detailed documentation that explains concepts and outlines complex workflows. + +## Domain purchase + +Domain purchase is a multi-step workflow. Run `gddy guide domain-purchase` for a detailed walkthrough. Always confirm with the user before finalizing a purchase — it's real money, and the action is not reversible. + +## DNS management + +Valid record types: `A AAAA ALIAS CAA CNAME MX NS SOA SRV TXT`. `NS` and `SOA` are GoDaddy-managed and read-only — you can list them but not add/set/delete them. + +```bash +gddy dns list example.com --type A +gddy dns add example.com --type A --name www --data 192.0.2.1 --ttl 3600 +gddy dns set example.com --type TXT --name @ --data "v=spf1 -all" +gddy dns delete example.com --type A --name www +``` + +`add` appends a new record; `set` replaces every record matching that type+name; `delete` removes every record matching that type+name. Type-specific requirements: `MX`/`SRV` need `--priority`; `SRV` also needs `--port`, `--weight`, `--protocol`, `--service`; `CAA` requires `--tag` (`--flag` is optional). + +`set` and `delete` are destructive. Run with `--dry-run` first and show the user what would change before applying it for real. + +## Payments + +`gddy payments add` opens the browser to the account's payment-methods page — no card data is ever handled by the CLI itself. Purchases fail (403/422) without a valid payment method or sufficient account balance; check the error's `code` field, not just the HTTP status, to tell that apart from other failures. + +## Reference material + +Read these only when the task needs the detail — they're not needed for common domain/DNS operations: + +- `reference/api.md` — raw GoDaddy Domains API fallback (when `gddy` isn't installed/available, e.g. CI in a non-shell language): base URL/auth, the public OpenAPI specs to fetch and search directly, and the durable gotchas (idempotency keys on registration, the MCP server's read-only/no-auth scope). +- `reference/errors-and-limits.md` — error envelope shape, retry/idempotency rules per HTTP method, and rate-limit headers/handling. diff --git a/.agents/skills/gddy/reference/api.md b/.agents/skills/gddy/reference/api.md new file mode 100644 index 0000000..f0f1090 --- /dev/null +++ b/.agents/skills/gddy/reference/api.md @@ -0,0 +1,19 @@ +# GoDaddy Domains API (raw HTTP fallback) + +Use this when the `gddy` CLI cannot be installed or isn't a good fit for the task (CI pipelines, non-shell languages, etc.). When `gddy` is available, prefer it — it handles auth, quote-token bookkeeping, and idempotency for you. To install `gddy` itself, see the Setup section in SKILL.md. + +Base URL: `https://api.godaddy.com` + +Auth header: `Authorization: Bearer $GDDY_PAT` (PAT generated from the Personal Access Token page under `https://developer.godaddy.com/docs/api-users/auth`). Legacy `sso-key key:secret` credentials still work for v1/v2 endpoints but not v3, and are deprecated — prefer a PAT for anything new. + +## Endpoint reference + +GoDaddy publishes machine-readable OpenAPI specs — fetch and search these directly instead of relying on hardcoded examples here, so this file doesn't need updating as the API grows: + +- Search, availability, registration (quote → register), DNS records: `https://developer.godaddy.com/openapi/domains-v3.json` +- Domain listing, bulk availability, contacts, transfers, legacy purchase: `https://developer.godaddy.com/openapi/domains-v1.json` + +## Gotchas that won't change even as the API grows + +- **Domain registration is two calls, never one** — mirrors the CLI's `gddy domain quote` / `gddy domain purchase` split (run `gddy guide domain-purchase` for the full walkthrough). Lock a quote first — valid ~10 minutes — then register against it with an `Idempotency-Key` header (required, not optional). Reuse the same key when retrying the same logical attempt; a new key on retry can register and charge for the domain twice. +- **MCP server** (`https://api.godaddy.com/v1/domains/mcp`, streamable-http) is read-only and needs no authentication — public domain search/availability only, never registration, DNS, or anything account-specific. Full docs: `https://developer.godaddy.com/docs/api-users/mcp`. diff --git a/.agents/skills/gddy/reference/errors-and-limits.md b/.agents/skills/gddy/reference/errors-and-limits.md new file mode 100644 index 0000000..e623b5f --- /dev/null +++ b/.agents/skills/gddy/reference/errors-and-limits.md @@ -0,0 +1,73 @@ +# Errors, retries, and rate limits + +## Error shape + +Every error response is a stable JSON envelope: + +```json +{ + "code": "INVALID_DOMAIN", + "message": "example is not a valid domain name", + "fields": [ + { "path": "domain", "code": "INVALID_FORMAT", "message": "..." } + ] +} +``` + +Always branch on `code`, never on `message` — message text can change between releases and isn't a stable contract. `fields` is present on validation errors (422) and points at which field(s) failed and why. + +429 (rate limited) responses add a `retryAfterSec` field and otherwise carry little useful body — read the headers instead (below). + +## Retry semantics — depends on the HTTP method, not just "is it safe to retry" + +| Operation | Idempotent? | Notes | +|---|---|---| +| Any `GET` | Yes | Always safe to retry. | +| `POST /v1/domains/purchase` (and registration create) | **No** | Retrying without reusing an `Idempotency-Key` (v3) or otherwise confirming state first can double-purchase/double-charge. Check current state (e.g. does the domain already show up under the account) before retrying a failed purchase. | +| `PUT` (e.g. DNS record replace / `gddy dns set`) | Yes | Safe to retry — it fully replaces state each time. | +| `PATCH` (e.g. DNS record add / `gddy dns add`) | **No** | Appends; retrying a failed "add" can create duplicate records. Check current state before retrying. | +| `DELETE` (e.g. `gddy dns delete`) | Yes | Safe to retry — deleting something already gone is a no-op. | + +## Rate limits + +60 requests/minute per credential, applied regardless of endpoint. Every response — not just 429s — carries these headers, so you can self-throttle before hitting the limit rather than reacting after: + +| Header | Meaning | +|---|---| +| `RateLimit-Limit` | Limit that applies to this request | +| `RateLimit-Remaining` | Requests left in the current window | +| `RateLimit-Reset` | Seconds until the window resets | + +On a 429, back off for at least `RateLimit-Reset` seconds (or the `retryAfterSec` field), plus some jitter if retrying programmatically in a loop. + +To stay under the limit in the first place: +- Prefer bulk endpoints where they exist (e.g. `POST /v1/domains/available` for many domains at once, instead of looping single `check-availability` calls). +- Use cursor pagination (`limit`/`marker`) sequentially rather than fanning out parallel page requests. +- Don't share one credential across many independent callers and assume the limit is per-account — it's per-credential today, but that's an implementation detail, not a guarantee. + +If a legitimate use case needs a sustained rate above 60/min, that's a conversation with GoDaddy developer support, not something to work around client-side. + +## Common error codes (registration) + +These are the `code` values you'll actually see while quoting/registering a domain, with what each means: + +| `code` | Meaning | What to do | +|---|---|---| +| `DOMAIN_NOT_AVAILABLE` | Someone else registered the name first (race between check and purchase). | Re-check availability, suggest alternatives. | +| `BILLING_DECLINED` | Payment method on file was charged and declined. | Surface to the user — they need to fix their payment method. | +| `NO_PAYMENT_PROFILE` | No payment method on the account at all. | Direct the user to `gddy payments add` or the account's payment-methods page. | +| `QUOTE_MISMATCH` | The `period` (or other term) at execute time doesn't match what was quoted. | Reuse the exact period from the quote, or fetch a fresh quote. | +| `INVALID_AGREEMENT_KEYS` | `agreementTypes` sent don't match the TLD's `requiredAgreements` from the quote. | Use the exact keys the quote response returned, not guessed/remembered ones. | +| `MISSING_CONTACT` | No registrant contact configured on the account. | Set up contacts (`gddy domain contacts init`, then fill in the file) before quoting. | +| `MISSING_BILLING_PHONE` | Contact phone is missing or malformed. | Verify the contact has a complete, valid phone number. | + +## Common status codes and what to do + +- **400** — malformed request (bad JSON, missing required field shape). Fix the request; don't retry as-is. +- **401** — missing/invalid/expired credential. Re-authenticate (`gddy auth login` or refresh the PAT) rather than retry. +- **403** — authenticated but not authorized for this action (e.g. a PAT trying to purchase, which requires OAuth; or no payment method on file). Check `code` to distinguish "wrong credential type" from "account not payment-ready." +- **404** — resource doesn't exist (domain not in the account, unknown operation ID). Don't retry. +- **409** — conflict with current state (e.g. domain already has a pending operation). Check current state before retrying. +- **422** — validation failure; see `fields` for which field(s) and why. +- **429** — rate limited; see above. +- **5xx** — server-side; safe to retry idempotent operations with backoff, not safe to retry non-idempotent ones (see table above) without first checking state. diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..885cfc5 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,18 @@ +{ + "name": "godaddy", + "owner": { + "name": "GoDaddy", + "email": "oss@godaddy.com" + }, + "description": "Skills for using GoDaddy's command-line tools with an AI coding agent.", + "plugins": [ + { + "name": "gddy", + "source": "./plugins/gddy", + "description": "Skill for using GoDaddy's gddy CLI — domain search, registration, and DNS management.", + "author": { + "name": "GoDaddy" + } + } + ] +} diff --git a/README.md b/README.md index 3016404..9386e74 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,12 @@ Agent-first CLI for interacting with GoDaddy Developer Platform. ## Installation +### Using an AI coding agent? + +Point your agent at this README and ask it to install the `gddy` skill for domain search/registration/DNS. Once installed, the skill teaches the agent the CLI's JSON output contract and typical workflows, so it can drive the CLI correctly without guessing at flags. See [.agents/skills/gddy/README.md](./.agents/skills/gddy/README.md) for one-line install commands (Claude Code and 70+ other agents). + +### Installing the CLI directly + ```bash npm install -g @godaddy/cli godaddy --help diff --git a/plugins/gddy/.claude-plugin/plugin.json b/plugins/gddy/.claude-plugin/plugin.json new file mode 100644 index 0000000..2f20735 --- /dev/null +++ b/plugins/gddy/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "gddy", + "description": "Skill for using GoDaddy's gddy CLI — domain search, registration, and DNS management.", + "version": "0.1.0", + "author": { + "name": "GoDaddy" + } +} diff --git a/plugins/gddy/skills/gddy b/plugins/gddy/skills/gddy new file mode 120000 index 0000000..c88e181 --- /dev/null +++ b/plugins/gddy/skills/gddy @@ -0,0 +1 @@ +../../../.agents/skills/gddy \ No newline at end of file