@vapi-ai/mcp-server 0.0.3 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -21
  3. package/dist/__tests__/mcp-server-e2e.test.d.ts +2 -0
  4. package/dist/__tests__/mcp-server-e2e.test.d.ts.map +1 -0
  5. package/dist/__tests__/mcp-server-mock.test.d.ts +2 -0
  6. package/dist/__tests__/mcp-server-mock.test.d.ts.map +1 -0
  7. package/dist/__tests__/mocks/vapi-client.mock.d.ts +9 -0
  8. package/dist/__tests__/mocks/vapi-client.mock.d.ts.map +1 -0
  9. package/dist/client.d.ts +3 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/index.d.ts +5 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/schemas/index.d.ts +524 -0
  14. package/dist/schemas/index.d.ts.map +1 -0
  15. package/dist/schemas/index.js +78 -6
  16. package/dist/tools/assistant.d.ts +4 -0
  17. package/dist/tools/assistant.d.ts.map +1 -0
  18. package/dist/tools/assistant.js +21 -2
  19. package/dist/tools/call.d.ts +4 -0
  20. package/dist/tools/call.d.ts.map +1 -0
  21. package/dist/tools/index.d.ts +4 -0
  22. package/dist/tools/index.d.ts.map +1 -0
  23. package/dist/tools/index.js +2 -0
  24. package/dist/tools/phone-number.d.ts +4 -0
  25. package/dist/tools/phone-number.d.ts.map +1 -0
  26. package/dist/tools/tool.d.ts +4 -0
  27. package/dist/tools/tool.d.ts.map +1 -0
  28. package/dist/tools/tool.js +13 -0
  29. package/dist/tools/utils.d.ts +16 -0
  30. package/dist/tools/utils.d.ts.map +1 -0
  31. package/dist/transformers/index.d.ts +11 -0
  32. package/dist/transformers/index.d.ts.map +1 -0
  33. package/dist/transformers/index.js +83 -1
  34. package/dist/utils/response.d.ts +2 -0
  35. package/dist/utils/response.d.ts.map +1 -0
  36. package/dist/utils/response.js +2 -2
  37. package/package.json +8 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Vapi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,24 +1,24 @@
1
1
  # Vapi MCP Server
2
2
 
3
- The Vapi [Model Context Protocol](https://modelcontextprotocol.com/) server allows you to integrate with Vapi APIs through function calling.
4
-
5
- ## Setup
6
-
7
- To run the Vapi MCP server using npx, use the following command:
3
+ [![smithery badge](https://smithery.ai/badge/@VapiAI/vapi-mcp-server)](https://smithery.ai/server/@VapiAI/vapi-mcp-server)
8
4
 
9
- ```bash
10
- # To set up all available tools
11
- export VAPI_TOKEN=your_vapi_token
12
-
13
- npx -y @vapi-ai/mcp-server
14
- ```
5
+ The Vapi [Model Context Protocol](https://modelcontextprotocol.com/) server allows you to integrate with Vapi APIs through function calling.
15
6
 
16
- ### Usage with Claude Desktop
7
+ <a href="https://glama.ai/mcp/servers/@VapiAI/mcp-server">
8
+ <img width="380" height="200" src="https://glama.ai/mcp/servers/@VapiAI/mcp-server/badge" alt="Vapi Server MCP server" />
9
+ </a>
17
10
 
18
- Add the following to your `claude_desktop_config.json`. See [here](https://modelcontextprotocol.io/quickstart/user) for more details.
11
+ ## Claude Desktop Setup
19
12
 
20
- ```
13
+ 1. Open `Claude Desktop` and press `CMD + ,` to go to `Settings`.
14
+ 2. Click on the `Developer` tab.
15
+ 3. Click on the `Edit Config` button.
16
+ 4. This will open the `claude_desktop_config.json` file in your file explorer.
17
+ 5. Get your Vapi API key from the Vapi dashboard (<https://dashboard.vapi.ai/org/api-keys>).
18
+ 6. Add the following to your `claude_desktop_config.json` file. See [here](https://modelcontextprotocol.io/quickstart/user) for more details.
19
+ 7. Restart the Claude Desktop after editing the config file.
21
20
 
21
+ ```json
22
22
  {
23
23
  "mcpServers": {
24
24
  "vapi-mcp-server": {
@@ -36,6 +36,35 @@ Add the following to your `claude_desktop_config.json`. See [here](https://model
36
36
 
37
37
  ```
38
38
 
39
+ ### Example Usage with Claude Desktop
40
+
41
+ 1. Create or import a phone number using the Vapi dashboard (<https://dashboard.vapi.ai/phone-numbers>).
42
+ 2. Create a new assistant using the existing 'Appointment Scheduler' template in the Vapi dashboard (<https://dashboard.vapi.ai/assistants>).
43
+ 3. Make sure to configure Claude Desktop to use the Vapi MCP server and restart the Claude Desktop app.
44
+ 4. Ask Claude to initiate or schedule a call. See examples below:
45
+
46
+ **Example 1:** Request an immediate call
47
+
48
+ ```md
49
+ I'd like to speak with my ShopHelper assistant to talk about my recent order. Can you have it call me at +1234567890?
50
+ ```
51
+
52
+ **Example 2:** Schedule a future call
53
+
54
+ ```md
55
+ I need to schedule a call with Mary assistant for next Tuesday at 3:00 PM. My phone number is +1555123456.
56
+ ```
57
+
58
+ ## Remote SSE Connection
59
+
60
+ To connect to Vapi's MCP server via Server-Sent Events (SSE) Transport:
61
+
62
+ - Connect to `https://mcp.vapi.ai/sse` from any MCP client using SSE Transport
63
+ - Include your Vapi API key as a bearer token in the request headers
64
+ - Example header: `Authorization: Bearer your_vapi_api_key_here`
65
+
66
+ This connection allows you to access Vapi's functionality remotely without running a local server.
67
+
39
68
  ## Development
40
69
 
41
70
  ```bash
@@ -46,16 +75,29 @@ npm install
46
75
  npm run build
47
76
  ```
48
77
 
49
- ```bash
50
- # Run the server in development mode with hot reloading
51
- npm run dev
78
+ Update your `claude_desktop_config.json` to use the local server.
79
+
80
+ ```json
81
+ {
82
+ "mcpServers": {
83
+ "vapi-local": {
84
+ "command": "node",
85
+ "args": [
86
+ "<path_to_vapi_mcp_server>/dist/index.js"
87
+ ],
88
+ "env": {
89
+ "VAPI_TOKEN": "<your_vapi_token>"
90
+ }
91
+ },
92
+ }
93
+ }
52
94
  ```
53
95
 
54
- ## Testing
96
+ ### Testing
55
97
 
56
98
  The project has two types of tests:
57
99
 
58
- ### Unit Tests
100
+ #### Unit Tests
59
101
 
60
102
  Unit tests use mocks to test the MCP server without making actual API calls to Vapi.
61
103
 
@@ -64,7 +106,7 @@ Unit tests use mocks to test the MCP server without making actual API calls to V
64
106
  npm run test:unit
65
107
  ```
66
108
 
67
- ### End-to-End Tests
109
+ #### End-to-End Tests
68
110
 
69
111
  E2E tests run the full MCP server with actual API calls to Vapi.
70
112
 
@@ -78,10 +120,40 @@ npm run test:e2e
78
120
 
79
121
  Note: E2E tests require a valid Vapi API token to be set in the environment.
80
122
 
81
- ## Running All Tests
123
+ #### Running All Tests
82
124
 
83
125
  To run all tests at once:
84
126
 
85
127
  ```bash
86
128
  npm test
87
129
  ```
130
+
131
+ ## References
132
+
133
+ - [VAPI Remote MCP Server](https://mcp.vapi.ai/)
134
+ - [VAPI MCP Tool](https://docs.vapi.ai/tools/mcp)
135
+ - [Model Context Protocol](https://modelcontextprotocol.com/)
136
+ - [Claude Desktop](https://modelcontextprotocol.io/quickstart/user)
137
+
138
+ ## Supported Actions
139
+
140
+ The Vapi MCP Server provides the following tools for integration:
141
+
142
+ ### Assistant Tools
143
+
144
+ - `list_assistants`: Lists all Vapi assistants
145
+ - `create_assistant`: Creates a new Vapi assistant
146
+ - `get_assistant`: Gets a Vapi assistant by ID
147
+
148
+ ### Call Tools
149
+
150
+ - `list_calls`: Lists all Vapi calls
151
+ - `create_call`: Creates an outbound call
152
+ - `get_call`: Gets details of a specific call
153
+
154
+ > **Note:** The `create_call` action supports scheduling calls for immediate execution or for a future time.
155
+
156
+ ### Phone Number Tools
157
+
158
+ - `list_phone_numbers`: Lists all Vapi phone numbers
159
+ - `get_phone_number`: Gets details of a specific phone number
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mcp-server-e2e.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server-e2e.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mcp-server-e2e.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mcp-server-mock.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server-mock.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mcp-server-mock.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ export declare class MockVapiClient {
2
+ assistants: {
3
+ list: jest.Mock<any, any, any>;
4
+ get: jest.Mock<any, any, any>;
5
+ create: jest.Mock<any, any, any>;
6
+ };
7
+ }
8
+ export declare const createMockVapiClient: () => MockVapiClient;
9
+ //# sourceMappingURL=vapi-client.mock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vapi-client.mock.d.ts","sourceRoot":"","sources":["../../../src/__tests__/mocks/vapi-client.mock.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAc;IACzB,UAAU;;;;MAuCR;CACH;AAED,eAAO,MAAM,oBAAoB,sBAEhC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { VapiClient } from '@vapi-ai/server-sdk';
2
+ export declare const createVapiClient: (token: string) => VapiClient;
3
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,UAKhD,CAAC"}
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ declare function createMcpServer(): McpServer;
4
+ export { createMcpServer };
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,iBAAS,eAAe,cAiBvB;AA8BD,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,524 @@
1
+ import { z } from 'zod';
2
+ export declare const ModelProvider: {
3
+ readonly OpenAI: "openai";
4
+ readonly Anthropic: "anthropic";
5
+ readonly GoogleAI: "google";
6
+ };
7
+ export declare const OpenAIModels: {
8
+ readonly GPT4o: "gpt-4o";
9
+ readonly GPT4oMini: "gpt-4o-mini";
10
+ };
11
+ export declare const AnthropicModels: {
12
+ readonly Claude3Sonnet: "claude-3-7-sonnet-20250219";
13
+ readonly Claude3Haiku: "claude-3-5-haiku-20241022";
14
+ };
15
+ export declare const GoogleModels: {
16
+ readonly GeminiPro: "gemini-1.5-pro";
17
+ readonly GeminiFlash: "gemini-1.5-flash";
18
+ readonly Gemini2Flash: "gemini-2.0-flash";
19
+ readonly Gemini2Pro: "gemini-2.0-pro";
20
+ };
21
+ export type ModelProviderType = (typeof ModelProvider)[keyof typeof ModelProvider];
22
+ export type OpenAIModelType = (typeof OpenAIModels)[keyof typeof OpenAIModels];
23
+ export type AnthropicModelType = (typeof AnthropicModels)[keyof typeof AnthropicModels];
24
+ export type GoogleModelType = (typeof GoogleModels)[keyof typeof GoogleModels];
25
+ export declare const DEFAULT_LLM: {
26
+ provider: "openai";
27
+ model: "gpt-4o";
28
+ };
29
+ declare const VoiceProviderSchema: z.ZodEnum<["vapi", "11labs", "azure", "cartesia", "custom-voice", "deepgram", "11labs", "hume", "lmnt", "neuphonic", "openai", "playht", "rime-ai", "smallest-ai", "tavus", "sesame"]>;
30
+ export type VoiceProviderType = z.infer<typeof VoiceProviderSchema>;
31
+ export declare const DEFAULT_VOICE: {
32
+ provider: VoiceProviderType;
33
+ voiceId: string;
34
+ };
35
+ export declare const DEFAULT_TRANSCRIBER: {
36
+ provider: string;
37
+ model: string;
38
+ };
39
+ export declare const ElevenLabsVoiceIds: {
40
+ readonly Sarah: "sarah";
41
+ readonly Phillip: "phillip";
42
+ readonly Steve: "steve";
43
+ readonly Joseph: "joseph";
44
+ readonly Myra: "myra";
45
+ };
46
+ export declare const BaseResponseSchema: z.ZodObject<{
47
+ id: z.ZodString;
48
+ createdAt: z.ZodString;
49
+ updatedAt: z.ZodString;
50
+ }, "strip", z.ZodTypeAny, {
51
+ id: string;
52
+ createdAt: string;
53
+ updatedAt: string;
54
+ }, {
55
+ id: string;
56
+ createdAt: string;
57
+ updatedAt: string;
58
+ }>;
59
+ export declare const CreateAssistantInputSchema: z.ZodObject<{
60
+ name: z.ZodString;
61
+ instructions: z.ZodDefault<z.ZodOptional<z.ZodString>>;
62
+ llm: z.ZodDefault<z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
63
+ provider: z.ZodLiteral<"openai">;
64
+ model: z.ZodEnum<["gpt-4o", "gpt-4o-mini"]>;
65
+ }, "strip", z.ZodTypeAny, {
66
+ provider: "openai";
67
+ model: "gpt-4o" | "gpt-4o-mini";
68
+ }, {
69
+ provider: "openai";
70
+ model: "gpt-4o" | "gpt-4o-mini";
71
+ }>, z.ZodObject<{
72
+ provider: z.ZodLiteral<"anthropic">;
73
+ model: z.ZodEnum<["claude-3-7-sonnet-20250219", "claude-3-5-haiku-20241022"]>;
74
+ }, "strip", z.ZodTypeAny, {
75
+ provider: "anthropic";
76
+ model: "claude-3-7-sonnet-20250219" | "claude-3-5-haiku-20241022";
77
+ }, {
78
+ provider: "anthropic";
79
+ model: "claude-3-7-sonnet-20250219" | "claude-3-5-haiku-20241022";
80
+ }>, z.ZodObject<{
81
+ provider: z.ZodLiteral<"google">;
82
+ model: z.ZodEnum<["gemini-1.5-pro", "gemini-1.5-flash", "gemini-2.0-flash", "gemini-2.0-pro"]>;
83
+ }, "strip", z.ZodTypeAny, {
84
+ provider: "google";
85
+ model: "gemini-1.5-pro" | "gemini-1.5-flash" | "gemini-2.0-flash" | "gemini-2.0-pro";
86
+ }, {
87
+ provider: "google";
88
+ model: "gemini-1.5-pro" | "gemini-1.5-flash" | "gemini-2.0-flash" | "gemini-2.0-pro";
89
+ }>, z.ZodObject<{
90
+ provider: z.ZodString;
91
+ model: z.ZodString;
92
+ }, "strip", z.ZodTypeAny, {
93
+ provider: string;
94
+ model: string;
95
+ }, {
96
+ provider: string;
97
+ model: string;
98
+ }>]>, z.ZodEffects<z.ZodString, any, string>]>>;
99
+ toolIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
100
+ transcriber: z.ZodDefault<z.ZodObject<{
101
+ provider: z.ZodString;
102
+ model: z.ZodString;
103
+ }, "strip", z.ZodTypeAny, {
104
+ provider: string;
105
+ model: string;
106
+ }, {
107
+ provider: string;
108
+ model: string;
109
+ }>>;
110
+ voice: z.ZodDefault<z.ZodObject<{
111
+ provider: z.ZodEnum<["vapi", "11labs", "azure", "cartesia", "custom-voice", "deepgram", "11labs", "hume", "lmnt", "neuphonic", "openai", "playht", "rime-ai", "smallest-ai", "tavus", "sesame"]>;
112
+ voiceId: z.ZodString;
113
+ model: z.ZodOptional<z.ZodString>;
114
+ }, "strip", z.ZodTypeAny, {
115
+ provider: "openai" | "vapi" | "11labs" | "azure" | "cartesia" | "custom-voice" | "deepgram" | "hume" | "lmnt" | "neuphonic" | "playht" | "rime-ai" | "smallest-ai" | "tavus" | "sesame";
116
+ voiceId: string;
117
+ model?: string | undefined;
118
+ }, {
119
+ provider: "openai" | "vapi" | "11labs" | "azure" | "cartesia" | "custom-voice" | "deepgram" | "hume" | "lmnt" | "neuphonic" | "playht" | "rime-ai" | "smallest-ai" | "tavus" | "sesame";
120
+ voiceId: string;
121
+ model?: string | undefined;
122
+ }>>;
123
+ firstMessage: z.ZodDefault<z.ZodOptional<z.ZodString>>;
124
+ firstMessageMode: z.ZodOptional<z.ZodDefault<z.ZodEnum<["assistant-speaks-first", "assistant-waits-for-user", "assistant-speaks-first-with-model-generated-message"]>>>;
125
+ }, "strip", z.ZodTypeAny, {
126
+ name: string;
127
+ instructions: string;
128
+ transcriber: {
129
+ provider: string;
130
+ model: string;
131
+ };
132
+ voice: {
133
+ provider: "openai" | "vapi" | "11labs" | "azure" | "cartesia" | "custom-voice" | "deepgram" | "hume" | "lmnt" | "neuphonic" | "playht" | "rime-ai" | "smallest-ai" | "tavus" | "sesame";
134
+ voiceId: string;
135
+ model?: string | undefined;
136
+ };
137
+ firstMessage: string;
138
+ llm?: any;
139
+ toolIds?: string[] | undefined;
140
+ firstMessageMode?: "assistant-speaks-first" | "assistant-waits-for-user" | "assistant-speaks-first-with-model-generated-message" | undefined;
141
+ }, {
142
+ name: string;
143
+ instructions?: string | undefined;
144
+ llm?: string | {
145
+ provider: "openai";
146
+ model: "gpt-4o" | "gpt-4o-mini";
147
+ } | {
148
+ provider: "anthropic";
149
+ model: "claude-3-7-sonnet-20250219" | "claude-3-5-haiku-20241022";
150
+ } | {
151
+ provider: "google";
152
+ model: "gemini-1.5-pro" | "gemini-1.5-flash" | "gemini-2.0-flash" | "gemini-2.0-pro";
153
+ } | {
154
+ provider: string;
155
+ model: string;
156
+ } | undefined;
157
+ toolIds?: string[] | undefined;
158
+ transcriber?: {
159
+ provider: string;
160
+ model: string;
161
+ } | undefined;
162
+ voice?: {
163
+ provider: "openai" | "vapi" | "11labs" | "azure" | "cartesia" | "custom-voice" | "deepgram" | "hume" | "lmnt" | "neuphonic" | "playht" | "rime-ai" | "smallest-ai" | "tavus" | "sesame";
164
+ voiceId: string;
165
+ model?: string | undefined;
166
+ } | undefined;
167
+ firstMessage?: string | undefined;
168
+ firstMessageMode?: "assistant-speaks-first" | "assistant-waits-for-user" | "assistant-speaks-first-with-model-generated-message" | undefined;
169
+ }>;
170
+ export declare const AssistantOutputSchema: z.ZodObject<z.objectUtil.extendShape<{
171
+ id: z.ZodString;
172
+ createdAt: z.ZodString;
173
+ updatedAt: z.ZodString;
174
+ }, {
175
+ name: z.ZodString;
176
+ llm: z.ZodObject<{
177
+ provider: z.ZodString;
178
+ model: z.ZodString;
179
+ }, "strip", z.ZodTypeAny, {
180
+ provider: string;
181
+ model: string;
182
+ }, {
183
+ provider: string;
184
+ model: string;
185
+ }>;
186
+ voice: z.ZodObject<{
187
+ provider: z.ZodString;
188
+ voiceId: z.ZodString;
189
+ model: z.ZodOptional<z.ZodString>;
190
+ }, "strip", z.ZodTypeAny, {
191
+ provider: string;
192
+ voiceId: string;
193
+ model?: string | undefined;
194
+ }, {
195
+ provider: string;
196
+ voiceId: string;
197
+ model?: string | undefined;
198
+ }>;
199
+ transcriber: z.ZodObject<{
200
+ provider: z.ZodString;
201
+ model: z.ZodString;
202
+ }, "strip", z.ZodTypeAny, {
203
+ provider: string;
204
+ model: string;
205
+ }, {
206
+ provider: string;
207
+ model: string;
208
+ }>;
209
+ toolIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
210
+ }>, "strip", z.ZodTypeAny, {
211
+ id: string;
212
+ createdAt: string;
213
+ updatedAt: string;
214
+ name: string;
215
+ llm: {
216
+ provider: string;
217
+ model: string;
218
+ };
219
+ transcriber: {
220
+ provider: string;
221
+ model: string;
222
+ };
223
+ voice: {
224
+ provider: string;
225
+ voiceId: string;
226
+ model?: string | undefined;
227
+ };
228
+ toolIds?: string[] | undefined;
229
+ }, {
230
+ id: string;
231
+ createdAt: string;
232
+ updatedAt: string;
233
+ name: string;
234
+ llm: {
235
+ provider: string;
236
+ model: string;
237
+ };
238
+ transcriber: {
239
+ provider: string;
240
+ model: string;
241
+ };
242
+ voice: {
243
+ provider: string;
244
+ voiceId: string;
245
+ model?: string | undefined;
246
+ };
247
+ toolIds?: string[] | undefined;
248
+ }>;
249
+ export declare const GetAssistantInputSchema: z.ZodObject<{
250
+ assistantId: z.ZodString;
251
+ }, "strip", z.ZodTypeAny, {
252
+ assistantId: string;
253
+ }, {
254
+ assistantId: string;
255
+ }>;
256
+ export declare const UpdateAssistantInputSchema: z.ZodObject<{
257
+ assistantId: z.ZodString;
258
+ name: z.ZodOptional<z.ZodString>;
259
+ instructions: z.ZodOptional<z.ZodString>;
260
+ llm: z.ZodOptional<z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
261
+ provider: z.ZodLiteral<"openai">;
262
+ model: z.ZodEnum<["gpt-4o", "gpt-4o-mini"]>;
263
+ }, "strip", z.ZodTypeAny, {
264
+ provider: "openai";
265
+ model: "gpt-4o" | "gpt-4o-mini";
266
+ }, {
267
+ provider: "openai";
268
+ model: "gpt-4o" | "gpt-4o-mini";
269
+ }>, z.ZodObject<{
270
+ provider: z.ZodLiteral<"anthropic">;
271
+ model: z.ZodEnum<["claude-3-7-sonnet-20250219", "claude-3-5-haiku-20241022"]>;
272
+ }, "strip", z.ZodTypeAny, {
273
+ provider: "anthropic";
274
+ model: "claude-3-7-sonnet-20250219" | "claude-3-5-haiku-20241022";
275
+ }, {
276
+ provider: "anthropic";
277
+ model: "claude-3-7-sonnet-20250219" | "claude-3-5-haiku-20241022";
278
+ }>, z.ZodObject<{
279
+ provider: z.ZodLiteral<"google">;
280
+ model: z.ZodEnum<["gemini-1.5-pro", "gemini-1.5-flash", "gemini-2.0-flash", "gemini-2.0-pro"]>;
281
+ }, "strip", z.ZodTypeAny, {
282
+ provider: "google";
283
+ model: "gemini-1.5-pro" | "gemini-1.5-flash" | "gemini-2.0-flash" | "gemini-2.0-pro";
284
+ }, {
285
+ provider: "google";
286
+ model: "gemini-1.5-pro" | "gemini-1.5-flash" | "gemini-2.0-flash" | "gemini-2.0-pro";
287
+ }>, z.ZodObject<{
288
+ provider: z.ZodString;
289
+ model: z.ZodString;
290
+ }, "strip", z.ZodTypeAny, {
291
+ provider: string;
292
+ model: string;
293
+ }, {
294
+ provider: string;
295
+ model: string;
296
+ }>]>, z.ZodEffects<z.ZodString, any, string>]>>;
297
+ toolIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
298
+ transcriber: z.ZodOptional<z.ZodObject<{
299
+ provider: z.ZodString;
300
+ model: z.ZodString;
301
+ }, "strip", z.ZodTypeAny, {
302
+ provider: string;
303
+ model: string;
304
+ }, {
305
+ provider: string;
306
+ model: string;
307
+ }>>;
308
+ voice: z.ZodOptional<z.ZodObject<{
309
+ provider: z.ZodEnum<["vapi", "11labs", "azure", "cartesia", "custom-voice", "deepgram", "11labs", "hume", "lmnt", "neuphonic", "openai", "playht", "rime-ai", "smallest-ai", "tavus", "sesame"]>;
310
+ voiceId: z.ZodString;
311
+ model: z.ZodOptional<z.ZodString>;
312
+ }, "strip", z.ZodTypeAny, {
313
+ provider: "openai" | "vapi" | "11labs" | "azure" | "cartesia" | "custom-voice" | "deepgram" | "hume" | "lmnt" | "neuphonic" | "playht" | "rime-ai" | "smallest-ai" | "tavus" | "sesame";
314
+ voiceId: string;
315
+ model?: string | undefined;
316
+ }, {
317
+ provider: "openai" | "vapi" | "11labs" | "azure" | "cartesia" | "custom-voice" | "deepgram" | "hume" | "lmnt" | "neuphonic" | "playht" | "rime-ai" | "smallest-ai" | "tavus" | "sesame";
318
+ voiceId: string;
319
+ model?: string | undefined;
320
+ }>>;
321
+ firstMessage: z.ZodOptional<z.ZodString>;
322
+ firstMessageMode: z.ZodOptional<z.ZodEnum<["assistant-speaks-first", "assistant-waits-for-user", "assistant-speaks-first-with-model-generated-message"]>>;
323
+ }, "strip", z.ZodTypeAny, {
324
+ assistantId: string;
325
+ name?: string | undefined;
326
+ instructions?: string | undefined;
327
+ llm?: any;
328
+ toolIds?: string[] | undefined;
329
+ transcriber?: {
330
+ provider: string;
331
+ model: string;
332
+ } | undefined;
333
+ voice?: {
334
+ provider: "openai" | "vapi" | "11labs" | "azure" | "cartesia" | "custom-voice" | "deepgram" | "hume" | "lmnt" | "neuphonic" | "playht" | "rime-ai" | "smallest-ai" | "tavus" | "sesame";
335
+ voiceId: string;
336
+ model?: string | undefined;
337
+ } | undefined;
338
+ firstMessage?: string | undefined;
339
+ firstMessageMode?: "assistant-speaks-first" | "assistant-waits-for-user" | "assistant-speaks-first-with-model-generated-message" | undefined;
340
+ }, {
341
+ assistantId: string;
342
+ name?: string | undefined;
343
+ instructions?: string | undefined;
344
+ llm?: string | {
345
+ provider: "openai";
346
+ model: "gpt-4o" | "gpt-4o-mini";
347
+ } | {
348
+ provider: "anthropic";
349
+ model: "claude-3-7-sonnet-20250219" | "claude-3-5-haiku-20241022";
350
+ } | {
351
+ provider: "google";
352
+ model: "gemini-1.5-pro" | "gemini-1.5-flash" | "gemini-2.0-flash" | "gemini-2.0-pro";
353
+ } | {
354
+ provider: string;
355
+ model: string;
356
+ } | undefined;
357
+ toolIds?: string[] | undefined;
358
+ transcriber?: {
359
+ provider: string;
360
+ model: string;
361
+ } | undefined;
362
+ voice?: {
363
+ provider: "openai" | "vapi" | "11labs" | "azure" | "cartesia" | "custom-voice" | "deepgram" | "hume" | "lmnt" | "neuphonic" | "playht" | "rime-ai" | "smallest-ai" | "tavus" | "sesame";
364
+ voiceId: string;
365
+ model?: string | undefined;
366
+ } | undefined;
367
+ firstMessage?: string | undefined;
368
+ firstMessageMode?: "assistant-speaks-first" | "assistant-waits-for-user" | "assistant-speaks-first-with-model-generated-message" | undefined;
369
+ }>;
370
+ export declare const CallInputSchema: z.ZodObject<{
371
+ assistantId: z.ZodOptional<z.ZodString>;
372
+ phoneNumberId: z.ZodOptional<z.ZodString>;
373
+ customer: z.ZodOptional<z.ZodObject<{
374
+ phoneNumber: z.ZodString;
375
+ }, "strip", z.ZodTypeAny, {
376
+ phoneNumber: string;
377
+ }, {
378
+ phoneNumber: string;
379
+ }>>;
380
+ scheduledAt: z.ZodOptional<z.ZodString>;
381
+ }, "strip", z.ZodTypeAny, {
382
+ assistantId?: string | undefined;
383
+ phoneNumberId?: string | undefined;
384
+ customer?: {
385
+ phoneNumber: string;
386
+ } | undefined;
387
+ scheduledAt?: string | undefined;
388
+ }, {
389
+ assistantId?: string | undefined;
390
+ phoneNumberId?: string | undefined;
391
+ customer?: {
392
+ phoneNumber: string;
393
+ } | undefined;
394
+ scheduledAt?: string | undefined;
395
+ }>;
396
+ export declare const CallOutputSchema: z.ZodObject<z.objectUtil.extendShape<{
397
+ id: z.ZodString;
398
+ createdAt: z.ZodString;
399
+ updatedAt: z.ZodString;
400
+ }, {
401
+ status: z.ZodString;
402
+ endedReason: z.ZodOptional<z.ZodString>;
403
+ assistantId: z.ZodOptional<z.ZodString>;
404
+ phoneNumberId: z.ZodOptional<z.ZodString>;
405
+ customer: z.ZodOptional<z.ZodObject<{
406
+ phoneNumber: z.ZodString;
407
+ }, "strip", z.ZodTypeAny, {
408
+ phoneNumber: string;
409
+ }, {
410
+ phoneNumber: string;
411
+ }>>;
412
+ scheduledAt: z.ZodOptional<z.ZodString>;
413
+ }>, "strip", z.ZodTypeAny, {
414
+ status: string;
415
+ id: string;
416
+ createdAt: string;
417
+ updatedAt: string;
418
+ assistantId?: string | undefined;
419
+ phoneNumberId?: string | undefined;
420
+ customer?: {
421
+ phoneNumber: string;
422
+ } | undefined;
423
+ scheduledAt?: string | undefined;
424
+ endedReason?: string | undefined;
425
+ }, {
426
+ status: string;
427
+ id: string;
428
+ createdAt: string;
429
+ updatedAt: string;
430
+ assistantId?: string | undefined;
431
+ phoneNumberId?: string | undefined;
432
+ customer?: {
433
+ phoneNumber: string;
434
+ } | undefined;
435
+ scheduledAt?: string | undefined;
436
+ endedReason?: string | undefined;
437
+ }>;
438
+ export declare const GetCallInputSchema: z.ZodObject<{
439
+ callId: z.ZodString;
440
+ }, "strip", z.ZodTypeAny, {
441
+ callId: string;
442
+ }, {
443
+ callId: string;
444
+ }>;
445
+ export declare const GetPhoneNumberInputSchema: z.ZodObject<{
446
+ phoneNumberId: z.ZodString;
447
+ }, "strip", z.ZodTypeAny, {
448
+ phoneNumberId: string;
449
+ }, {
450
+ phoneNumberId: string;
451
+ }>;
452
+ export declare const PhoneNumberOutputSchema: z.ZodObject<z.objectUtil.extendShape<{
453
+ id: z.ZodString;
454
+ createdAt: z.ZodString;
455
+ updatedAt: z.ZodString;
456
+ }, {
457
+ name: z.ZodOptional<z.ZodString>;
458
+ phoneNumber: z.ZodString;
459
+ status: z.ZodString;
460
+ capabilities: z.ZodOptional<z.ZodObject<{
461
+ sms: z.ZodOptional<z.ZodBoolean>;
462
+ voice: z.ZodOptional<z.ZodBoolean>;
463
+ }, "strip", z.ZodTypeAny, {
464
+ voice?: boolean | undefined;
465
+ sms?: boolean | undefined;
466
+ }, {
467
+ voice?: boolean | undefined;
468
+ sms?: boolean | undefined;
469
+ }>>;
470
+ }>, "strip", z.ZodTypeAny, {
471
+ status: string;
472
+ id: string;
473
+ createdAt: string;
474
+ updatedAt: string;
475
+ phoneNumber: string;
476
+ name?: string | undefined;
477
+ capabilities?: {
478
+ voice?: boolean | undefined;
479
+ sms?: boolean | undefined;
480
+ } | undefined;
481
+ }, {
482
+ status: string;
483
+ id: string;
484
+ createdAt: string;
485
+ updatedAt: string;
486
+ phoneNumber: string;
487
+ name?: string | undefined;
488
+ capabilities?: {
489
+ voice?: boolean | undefined;
490
+ sms?: boolean | undefined;
491
+ } | undefined;
492
+ }>;
493
+ export declare const GetToolInputSchema: z.ZodObject<{
494
+ toolId: z.ZodString;
495
+ }, "strip", z.ZodTypeAny, {
496
+ toolId: string;
497
+ }, {
498
+ toolId: string;
499
+ }>;
500
+ export declare const ToolOutputSchema: z.ZodObject<z.objectUtil.extendShape<{
501
+ id: z.ZodString;
502
+ createdAt: z.ZodString;
503
+ updatedAt: z.ZodString;
504
+ }, {
505
+ type: z.ZodString;
506
+ name: z.ZodString;
507
+ description: z.ZodString;
508
+ }>, "strip", z.ZodTypeAny, {
509
+ type: string;
510
+ id: string;
511
+ createdAt: string;
512
+ updatedAt: string;
513
+ name: string;
514
+ description: string;
515
+ }, {
516
+ type: string;
517
+ id: string;
518
+ createdAt: string;
519
+ updatedAt: string;
520
+ name: string;
521
+ description: string;
522
+ }>;
523
+ export {};
524
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AAEX,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX,eAAO,MAAM,eAAe;;;CAGlB,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;CAKf,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAC3B,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AACrD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAC/E,MAAM,MAAM,kBAAkB,GAC5B,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AACzD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAqC/E,eAAO,MAAM,WAAW;;;CAGvB,CAAC;AAEF,QAAA,MAAM,mBAAmB,wLAiBvB,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEpE,eAAO,MAAM,aAAa;cACF,iBAAiB;;CAExC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;CAG/B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;CAMrB,CAAC;AAIX,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAI7B,CAAC;AAIH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqDrC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBhC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;EAElC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDrC,CAAC;AAIH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;EAqB1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;EAE7B,CAAC;AAIH,eAAO,MAAM,yBAAyB;;;;;;EAEpC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUlC,CAAC;AAIH,eAAO,MAAM,kBAAkB;;;;;;EAE7B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;EAM3B,CAAC"}
@@ -114,6 +114,10 @@ export const CreateAssistantInputSchema = z.object({
114
114
  ])
115
115
  .default(DEFAULT_LLM)
116
116
  .describe('LLM configuration'),
117
+ toolIds: z
118
+ .array(z.string())
119
+ .optional()
120
+ .describe('IDs of tools to use with this assistant'),
117
121
  transcriber: z
118
122
  .object({
119
123
  provider: z.string().describe('Provider to use for transcription'),
@@ -133,7 +137,7 @@ export const CreateAssistantInputSchema = z.object({
133
137
  .string()
134
138
  .optional()
135
139
  .default('Hello, how can I help you today?')
136
- .describe('First message to send'),
140
+ .describe('First message to say to the user'),
137
141
  firstMessageMode: z
138
142
  .enum([
139
143
  'assistant-speaks-first',
@@ -142,7 +146,7 @@ export const CreateAssistantInputSchema = z.object({
142
146
  ])
143
147
  .default('assistant-speaks-first')
144
148
  .optional()
145
- .describe('First message mode'),
149
+ .describe('This determines who speaks first, either assistant or user'),
146
150
  });
147
151
  export const AssistantOutputSchema = BaseResponseSchema.extend({
148
152
  name: z.string(),
@@ -159,10 +163,64 @@ export const AssistantOutputSchema = BaseResponseSchema.extend({
159
163
  provider: z.string(),
160
164
  model: z.string(),
161
165
  }),
166
+ toolIds: z.array(z.string()).optional(),
162
167
  });
163
168
  export const GetAssistantInputSchema = z.object({
164
169
  assistantId: z.string().describe('ID of the assistant to get'),
165
170
  });
171
+ export const UpdateAssistantInputSchema = z.object({
172
+ assistantId: z.string().describe('ID of the assistant to update'),
173
+ name: z.string().optional().describe('New name for the assistant'),
174
+ instructions: z
175
+ .string()
176
+ .optional()
177
+ .describe('New instructions for the assistant'),
178
+ llm: z
179
+ .union([
180
+ LLMSchema,
181
+ z.string().transform((str) => {
182
+ try {
183
+ return JSON.parse(str);
184
+ }
185
+ catch (e) {
186
+ throw new Error(`Invalid LLM JSON string: ${str}`);
187
+ }
188
+ }),
189
+ ])
190
+ .optional()
191
+ .describe('New LLM configuration'),
192
+ toolIds: z
193
+ .array(z.string())
194
+ .optional()
195
+ .describe('New IDs of tools to use with this assistant'),
196
+ transcriber: z
197
+ .object({
198
+ provider: z.string().describe('Provider to use for transcription'),
199
+ model: z.string().describe('Transcription model to use'),
200
+ })
201
+ .optional()
202
+ .describe('New transcription configuration'),
203
+ voice: z
204
+ .object({
205
+ provider: VoiceProviderSchema.describe('Provider to use for voice'),
206
+ voiceId: z.string().describe('Voice ID to use'),
207
+ model: z.string().optional().describe('Voice model to use'),
208
+ })
209
+ .optional()
210
+ .describe('New voice configuration'),
211
+ firstMessage: z
212
+ .string()
213
+ .optional()
214
+ .describe('First message to say to the user'),
215
+ firstMessageMode: z
216
+ .enum([
217
+ 'assistant-speaks-first',
218
+ 'assistant-waits-for-user',
219
+ 'assistant-speaks-first-with-model-generated-message',
220
+ ])
221
+ .optional()
222
+ .describe('This determines who speaks first, either assistant or user'),
223
+ });
166
224
  // ===== Call Schemas =====
167
225
  export const CallInputSchema = z.object({
168
226
  assistantId: z
@@ -179,6 +237,10 @@ export const CallInputSchema = z.object({
179
237
  })
180
238
  .optional()
181
239
  .describe('Customer information'),
240
+ scheduledAt: z
241
+ .string()
242
+ .optional()
243
+ .describe('ISO datetime string for when the call should be scheduled (e.g. "2025-03-25T22:39:27.771Z")'),
182
244
  });
183
245
  export const CallOutputSchema = BaseResponseSchema.extend({
184
246
  status: z.string(),
@@ -190,15 +252,17 @@ export const CallOutputSchema = BaseResponseSchema.extend({
190
252
  phoneNumber: z.string(),
191
253
  })
192
254
  .optional(),
255
+ scheduledAt: z.string().optional(),
193
256
  });
194
257
  export const GetCallInputSchema = z.object({
195
258
  callId: z.string().describe('ID of the call to get'),
196
259
  });
197
260
  // ===== Phone Number Schemas =====
198
- export const PhoneNumberInputSchema = z.object({
199
- areaCode: z.string().describe('Area code to search for'),
261
+ export const GetPhoneNumberInputSchema = z.object({
262
+ phoneNumberId: z.string().describe('ID of the phone number to get'),
200
263
  });
201
264
  export const PhoneNumberOutputSchema = BaseResponseSchema.extend({
265
+ name: z.string().optional(),
202
266
  phoneNumber: z.string(),
203
267
  status: z.string(),
204
268
  capabilities: z
@@ -208,6 +272,14 @@ export const PhoneNumberOutputSchema = BaseResponseSchema.extend({
208
272
  })
209
273
  .optional(),
210
274
  });
211
- export const GetPhoneNumberInputSchema = z.object({
212
- phoneNumberId: z.string().describe('ID of the phone number to get'),
275
+ // ===== Tool Schemas =====
276
+ export const GetToolInputSchema = z.object({
277
+ toolId: z.string().describe('ID of the tool to get'),
278
+ });
279
+ export const ToolOutputSchema = BaseResponseSchema.extend({
280
+ type: z
281
+ .string()
282
+ .describe('Type of the tool (dtmf, function, mcp, query, etc.)'),
283
+ name: z.string().describe('Name of the tool'),
284
+ description: z.string().describe('Description of the tool'),
213
285
  });
@@ -0,0 +1,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { VapiClient } from '@vapi-ai/server-sdk';
3
+ export declare const registerAssistantTools: (server: McpServer, vapiClient: VapiClient) => void;
4
+ //# sourceMappingURL=assistant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant.d.ts","sourceRoot":"","sources":["../../src/tools/assistant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAQ,MAAM,qBAAqB,CAAC;AAavD,eAAO,MAAM,sBAAsB,GACjC,QAAQ,SAAS,EACjB,YAAY,UAAU,SA2EvB,CAAC"}
@@ -1,5 +1,5 @@
1
- import { CreateAssistantInputSchema, GetAssistantInputSchema, } from '../schemas/index.js';
2
- import { transformAssistantInput, transformAssistantOutput, } from '../transformers/index.js';
1
+ import { CreateAssistantInputSchema, GetAssistantInputSchema, UpdateAssistantInputSchema, } from '../schemas/index.js';
2
+ import { transformAssistantInput, transformAssistantOutput, transformUpdateAssistantInput, } from '../transformers/index.js';
3
3
  import { createToolHandler } from './utils.js';
4
4
  export const registerAssistantTools = (server, vapiClient) => {
5
5
  server.tool('list_assistants', 'Lists all Vapi assistants', {}, createToolHandler(async () => {
@@ -29,4 +29,23 @@ export const registerAssistantTools = (server, vapiClient) => {
29
29
  throw error;
30
30
  }
31
31
  }));
32
+ server.tool('update_assistant', 'Updates an existing Vapi assistant', UpdateAssistantInputSchema.shape, createToolHandler(async (data) => {
33
+ const assistantId = data.assistantId;
34
+ try {
35
+ // First check if the assistant exists
36
+ const existingAssistant = await vapiClient.assistants.get(assistantId);
37
+ if (!existingAssistant) {
38
+ throw new Error(`Assistant with ID ${assistantId} not found`);
39
+ }
40
+ // Transform the update data
41
+ const updateAssistantDto = transformUpdateAssistantInput(data);
42
+ // Update the assistant
43
+ const updatedAssistant = await vapiClient.assistants.update(assistantId, updateAssistantDto);
44
+ return transformAssistantOutput(updatedAssistant);
45
+ }
46
+ catch (error) {
47
+ console.error(`Error updating assistant: ${error.message}`);
48
+ throw error;
49
+ }
50
+ }));
32
51
  };
@@ -0,0 +1,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { VapiClient } from '@vapi-ai/server-sdk';
3
+ export declare const registerCallTools: (server: McpServer, vapiClient: VapiClient) => void;
4
+ //# sourceMappingURL=call.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../src/tools/call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAQ,MAAM,qBAAqB,CAAC;AASvD,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,SAAS,EACjB,YAAY,UAAU,SAgCvB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { VapiClient } from '@vapi-ai/server-sdk';
3
+ export declare const registerAllTools: (server: McpServer, vapiClient: VapiClient) => void;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAOjD,eAAO,MAAM,gBAAgB,GAAI,QAAQ,SAAS,EAAE,YAAY,UAAU,SAKzE,CAAC"}
@@ -1,8 +1,10 @@
1
1
  import { registerAssistantTools } from './assistant.js';
2
2
  import { registerCallTools } from './call.js';
3
3
  import { registerPhoneNumberTools } from './phone-number.js';
4
+ import { registerToolTools } from './tool.js';
4
5
  export const registerAllTools = (server, vapiClient) => {
5
6
  registerAssistantTools(server, vapiClient);
6
7
  registerCallTools(server, vapiClient);
7
8
  registerPhoneNumberTools(server, vapiClient);
9
+ registerToolTools(server, vapiClient);
8
10
  };
@@ -0,0 +1,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { VapiClient } from '@vapi-ai/server-sdk';
3
+ export declare const registerPhoneNumberTools: (server: McpServer, vapiClient: VapiClient) => void;
4
+ //# sourceMappingURL=phone-number.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phone-number.d.ts","sourceRoot":"","sources":["../../src/tools/phone-number.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMjD,eAAO,MAAM,wBAAwB,GACnC,QAAQ,SAAS,EACjB,YAAY,UAAU,SAsBvB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { VapiClient } from '@vapi-ai/server-sdk';
3
+ export declare const registerToolTools: (server: McpServer, vapiClient: VapiClient) => void;
4
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/tools/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAQ,MAAM,qBAAqB,CAAC;AAMvD,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,SAAS,EACjB,YAAY,UAAU,SAqBvB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { GetToolInputSchema } from '../schemas/index.js';
2
+ import { transformToolOutput } from '../transformers/index.js';
3
+ import { createToolHandler } from './utils.js';
4
+ export const registerToolTools = (server, vapiClient) => {
5
+ server.tool('list_tools', 'Lists all Vapi tools', {}, createToolHandler(async () => {
6
+ const tools = await vapiClient.tools.list({ limit: 10 });
7
+ return tools.map(transformToolOutput);
8
+ }));
9
+ server.tool('get_tool', 'Gets details of a specific tool', GetToolInputSchema.shape, createToolHandler(async (data) => {
10
+ const tool = await vapiClient.tools.get(data.toolId);
11
+ return transformToolOutput(tool);
12
+ }));
13
+ };
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ export type ToolResponse = {
3
+ content: Array<{
4
+ type: 'text';
5
+ text: string;
6
+ }>;
7
+ };
8
+ export declare function createSuccessResponse(data: any): ToolResponse;
9
+ export declare function createErrorResponse(error: any): ToolResponse;
10
+ export declare function createToolHandler<T>(handler: (params: T) => Promise<any>): (params: T) => Promise<ToolResponse>;
11
+ export declare function createParamsSchema<T>(schema: z.ZodType<T>): any;
12
+ export declare function createIdParamSchema(paramName: string, description: string): any;
13
+ export declare const withErrorHandling: <T>(handler: () => Promise<T>) => Promise<ToolResponse>;
14
+ export declare const filterResponseWithSchema: <T>(data: any, schema: z.ZodType<T>) => T;
15
+ export declare const withSchemaFiltering: <T>(handler: () => Promise<any>, schema: z.ZodType<T>) => Promise<ToolResponse>;
16
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,GAAG,GAAG,YAAY,CAS7D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,GAAG,YAAY,CAU5D;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,GACnC,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAStC;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAO/D;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,GAAG,CAOL;AAED,eAAO,MAAM,iBAAiB,GAAI,CAAC,EACjC,SAAS,MAAM,OAAO,CAAC,CAAC,CAAC,KACxB,OAAO,CAAC,YAAY,CAItB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,CAAC,EACxC,MAAM,GAAG,EACT,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KACnB,CAKF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,CAAC,EACnC,SAAS,MAAM,OAAO,CAAC,GAAG,CAAC,EAC3B,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KACnB,OAAO,CAAC,YAAY,CAOtB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Vapi } from '@vapi-ai/server-sdk';
2
+ import { z } from 'zod';
3
+ import { CreateAssistantInputSchema, CallInputSchema, AssistantOutputSchema, CallOutputSchema, PhoneNumberOutputSchema, ToolOutputSchema, UpdateAssistantInputSchema } from '../schemas/index.js';
4
+ export declare function transformAssistantInput(input: z.infer<typeof CreateAssistantInputSchema>): Vapi.CreateAssistantDto;
5
+ export declare function transformUpdateAssistantInput(input: z.infer<typeof UpdateAssistantInputSchema>): Vapi.UpdateAssistantDto;
6
+ export declare function transformAssistantOutput(assistant: Vapi.Assistant): z.infer<typeof AssistantOutputSchema>;
7
+ export declare function transformCallInput(input: z.infer<typeof CallInputSchema>): Vapi.CreateCallDto;
8
+ export declare function transformCallOutput(call: Vapi.Call): z.infer<typeof CallOutputSchema>;
9
+ export declare function transformPhoneNumberOutput(phoneNumber: any): z.infer<typeof PhoneNumberOutputSchema>;
10
+ export declare function transformToolOutput(tool: any): z.infer<typeof ToolOutputSchema>;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transformers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,gBAAgB,EAChB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAI7B,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,GAChD,IAAI,CAAC,kBAAkB,CA2CzB;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,GAChD,IAAI,CAAC,kBAAkB,CAiEzB;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,IAAI,CAAC,SAAS,GACxB,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAqBvC;AA2BD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,GACrC,IAAI,CAAC,aAAa,CAmBpB;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,CAAC,IAAI,GACd,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAgBlC;AAID,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,GAAG,GACf,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CASzC;AAID,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,GAAG,GACR,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CASlC"}
@@ -7,6 +7,9 @@ export function transformAssistantInput(input) {
7
7
  provider: input.llm.provider,
8
8
  model: input.llm.model,
9
9
  };
10
+ if (input.toolIds && input.toolIds.length > 0) {
11
+ assistantDto.model.toolIds = input.toolIds;
12
+ }
10
13
  if (input.instructions) {
11
14
  assistantDto.model.messages = [
12
15
  {
@@ -32,6 +35,64 @@ export function transformAssistantInput(input) {
32
35
  }
33
36
  return assistantDto;
34
37
  }
38
+ export function transformUpdateAssistantInput(input) {
39
+ const updateDto = {};
40
+ if (input.name) {
41
+ updateDto.name = input.name;
42
+ }
43
+ if (input.llm) {
44
+ updateDto.model = {
45
+ provider: input.llm.provider,
46
+ model: input.llm.model,
47
+ };
48
+ if (input.toolIds && input.toolIds.length > 0) {
49
+ updateDto.model.toolIds = input.toolIds;
50
+ }
51
+ if (input.instructions) {
52
+ updateDto.model.messages = [
53
+ {
54
+ role: 'system',
55
+ content: input.instructions,
56
+ },
57
+ ];
58
+ }
59
+ }
60
+ else {
61
+ if (input.toolIds && input.toolIds.length > 0) {
62
+ updateDto.model = { toolIds: input.toolIds };
63
+ }
64
+ if (input.instructions) {
65
+ if (!updateDto.model)
66
+ updateDto.model = {};
67
+ updateDto.model.messages = [
68
+ {
69
+ role: 'system',
70
+ content: input.instructions,
71
+ },
72
+ ];
73
+ }
74
+ }
75
+ if (input.transcriber) {
76
+ updateDto.transcriber = {
77
+ provider: input.transcriber.provider,
78
+ ...(input.transcriber.model ? { model: input.transcriber.model } : {}),
79
+ };
80
+ }
81
+ if (input.voice) {
82
+ updateDto.voice = {
83
+ provider: input.voice.provider,
84
+ voiceId: input.voice.voiceId,
85
+ ...(input.voice.model ? { model: input.voice.model } : {}),
86
+ };
87
+ }
88
+ if (input.firstMessage) {
89
+ updateDto.firstMessage = input.firstMessage;
90
+ }
91
+ if (input.firstMessageMode) {
92
+ updateDto.firstMessageMode = input.firstMessageMode;
93
+ }
94
+ return updateDto;
95
+ }
35
96
  export function transformAssistantOutput(assistant) {
36
97
  return {
37
98
  id: assistant.id,
@@ -51,6 +112,7 @@ export function transformAssistantOutput(assistant) {
51
112
  provider: assistant.transcriber?.provider || 'deepgram',
52
113
  model: getAssistantTranscriberModel(assistant.transcriber) || 'nova-3',
53
114
  },
115
+ toolIds: assistant.model?.toolIds || [],
54
116
  };
55
117
  }
56
118
  function getAssistantVoiceId(voice) {
@@ -83,6 +145,13 @@ export function transformCallInput(input) {
83
145
  },
84
146
  }
85
147
  : {}),
148
+ ...(input.scheduledAt
149
+ ? {
150
+ schedulePlan: {
151
+ earliestAt: input.scheduledAt,
152
+ },
153
+ }
154
+ : {}),
86
155
  };
87
156
  }
88
157
  export function transformCallOutput(call) {
@@ -99,15 +168,28 @@ export function transformCallOutput(call) {
99
168
  phoneNumber: call.customer.number || '',
100
169
  }
101
170
  : undefined,
171
+ scheduledAt: call.schedulePlan?.earliestAt,
102
172
  };
103
173
  }
104
174
  // ===== Phone Number Transformers =====
105
175
  export function transformPhoneNumberOutput(phoneNumber) {
106
176
  return {
107
177
  id: phoneNumber.id,
178
+ name: phoneNumber.name,
108
179
  createdAt: phoneNumber.createdAt,
109
180
  updatedAt: phoneNumber.updatedAt,
110
- phoneNumber: phoneNumber.phoneNumber,
181
+ phoneNumber: phoneNumber.number,
111
182
  status: phoneNumber.status,
112
183
  };
113
184
  }
185
+ // ===== Tool Transformers =====
186
+ export function transformToolOutput(tool) {
187
+ return {
188
+ id: tool.id,
189
+ createdAt: tool.createdAt,
190
+ updatedAt: tool.updatedAt,
191
+ type: tool.type || '',
192
+ name: tool.function?.name || '',
193
+ description: tool.function?.description || '',
194
+ };
195
+ }
@@ -0,0 +1,2 @@
1
+ export declare function parseToolResponse(response: any): any;
2
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CA6BpD"}
@@ -6,8 +6,8 @@ export function parseToolResponse(response) {
6
6
  if (response.content && Array.isArray(response.content)) {
7
7
  const textContent = response.content.find((item) => item.type === 'text')?.text;
8
8
  if (textContent) {
9
- // Check if it's an error message first
10
- if (textContent.startsWith('Error:') || textContent.includes('error')) {
9
+ // Check if it's an error message first - only if it starts with 'Error:'
10
+ if (textContent.startsWith('Error:')) {
11
11
  return { error: textContent };
12
12
  }
13
13
  try {
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@vapi-ai/mcp-server",
3
3
  "description": "Vapi MCP Server",
4
- "version": "0.0.3",
4
+ "version": "0.0.6",
5
5
  "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
6
7
  "type": "module",
7
8
  "author": {
8
9
  "name": "Vapi AI",
@@ -36,17 +37,20 @@
36
37
  "build": "tsc && shx chmod +x dist/*.js",
37
38
  "start": "node dist/index.js",
38
39
  "dev": "tsx watch src/index.ts",
39
- "dev:example": "tsx examples/client.ts",
40
+ "dev:stdio-example": "tsx examples/stdio-client.ts",
41
+ "dev:sse-example": "tsx examples/sse-client.ts",
40
42
  "inspector": "mcp-inspector",
41
43
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
42
44
  "test:unit": "NODE_OPTIONS=--experimental-vm-modules jest src/tests/mcp-server-mock.test.ts",
43
45
  "test:e2e": "NODE_OPTIONS=--experimental-vm-modules jest src/tests/mcp-server-e2e.test.ts"
44
46
  },
45
47
  "files": [
46
- "dist"
48
+ "dist",
49
+ "dist/**/*.d.ts",
50
+ "dist/**/*.d.ts.map"
47
51
  ],
48
52
  "dependencies": {
49
- "@modelcontextprotocol/sdk": "^1.9.0",
53
+ "@modelcontextprotocol/sdk": "^1.11.0",
50
54
  "@vapi-ai/server-sdk": "^0.5.2",
51
55
  "dotenv": "^16.4.7",
52
56
  "zod": "^3.24.2",