Namecheap DNS management
Manage Namecheap domains and DNS records through the bundled namecheap.py utility while protecting API credentials and avoiding destructive record replacement. This is a UTILITY SKILL for add/change/remove DNS work, not registration/purchase.
When to invoke
- "Add a DNS record in Namecheap."
- "Update this A record or CNAME."
- "List my Namecheap domains."
- "Show DNS records for this domain."
- "Configure the Namecheap API and whitelist my public IP."
Prerequisites and context
- Use
namecheap.py in this skill directory for all API interactions.
- The script requires Python 3 standard library only; no
pip install is needed.
- Credentials come from
~/.namecheap-api or environment variables.
- Namecheap API access must be enabled and the caller's public IP must be whitelisted at https://ap.www.namecheap.com/settings/tools/apiaccess/.
Credential setup
Before any API operation, verify ~/.namecheap-api exists and is readable or that NAMECHEAP_API_USER and NAMECHEAP_API_KEY are exported. If not configured:
- Run
python3 namecheap.py public-ip to display the public IP.
- Instruct the user to enable API access at https://ap.www.namecheap.com/settings/tools/apiaccess/, select ON, and whitelist the displayed IP.
- Have the user run
python3 namecheap.py setup in their own terminal. The setup script prompts for username, reads the API key with getpass, writes ~/.namecheap-api, applies chmod 600 owner read/write permissions, and validates the connection.
- Never ask the user to paste the API key into chat. Never log, echo, or display the key. If interactive setup is unavailable, instruct the user to export
NAMECHEAP_API_USER and NAMECHEAP_API_KEY in their own shell.
Credential file format:
NAMECHEAP_API_USER="username"
NAMECHEAP_API_KEY="api-key-here"
Environment variables take precedence over the file.
DNS operations
Show current records before modifying. Use dns.addHost and dns.removeHost for safe single-record changes because they perform fetch-modify-write internally. Confirm destructive changes with ask_user-style confirmation before removing records or replacing all records with domains.dns.setHosts / setHosts.
# Show public IP (for setup)
python3 namecheap.py public-ip
# Run setup flow
python3 namecheap.py setup
# List domains
python3 namecheap.py domains.getList
# Get nameservers for a domain (shows if using Namecheap DNS or custom)
python3 namecheap.py domains.dns.getList --domain example.com
# Get DNS records for a domain
python3 namecheap.py domains.dns.getHosts --domain example.com
# Add a single record (preserves existing records)
python3 namecheap.py dns.addHost --domain example.com --type A --name www --address 1.2.3.4 --ttl 1800
# Remove a single record
python3 namecheap.py dns.removeHost --domain example.com --type A --name www --address 1.2.3.4
# Replace all records from a JSON file
python3 namecheap.py domains.dns.setHosts --domain example.com --hosts records.json
# Switch to Namecheap default DNS
python3 namecheap.py domains.dns.setDefault --domain example.com
# Switch to custom nameservers
python3 namecheap.py domains.dns.setCustom --domain example.com --nameservers ns1.cloudflare.com,ns2.cloudflare.com
# Get email forwarding rules
python3 namecheap.py domains.dns.getEmailForwarding --domain example.com
# Set email forwarding (single rule)
python3 namecheap.py domains.dns.setEmailForwarding --domain example.com --mailbox info --forward-to user@gmail.com
# Set email forwarding (from JSON file)
python3 namecheap.py domains.dns.setEmailForwarding --domain example.com --forwards forwards.json
# Create a child nameserver (glue record)
python3 namecheap.py domains.ns.create --domain example.com --nameserver ns1.example.com --ip 1.2.3.4
# Delete a child nameserver
python3 namecheap.py domains.ns.delete --domain example.com --nameserver ns1.example.com
# Get nameserver info
python3 namecheap.py domains.ns.getInfo --domain example.com --nameserver ns1.example.com
# Update nameserver IP
python3 namecheap.py domains.ns.update --domain example.com --nameserver ns1.example.com --old-ip 1.2.3.4 --ip 5.6.7.8
Supported record types: A, AAAA, CNAME, MX, MXE, TXT, URL, URL301, FRAME.
JSON file formats
domains.dns.setHosts --hosts records.json expects an array of Namecheap API field names:
[
{ "HostName": "@", "RecordType": "A", "Address": "1.2.3.4", "TTL": 1800 },
{ "HostName": "www", "RecordType": "CNAME", "Address": "@", "TTL": 1800 },
{ "HostName": "@", "RecordType": "MX", "Address": "mail.example.com.", "TTL": 1800, "MXPref": 10 }
]
domains.dns.setEmailForwarding --forwards forwards.json expects mailbox rules:
[
{ "MailBox": "info", "ForwardTo": "team@example.net" },
{ "MailBox": "sales", "ForwardTo": "owner@example.net" }
]
Gotchas
domains.dns.setHosts replaces ALL records: never call it until you have fetched all existing records and confirmed the replacement.
- Explain TTL in human terms: 1800 = 30 minutes and 3600 = 1 hour.
- Handle multi-part TLDs: domains such as
example.co.uk have SLD=example and TLD=co.uk. The script has a built-in, best-effort second-level suffix list including co.uk, com.au, co.jp, and com.br, not a full public-suffix database. Error 2019166 ("Domain not found") can mean the SLD/TLD split was wrong; confirm the registered domain with the user.
- Out of scope: do not use this skill for domain registration/purchase, SSL certificate management, hosting configuration, or non-Namecheap DNS providers.
Progressive disclosure and bundled resources
namecheap.py: standard-library Python utility for Namecheap API operations.
references/namecheap-api.md: request/response details for Namecheap API commands.
Output template
## Namecheap DNS result — <domain>
**Status:** changed | reviewed | blocked
**Operation:** <public-ip | setup | list domains | get hosts | add host | remove host | set hosts | nameserver | email forwarding>
| Step | Command | Result |
| --- | --- | --- |
| Credential check | `<command or file check>` | <configured or setup needed> |
| Current records | `python3 namecheap.py domains.dns.getHosts --domain <domain>` | <summary> |
| Change | `<namecheap.py command>` | <success, skipped, or blocked> |
**TTL explanation:** <human-readable TTL if relevant>
**Confirmation required:** yes | no | already provided
Quality gate
References
1---2name: namecheap3description: Manage Namecheap DNS through the bundled Python API utility, including domain listing, DNS host record view/add/update/remove operations, nameserver changes, email forwarding, glue records, public IP detection, API setup, and credential checks. Use when the user mentions Namecheap, DNS records, domains, A, AAAA, CNAME, MX, TXT, URL, URL301, FRAME, MXE, nameservers, or Namecheap API setup.4---56<!-- Generated from harness/github-copilot/skills/namecheap/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# Namecheap DNS management910Manage Namecheap domains and DNS records through the bundled `namecheap.py` utility while protecting API credentials and avoiding destructive record replacement. This is a UTILITY SKILL for add/change/remove DNS work, not registration/purchase.1112## When to invoke1314- "Add a DNS record in Namecheap."15- "Update this A record or CNAME."16- "List my Namecheap domains."17- "Show DNS records for this domain."18- "Configure the Namecheap API and whitelist my public IP."1920## Prerequisites and context2122- Use `namecheap.py` in this skill directory for all API interactions.23- The script requires Python 3 standard library only; no `pip install` is needed.24- Credentials come from `~/.namecheap-api` or environment variables.25- Namecheap API access must be enabled and the caller's public IP must be whitelisted at https://ap.www.namecheap.com/settings/tools/apiaccess/.2627## Credential setup2829Before any API operation, verify `~/.namecheap-api` exists and is readable or that `NAMECHEAP_API_USER` and `NAMECHEAP_API_KEY` are exported. If not configured:30311. Run `python3 namecheap.py public-ip` to display the public IP.322. Instruct the user to enable API access at https://ap.www.namecheap.com/settings/tools/apiaccess/, select ON, and whitelist the displayed IP.333. Have the user run `python3 namecheap.py setup` in their own terminal. The `setup` script prompts for username, reads the API key with `getpass`, writes `~/.namecheap-api`, applies `chmod 600` owner read/write permissions, and validates the connection.344. Never ask the user to paste the API key into chat. Never log, echo, or display the key. If interactive setup is unavailable, instruct the user to export `NAMECHEAP_API_USER` and `NAMECHEAP_API_KEY` in their own shell.3536Credential file format:3738```bash39NAMECHEAP_API_USER="username"40NAMECHEAP_API_KEY="api-key-here"41```4243Environment variables take precedence over the file.4445## DNS operations4647Show current records before modifying. Use `dns.addHost` and `dns.removeHost` for safe single-record changes because they perform fetch-modify-write internally. Confirm destructive changes with `ask_user`-style confirmation before removing records or replacing all records with `domains.dns.setHosts` / `setHosts`.4849```bash50# Show public IP (for setup)51python3 namecheap.py public-ip5253# Run setup flow54python3 namecheap.py setup5556# List domains57python3 namecheap.py domains.getList5859# Get nameservers for a domain (shows if using Namecheap DNS or custom)60python3 namecheap.py domains.dns.getList --domain example.com6162# Get DNS records for a domain63python3 namecheap.py domains.dns.getHosts --domain example.com6465# Add a single record (preserves existing records)66python3 namecheap.py dns.addHost --domain example.com --type A --name www --address 1.2.3.4 --ttl 18006768# Remove a single record69python3 namecheap.py dns.removeHost --domain example.com --type A --name www --address 1.2.3.47071# Replace all records from a JSON file72python3 namecheap.py domains.dns.setHosts --domain example.com --hosts records.json7374# Switch to Namecheap default DNS75python3 namecheap.py domains.dns.setDefault --domain example.com7677# Switch to custom nameservers78python3 namecheap.py domains.dns.setCustom --domain example.com --nameservers ns1.cloudflare.com,ns2.cloudflare.com7980# Get email forwarding rules81python3 namecheap.py domains.dns.getEmailForwarding --domain example.com8283# Set email forwarding (single rule)84python3 namecheap.py domains.dns.setEmailForwarding --domain example.com --mailbox info --forward-to user@gmail.com8586# Set email forwarding (from JSON file)87python3 namecheap.py domains.dns.setEmailForwarding --domain example.com --forwards forwards.json8889# Create a child nameserver (glue record)90python3 namecheap.py domains.ns.create --domain example.com --nameserver ns1.example.com --ip 1.2.3.49192# Delete a child nameserver93python3 namecheap.py domains.ns.delete --domain example.com --nameserver ns1.example.com9495# Get nameserver info96python3 namecheap.py domains.ns.getInfo --domain example.com --nameserver ns1.example.com9798# Update nameserver IP99python3 namecheap.py domains.ns.update --domain example.com --nameserver ns1.example.com --old-ip 1.2.3.4 --ip 5.6.7.8100```101102Supported record types: A, AAAA, CNAME, MX, MXE, TXT, URL, URL301, FRAME.103104## JSON file formats105106`domains.dns.setHosts --hosts records.json` expects an array of Namecheap API field names:107108```json109[110 { "HostName": "@", "RecordType": "A", "Address": "1.2.3.4", "TTL": 1800 },111 { "HostName": "www", "RecordType": "CNAME", "Address": "@", "TTL": 1800 },112 { "HostName": "@", "RecordType": "MX", "Address": "mail.example.com.", "TTL": 1800, "MXPref": 10 }113]114```115116`domains.dns.setEmailForwarding --forwards forwards.json` expects mailbox rules:117118```json119[120 { "MailBox": "info", "ForwardTo": "team@example.net" },121 { "MailBox": "sales", "ForwardTo": "owner@example.net" }122]123```124125## Gotchas126127- **`domains.dns.setHosts` replaces ALL records**: never call it until you have fetched all existing records and confirmed the replacement.128- **Explain TTL in human terms**: 1800 = 30 minutes and 3600 = 1 hour.129- **Handle multi-part TLDs**: domains such as `example.co.uk` have SLD=`example` and TLD=`co.uk`. The script has a built-in, best-effort second-level suffix list including `co.uk`, `com.au`, `co.jp`, and `com.br`, not a full public-suffix database. Error `2019166` ("Domain not found") can mean the SLD/TLD split was wrong; confirm the registered domain with the user.130- **Out of scope**: do not use this skill for domain registration/purchase, SSL certificate management, hosting configuration, or non-Namecheap DNS providers.131132## Progressive disclosure and bundled resources133134- `namecheap.py`: standard-library Python utility for Namecheap API operations.135- `references/namecheap-api.md`: request/response details for Namecheap API commands.136137## Output template138139```markdown140## Namecheap DNS result — <domain>141142**Status:** changed | reviewed | blocked143**Operation:** <public-ip | setup | list domains | get hosts | add host | remove host | set hosts | nameserver | email forwarding>144145| Step | Command | Result |146| --- | --- | --- |147| Credential check | `<command or file check>` | <configured or setup needed> |148| Current records | `python3 namecheap.py domains.dns.getHosts --domain <domain>` | <summary> |149| Change | `<namecheap.py command>` | <success, skipped, or blocked> |150151**TTL explanation:** <human-readable TTL if relevant>152**Confirmation required:** yes | no | already provided153```154155## Quality gate156157- [ ] Credentials were checked before API operations.158- [ ] API keys were never requested, displayed, logged, or placed in chat.159- [ ] Current DNS records were fetched before add, remove, or replacement operations.160- [ ] Destructive removal or `domains.dns.setHosts` replacement was confirmed.161- [ ] Single-record changes used `dns.addHost` or `dns.removeHost` where possible.162- [ ] Multi-part TLD and `2019166` cases were handled explicitly.163- [ ] TTL values were explained in human terms when relevant.164165## References166167- [Namecheap API access settings](https://ap.www.namecheap.com/settings/tools/apiaccess/)