Skip to main content
Glama

dynadot_contact

Manage WHOIS contact information for domains: create, edit, delete contacts, handle regional settings, and process .CN domain audits.

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

  • Generic handler for 'dynadot_contact' tool: extracts action from input, applies action-specific transform if defined, executes Dynadot API command via 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) }],
      };
    }
  • Full schema definition for 'dynadot_contact' composite tool with 9 actions mapping to Dynadot contact API commands, Zod input validation schemas, descriptions, and input transform functions to API params.
    {
      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)
    registerAllTools iterates over compositeTools (including 'dynadot_contact') and registers each as an MCP tool with combined input schema and 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) }],
            };
          }
        );
      }
    }
  • tx.contact transform function used by create/edit actions to map tool input fields to Dynadot API param format (e.g., phoneCc -> phonecc, zipCode -> zip).
    contact: (input: Record<string, unknown>): ApiParams => ({
      name: input.name as string,
      organization: input.organization as string | undefined,
      email: input.email as string,
      phonecc: input.phoneCc as string,
      phonenum: input.phoneNum as string,
      address1: input.address1 as string,
      address2: input.address2 as string | undefined,
      city: input.city as string,
      state: input.state as string,
      zip: input.zipCode as string,
      country: input.country as string,
    }),
  • Core API execution helper: formats params into URLSearchParams, sends GET to Dynadot api3.json endpoint, parses response, throws on error.
    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