Skip to main content
Glama

dynadot_dns

Manage DNS records and DNSSEC configuration for domains through the Domain MCP server. Get, set, or clear DNS settings including A, AAAA, CNAME, MX, and TXT records.

Instructions

DNS management: get/set DNS records, DNSSEC configuration

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform: get: Get current DNS records | set: Set DNS records | set_dnssec: Enable DNSSEC | get_dnssec: Get DNSSEC settings | clear_dnssec: Remove DNSSEC
domainNoDomain name (e.g., example.com)
mainRecordsNoMain domain records
subdomainRecordsNoSubdomain records
keyTagNoKey tag
algorithmNoAlgorithm
digestTypeNoDigest type
digestNoDS record digest

Implementation Reference

  • Shared handler function for dynadot_dns and all composite tools: extracts action, applies action-specific transform to build API params, executes Dynadot API command via client, returns JSON-formatted response.
    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) }], }; }
  • Zod schema and action definitions for dynadot_dns tool, mapping user-friendly inputs to Dynadot API commands like get_dns, set_dns2, set_dnssec with specific param 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:6-65 (registration)
    Registers dynadot_dns (via compositeTools loop) as MCP tool with combined input schema supporting all actions' parameters and shared 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) }], }; } ); } }
  • Transform helper tx.dnsRecords flattens structured DNS records (mainRecords, subdomainRecords) into indexed API parameters for 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; },
  • DynadotClient.execute makes authenticated HTTP GET to api3.json with command and params, parses response, throws on API errors.
    async execute(command: string, params: ApiParams = {}): Promise<ApiResponse> { const searchParams = new URLSearchParams(); searchParams.set('key', this.apiKey); searchParams.set('command', command); for (const [key, value] of Object.entries(params)) { if (value !== undefined) { searchParams.set(key, String(value)); } } const response = await this.client.get('api3.json', { searchParams }).json<ApiResponse>(); if (response.Status === 'error') { throw new Error(`Dynadot API error: ${response.Error || 'Unknown error'}`); } return response; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/joachimBrindeau/domain-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server