Vapi MCP Server

Connect Vapi to AI assistants with Model Context Protocol (MCP)

Overview

The Vapi MCP Server exposes Vapi APIs as tools via the Model Context Protocol (MCP), so you can manage assistants, phone numbers, and calls from any MCP-compatible AI assistant (like Claude Desktop) or agent framework.

Use this server to connect your AI workflows to real-world telephony, automate voice tasks, and build richer conversational agents.

Looking to use MCP tools inside a Vapi assistant? See the MCP Tool documentation for integrating external MCP servers with your Vapi agents.

Quickstart: Claude Desktop Config

Fastest way to get started: connect Claude Desktop to the Vapi MCP Server.

2

Edit Claude Desktop config

Open SettingsDeveloper tab → Edit Config.

3

Add the Vapi MCP server block

Insert this into your claude_desktop_config.json:

1{
2 "mcpServers": {
3 "vapi-mcp": {
4 "command": "npx",
5 "args": [
6 "mcp-remote",
7 "https://mcp.vapi.ai/mcp",
8 "--header",
9 "Authorization: Bearer ${VAPI_TOKEN}"
10 ],
11 "env": {
12 "VAPI_TOKEN": "YOUR_VAPI_API_KEY"
13 }
14 }
15 }
16}

Replace YOUR_VAPI_API_KEY with your API key.

4

Restart Claude Desktop

Save and restart Claude Desktop.

Example prompt:

“Have my customer support assistant call Jeremy at +1555123456.”


Core Tools

The Vapi MCP Server exposes these actions as MCP tools:

ToolDescriptionExample Usage
list_assistantsList all Vapi assistantsShow all configured assistants
create_assistantCreate a new Vapi assistantAdd a new assistant for a use case
get_assistantGet a Vapi assistant by IDView assistant config
list_callsList all callsReview call activity
create_callCreate an outbound call (now or scheduled)Initiate or schedule a call
get_callGet details for a specific callCheck status or result of a call
list_phone_numbersList all Vapi phone numbersSee available numbers
get_phone_numberGet details of a specific phone numberInspect a phone number
list_toolsList all available Vapi toolsTool discovery
get_toolGet details of a specific toolTool integration info

Scheduling calls: The create_call action supports scheduling with the optional scheduledAt parameter.


Integration Options

Connect to the Vapi-hosted MCP server using the streamable-HTTP protocol.

Recommended for most production use cases.

Use this for clients or SDKs that support streamable-HTTP transport.

  • Endpoint: https://mcp.vapi.ai/mcp
  • Authentication: Pass your Vapi API key as a bearer token:
    Authorization: Bearer YOUR_VAPI_API_KEY

Example config:

1{
2 "mcpServers": {
3 "vapi-mcp": {
4 "command": "npx",
5 "args": [
6 "mcp-remote",
7 "https://mcp.vapi.ai/mcp",
8 "--header",
9 "Authorization: Bearer ${VAPI_TOKEN}"
10 ],
11 "env": {
12 "VAPI_TOKEN": "YOUR_VAPI_API_KEY"
13 }
14 }
15 }
16}

Custom MCP Client Integration

You can use any MCP-compatible client (SDKs available for multiple languages).

1

Install an MCP client SDK

Choose a language:

2

Configure your connection

Set up your SDK to connect to the Vapi MCP Server (https://mcp.vapi.ai/sse) and authenticate with your API key.

3

Use MCP tools

Query available tools, list assistants, create calls, etc, via your SDK.


Example: Build a client with Node.js

1import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
3import dotenv from 'dotenv';
4
5dotenv.config();
6
7const mcpClient = new Client({ name: 'vapi-client', version: '1.0.0' });
8const transport = new StreamableHTTPClientTransport(
9 new URL('https://mcp.vapi.ai/mcp'),
10 { requestInit: { headers: { Authorization: `Bearer ${process.env.VAPI_TOKEN}` } } }
11);
12
13async function main() {
14 await mcpClient.connect(transport);
15 const assistants = await mcpClient.callTool({ name: 'list_assistants', arguments: {} });
16 console.log(assistants);
17 await mcpClient.close();
18}
19
20main();

Detailed example: Build a client with Node.js

1#!/usr/bin/env node
2import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
4import dotenv from 'dotenv';
5
6// Load environment variables from .env file
7dotenv.config();
8
9// Ensure API key is available
10if (!process.env.VAPI_TOKEN) {
11 console.error('Error: VAPI_TOKEN environment variable is required');
12 process.exit(1);
13}
14
15async function main() {
16 try {
17 // Initialize MCP client
18 const mcpClient = new Client({
19 name: 'vapi-client-example',
20 version: '1.0.0',
21 });
22 // Create Streamable-HTTP transport for connection to remote Vapi MCP server
23 const serverUrl = 'https://mcp.vapi.ai/mcp';
24 const headers = {
25 Authorization: `Bearer ${process.env.VAPI_TOKEN}`,
26 };
27 const options = {
28 requestInit: { headers: headers },
29 };
30 const transport = new StreamableHTTPClientTransport(new URL(serverUrl), options);
31 console.log('Connecting to Vapi MCP server via Streamable HTTP...');
32 await mcpClient.connect(transport);
33 console.log('Connected successfully');
34
35 // Helper function to parse tool responses
36 function parseToolResponse(response) {
37 if (!response?.content) return response;
38 const textItem = response.content.find(item => item.type === 'text');
39 if (textItem?.text) {
40 try {
41 return JSON.parse(textItem.text);
42 } catch {
43 return textItem.text;
44 }
45 }
46 return response;
47 }
48
49 try {
50 // List available tools
51 const toolsResult = await mcpClient.listTools();
52 console.log('Available tools:');
53 toolsResult.tools.forEach((tool) => {
54 console.log(`- ${tool.name}: ${tool.description}`);
55 });
56
57 // List assistants
58 console.log('\nListing assistants...');
59 const assistantsResponse = await mcpClient.callTool({
60 name: 'list_assistants',
61 arguments: {},
62 });
63 const assistants = parseToolResponse(assistantsResponse);
64 if (!(Array.isArray(assistants) && assistants.length > 0)) {
65 console.log('No assistants found. Please create an assistant in the Vapi dashboard first.');
66 return;
67 }
68 console.log('Your assistants:');
69 assistants.forEach((assistant) => {
70 console.log(`- ${assistant.name} (${assistant.id})`);
71 });
72
73 // List phone numbers
74 console.log('\nListing phone numbers...');
75 const phoneNumbersResponse = await mcpClient.callTool({
76 name: 'list_phone_numbers',
77 arguments: {},
78 });
79 const phoneNumbers = parseToolResponse(phoneNumbersResponse);
80 if (!(Array.isArray(phoneNumbers) && phoneNumbers.length > 0)) {
81 console.log('No phone numbers found. Please add a phone number in the Vapi dashboard first.');
82 return;
83 }
84 console.log('Your phone numbers:');
85 phoneNumbers.forEach((phoneNumber) => {
86 console.log(`- ${phoneNumber.phoneNumber} (${phoneNumber.id})`);
87 });
88
89 // Create a call using the first assistant and first phone number
90 const phoneNumberId = phoneNumbers[0].id;
91 const assistantId = assistants[0].id;
92 console.log(`\nCreating a call using assistant (${assistantId}) and phone number (${phoneNumberId})...`);
93 const createCallResponse = await mcpClient.callTool({
94 name: 'create_call',
95 arguments: {
96 assistantId: assistantId,
97 phoneNumberId: phoneNumberId,
98 customer: {
99 phoneNumber: "+1234567890" // Replace with actual customer phone number
100 }
101 // Optional: schedule a call for the future
102 // scheduledAt: "2025-04-15T15:30:00Z"
103 },
104 });
105 const createdCall = parseToolResponse(createCallResponse);
106 console.log('Call created:', JSON.stringify(createdCall, null, 2));
107 } finally {
108 console.log('\nDisconnecting from server...');
109 await mcpClient.close();
110 console.log('Disconnected');
111 }
112 } catch (error) {
113 console.error('Error:', error);
114 process.exit(1);
115 }
116}
117
118main();
For more detailed examples and complete client implementations, see the MCP Client Quickstart.

References