Skip to main content
Glama

dynadot_contact

Manage WHOIS contact information for domains: create, edit, delete contacts, and configure regional settings for compliance.

Instructions

WHOIS contact management: create, edit, delete, list, regional settings

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform: list: List all contacts | get: Get contact details | create: Create new contact | edit: Update contact | delete: Delete contact | create_cn_audit: Create .CN domain audit | get_cn_audit_status: Get .CN audit status | set_eu_setting: Set EU contact settings | set_lv_setting: Set Latvia contact settings | set_lt_setting: Set Lithuania contact settings
contactIdNoContact ID
nameNoContact name
emailNoEmail
phoneCcNoPhone country code (e.g., "1" for US, "33" for France)
phoneNumNoPhone number without country code (e.g., "5551234567")
address1NoAddress line 1
cityNoCity
stateNoState/Province
zipCodeNoPostal code
countryNoCountry code (2-letter)
organizationNoOrganization
address2NoAddress line 2
auditDetailsNoAudit details
settingsNo

Implementation Reference

  • Schema and action definitions for the 'dynadot_contact' tool, including Zod schemas, descriptions, API commands, and transform functions for each contact management operation.
    { name: 'dynadot_contact', description: 'WHOIS contact management: create, edit, delete, list, regional settings', actions: { list: { command: 'contact_list', description: 'List all contacts', }, get: { command: 'get_contact', description: 'Get contact details', params: z.object({ contactId: p.contactId }), transform: (_, input) => ({ contact_id: input.contactId as string }), }, create: { command: 'create_contact', description: 'Create new contact', params: contactFields, transform: (_, input) => tx.contact(input), }, edit: { command: 'edit_contact', description: 'Update contact', params: z.object({ contactId: p.contactId, name: p.name.optional(), email: p.email.optional(), phoneCc: z.string().optional().describe('Phone country code'), phoneNum: z.string().optional().describe('Phone number without country code'), address1: z.string().optional(), city: z.string().optional(), state: z.string().optional(), zipCode: z.string().optional(), country: z.string().optional(), }), transform: (_, input) => ({ contact_id: input.contactId as string, name: input.name as string | undefined, email: input.email as string | undefined, phonecc: input.phoneCc as string | undefined, phonenum: input.phoneNum as string | undefined, address1: input.address1 as string | undefined, city: input.city as string | undefined, state: input.state as string | undefined, zip: input.zipCode as string | undefined, country: input.country as string | undefined, }), }, delete: { command: 'delete_contact', description: 'Delete contact', params: z.object({ contactId: p.contactId }), transform: (_, input) => ({ contact_id: input.contactId as string }), }, create_cn_audit: { command: 'create_cn_audit', description: 'Create .CN domain audit', params: z.object({ contactId: p.contactId, auditDetails: z.record(z.string(), z.string()).describe('Audit details'), }), transform: (_, input) => { const params: ApiParams = { contact_id: input.contactId as string }; for (const [k, v] of Object.entries(input.auditDetails as Record<string, string>)) { params[k] = v; } return params; }, }, get_cn_audit_status: { command: 'get_cn_audit_status', description: 'Get .CN audit status', params: z.object({ contactId: p.contactId }), transform: (_, input) => ({ contact_id: input.contactId as string }), }, set_eu_setting: { command: 'set_contact_eu_setting', description: 'Set EU contact settings', params: z.object({ contactId: p.contactId, settings: z.record(z.string(), z.string()) }), transform: (_, input) => { const params: ApiParams = { contact_id: input.contactId as string }; for (const [k, v] of Object.entries(input.settings as Record<string, string>)) { params[k] = v; } return params; }, }, set_lv_setting: { command: 'set_contact_lv_setting', description: 'Set Latvia contact settings', params: z.object({ contactId: p.contactId, settings: z.record(z.string(), z.string()) }), transform: (_, input) => { const params: ApiParams = { contact_id: input.contactId as string }; for (const [k, v] of Object.entries(input.settings as Record<string, string>)) { params[k] = v; } return params; }, }, set_lt_setting: { command: 'set_contact_lt_setting', description: 'Set Lithuania contact settings', params: z.object({ contactId: p.contactId, settings: z.record(z.string(), z.string()) }), transform: (_, input) => { const params: ApiParams = { contact_id: input.contactId as string }; for (const [k, v] of Object.entries(input.settings as Record<string, string>)) { params[k] = v; } return params; }, }, }, },
  • src/register.ts:6-65 (registration)
    Registers the 'dynadot_contact' tool (and all composite tools) with the MCP server, building dynamic inputSchema from actions and providing a 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) }], }; } ); } }
  • Core handler logic for executing dynadot_contact actions: selects action definition, transforms input to API params, calls Dynadot client, returns formatted JSON 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) }], }; }
  • DynadotClient.execute method: formats API request with key and params, sends to api.dynadot.com/api3.json, handles response and errors. Used by all tools.
    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