buy_phone_number
Purchase phone numbers for AI voice agents. Configure webhooks for incoming calls, set labels, and choose from local, mobile, toll-free, or national types across 30+ countries. Requires searching available numbers first. Setup and monthly fees apply.
Instructions
Purchase a phone number. This costs money from your balance (setup fee + monthly). Use search_phone_numbers first to find available numbers.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| phone_number | Yes | The phone number to purchase in E.164 format (e.g. +12125551234) | |
| label | No | Friendly label for this number | |
| webhook_url | No | Webhook URL for incoming call events | |
| country_code | No | Two-letter country code (default: US) | |
| number_type | No | Number type |
Implementation Reference
- src/tools/phone-numbers.ts:76-83 (handler)The handler function for buy_phone_number tool. It constructs the request body from parameters and calls client.post() to purchase the phone number via the API.
async (params) => { const body: Record<string, unknown> = { phone_number: params.phone_number }; if (params.label) body.label = params.label; if (params.webhook_url) body.webhook_url = params.webhook_url; if (params.country_code) body.country_code = params.country_code; if (params.number_type) body.number_type = params.number_type; return callTool(() => client.post("/phone-numbers", body)); } - src/tools/phone-numbers.ts:63-74 (schema)Input schema validation for buy_phone_number using Zod. Defines phone_number (required), label, webhook_url, country_code, and number_type parameters with their descriptions and constraints.
{ description: "Purchase a phone number. This costs money from your balance (setup fee + monthly). " + "Use search_phone_numbers first to find available numbers.", inputSchema: { phone_number: z.string().describe("The phone number to purchase in E.164 format (e.g. +12125551234)"), label: z.string().optional().describe("Friendly label for this number"), webhook_url: z.string().url().optional().describe("Webhook URL for incoming call events"), country_code: z.string().length(2).optional().describe("Two-letter country code (default: US)"), number_type: z.enum(["local", "mobile", "toll_free", "national"]).optional().describe("Number type"), }, annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }, - src/tools/phone-numbers.ts:61-84 (registration)Registration of the buy_phone_number tool with the MCP server. Includes tool name, description, input schema, annotations, and the handler function.
server.registerTool( "buy_phone_number", { description: "Purchase a phone number. This costs money from your balance (setup fee + monthly). " + "Use search_phone_numbers first to find available numbers.", inputSchema: { phone_number: z.string().describe("The phone number to purchase in E.164 format (e.g. +12125551234)"), label: z.string().optional().describe("Friendly label for this number"), webhook_url: z.string().url().optional().describe("Webhook URL for incoming call events"), country_code: z.string().length(2).optional().describe("Two-letter country code (default: US)"), number_type: z.enum(["local", "mobile", "toll_free", "national"]).optional().describe("Number type"), }, annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }, }, async (params) => { const body: Record<string, unknown> = { phone_number: params.phone_number }; if (params.label) body.label = params.label; if (params.webhook_url) body.webhook_url = params.webhook_url; if (params.country_code) body.country_code = params.country_code; if (params.number_type) body.number_type = params.number_type; return callTool(() => client.post("/phone-numbers", body)); } ); - src/tools/phone-numbers.ts:13-20 (helper)Helper function callTool that wraps async tool calls with error handling. Catches ApiError and returns formatted error responses, or returns JSON-stringified success results.
async function callTool<T>(fn: () => Promise<T>) { try { return toolResult(await fn()); } catch (err) { const apiErr = err as ApiError; return toolError(`API error (${apiErr.status}): ${apiErr.message}`); } }