elevenlabs-voice-agent-mcp 1.0.0 → 1.0.1

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 (44) 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 +0 -0
  12. package/elevenlabs-voice-agent-mcp-1.0.0.tgz +0 -0
  13. package/em_positive_leads.csv +25 -0
  14. package/list-resources.ts +93 -0
  15. package/make-call-now.ts +66 -0
  16. package/make-test-call.ts +80 -0
  17. package/openapi.json +3238 -0
  18. package/package.json +3 -33
  19. package/src/constants.ts +62 -0
  20. package/src/index.ts +143 -0
  21. package/src/schemas/agent-schemas.ts +193 -0
  22. package/src/schemas/batch-calling-schemas.ts +96 -0
  23. package/src/schemas/common-schemas.ts +83 -0
  24. package/src/schemas/conversation-schemas.ts +44 -0
  25. package/src/schemas/outbound-schemas.ts +70 -0
  26. package/src/schemas/phone-number-schemas.ts +140 -0
  27. package/src/schemas/tool-schemas.ts +161 -0
  28. package/src/services/elevenlabs-api.ts +113 -0
  29. package/src/services/formatters.ts +623 -0
  30. package/src/tools/agent-tools.ts +425 -0
  31. package/src/tools/batch-calling-tools.ts +237 -0
  32. package/src/tools/conversation-tools.ts +167 -0
  33. package/src/tools/knowledge-tools.ts +73 -0
  34. package/src/tools/outbound-tools.ts +95 -0
  35. package/src/tools/phone-number-tools.ts +346 -0
  36. package/src/tools/tool-tools.ts +195 -0
  37. package/src/tools/utility-tools.ts +147 -0
  38. package/src/types.ts +327 -0
  39. package/src/utils/error-handlers.ts +98 -0
  40. package/src/utils/truncation.ts +97 -0
  41. package/test-call-wait-for-hello.ts +76 -0
  42. package/test-call.json +5 -0
  43. package/tsconfig.json +21 -0
  44. package/LICENSE +0 -21
@@ -0,0 +1,425 @@
1
+ /**
2
+ * Agent management tools
3
+ *
4
+ * MCP tools for creating, retrieving, updating, deleting, and listing voice agents.
5
+ */
6
+
7
+ import { z } from "zod";
8
+ import { getRequest, postRequest, patchRequest, deleteRequest } from "../services/elevenlabs-api.js";
9
+ import { formatResponse } from "../services/formatters.js";
10
+ import { Agent, PaginatedResponse, ResponseFormat } from "../types.js";
11
+ import {
12
+ CreateAgentSchema,
13
+ GetAgentSchema,
14
+ UpdateAgentSchema,
15
+ DeleteAgentSchema,
16
+ ListAgentsSchema
17
+ } from "../schemas/agent-schemas.js";
18
+
19
+ /**
20
+ * Creates a new ElevenLabs Voice Agent
21
+ */
22
+ export const elevenlabs_create_agent = {
23
+ name: "elevenlabs_create_agent",
24
+ description: `Create a new ElevenLabs Voice Agent with specified configuration.
25
+
26
+ This tool creates a complete voice agent with conversation settings, including the AI model, voice configuration, ASR settings, and initial behavior. It does NOT start conversations or deploy the agent - it only creates the configuration.
27
+
28
+ Args:
29
+ - name (string): Display name for the agent (max 100 chars)
30
+ - prompt (string): System prompt defining behavior (10-5000 chars)
31
+ - llm (string): AI model to use (default: "gpt-4o-mini")
32
+ Options: gpt-4o, gpt-4o-mini, claude-3-5-sonnet-20241022, claude-3-5-haiku-20241022, gemini-2.0-flash-exp
33
+ - voice_id (string): ElevenLabs voice ID (default: "21m00Tcm4TlvDq8ikWAM" - Rachel)
34
+ - voice_model (string): Voice synthesis model (default: "eleven_flash_v2_5")
35
+ Options: eleven_turbo_v2_5, eleven_flash_v2_5, eleven_multilingual_v2
36
+ - first_message (string): Optional greeting message (max 500 chars)
37
+ - language (string): Primary language code (default: "en")
38
+ - temperature (number): LLM temperature 0-2 for response randomness (higher = more creative)
39
+ - max_tokens (number): Maximum tokens for LLM responses (1-4096)
40
+ - stability (number): Voice stability 0-1 (higher = more consistent)
41
+ - similarity_boost (number): Voice similarity boost 0-1 (higher = closer to original)
42
+ - widget_color (string): Widget theme color in hex format (e.g., "#FF5733")
43
+ - widget_avatar_url (string): Widget avatar image URL
44
+ - response_format ('markdown' | 'json'): Output format
45
+
46
+ Returns:
47
+ For JSON format: Complete agent object with agent_id, name, conversation_config, created_at
48
+ For Markdown format: Formatted agent details with configuration summary
49
+
50
+ Examples:
51
+ - Use when: "Create a customer service agent for tech support"
52
+ - Use when: "Set up a voice agent for appointment scheduling"
53
+ - Don't use when: You want to test an existing agent (use elevenlabs_generate_widget_code)
54
+ - Don't use when: You want to modify an agent (use elevenlabs_update_agent)
55
+
56
+ Error Handling:
57
+ - Returns "Error: Invalid voice_id" if voice doesn't exist
58
+ - Returns "Error: Invalid API key" if authentication fails
59
+ - Returns "Error: Rate limit exceeded" if too many requests (wait 60s and retry)`,
60
+
61
+ zodSchema: CreateAgentSchema,
62
+
63
+ annotations: {
64
+ readOnlyHint: false,
65
+ destructiveHint: false,
66
+ idempotentHint: false,
67
+ openWorldHint: true
68
+ },
69
+
70
+ handler: async (args: unknown) => {
71
+ const parsed = CreateAgentSchema.parse(args);
72
+
73
+ // Build agent configuration
74
+ const agentData = {
75
+ name: parsed.name,
76
+ conversation_config: {
77
+ agent: {
78
+ prompt: {
79
+ prompt: parsed.prompt,
80
+ llm: parsed.llm,
81
+ ...(parsed.temperature !== undefined && { temperature: parsed.temperature }),
82
+ ...(parsed.max_tokens !== undefined && { max_tokens: parsed.max_tokens })
83
+ },
84
+ ...(parsed.first_message && { first_message: parsed.first_message }),
85
+ language: parsed.language
86
+ },
87
+ tts: {
88
+ voice_id: parsed.voice_id,
89
+ model_id: parsed.voice_model,
90
+ ...(parsed.stability !== undefined && { stability: parsed.stability }),
91
+ ...(parsed.similarity_boost !== undefined && { similarity_boost: parsed.similarity_boost })
92
+ }
93
+ },
94
+ ...(parsed.widget_color || parsed.widget_avatar_url ? {
95
+ platform_settings: {
96
+ widget: {
97
+ ...(parsed.widget_color && { color: parsed.widget_color }),
98
+ ...(parsed.widget_avatar_url && { avatar_url: parsed.widget_avatar_url })
99
+ }
100
+ }
101
+ } : {})
102
+ };
103
+
104
+ const agent = await postRequest<Agent>("/convai/agents", agentData);
105
+
106
+ return {
107
+ content: [
108
+ {
109
+ type: "text",
110
+ text: formatResponse(agent, parsed.response_format, "agent")
111
+ }
112
+ ]
113
+ };
114
+ }
115
+ };
116
+
117
+ /**
118
+ * Retrieves an agent by ID
119
+ */
120
+ export const elevenlabs_get_agent = {
121
+ name: "elevenlabs_get_agent",
122
+ description: `Retrieve complete configuration for an existing ElevenLabs Voice Agent.
123
+
124
+ This tool fetches all details about an agent including its conversation configuration, tools, knowledge base, and platform settings. Use this to inspect an agent before modifying it or to check current settings.
125
+
126
+ Args:
127
+ - agent_id (string): Unique agent identifier (e.g., 'ag_abc123')
128
+ - response_format ('markdown' | 'json'): Output format
129
+
130
+ Returns:
131
+ Complete agent configuration including prompt, LLM settings, voice configuration, tools, and knowledge base.
132
+
133
+ Examples:
134
+ - Use when: "Show me the configuration for agent ag_abc123"
135
+ - Use when: "What's the current prompt for this agent?"
136
+ - Don't use when: You want to list all agents (use elevenlabs_list_agents)
137
+
138
+ Error Handling:
139
+ - Returns "Error: Agent not found" if agent_id doesn't exist
140
+ - Returns "Error: Invalid API key" if authentication fails`,
141
+
142
+ zodSchema: GetAgentSchema,
143
+
144
+ annotations: {
145
+ readOnlyHint: true,
146
+ destructiveHint: false,
147
+ idempotentHint: true,
148
+ openWorldHint: true
149
+ },
150
+
151
+ handler: async (args: unknown) => {
152
+ const parsed = GetAgentSchema.parse(args);
153
+ const agent = await getRequest<Agent>(`/convai/agents/${parsed.agent_id}`);
154
+
155
+ return {
156
+ content: [
157
+ {
158
+ type: "text",
159
+ text: formatResponse(agent, parsed.response_format, "agent")
160
+ }
161
+ ]
162
+ };
163
+ }
164
+ };
165
+
166
+ /**
167
+ * Updates an existing agent
168
+ */
169
+ export const elevenlabs_update_agent = {
170
+ name: "elevenlabs_update_agent",
171
+ description: `Update an existing ElevenLabs Voice Agent's configuration.
172
+
173
+ This tool modifies one or more settings of an existing agent. You only need to provide the fields you want to change - all other settings will remain the same. Changes take effect immediately for new conversations.
174
+
175
+ Args:
176
+ - agent_id (string): Unique agent identifier (e.g., 'ag_abc123')
177
+ - name (string): Updated display name (max 100 chars)
178
+ - prompt (string): Updated system prompt (10-5000 chars)
179
+ - llm (string): Updated AI model
180
+ - voice_id (string): Updated voice ID
181
+ - voice_model (string): Updated voice model
182
+ - first_message (string): Updated greeting (max 500 chars)
183
+ - language (string): Updated language code
184
+ - temperature (number): Updated temperature (0-2)
185
+ - max_tokens (number): Updated max tokens (1-4096)
186
+ - stability (number): Updated voice stability (0-1)
187
+ - similarity_boost (number): Updated similarity boost (0-1)
188
+ - widget_color (string): Updated widget color
189
+ - widget_avatar_url (string): Updated widget avatar URL
190
+ - response_format ('markdown' | 'json'): Output format
191
+
192
+ Returns:
193
+ Updated agent configuration.
194
+
195
+ Examples:
196
+ - Use when: "Change the agent's voice to voice ID xyz123"
197
+ - Use when: "Update the system prompt to be more friendly"
198
+ - Use when: "Switch the agent to use Claude instead of GPT"
199
+ - Don't use when: You want to create a new agent (use elevenlabs_create_agent)
200
+
201
+ Error Handling:
202
+ - Returns "Error: Agent not found" if agent_id doesn't exist
203
+ - Returns "Error: Invalid voice_id" if new voice doesn't exist`,
204
+
205
+ zodSchema: UpdateAgentSchema,
206
+
207
+ annotations: {
208
+ readOnlyHint: false,
209
+ destructiveHint: false,
210
+ idempotentHint: true,
211
+ openWorldHint: true
212
+ },
213
+
214
+ handler: async (args: unknown) => {
215
+ const parsed = UpdateAgentSchema.parse(args);
216
+
217
+ // Get current agent config
218
+ const currentAgent = await getRequest<Agent>(`/convai/agents/${parsed.agent_id}`);
219
+
220
+ // Build update payload with only changed fields
221
+ const updateData: Record<string, unknown> = {};
222
+
223
+ if (parsed.name !== undefined) {
224
+ updateData.name = parsed.name;
225
+ }
226
+
227
+ // Build conversation config updates
228
+ const conversationConfigUpdates: Record<string, unknown> = {
229
+ agent: { ...currentAgent.conversation_config.agent } as Record<string, unknown>,
230
+ tts: { ...currentAgent.conversation_config.tts } as Record<string, unknown>
231
+ };
232
+
233
+ let hasConversationConfigChanges = false;
234
+
235
+ // Agent updates
236
+ if (parsed.prompt !== undefined || parsed.llm !== undefined ||
237
+ parsed.temperature !== undefined || parsed.max_tokens !== undefined) {
238
+ conversationConfigUpdates.agent = {
239
+ ...(conversationConfigUpdates.agent as Record<string, unknown>),
240
+ prompt: {
241
+ ...(currentAgent.conversation_config.agent.prompt),
242
+ ...(parsed.prompt !== undefined && { prompt: parsed.prompt }),
243
+ ...(parsed.llm !== undefined && { llm: parsed.llm }),
244
+ ...(parsed.temperature !== undefined && { temperature: parsed.temperature }),
245
+ ...(parsed.max_tokens !== undefined && { max_tokens: parsed.max_tokens })
246
+ }
247
+ };
248
+ hasConversationConfigChanges = true;
249
+ }
250
+
251
+ if (parsed.first_message !== undefined) {
252
+ (conversationConfigUpdates.agent as Record<string, unknown>).first_message = parsed.first_message;
253
+ hasConversationConfigChanges = true;
254
+ }
255
+
256
+ if (parsed.language !== undefined) {
257
+ (conversationConfigUpdates.agent as Record<string, unknown>).language = parsed.language;
258
+ hasConversationConfigChanges = true;
259
+ }
260
+
261
+ // TTS updates
262
+ if (parsed.voice_id !== undefined || parsed.voice_model !== undefined ||
263
+ parsed.stability !== undefined || parsed.similarity_boost !== undefined) {
264
+ conversationConfigUpdates.tts = {
265
+ ...(conversationConfigUpdates.tts as Record<string, unknown>),
266
+ ...(parsed.voice_id !== undefined && { voice_id: parsed.voice_id }),
267
+ ...(parsed.voice_model !== undefined && { model_id: parsed.voice_model }),
268
+ ...(parsed.stability !== undefined && { stability: parsed.stability }),
269
+ ...(parsed.similarity_boost !== undefined && { similarity_boost: parsed.similarity_boost })
270
+ };
271
+ hasConversationConfigChanges = true;
272
+ }
273
+
274
+ if (hasConversationConfigChanges) {
275
+ updateData.conversation_config = conversationConfigUpdates;
276
+ }
277
+
278
+ // Widget updates
279
+ if (parsed.widget_color !== undefined || parsed.widget_avatar_url !== undefined) {
280
+ updateData.platform_settings = {
281
+ ...(currentAgent.platform_settings || {}),
282
+ widget: {
283
+ ...(currentAgent.platform_settings?.widget || {}),
284
+ ...(parsed.widget_color !== undefined && { color: parsed.widget_color }),
285
+ ...(parsed.widget_avatar_url !== undefined && { avatar_url: parsed.widget_avatar_url })
286
+ }
287
+ };
288
+ }
289
+
290
+ const updatedAgent = await patchRequest<Agent>(
291
+ `/convai/agents/${parsed.agent_id}`,
292
+ updateData
293
+ );
294
+
295
+ return {
296
+ content: [
297
+ {
298
+ type: "text",
299
+ text: formatResponse(updatedAgent, parsed.response_format, "agent")
300
+ }
301
+ ]
302
+ };
303
+ }
304
+ };
305
+
306
+ /**
307
+ * Deletes an agent
308
+ */
309
+ export const elevenlabs_delete_agent = {
310
+ name: "elevenlabs_delete_agent",
311
+ description: `Delete an ElevenLabs Voice Agent permanently.
312
+
313
+ This tool permanently removes an agent and all its configuration. This action CANNOT be undone. All conversations associated with this agent will remain accessible, but the agent itself will be deleted.
314
+
315
+ Args:
316
+ - agent_id (string): Unique agent identifier to delete (e.g., 'ag_abc123')
317
+
318
+ Returns:
319
+ Confirmation message indicating successful deletion.
320
+
321
+ Examples:
322
+ - Use when: "Delete the test agent ag_test123"
323
+ - Use when: "Remove agent ag_old456 permanently"
324
+ - Don't use when: You want to temporarily disable an agent (no disable feature - just don't use it)
325
+ - Don't use when: You're not sure - this is permanent!
326
+
327
+ Error Handling:
328
+ - Returns "Error: Agent not found" if agent_id doesn't exist
329
+ - Returns "Error: Invalid API key" if authentication fails`,
330
+
331
+ zodSchema: DeleteAgentSchema,
332
+
333
+ annotations: {
334
+ readOnlyHint: false,
335
+ destructiveHint: true,
336
+ idempotentHint: true,
337
+ openWorldHint: true
338
+ },
339
+
340
+ handler: async (args: unknown) => {
341
+ const parsed = DeleteAgentSchema.parse(args);
342
+ await deleteRequest(`/convai/agents/${parsed.agent_id}`);
343
+
344
+ return {
345
+ content: [
346
+ {
347
+ type: "text",
348
+ text: `Successfully deleted agent: ${parsed.agent_id}`
349
+ }
350
+ ]
351
+ };
352
+ }
353
+ };
354
+
355
+ /**
356
+ * Lists all agents with pagination
357
+ */
358
+ export const elevenlabs_list_agents = {
359
+ name: "elevenlabs_list_agents",
360
+ description: `List all ElevenLabs Voice Agents with pagination.
361
+
362
+ This tool retrieves a paginated list of all your voice agents. Use the offset and limit parameters to navigate through large agent lists. The response includes pagination metadata to help you fetch additional pages.
363
+
364
+ Args:
365
+ - limit (number): Maximum agents to return (1-100, default: 20)
366
+ - offset (number): Number of agents to skip (default: 0)
367
+ - response_format ('markdown' | 'json'): Output format
368
+
369
+ Returns:
370
+ For JSON format: Object with total count, items array, offset, has_more, and next_offset
371
+ For Markdown format: Formatted list of agents with key details and pagination guidance
372
+
373
+ Examples:
374
+ - Use when: "Show me all my voice agents"
375
+ - Use when: "List the first 10 agents"
376
+ - Use when: "Get the next page of agents with offset=20"
377
+ - Don't use when: You want details about a specific agent (use elevenlabs_get_agent)
378
+
379
+ Error Handling:
380
+ - Returns empty list if no agents exist
381
+ - Returns "Error: Invalid API key" if authentication fails`,
382
+
383
+ zodSchema: ListAgentsSchema,
384
+
385
+ annotations: {
386
+ readOnlyHint: true,
387
+ destructiveHint: false,
388
+ idempotentHint: true,
389
+ openWorldHint: true
390
+ },
391
+
392
+ handler: async (args: unknown) => {
393
+ const parsed = ListAgentsSchema.parse(args);
394
+
395
+ const response = await getRequest<{ agents: Agent[] }>(
396
+ "/convai/agents",
397
+ {
398
+ limit: parsed.limit,
399
+ offset: parsed.offset
400
+ }
401
+ );
402
+
403
+ const agents = response.agents || [];
404
+ const total = agents.length; // Note: ElevenLabs API may not return total count
405
+ const hasMore = agents.length === parsed.limit;
406
+
407
+ const paginatedResponse: PaginatedResponse<Agent> = {
408
+ total,
409
+ count: agents.length,
410
+ offset: parsed.offset,
411
+ items: agents,
412
+ has_more: hasMore,
413
+ next_offset: hasMore ? parsed.offset + agents.length : undefined
414
+ };
415
+
416
+ return {
417
+ content: [
418
+ {
419
+ type: "text",
420
+ text: formatResponse(paginatedResponse, parsed.response_format, "agent_list")
421
+ }
422
+ ]
423
+ };
424
+ }
425
+ };
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Batch calling tools
3
+ *
4
+ * MCP tools for submitting batch call jobs, listing batches, and retrieving batch details.
5
+ */
6
+
7
+ import { getRequest, postRequest } from "../services/elevenlabs-api.js";
8
+ import { formatResponse } from "../services/formatters.js";
9
+ import { BatchCallResponse, BatchCallDetailedResponse, WorkspaceBatchCallsResponse } from "../types.js";
10
+ import {
11
+ SubmitBatchCallSchema,
12
+ ListBatchCallsSchema,
13
+ GetBatchCallSchema
14
+ } from "../schemas/batch-calling-schemas.js";
15
+
16
+ /**
17
+ * Submits a batch calling job
18
+ */
19
+ export const elevenlabs_submit_batch_call = {
20
+ name: "elevenlabs_submit_batch_call",
21
+ description: `Submit a batch calling job to initiate multiple outbound calls simultaneously.
22
+
23
+ This tool allows you to call multiple phone numbers in parallel using your voice agent. Upload a list of recipients with optional personalization data for each call. Batch calling is ideal for surveys, alerts, reminders, appointment confirmations, and mass outreach.
24
+
25
+ Prerequisites:
26
+ - A Twilio phone number must be imported and associated with an agent
27
+ - Zero Retention Mode (ZRM) must be disabled
28
+ - Minimum 50% workspace concurrency or 70% agent concurrency available
29
+
30
+ Args:
31
+ - call_name (string): Descriptive name for this batch (e.g., "Q4 Customer Survey")
32
+ - agent_id (string): Agent to use for all calls (e.g., 'ag_abc123')
33
+ - recipients (array): Array of recipient objects, each containing:
34
+ - phone_number (string): Phone in E.164 format (e.g., '+1234567890')
35
+ - OR whatsapp_user_id (string): WhatsApp user ID (alternative)
36
+ - id (string, optional): Custom tracking ID for this recipient
37
+ - conversation_initiation_client_data (object, optional): Personalization data
38
+ - dynamic_variables (object): Dynamic variables for personalization
39
+ Example: {dynamic_variables: {name: 'John', appointment_time: '3pm'}}
40
+ - conversation_config_override (object): Override agent settings for this call
41
+ - Special fields: language, first_message, prompt.prompt, voice_id
42
+ - scheduled_time_unix (number, optional): Unix timestamp to schedule for future
43
+ - agent_phone_number_id (string, optional): Phone number ID to use as caller ID
44
+ - response_format ('markdown' | 'json'): Output format
45
+
46
+ Returns:
47
+ Batch job details including ID, status, scheduling info, and call counts.
48
+
49
+ Limits:
50
+ - Minimum: 1 recipient
51
+ - Maximum: 10,000 recipients per batch
52
+
53
+ Examples:
54
+ - Use when: "Call 500 customers with appointment reminders"
55
+ - Use when: "Send survey to all users with personalized greetings"
56
+ - Use when: "Dispatch agent to call lead list from CSV"
57
+ - Don't use when: Making a single call (use elevenlabs_start_outbound_call)
58
+ - Don't use when: Phone number isn't assigned to agent yet
59
+
60
+ Error Handling:
61
+ - Returns "Error: Invalid recipient count" if outside 1-10,000 range
62
+ - Returns "Error: Phone number not assigned" if agent lacks phone number
63
+ - Returns "Error: ZRM enabled" if Zero Retention Mode is active`,
64
+
65
+ zodSchema: SubmitBatchCallSchema,
66
+
67
+ annotations: {
68
+ readOnlyHint: false,
69
+ destructiveHint: false,
70
+ idempotentHint: false,
71
+ openWorldHint: true
72
+ },
73
+
74
+ handler: async (args: unknown) => {
75
+ const parsed = SubmitBatchCallSchema.parse(args);
76
+
77
+ const requestData = {
78
+ call_name: parsed.call_name,
79
+ agent_id: parsed.agent_id,
80
+ recipients: parsed.recipients,
81
+ ...(parsed.scheduled_time_unix !== undefined && {
82
+ scheduled_time_unix: parsed.scheduled_time_unix
83
+ }),
84
+ ...(parsed.agent_phone_number_id && {
85
+ agent_phone_number_id: parsed.agent_phone_number_id
86
+ })
87
+ };
88
+
89
+ const response = await postRequest<BatchCallResponse>(
90
+ "/convai/batch-calling/submit",
91
+ requestData
92
+ );
93
+
94
+ return {
95
+ content: [
96
+ {
97
+ type: "text",
98
+ text: formatResponse(response, parsed.response_format, "batch_call")
99
+ }
100
+ ]
101
+ };
102
+ }
103
+ };
104
+
105
+ /**
106
+ * Lists all batch calling jobs in workspace
107
+ */
108
+ export const elevenlabs_list_batch_calls = {
109
+ name: "elevenlabs_list_batch_calls",
110
+ description: `List all batch calling jobs in your workspace with pagination.
111
+
112
+ This tool retrieves all batch call jobs you've submitted, showing their status, scheduling, and progress. Use cursor-based pagination to navigate through large lists.
113
+
114
+ Args:
115
+ - limit (number): Maximum items to return (1-100, default: 20)
116
+ - last_doc (string, optional): Pagination cursor from previous response
117
+ - response_format ('markdown' | 'json'): Output format
118
+
119
+ Returns:
120
+ - batch_calls: Array of batch job objects with status and metrics
121
+ - next_doc: Cursor for next page (null if no more pages)
122
+ - has_more: Whether more batches exist
123
+
124
+ Pagination:
125
+ - First page: Don't include last_doc parameter
126
+ - Next pages: Use next_doc value from previous response as last_doc
127
+
128
+ Examples:
129
+ - Use when: "Show me all my batch calling jobs"
130
+ - Use when: "List recent batch calls"
131
+ - Use when: "Get next page of batches with cursor xyz123"
132
+ - Don't use when: You want details about a specific batch (use elevenlabs_get_batch_call)
133
+
134
+ Error Handling:
135
+ - Returns empty list if no batches exist
136
+ - Returns "Error: Invalid API key" if authentication fails`,
137
+
138
+ zodSchema: ListBatchCallsSchema,
139
+
140
+ annotations: {
141
+ readOnlyHint: true,
142
+ destructiveHint: false,
143
+ idempotentHint: true,
144
+ openWorldHint: true
145
+ },
146
+
147
+ handler: async (args: unknown) => {
148
+ const parsed = ListBatchCallsSchema.parse(args);
149
+
150
+ const params: Record<string, unknown> = {
151
+ limit: parsed.limit
152
+ };
153
+
154
+ if (parsed.last_doc) {
155
+ params.last_doc = parsed.last_doc;
156
+ }
157
+
158
+ const response = await getRequest<WorkspaceBatchCallsResponse>(
159
+ "/convai/batch-calling/workspace",
160
+ params
161
+ );
162
+
163
+ return {
164
+ content: [
165
+ {
166
+ type: "text",
167
+ text: formatResponse(response, parsed.response_format, "batch_call_list")
168
+ }
169
+ ]
170
+ };
171
+ }
172
+ };
173
+
174
+ /**
175
+ * Gets detailed information about a specific batch call
176
+ */
177
+ export const elevenlabs_get_batch_call = {
178
+ name: "elevenlabs_get_batch_call",
179
+ description: `Get detailed information about a specific batch calling job including all recipient statuses.
180
+
181
+ This tool retrieves complete details for a batch call job, including the status of each individual recipient. Use this to monitor batch progress, identify failed calls, detect voicemails, and track which recipients have been successfully contacted.
182
+
183
+ Args:
184
+ - batch_id (string): Unique batch job identifier (e.g., 'batch_abc123')
185
+ - response_format ('markdown' | 'json'): Output format
186
+
187
+ Returns:
188
+ Complete batch details including:
189
+ - Batch metadata (name, agent, status, timing)
190
+ - Call metrics (dispatched, scheduled counts)
191
+ - Recipients array with individual statuses:
192
+ - pending: Not yet called
193
+ - initiated: Call started
194
+ - in_progress: Currently in conversation
195
+ - completed: Call finished successfully
196
+ - failed: Call failed
197
+ - cancelled: Call was cancelled
198
+ - voicemail: Went to voicemail
199
+ - Each recipient includes conversation_id for transcript lookup
200
+
201
+ Examples:
202
+ - Use when: "Check status of batch job batch_abc123"
203
+ - Use when: "Show me which recipients answered in the sales batch"
204
+ - Use when: "Get details on appointment reminder batch"
205
+ - Use when: "Find failed calls in batch xyz789"
206
+ - Don't use when: You want to list all batches (use elevenlabs_list_batch_calls)
207
+
208
+ Error Handling:
209
+ - Returns "Error: Batch not found" if batch_id doesn't exist
210
+ - Returns "Error: Invalid API key" if authentication fails`,
211
+
212
+ zodSchema: GetBatchCallSchema,
213
+
214
+ annotations: {
215
+ readOnlyHint: true,
216
+ destructiveHint: false,
217
+ idempotentHint: true,
218
+ openWorldHint: true
219
+ },
220
+
221
+ handler: async (args: unknown) => {
222
+ const parsed = GetBatchCallSchema.parse(args);
223
+
224
+ const response = await getRequest<BatchCallDetailedResponse>(
225
+ `/convai/batch-calling/${parsed.batch_id}`
226
+ );
227
+
228
+ return {
229
+ content: [
230
+ {
231
+ type: "text",
232
+ text: formatResponse(response, parsed.response_format, "batch_call_detail")
233
+ }
234
+ ]
235
+ };
236
+ }
237
+ };