Manages DNS records on DNSPod (Tencent Cloud) via CLI or Python SDK. Add/update/delete A, AAAA, CNAME, MX, TXT, NS, SRV, CAA records; list/search domains; add ACME, SPF, DKIM, and domain-verification TXT records.
How this skill is triggered — by the user, by Claude, or both
Slash command
/acedatacloud-ai-media:tencentcloud-dnsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Manage DNS records via the DNSPod API.
Manage DNS records via the DNSPod API.
Setup: See tencentcloud authentication. DNSPod uses the same Tencent Cloud SecretId / SecretKey as the rest of the platform — there's no separate
DP_Id/DP_Keyfor the v3 API. The SDK client below auto-readsTENCENTCLOUD_SECRET_ID/TENCENTCLOUD_SECRET_KEYfrom env.The legacy v2 DNSPod API used a different key format; this skill targets the v3 SDK exclusively.
The skill ships scripts/dns.py — wraps every common DNSPod v3 operation.
DNS=$SKILL_DIR/scripts/dns.py
python3 $DNS domains # list domains
python3 $DNS list example.com # records on one domain
python3 $DNS list example.com --type CNAME # filter by type
python3 $DNS search example.com --keyword api # client-side keyword search
python3 $DNS create example.com --sub www --type A --value 1.2.3.4
python3 $DNS create example.com --sub @ --type MX --value 'mail.example.com.' --mx 10
python3 $DNS create example.com --sub _acme-challenge --type TXT --value '"<token>"'
python3 $DNS update example.com <record-id> --sub www --type A --value 5.6.7.8
python3 $DNS delete example.com <record-id> --yes # destructive, requires --yes
The delete subcommand requires --yes — without it, it prints a dry-run line so you can confirm the right record-id first.
pip install tencentcloud-sdk-python
import os
from tencentcloud.common import credential
from tencentcloud.dnspod.v20210323 import dnspod_client, models
cred = credential.EnvironmentVariableCredential().get_credential()
# DNSPod is global — region is ignored, but the SDK still requires one.
client = dnspod_client.DnspodClient(cred, "")
req = models.DescribeDomainListRequest()
req.Limit = 100
resp = client.DescribeDomainList(req)
for d in resp.DomainList:
print(d.DomainId, d.Name, d.Status, d.RecordCount)
req = models.DescribeRecordListRequest()
req.Domain = "example.com"
req.Limit = 100 # max 3000
# Optional: req.RecordType = "A"
# Optional: req.Subdomain = "api"
resp = client.DescribeRecordList(req)
for r in resp.RecordList:
print(r.RecordId, r.Name, r.Type, r.Value, "TTL=", r.TTL, "Line=", r.Line)
req = models.DescribeRecordListRequest()
req.Domain = "example.com"
req.Limit = 3000
resp = client.DescribeRecordList(req)
matches = [r for r in resp.RecordList if "api" in r.Name or "api" in r.Value]
for r in matches:
print(r.RecordId, r.Name, r.Type, r.Value)
def create_record(domain, sub_domain, record_type, value, ttl=600, mx=None):
req = models.CreateRecordRequest()
req.Domain = domain
req.SubDomain = sub_domain # use "@" for the apex
req.RecordType = record_type
req.RecordLine = "默认" # "Default" line — works in all environments
req.Value = value
req.TTL = ttl
if mx is not None:
req.MX = mx
resp = client.CreateRecord(req)
return resp.RecordId
# A record
rid = create_record("example.com", "www", "A", "1.2.3.4")
# CNAME (note: Value MUST end with a dot for absolute target)
rid = create_record("example.com", "api2", "CNAME", "api.example.com.")
# MX (priority via mx=)
rid = create_record("example.com", "@", "MX", "mail.example.com.", mx=10)
# TXT (SPF)
rid = create_record("example.com", "@", "TXT", '"v=spf1 include:_spf.google.com ~all"')
# ACME challenge for cert issuance
rid = create_record("example.com", "_acme-challenge", "TXT", '"<validation-token>"')
req = models.ModifyRecordRequest()
req.Domain = "example.com"
req.RecordId = 123456789
req.SubDomain = "www"
req.RecordType = "A"
req.RecordLine = "默认"
req.Value = "5.6.7.8"
req.TTL = 600
client.ModifyRecord(req)
# Confirm with the user before running.
req = models.DeleteRecordRequest()
req.Domain = "example.com"
req.RecordId = 123456789
client.DeleteRecord(req)
| Type | Use For | Example Value |
|---|---|---|
A | IPv4 address | 1.2.3.4 |
AAAA | IPv6 address | 2001:db8::1 |
CNAME | Alias to another hostname | target.example.com. |
MX | Mail server | mail.example.com. (set MX= priority) |
TXT | SPF / DKIM / DMARC / domain verification / ACME | "v=spf1 ..." (quoted) |
NS | Delegate subzone | ns1.example.com. |
SRV | Service discovery | 0 5 443 api.example.com. |
CAA | Cert Authority Authorization | 0 issue "letsencrypt.org" |
DNSPod (like every other DNS service) does not support CNAME on the apex @ (the bare domain) when other record types exist. Use A for the apex; CNAME for subdomains. If the upstream is itself a hostname (e.g. an EdgeOne / CDN endpoint), use the Alias record type via the EdgeOne console — DNSPod itself doesn't have an ALIAS type.
DNSPod can serve different values to different ISPs / regions via RecordLine. For 99% of cases pick "默认" (Default) — it serves to every resolver. Other common lines: "电信", "联通", "移动", "境外", "国内". Use the console to set up split-horizon DNS; the API just lets you write the records.
dig @119.29.29.29 www.example.com +short # 119.29.29.29 = DNSPod's recursor
dig www.example.com +trace # follow the delegation chain
DNSPod propagation is usually under a minute on its own resolver and bounded by the TTL elsewhere. Use TTL=60 while iterating; raise to 600 once stable.
api.example.com.). Without it, DNSPod won't reject — but resolvers will hate you.RecordId is required, so search first to be sure.NS records lightly — losing nameserver delegation takes the entire domain offline until you fix it.RecordCount and RecordsPerMinute. Check the console if LimitExceeded errors appear.npx claudepluginhub acedatacloud/skills --plugin acedatacloud-ai-toolsCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.