dynadot_dns
Manage DNS records and DNSSEC configuration for domains through the Domain MCP server. Get, set, or modify DNS settings to control domain routing and security.
Instructions
DNS management: get/set DNS records, DNSSEC configuration
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform: get: Get current DNS records | set: Set DNS records | set_dnssec: Enable DNSSEC | get_dnssec: Get DNSSEC settings | clear_dnssec: Remove DNSSEC | |
| domain | No | Domain name (e.g., example.com) | |
| mainRecords | No | Main domain records | |
| subdomainRecords | No | Subdomain records | |
| keyTag | No | Key tag | |
| algorithm | No | Algorithm | |
| digestType | No | Digest type | |
| digest | No | DS record digest |
Implementation Reference
- src/schema.ts:488-536 (schema)Schema definition for the 'dynadot_dns' composite tool, including input validation schemas, action mappings to Dynadot API commands (get_dns, set_dns2, etc.), descriptions, and input transforms.{ name: 'dynadot_dns', description: 'DNS management: get/set DNS records, DNSSEC configuration', actions: { get: { command: 'get_dns', description: 'Get current DNS records', params: z.object({ domain: p.domain }), }, set: { command: 'set_dns2', description: 'Set DNS records', params: z.object({ domain: p.domain, mainRecords: z.array(dnsRecord).optional().describe('Main domain records'), subdomainRecords: z.array(subdomainRecord).optional().describe('Subdomain records'), }), transform: (_, input) => tx.dnsRecords(input), }, set_dnssec: { command: 'set_dnssec', description: 'Enable DNSSEC', params: z.object({ domain: p.domain, keyTag: z.number().describe('Key tag'), algorithm: z.number().describe('Algorithm'), digestType: z.number().describe('Digest type'), digest: z.string().describe('DS record digest'), }), transform: (_, input) => ({ domain: input.domain as string, key_tag: input.keyTag as number, algorithm: input.algorithm as number, digest_type: input.digestType as number, digest: input.digest as string, }), }, get_dnssec: { command: 'get_dnssec', description: 'Get DNSSEC settings', params: z.object({ domain: p.domain }), }, clear_dnssec: { command: 'clear_dnssec', description: 'Remove DNSSEC', params: z.object({ domain: p.domain }), }, }, },
- src/register.ts:37-62 (handler)Generic MCP tool handler executed for 'dynadot_dns'. Parses input.action, looks up the corresponding Dynadot API command and transform from schema, calls DynadotClient.execute, and returns JSON-formatted result.tool.name, { description: tool.description, inputSchema, }, async (input) => { const action = input.action as string; const actionDef = tool.actions[action]; if (!actionDef) { throw new Error(`Unknown action: ${action}. Valid actions: ${actionKeys.join(', ')}`); } const client = getClient(); const params = actionDef.transform ? actionDef.transform(action, input as Record<string, unknown>) : (input as ApiParams); // Remove 'action' from params sent to API delete params.action; const result = await client.execute(actionDef.command, params); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], }; }
- src/register.ts:6-65 (registration)Registers the 'dynadot_dns' tool (among others from compositeTools) with the MCP server, dynamically building a combined Zod input schema from all actions' params and registering with the generic handler.export function registerAllTools(server: McpServer): void { for (const tool of compositeTools) { // Build action enum from keys const actionKeys = Object.keys(tool.actions) as [string, ...string[]]; // Build combined input schema with action + all possible params const actionDescriptions = actionKeys .map((k) => { const actionDef = tool.actions[k]; return actionDef ? `${k}: ${actionDef.description}` : k; }) .join(' | '); const inputSchema: Record<string, z.ZodTypeAny> = { action: z.enum(actionKeys).describe(`Action to perform: ${actionDescriptions}`), }; // Collect all unique params across actions for (const action of Object.values(tool.actions)) { if (action?.params) { const shape = action.params.shape; for (const [key, schema] of Object.entries(shape)) { if (!inputSchema[key]) { // Make optional since not all actions need all params inputSchema[key] = (schema as z.ZodTypeAny).optional(); } } } } server.registerTool( tool.name, { description: tool.description, inputSchema, }, async (input) => { const action = input.action as string; const actionDef = tool.actions[action]; if (!actionDef) { throw new Error(`Unknown action: ${action}. Valid actions: ${actionKeys.join(', ')}`); } const client = getClient(); const params = actionDef.transform ? actionDef.transform(action, input as Record<string, unknown>) : (input as ApiParams); // Remove 'action' from params sent to API delete params.action; const result = await client.execute(actionDef.command, params); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], }; } ); } }
- src/schema.ts:102-127 (helper)Transform helper 'tx.dnsRecords' used by the 'set' action of dynadot_dns to convert structured DNS records (mainRecords, subdomainRecords) into flattened API parameters expected by Dynadot's set_dns2 command.dnsRecords: (input: Record<string, unknown>): ApiParams => { const params: ApiParams = { domain: input.domain as string }; const main = input.mainRecords as | Array<{ type: string; value: string; ttl?: number; priority?: number }> | undefined; const sub = input.subdomainRecords as | Array<{ subdomain: string; type: string; value: string; ttl?: number; priority?: number }> | undefined; main?.forEach((r, i) => { params[`main_record_type${i}`] = r.type; params[`main_record${i}`] = r.value; if (r.ttl) params[`main_record_ttl${i}`] = r.ttl; if (r.priority !== undefined) params[`main_record_distance${i}`] = r.priority; }); sub?.forEach((r, i) => { params[`subdomain${i}`] = r.subdomain; params[`sub_record_type${i}`] = r.type; params[`sub_record${i}`] = r.value; if (r.ttl) params[`sub_record_ttl${i}`] = r.ttl; if (r.priority !== undefined) params[`sub_record_distance${i}`] = r.priority; }); return params; },
- src/schema.ts:46-51 (helper)Zod schema for individual DNS records used in dynadot_dns input validation.const dnsRecord = z.object({ type: z.string().describe('Record type (A, AAAA, CNAME, MX, TXT)'), value: z.string().describe('Record value'), ttl: z.number().optional().describe('TTL in seconds'), priority: z.number().optional().describe('Priority (for MX)'), });