MCP Phone Tool: Give Claude a Phone Line
What You're Building
An MCP server that gives any MCP-compatible client — Claude Code, Cursor, Windsurf, or your own agent — the ability to place real phone calls.
The server exposes one tool: place_phone_call. Claude says "call the restaurant and book a table," the tool dials the number, handles the conversation, and returns structured results.
Prerequisites:
- Node.js 18+
npm install @modelcontextprotocol/sdk zod- An AgentPhone API key (get one free — 5 calls, no credit card)
The MCP Server
Here's the complete server. Save this as index.ts:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const API_KEY = process.env.AGENTPHONE_API_KEY!;
const BASE = "https://agentphone.app/api/v1";
const HEADERS = {
"x-api-key": API_KEY,
"Content-Type": "application/json",
};
const server = new McpServer({
name: "agentphone",
version: "1.0.0",
});
server.tool(
"place_phone_call",
"Place a real phone call to a business or person. The call is handled by " +
"a voice AI that navigates IVR menus, waits on hold, handles transfers, " +
"and has a natural conversation. Returns the outcome (achieved / " +
"not_achieved / partial), a summary, and the full transcript. " +
"Use when a task requires calling someone by phone — booking appointments, " +
"verifying information, following up on orders, getting quotes.",
{
to_phone_number: z
.string()
.describe("Phone number in E.164 format (e.g. +14155551234)"),
objective: z
.string()
.describe(
"What the call should accomplish. Be specific — include names, " +
"dates, reference numbers, relevant context."
),
business_name: z
.string()
.optional()
.describe("Name of the business being called"),
website: z
.string()
.optional()
.describe("Business website URL (provides additional context)"),
},
async ({ to_phone_number, objective, business_name, website }) => {
// Create the call
const createRes = await fetch(`${BASE}/calls`, {
method: "POST",
headers: HEADERS,
body: JSON.stringify({
to_phone_number,
objective,
business_name: business_name || "",
website: website || "",
}),
});
if (!createRes.ok) {
const err = await createRes.json();
return {
content: [
{ type: "text", text: `Failed to create call: ${JSON.stringify(err)}` },
],
};
}
const { data } = await createRes.json();
const callId = data.call_id;
// Poll until done
let result: any;
while (true) {
await new Promise((r) => setTimeout(r, 4000));
const pollRes = await fetch(`${BASE}/calls/${callId}`, {
headers: HEADERS,
});
result = (await pollRes.json()).data;
if (["completed", "failed", "canceled"].includes(result.status)) break;
}
const output = [
`Call Status: ${result.status}`,
`Outcome: ${result.outcome || "unknown"}`,
`Details: ${result.outcome_details || ""}`,
`Summary: ${result.summary || ""}`,
`Duration: ${result.duration_seconds || 0}s`,
``,
`Transcript:`,
result.transcript || "No transcript available",
].join("\n");
return { content: [{ type: "text", text: output }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
That's the entire server — 80 lines of TypeScript. One tool, clear description, straightforward implementation.
Setup
Install Dependencies
mkdir agentphone-mcp && cd agentphone-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod tsx
Configure Claude Code
Add to your MCP config. For Claude Code, edit ~/.claude.json or run:
claude mcp add agentphone -- npx tsx /path/to/agentphone-mcp/index.ts
Or manually add to your config file:
{
"mcpServers": {
"agentphone": {
"command": "npx",
"args": ["tsx", "/path/to/agentphone-mcp/index.ts"],
"env": {
"AGENTPHONE_API_KEY": "your_api_key_here"
}
}
}
}
Configure Cursor
Cursor uses .cursor/mcp.json in your project root — same config as above.
Restart your MCP client after adding the config.
Using It
Once configured, ask your MCP client to call any number with an objective — it uses the tool, waits for results, and reports outcome, summary, and transcript.
What You Can Do With It
- "Call the hosting provider and ask about upgrading our plan"
- "Check if the API vendor has 24/7 support, their number is +18005551234"
- "Call the office supply store and place a reorder for toner cartridges"
- "I'm getting errors with their API. Call their developer support line and describe the issue"
- "Call the client and confirm the deployment window for Saturday"
- Build a scheduling agent that calls businesses to book on behalf of users
- Build a procurement agent that calls vendors for quotes
- Build a research agent that calls businesses to verify information
Other frameworks (no MCP needed): OpenAI Agents SDK | LangChain | CrewAI
