elevenlabs-voice-agent-mcp 1.0.0 → 1.0.2

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 (45) hide show
  1. package/.claude/settings.local.json +23 -0
  2. package/.env.example +3 -0
  3. package/AGENTS.md +37 -0
  4. package/CLAUDE.md +233 -0
  5. package/README.md +9 -30
  6. package/call-exact-format.ts +66 -0
  7. package/call-wait-null.ts +71 -0
  8. package/create-agent-simple.ts +84 -0
  9. package/create-new-agent.ts +98 -0
  10. package/demo-agent-system-prompt.xml +166 -0
  11. package/dist/index.js +1 -3
  12. package/dist/index.js.map +1 -1
  13. package/elevenlabs-voice-agent-mcp-1.0.0.tgz +0 -0
  14. package/em_positive_leads.csv +25 -0
  15. package/list-resources.ts +93 -0
  16. package/make-call-now.ts +66 -0
  17. package/make-test-call.ts +80 -0
  18. package/openapi.json +3238 -0
  19. package/package.json +3 -33
  20. package/src/constants.ts +62 -0
  21. package/src/index.ts +141 -0
  22. package/src/schemas/agent-schemas.ts +193 -0
  23. package/src/schemas/batch-calling-schemas.ts +96 -0
  24. package/src/schemas/common-schemas.ts +83 -0
  25. package/src/schemas/conversation-schemas.ts +44 -0
  26. package/src/schemas/outbound-schemas.ts +70 -0
  27. package/src/schemas/phone-number-schemas.ts +140 -0
  28. package/src/schemas/tool-schemas.ts +161 -0
  29. package/src/services/elevenlabs-api.ts +113 -0
  30. package/src/services/formatters.ts +623 -0
  31. package/src/tools/agent-tools.ts +425 -0
  32. package/src/tools/batch-calling-tools.ts +237 -0
  33. package/src/tools/conversation-tools.ts +167 -0
  34. package/src/tools/knowledge-tools.ts +73 -0
  35. package/src/tools/outbound-tools.ts +95 -0
  36. package/src/tools/phone-number-tools.ts +346 -0
  37. package/src/tools/tool-tools.ts +195 -0
  38. package/src/tools/utility-tools.ts +147 -0
  39. package/src/types.ts +327 -0
  40. package/src/utils/error-handlers.ts +98 -0
  41. package/src/utils/truncation.ts +97 -0
  42. package/test-call-wait-for-hello.ts +76 -0
  43. package/test-call.json +5 -0
  44. package/tsconfig.json +21 -0
  45. package/LICENSE +0 -21
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Zod validation schemas for outbound calling operations
3
+ *
4
+ * Provides strict input validation for making single outbound calls via Twilio.
5
+ */
6
+
7
+ import { z } from "zod";
8
+ import { ResponseFormatSchema, AgentIdSchema } from "./common-schemas.js";
9
+
10
+ /**
11
+ * Phone number schema with E.164 format validation
12
+ */
13
+ export const PhoneNumberSchema = z.string()
14
+ .min(1, "Phone number is required")
15
+ .regex(/^\+?[1-9]\d{1,14}$/, "Phone number must be in E.164 format (e.g., +1234567890)")
16
+ .describe("Phone number in E.164 format (e.g., '+1234567890')");
17
+
18
+ /**
19
+ * Phone number ID schema
20
+ */
21
+ export const PhoneNumberIdSchema = z.string()
22
+ .min(1, "Phone number ID is required")
23
+ .regex(/^[a-zA-Z0-9_-]+$/, "Phone number ID must contain only alphanumeric characters, hyphens, and underscores")
24
+ .describe("Unique identifier for the phone number");
25
+
26
+ /**
27
+ * Config overrides schema for conversation customization
28
+ */
29
+ export const ConfigOverridesSchema = z.object({
30
+ agent: z.object({
31
+ first_message: z.string().optional(),
32
+ system_prompt: z.string().optional(),
33
+ language: z.string().optional()
34
+ }).optional(),
35
+ tts: z.object({
36
+ voice_id: z.string().optional(),
37
+ model_id: z.string().optional()
38
+ }).optional(),
39
+ turn: z.object({
40
+ mode: z.string().optional()
41
+ }).optional(),
42
+ conversation: z.object({
43
+ max_duration_seconds: z.number().int().positive().optional()
44
+ }).optional()
45
+ }).optional().describe("Configuration overrides for this specific call");
46
+
47
+ /**
48
+ * Conversation initiation data schema
49
+ */
50
+ export const ConversationInitDataSchema = z.record(z.any())
51
+ .optional()
52
+ .describe("Dynamic variables and configuration overrides for personalization");
53
+
54
+ /**
55
+ * Schema for starting an outbound call
56
+ */
57
+ export const StartOutboundCallSchema = z.object({
58
+ agent_id: AgentIdSchema,
59
+
60
+ agent_phone_number_id: PhoneNumberIdSchema,
61
+
62
+ to_number: PhoneNumberSchema
63
+ .describe("Destination phone number to call"),
64
+
65
+ conversation_initiation_client_data: z.record(z.any())
66
+ .optional()
67
+ .describe("Personalization data including dynamic_variables object (e.g., {dynamic_variables: {name: 'John', user_id: '123'}})"),
68
+
69
+ response_format: ResponseFormatSchema
70
+ }).passthrough();
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Zod validation schemas for phone number management operations
3
+ *
4
+ * Provides strict input validation for listing, importing, updating,
5
+ * and deleting phone numbers connected to voice agents.
6
+ */
7
+
8
+ import { z } from "zod";
9
+ import { ResponseFormatSchema, AgentIdSchema } from "./common-schemas.js";
10
+ import { PhoneNumberSchema, PhoneNumberIdSchema } from "./outbound-schemas.js";
11
+
12
+ /**
13
+ * Phone provider enum
14
+ */
15
+ export const PhoneProviderSchema = z.enum(["twilio", "sip_trunk"], {
16
+ errorMap: () => ({ message: "Provider must be 'twilio' or 'sip_trunk'" })
17
+ }).describe("Phone number provider");
18
+
19
+ /**
20
+ * Region ID schema
21
+ */
22
+ export const RegionIdSchema = z.enum(["us1", "ie1", "au1"], {
23
+ errorMap: () => ({ message: "Region must be 'us1', 'ie1', or 'au1'" })
24
+ }).describe("ElevenLabs region identifier");
25
+
26
+ /**
27
+ * Edge location schema
28
+ */
29
+ export const EdgeLocationSchema = z.enum([
30
+ "ashburn", "dublin", "frankfurt", "sao-paulo",
31
+ "singapore", "sydney", "tokyo", "umatilla", "roaming"
32
+ ], {
33
+ errorMap: () => ({ message: "Invalid edge location" })
34
+ }).describe("Twilio edge location");
35
+
36
+ /**
37
+ * LiveKit stack schema
38
+ */
39
+ export const LiveKitStackSchema = z.enum(["standard", "static"], {
40
+ errorMap: () => ({ message: "LiveKit stack must be 'standard' or 'static'" })
41
+ }).describe("LiveKit stack configuration");
42
+
43
+ /**
44
+ * Region config schema for Twilio
45
+ */
46
+ export const RegionConfigSchema = z.object({
47
+ region_id: RegionIdSchema,
48
+ token: z.string().min(1, "Region token is required"),
49
+ edge_location: EdgeLocationSchema
50
+ }).describe("Regional configuration for Twilio phone numbers");
51
+
52
+ /**
53
+ * Schema for listing phone numbers
54
+ */
55
+ export const ListPhoneNumbersSchema = z.object({
56
+ response_format: ResponseFormatSchema
57
+ }).passthrough();
58
+
59
+ /**
60
+ * Schema for getting a phone number
61
+ */
62
+ export const GetPhoneNumberSchema = z.object({
63
+ phone_number_id: PhoneNumberIdSchema,
64
+
65
+ response_format: ResponseFormatSchema
66
+ }).passthrough();
67
+
68
+ /**
69
+ * Schema for importing a Twilio phone number
70
+ */
71
+ export const ImportPhoneNumberSchema = z.object({
72
+ phone_number: PhoneNumberSchema
73
+ .describe("Phone number to import from Twilio"),
74
+
75
+ label: z.string()
76
+ .min(1, "Label is required")
77
+ .max(100, "Label must not exceed 100 characters")
78
+ .describe("Descriptive label for this phone number"),
79
+
80
+ sid: z.string()
81
+ .min(1, "Twilio Account SID is required")
82
+ .describe("Twilio Account SID"),
83
+
84
+ token: z.string()
85
+ .min(1, "Twilio Auth Token is required")
86
+ .describe("Twilio Auth Token"),
87
+
88
+ provider: z.literal("twilio")
89
+ .describe("Must be 'twilio' for Twilio phone numbers"),
90
+
91
+ supports_inbound: z.boolean()
92
+ .default(true)
93
+ .describe("Enable inbound call handling"),
94
+
95
+ supports_outbound: z.boolean()
96
+ .default(true)
97
+ .describe("Enable outbound call capability"),
98
+
99
+ region_config: RegionConfigSchema
100
+ .optional()
101
+ .describe("Optional regional configuration for Twilio"),
102
+
103
+ response_format: ResponseFormatSchema
104
+ }).passthrough();
105
+
106
+ /**
107
+ * Schema for updating a phone number
108
+ */
109
+ export const UpdatePhoneNumberSchema = z.object({
110
+ phone_number_id: PhoneNumberIdSchema,
111
+
112
+ agent_id: AgentIdSchema
113
+ .optional()
114
+ .nullable()
115
+ .describe("Assign or unassign agent (null to unassign)"),
116
+
117
+ inbound_trunk_config: z.record(z.any())
118
+ .optional()
119
+ .nullable()
120
+ .describe("SIP trunk configuration for inbound calls"),
121
+
122
+ outbound_trunk_config: z.record(z.any())
123
+ .optional()
124
+ .nullable()
125
+ .describe("SIP trunk configuration for outbound calls"),
126
+
127
+ livekit_stack: LiveKitStackSchema
128
+ .optional()
129
+ .nullable()
130
+ .describe("LiveKit stack configuration"),
131
+
132
+ response_format: ResponseFormatSchema
133
+ }).passthrough();
134
+
135
+ /**
136
+ * Schema for deleting a phone number
137
+ */
138
+ export const DeletePhoneNumberSchema = z.object({
139
+ phone_number_id: PhoneNumberIdSchema
140
+ }).passthrough();
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Zod validation schemas for tool and knowledge base operations
3
+ *
4
+ * Provides strict input validation for managing agent tools and knowledge bases.
5
+ */
6
+
7
+ import { z } from "zod";
8
+ import { AgentIdSchema, ResponseFormatSchema, URLSchema } from "./common-schemas.js";
9
+
10
+ /**
11
+ * Tool parameter schema
12
+ */
13
+ const ToolParameterSchema = z.object({
14
+ name: z.string()
15
+ .min(1, "Parameter name is required")
16
+ .describe("Name of the parameter"),
17
+
18
+ type: z.enum(["string", "number", "boolean", "object", "array"], {
19
+ errorMap: () => ({ message: "Type must be: string, number, boolean, object, or array" })
20
+ }).describe("Data type of the parameter"),
21
+
22
+ description: z.string()
23
+ .min(1, "Parameter description is required")
24
+ .describe("Description of what this parameter does"),
25
+
26
+ required: z.boolean()
27
+ .describe("Whether this parameter is required"),
28
+
29
+ enum: z.array(z.string())
30
+ .optional()
31
+ .describe("Optional array of allowed values for this parameter")
32
+ }).passthrough();
33
+
34
+ /**
35
+ * Schema for creating a webhook tool
36
+ */
37
+ export const CreateWebhookToolSchema = z.object({
38
+ agent_id: AgentIdSchema,
39
+
40
+ name: z.string()
41
+ .min(1, "Tool name is required")
42
+ .max(64, "Tool name must not exceed 64 characters")
43
+ .regex(/^[a-zA-Z0-9_-]+$/, "Tool name must contain only alphanumeric characters, hyphens, and underscores")
44
+ .describe("Unique name for the tool (e.g., 'check_order_status')"),
45
+
46
+ description: z.string()
47
+ .min(10, "Description must be at least 10 characters")
48
+ .max(500, "Description must not exceed 500 characters")
49
+ .describe("Clear description of what this tool does"),
50
+
51
+ url: URLSchema
52
+ .describe("Webhook URL that will be called when the tool is invoked"),
53
+
54
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"], {
55
+ errorMap: () => ({ message: "Method must be: GET, POST, PUT, PATCH, or DELETE" })
56
+ })
57
+ .default("POST")
58
+ .describe("HTTP method to use (default: POST)"),
59
+
60
+ headers: z.record(z.string(), z.string())
61
+ .optional()
62
+ .describe("Optional custom headers to send with the request"),
63
+
64
+ parameters: z.array(ToolParameterSchema)
65
+ .min(0, "Parameters array is required (can be empty)")
66
+ .describe("Array of parameters the tool accepts"),
67
+
68
+ response_format: ResponseFormatSchema
69
+ }).passthrough();
70
+
71
+ /**
72
+ * Schema for listing tools
73
+ */
74
+ export const ListToolsSchema = z.object({
75
+ agent_id: AgentIdSchema,
76
+ response_format: ResponseFormatSchema
77
+ }).passthrough();
78
+
79
+ /**
80
+ * Schema for deleting a tool
81
+ */
82
+ export const DeleteToolSchema = z.object({
83
+ agent_id: AgentIdSchema,
84
+
85
+ tool_name: z.string()
86
+ .min(1, "Tool name is required")
87
+ .describe("Name of the tool to delete")
88
+ }).passthrough();
89
+
90
+ /**
91
+ * Knowledge base document schema
92
+ */
93
+ const KnowledgeBaseDocumentSchema = z.object({
94
+ type: z.enum(["text", "url"], {
95
+ errorMap: () => ({ message: "Document type must be 'text' or 'url'" })
96
+ }).describe("Type of document to add"),
97
+
98
+ content: z.string()
99
+ .min(1, "Document content is required")
100
+ .describe("For 'text' type: the actual text content. For 'url' type: the URL to fetch"),
101
+
102
+ metadata: z.record(z.string(), z.string())
103
+ .optional()
104
+ .describe("Optional metadata about the document")
105
+ }).passthrough();
106
+
107
+ /**
108
+ * Schema for adding knowledge base documents
109
+ */
110
+ export const AddKnowledgeBaseSchema = z.object({
111
+ agent_id: AgentIdSchema,
112
+
113
+ documents: z.array(KnowledgeBaseDocumentSchema)
114
+ .min(1, "At least one document is required")
115
+ .max(100, "Cannot add more than 100 documents at once")
116
+ .describe("Array of documents to add to the agent's knowledge base"),
117
+
118
+ response_format: ResponseFormatSchema
119
+ }).passthrough();
120
+
121
+ /**
122
+ * Schema for generating widget code
123
+ */
124
+ export const GenerateWidgetCodeSchema = z.object({
125
+ agent_id: AgentIdSchema,
126
+
127
+ color: z.string()
128
+ .regex(/^#[0-9A-Fa-f]{6}$/, "Must be a valid hex color (e.g., #FF5733)")
129
+ .optional()
130
+ .describe("Optional widget color (hex format)"),
131
+
132
+ avatar_url: URLSchema
133
+ .optional()
134
+ .describe("Optional avatar image URL for the widget")
135
+ }).passthrough();
136
+
137
+ /**
138
+ * Schema for listing voices
139
+ */
140
+ export const ListVoicesSchema = z.object({
141
+ language: z.string()
142
+ .optional()
143
+ .describe("Filter by language code (e.g., 'en', 'es')"),
144
+
145
+ gender: z.enum(["male", "female"])
146
+ .optional()
147
+ .describe("Filter by gender"),
148
+
149
+ age: z.enum(["young", "middle_aged", "old"])
150
+ .optional()
151
+ .describe("Filter by age category"),
152
+
153
+ limit: z.number()
154
+ .int()
155
+ .min(1)
156
+ .max(100)
157
+ .default(20)
158
+ .describe("Maximum number of voices to return"),
159
+
160
+ response_format: ResponseFormatSchema
161
+ }).passthrough();
@@ -0,0 +1,113 @@
1
+ /**
2
+ * ElevenLabs API client service
3
+ *
4
+ * Provides core HTTP request functionality for interacting with the
5
+ * ElevenLabs Voice Agent API, including authentication and error handling.
6
+ */
7
+
8
+ import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
9
+ import { API_BASE_URL, REQUEST_TIMEOUT } from "../constants.js";
10
+ import { handleElevenLabsError } from "../utils/error-handlers.js";
11
+
12
+ /**
13
+ * Makes an authenticated request to the ElevenLabs API
14
+ *
15
+ * @param method - HTTP method (GET, POST, PUT, DELETE, etc.)
16
+ * @param endpoint - API endpoint path (e.g., "/convai/agents")
17
+ * @param data - Request body data (for POST, PUT, PATCH)
18
+ * @param params - URL query parameters
19
+ * @returns Response data from the API
20
+ */
21
+ export async function makeElevenLabsRequest<T = unknown>(
22
+ method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
23
+ endpoint: string,
24
+ data?: unknown,
25
+ params?: Record<string, unknown>
26
+ ): Promise<T> {
27
+ const apiKey = process.env.ELEVENLABS_API_KEY;
28
+
29
+ if (!apiKey) {
30
+ throw new Error(
31
+ "ELEVENLABS_API_KEY environment variable is not set. " +
32
+ "Please set it to your ElevenLabs API key."
33
+ );
34
+ }
35
+
36
+ const config: AxiosRequestConfig = {
37
+ method,
38
+ url: `${API_BASE_URL}${endpoint}`,
39
+ headers: {
40
+ "xi-api-key": apiKey,
41
+ "Content-Type": "application/json",
42
+ },
43
+ timeout: REQUEST_TIMEOUT,
44
+ };
45
+
46
+ if (data) {
47
+ config.data = data;
48
+ }
49
+
50
+ if (params) {
51
+ config.params = params;
52
+ }
53
+
54
+ try {
55
+ const response: AxiosResponse<T> = await axios(config);
56
+ return response.data;
57
+ } catch (error) {
58
+ throw new Error(handleElevenLabsError(error));
59
+ }
60
+ }
61
+
62
+ /**
63
+ * GET request helper
64
+ */
65
+ export async function getRequest<T>(
66
+ endpoint: string,
67
+ params?: Record<string, unknown>
68
+ ): Promise<T> {
69
+ return makeElevenLabsRequest<T>("GET", endpoint, undefined, params);
70
+ }
71
+
72
+ /**
73
+ * POST request helper
74
+ */
75
+ export async function postRequest<T>(
76
+ endpoint: string,
77
+ data: unknown,
78
+ params?: Record<string, unknown>
79
+ ): Promise<T> {
80
+ return makeElevenLabsRequest<T>("POST", endpoint, data, params);
81
+ }
82
+
83
+ /**
84
+ * PUT request helper
85
+ */
86
+ export async function putRequest<T>(
87
+ endpoint: string,
88
+ data: unknown,
89
+ params?: Record<string, unknown>
90
+ ): Promise<T> {
91
+ return makeElevenLabsRequest<T>("PUT", endpoint, data, params);
92
+ }
93
+
94
+ /**
95
+ * PATCH request helper
96
+ */
97
+ export async function patchRequest<T>(
98
+ endpoint: string,
99
+ data: unknown,
100
+ params?: Record<string, unknown>
101
+ ): Promise<T> {
102
+ return makeElevenLabsRequest<T>("PATCH", endpoint, data, params);
103
+ }
104
+
105
+ /**
106
+ * DELETE request helper
107
+ */
108
+ export async function deleteRequest<T>(
109
+ endpoint: string,
110
+ params?: Record<string, unknown>
111
+ ): Promise<T> {
112
+ return makeElevenLabsRequest<T>("DELETE", endpoint, undefined, params);
113
+ }