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,23 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebSearch",
5
+ "Bash(git init:*)",
6
+ "Bash(git branch:*)",
7
+ "Bash(git add:*)",
8
+ "mcp__elevenlabs-voice-agents__elevenlabs_list_agents",
9
+ "mcp__elevenlabs-voice-agents__elevenlabs_list_phone_numbers",
10
+ "mcp__elevenlabs-voice-agents__elevenlabs_start_outbound_call",
11
+ "Bash(git checkout:*)",
12
+ "Bash(npx tsx:*)",
13
+ "Bash(npm run clean:*)",
14
+ "Bash(npm run build:*)",
15
+ "Bash(curl:*)"
16
+ ],
17
+ "deny": [],
18
+ "ask": []
19
+ },
20
+ "enabledMcpjsonServers": [
21
+ "elevenlabs-voice-agents"
22
+ ]
23
+ }
package/.env.example ADDED
@@ -0,0 +1,3 @@
1
+ # ElevenLabs API Configuration
2
+ # Get your API key from: https://elevenlabs.io/app/settings/api-keys
3
+ ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
package/AGENTS.md ADDED
@@ -0,0 +1,37 @@
1
+ # Repository Guidelines
2
+
3
+ ## Project Structure & Module Organization
4
+ - `src/index.ts` boots the MCP server and registers tools; keep new exports centralized here.
5
+ - `src/tools/*.ts` house tool implementations grouped by domain (agent, knowledge, outbound calling, batch jobs, phone numbers, utility).
6
+ - `src/schemas/*.ts` contain Zod schemas for request/response validation; add or extend schemas before wiring new tools.
7
+ - `src/services/elevenlabs-api.ts` wraps ElevenLabs HTTP calls; `src/services/formatters.ts` normalizes responses; `src/utils/*` holds shared helpers.
8
+ - `dist/` stores compiled JS; edit TypeScript in `src/` and rebuild instead of touching `dist/`.
9
+
10
+ ## Build, Test, and Development Commands
11
+ - `npm run dev` — run the server in watch mode via `tsx` for rapid iteration.
12
+ - `npm run build` — type-check and emit JS to `dist/` using `tsc`.
13
+ - `npm start` — run the compiled server (requires a fresh build).
14
+ - `npm run clean` — remove `dist/` artifacts before fresh builds.
15
+ - `npm test` — currently a stub; replace with real tests when added.
16
+ - Set `ELEVENLABS_API_KEY` in `.env` (not committed) before running any command.
17
+
18
+ ## Coding Style & Naming Conventions
19
+ - TypeScript ES modules, 2-space indentation, prefer explicit return types and narrow Zod schemas.
20
+ - Tool identifiers follow the existing snake_case `elevenlabs_*` pattern to match client expectations; keep filenames descriptive (`outbound-tools.ts`, etc.).
21
+ - Favor small, single-purpose helpers in `utils/` and reuse shared error handling patterns from `utils/error-handlers.ts`.
22
+ - Keep public schemas and tool definitions colocated; avoid implicit `any` and keep imports relative within `src/`.
23
+
24
+ ## Testing Guidelines
25
+ - No active test suite yet; when adding tests, keep them near sources (e.g., `src/tools/__tests__/`) and align names with the tool or schema under test.
26
+ - Aim for request/response fixture coverage around new schemas and integration smoke tests for ElevenLabs API calls (use mocked HTTP).
27
+ - Update `npm test` to run the chosen framework once added (Vitest/Jest are common fits for TS).
28
+
29
+ ## Commit & Pull Request Guidelines
30
+ - Use concise, imperative commit subjects tied to scope (e.g., `Add batch call schema validation`, `Fix phone-number tool error handling`).
31
+ - For PRs, include: summary of changes, commands run (`npm run build`, tests), any new env vars/config, and sample tool payloads/responses when behavior changes.
32
+ - Avoid committing compiled `dist/` outputs or `.env`; prefer rebasing small topic branches for review clarity.
33
+
34
+ ## Security & Configuration Tips
35
+ - Keep `ELEVENLABS_API_KEY` and any Twilio credentials in local `.env`; never log secrets.
36
+ - When wiring into Claude Desktop, use absolute paths to `dist/index.js` and confirm Node 18+.
37
+ - If adding new tools, document required permissions and expected side effects in the tool description so clients can surface them clearly.
package/CLAUDE.md ADDED
@@ -0,0 +1,233 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ This is an MCP (Model Context Protocol) server that provides 23 specialized tools for developing and managing ElevenLabs Voice Agents. It enables Claude and other MCP clients to create, configure, test, monitor, and deploy AI-powered voice agents with outbound calling capabilities.
8
+
9
+ ## Development Commands
10
+
11
+ ### Build and Run
12
+ ```bash
13
+ npm run build # Compile TypeScript to JavaScript (outputs to dist/)
14
+ npm run dev # Development mode with auto-reload (uses tsx watch)
15
+ npm start # Run the compiled server from dist/
16
+ npm run clean # Remove build artifacts
17
+ ```
18
+
19
+ ### Environment Setup
20
+ - Copy `.env.example` to `.env`
21
+ - Set `ELEVENLABS_API_KEY` with your ElevenLabs API key
22
+ - The server validates the API key on startup
23
+
24
+ ### Testing the Server
25
+ After building, configure in Claude Desktop's config file (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
26
+ ```json
27
+ {
28
+ "mcpServers": {
29
+ "elevenlabs-voice-agents": {
30
+ "command": "node",
31
+ "args": ["/absolute/path/to/dist/index.js"],
32
+ "env": {
33
+ "ELEVENLABS_API_KEY": "your_key_here"
34
+ }
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ## Architecture
41
+
42
+ ### Core Structure
43
+
44
+ The codebase follows a modular architecture with clear separation of concerns:
45
+
46
+ 1. **Entry Point** (`src/index.ts`)
47
+ - Initializes MCP server using `@modelcontextprotocol/sdk`
48
+ - Validates API key on startup
49
+ - Registers all tools from different modules
50
+ - Sets up stdio transport for communication
51
+
52
+ 2. **API Layer** (`src/services/elevenlabs-api.ts`)
53
+ - Central HTTP client for all ElevenLabs API requests
54
+ - Handles authentication via `xi-api-key` header
55
+ - Provides typed request helpers (GET, POST, PUT, PATCH, DELETE)
56
+ - 30-second request timeout
57
+
58
+ 3. **Tools Layer** (`src/tools/`)
59
+ - Each file exports MCP tool definitions with:
60
+ - `name`: Tool identifier
61
+ - `description`: What the tool does
62
+ - `inputSchema`: Zod schema for validation
63
+ - `handler`: Async function that executes the tool
64
+ - Tools are organized by functionality:
65
+ - `agent-tools.ts`: CRUD operations for voice agents
66
+ - `knowledge-tools.ts`: Adding knowledge bases to agents
67
+ - `tool-tools.ts`: Creating/managing webhook tools
68
+ - `conversation-tools.ts`: Retrieving conversation data
69
+ - `utility-tools.ts`: Voice listing, widget generation
70
+ - `outbound-tools.ts`: Single outbound call initiation
71
+ - `batch-calling-tools.ts`: Batch calling jobs management
72
+ - `phone-number-tools.ts`: Phone number import/management
73
+
74
+ 4. **Validation Layer** (`src/schemas/`)
75
+ - Zod schemas for runtime type validation
76
+ - Organized by domain (agents, tools, conversations, etc.)
77
+ - Defines input schemas used by MCP tools
78
+ - Reusable schema components in `common-schemas.ts`
79
+
80
+ 5. **Type System** (`src/types.ts`, `src/constants.ts`)
81
+ - TypeScript interfaces for all API entities
82
+ - Constants for supported models, languages, limits
83
+ - Type-safe enums derived from constant arrays
84
+
85
+ ### Data Flow
86
+
87
+ 1. MCP client (Claude) calls a tool with parameters
88
+ 2. Tool handler receives validated input (Zod schema)
89
+ 3. Handler calls API service with appropriate HTTP method
90
+ 4. API service authenticates and makes request to ElevenLabs
91
+ 5. Response is formatted (markdown or JSON) and returned
92
+ 6. Error handling catches and formats API errors
93
+
94
+ ### Key Design Patterns
95
+
96
+ **Tool Structure**: Every tool follows this pattern:
97
+ ```typescript
98
+ export const toolName = {
99
+ name: "elevenlabs_action_name",
100
+ description: "What it does",
101
+ inputSchema: zodSchema,
102
+ handler: async (args: SchemaType) => {
103
+ // 1. Make API request
104
+ // 2. Format response
105
+ // 3. Return formatted result
106
+ }
107
+ };
108
+ ```
109
+
110
+ **Response Formatting**: Tools support two formats:
111
+ - `response_format: "markdown"` (default): Human-readable formatted output
112
+ - `response_format: "json"`: Raw structured data
113
+
114
+ **Pagination**: List endpoints use consistent pagination:
115
+ - `limit`: Items per page (1-100, default 20)
116
+ - `offset`: Skip N items
117
+ - Response includes `has_more`, `next_offset`, `total`
118
+
119
+ **Error Handling**: Centralized in `src/utils/error-handlers.ts`:
120
+ - `handleElevenLabsError()`: Parses axios errors, provides actionable messages
121
+ - `validateApiKey()`: Checks for API key on startup
122
+ - HTTP status codes are mapped to user-friendly error messages
123
+
124
+ **Response Truncation**: `src/utils/truncation.ts`:
125
+ - Automatically truncates responses over 25,000 characters
126
+ - Appends guidance on using pagination or filtering
127
+
128
+ ## Important Implementation Notes
129
+
130
+ ### API Authentication
131
+ - All requests require `xi-api-key` header with ElevenLabs API key
132
+ - Key is read from `process.env.ELEVENLABS_API_KEY`
133
+ - Server exits with error if key is not set
134
+
135
+ ### Type Safety
136
+ - Use strict TypeScript (`strict: true` in tsconfig.json)
137
+ - ES2022 module system with Node16 resolution
138
+ - All `.ts` imports must include `.js` extension (ESM requirement)
139
+
140
+ ### Tool Registration
141
+ When adding new tools:
142
+ 1. Create tool definition in appropriate `src/tools/*.ts` file
143
+ 2. Create/update Zod schema in `src/schemas/*.ts`
144
+ 3. Add types to `src/types.ts` if needed
145
+ 4. Import and add to tools array in `src/index.ts`
146
+ 5. Rebuild with `npm run build`
147
+
148
+ ### Constants and Defaults
149
+ - Default LLM: `gpt-4o-mini`
150
+ - Default voice model: `eleven_flash_v2_5`
151
+ - Default language: `en`
152
+ - Character limit: 25,000
153
+ - Request timeout: 30 seconds
154
+ - Max batch recipients: 10,000
155
+
156
+ ### Outbound Calling Architecture
157
+ - Requires Twilio integration
158
+ - Phone numbers must be imported before use
159
+ - Phone numbers must be assigned to agents
160
+ - Batch calling supports up to 10,000 recipients
161
+ - Supports dynamic variables via `conversation_initiation_client_data`
162
+ - Dynamic variables must be nested: `{dynamic_variables: {name: 'John', user_id: '123'}}`
163
+ - Can also include `conversation_config_override` for per-call customization
164
+ - Example: `{dynamic_variables: {customer_name: "Alice"}, conversation_config_override: {agent: {first_message: "Hi!"}}}`
165
+
166
+ ## Common Patterns
167
+
168
+ ### Making API Requests
169
+ ```typescript
170
+ import { postRequest, getRequest } from "../services/elevenlabs-api.js";
171
+
172
+ // POST request
173
+ const result = await postRequest<ResponseType>(
174
+ "/convai/agents",
175
+ requestBody
176
+ );
177
+
178
+ // GET request with params
179
+ const result = await getRequest<ResponseType>(
180
+ "/convai/agents",
181
+ { limit: 20, offset: 0 }
182
+ );
183
+ ```
184
+
185
+ ### Creating Zod Schemas
186
+ ```typescript
187
+ import { z } from "zod";
188
+
189
+ export const MyToolInputSchema = z.object({
190
+ required_field: z.string(),
191
+ optional_field: z.string().optional(),
192
+ enum_field: z.enum(["option1", "option2"]),
193
+ response_format: z.enum(["markdown", "json"]).default("markdown")
194
+ });
195
+
196
+ export type MyToolInput = z.infer<typeof MyToolInputSchema>;
197
+ ```
198
+
199
+ ### Formatting Responses
200
+ ```typescript
201
+ if (args.response_format === "json") {
202
+ return JSON.stringify(data, null, 2);
203
+ }
204
+
205
+ // Return markdown formatted string
206
+ return `# Heading\n\n**Field**: ${data.field}\n`;
207
+ ```
208
+
209
+ ## Dependencies
210
+
211
+ ### Runtime
212
+ - `@modelcontextprotocol/sdk`: ^1.6.1 - MCP server implementation
213
+ - `axios`: ^1.7.9 - HTTP client for API requests
214
+ - `zod`: ^3.23.8 - Runtime type validation
215
+
216
+ ### Development
217
+ - `typescript`: ^5.7.2 - TypeScript compiler
218
+ - `tsx`: ^4.19.2 - TypeScript execution and watch mode
219
+ - `@types/node`: ^22.10.0 - Node.js type definitions
220
+
221
+ ### Requirements
222
+ - Node.js 18 or higher (specified in package.json engines)
223
+
224
+ ## API Integration Notes
225
+
226
+ - Base URL: `https://api.elevenlabs.io/v1`
227
+ - All endpoints are under `/convai/` prefix
228
+ - Rate limiting: 429 errors suggest waiting 60 seconds
229
+ - Authentication: Header-based with `xi-api-key`
230
+ - Conversation IDs start with `conv_`
231
+ - Agent IDs start with `ag_`
232
+ - Phone number IDs start with `pn_`
233
+ - Batch IDs start with `batch_`
package/README.md CHANGED
@@ -42,17 +42,10 @@ A Model Context Protocol (MCP) server for developing and managing ElevenLabs Voi
42
42
  - Node.js 18 or higher
43
43
  - ElevenLabs API key ([Get one here](https://elevenlabs.io))
44
44
 
45
- ### Option 1: Install from npm (Recommended)
45
+ ### Setup
46
46
 
47
- ```bash
48
- npm install -g elevenlabs-voice-agent-mcp
49
- ```
50
-
51
- ### Option 2: Install from source
52
-
53
- 1. **Clone the repository:**
47
+ 1. **Clone or navigate to the project directory:**
54
48
  ```bash
55
- git clone https://github.com/griffinwork40/elevenlabs-voice-agent-mcp.git
56
49
  cd elevenlabs-voice-agent-mcp
57
50
  ```
58
51
 
@@ -61,7 +54,13 @@ npm install -g elevenlabs-voice-agent-mcp
61
54
  npm install
62
55
  ```
63
56
 
64
- 3. **Build the project:**
57
+ 3. **Set up environment variables:**
58
+ ```bash
59
+ cp .env.example .env
60
+ # Edit .env and add your ElevenLabs API key
61
+ ```
62
+
63
+ 4. **Build the project:**
65
64
  ```bash
66
65
  npm run build
67
66
  ```
@@ -85,26 +84,6 @@ Add this to your Claude Desktop configuration file:
85
84
  **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
86
85
  **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
87
86
 
88
- #### If installed via npm:
89
-
90
- ```json
91
- {
92
- "mcpServers": {
93
- "elevenlabs-voice-agents": {
94
- "command": "npx",
95
- "args": [
96
- "elevenlabs-voice-agent-mcp"
97
- ],
98
- "env": {
99
- "ELEVENLABS_API_KEY": "your_elevenlabs_api_key_here"
100
- }
101
- }
102
- }
103
- }
104
- ```
105
-
106
- #### If installed from source:
107
-
108
87
  ```json
109
88
  {
110
89
  "mcpServers": {
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Replicates the EXACT successful call format from documentation
3
+ * No conversation_config_override - just dynamic variables
4
+ */
5
+
6
+ import axios from 'axios';
7
+
8
+ const apiKey = process.env.ELEVENLABS_API_KEY;
9
+
10
+ if (!apiKey) {
11
+ console.error('❌ Error: ELEVENLABS_API_KEY environment variable not set');
12
+ process.exit(1);
13
+ }
14
+
15
+ async function makeTestCall() {
16
+ try {
17
+ console.log('🔄 Initiating call with EXACT format from documentation...\n');
18
+
19
+ // EXACT format from SUCCESSFUL_TEST_CALL_DOCUMENTATION.md
20
+ const response = await axios.post(
21
+ 'https://api.elevenlabs.io/v1/convai/twilio/outbound-call',
22
+ {
23
+ agent_id: 'agent_2601kahgbheaftnr7150xp0x8jbf',
24
+ agent_phone_number_id: 'phnum_4501kayyj6xtfak80g09czq6yzxm',
25
+ to_number: '+16184072273',
26
+ conversation_initiation_client_data: {
27
+ dynamic_variables: {
28
+ lead_name: 'Connor',
29
+ rep_name: 'Connor',
30
+ lead_email: 'connor@atlasdigitalusa.com',
31
+ their_timezone: 'Central Time'
32
+ }
33
+ }
34
+ },
35
+ {
36
+ headers: {
37
+ 'xi-api-key': apiKey,
38
+ 'Content-Type': 'application/json'
39
+ }
40
+ }
41
+ );
42
+
43
+ console.log('✅ Call initiated successfully!\n');
44
+ console.log('📞 Call Details:');
45
+ console.log('─────────────────────────────────────');
46
+ console.log(`Conversation ID: ${response.data.conversation_id}`);
47
+ console.log(`Twilio Call SID: ${response.data.callSid}`);
48
+ console.log('─────────────────────────────────────\n');
49
+ console.log('Full Response:');
50
+ console.log(JSON.stringify(response.data, null, 2));
51
+
52
+ } catch (error) {
53
+ if (axios.isAxiosError(error)) {
54
+ console.error('❌ API Error:', error.response?.status);
55
+ console.error('Message:', error.response?.data?.detail || error.message);
56
+ if (error.response?.data) {
57
+ console.error('Full error:', JSON.stringify(error.response.data, null, 2));
58
+ }
59
+ } else {
60
+ console.error('❌ Unexpected error:', error);
61
+ }
62
+ process.exit(1);
63
+ }
64
+ }
65
+
66
+ makeTestCall();
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Test call with first_message set to null (not empty string)
3
+ * This should make the agent wait for human to speak first
4
+ */
5
+
6
+ import axios from 'axios';
7
+
8
+ const apiKey = process.env.ELEVENLABS_API_KEY;
9
+
10
+ if (!apiKey) {
11
+ console.error('❌ Error: ELEVENLABS_API_KEY environment variable not set');
12
+ process.exit(1);
13
+ }
14
+
15
+ async function makeTestCall() {
16
+ try {
17
+ console.log('🔄 Testing call with first_message: null\n');
18
+
19
+ const response = await axios.post(
20
+ 'https://api.elevenlabs.io/v1/convai/twilio/outbound-call',
21
+ {
22
+ agent_id: 'agent_2601kahgbheaftnr7150xp0x8jbf',
23
+ agent_phone_number_id: 'phnum_4501kayyj6xtfak80g09czq6yzxm',
24
+ to_number: '+16184072273',
25
+ conversation_initiation_client_data: {
26
+ dynamic_variables: {
27
+ lead_name: 'Connor',
28
+ rep_name: 'Connor',
29
+ lead_email: 'connor@atlasdigitalusa.com',
30
+ their_timezone: 'Central Time'
31
+ },
32
+ conversation_config_override: {
33
+ agent: {
34
+ first_message: null // Try null instead of empty string
35
+ }
36
+ }
37
+ }
38
+ },
39
+ {
40
+ headers: {
41
+ 'xi-api-key': apiKey,
42
+ 'Content-Type': 'application/json'
43
+ }
44
+ }
45
+ );
46
+
47
+ console.log('✅ Call initiated!\n');
48
+ console.log('📞 Call Details:');
49
+ console.log('─────────────────────────────────────');
50
+ console.log(`Conversation ID: ${response.data.conversation_id}`);
51
+ console.log(`Twilio Call SID: ${response.data.callSid}`);
52
+ console.log('─────────────────────────────────────\n');
53
+ console.log('⚠️ Agent should wait for human to speak first\n');
54
+ console.log('Full Response:');
55
+ console.log(JSON.stringify(response.data, null, 2));
56
+
57
+ } catch (error) {
58
+ if (axios.isAxiosError(error)) {
59
+ console.error('❌ API Error:', error.response?.status);
60
+ console.error('Message:', error.response?.data?.detail || error.message);
61
+ if (error.response?.data) {
62
+ console.error('Full error:', JSON.stringify(error.response.data, null, 2));
63
+ }
64
+ } else {
65
+ console.error('❌ Unexpected error:', error);
66
+ }
67
+ process.exit(1);
68
+ }
69
+ }
70
+
71
+ makeTestCall();
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Creates a new ElevenLabs voice agent using direct API call
3
+ * Simplified version that follows the working outbound call pattern
4
+ */
5
+
6
+ import axios from 'axios';
7
+ import fs from 'fs';
8
+
9
+ const apiKey = process.env.ELEVENLABS_API_KEY;
10
+
11
+ if (!apiKey) {
12
+ console.error('❌ Error: ELEVENLABS_API_KEY environment variable not set');
13
+ process.exit(1);
14
+ }
15
+
16
+ async function createAgent() {
17
+ try {
18
+ console.log('📖 Reading system prompt...\n');
19
+
20
+ // Read the system prompt from file
21
+ const systemPrompt = fs.readFileSync('demo-agent-system-prompt.xml', 'utf-8');
22
+
23
+ console.log('🔄 Creating agent via API...\n');
24
+
25
+ const requestBody = {
26
+ name: 'Positive Lead Outreach Agent',
27
+ conversation_config: {
28
+ agent: {
29
+ prompt: {
30
+ prompt: systemPrompt,
31
+ llm: 'gpt-4o-mini'
32
+ },
33
+ language: 'en'
34
+ // NOTE: first_message is INTENTIONALLY OMITTED so agent waits for human
35
+ },
36
+ tts: {
37
+ voice_id: '21m00Tcm4TlvDq8ikWAM',
38
+ model_id: 'eleven_flash_v2_5'
39
+ }
40
+ }
41
+ };
42
+
43
+ console.log('Request body structure:');
44
+ console.log(JSON.stringify(requestBody, null, 2).substring(0, 500) + '...\n');
45
+
46
+ const response = await axios.post(
47
+ 'https://api.elevenlabs.io/v1/convai/agents',
48
+ requestBody,
49
+ {
50
+ headers: {
51
+ 'xi-api-key': apiKey,
52
+ 'Content-Type': 'application/json'
53
+ }
54
+ }
55
+ );
56
+
57
+ console.log('✅ Agent created successfully!\n');
58
+ console.log('📋 Agent Details:');
59
+ console.log('─────────────────────────────────────');
60
+ console.log(`Agent ID: ${response.data.agent_id}`);
61
+ console.log(`Name: ${response.data.name}`);
62
+ console.log('─────────────────────────────────────\n');
63
+
64
+ // Save agent ID
65
+ fs.writeFileSync('new-agent-id.txt', response.data.agent_id);
66
+ console.log(`💾 Agent ID saved to: new-agent-id.txt\n`);
67
+ console.log('Full response:');
68
+ console.log(JSON.stringify(response.data, null, 2));
69
+
70
+ } catch (error) {
71
+ if (axios.isAxiosError(error)) {
72
+ console.error('❌ API Error:', error.response?.status);
73
+ console.error('Message:', error.response?.data?.detail || error.response?.data?.message || error.message);
74
+ if (error.response?.data) {
75
+ console.error('Full error:', JSON.stringify(error.response.data, null, 2));
76
+ }
77
+ } else {
78
+ console.error('❌ Unexpected error:', error);
79
+ }
80
+ process.exit(1);
81
+ }
82
+ }
83
+
84
+ createAgent();
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Creates a new ElevenLabs voice agent for calling positive email leads
3
+ * Key feature: Agent waits for human to speak first (no first_message)
4
+ */
5
+
6
+ import axios from 'axios';
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+
11
+ const apiKey = process.env.ELEVENLABS_API_KEY;
12
+
13
+ if (!apiKey) {
14
+ console.error('❌ Error: ELEVENLABS_API_KEY environment variable not set');
15
+ process.exit(1);
16
+ }
17
+
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = path.dirname(__filename);
20
+
21
+ async function createAgent() {
22
+ try {
23
+ console.log('📖 Reading system prompt from demo-agent-system-prompt.xml...\n');
24
+
25
+ // Read the system prompt from file
26
+ const promptPath = path.join(__dirname, 'demo-agent-system-prompt.xml');
27
+ const systemPrompt = fs.readFileSync(promptPath, 'utf-8');
28
+
29
+ console.log('🔄 Creating new agent: "Positive Lead Outreach Agent"\n');
30
+ console.log('Configuration:');
31
+ console.log(' - LLM: gpt-4o-mini');
32
+ console.log(' - Voice: Rachel (21m00Tcm4TlvDq8ikWAM)');
33
+ console.log(' - Voice Model: eleven_flash_v2_5');
34
+ console.log(' - Language: en');
35
+ console.log(' - First Message: NONE (waits for human)\n');
36
+
37
+ const response = await axios.post(
38
+ 'https://api.elevenlabs.io/v1/convai/agents',
39
+ {
40
+ name: 'Positive Lead Outreach Agent',
41
+ conversation_config: {
42
+ agent: {
43
+ prompt: {
44
+ prompt: systemPrompt,
45
+ llm: 'gpt-4o-mini'
46
+ },
47
+ // first_message is INTENTIONALLY OMITTED - agent will wait for human
48
+ language: 'en'
49
+ },
50
+ tts: {
51
+ voice_id: '21m00Tcm4TlvDq8ikWAM',
52
+ model_id: 'eleven_flash_v2_5'
53
+ }
54
+ }
55
+ },
56
+ {
57
+ headers: {
58
+ 'xi-api-key': apiKey,
59
+ 'Content-Type': 'application/json'
60
+ }
61
+ }
62
+ );
63
+
64
+ console.log('✅ Agent created successfully!\n');
65
+ console.log('📋 Agent Details:');
66
+ console.log('─────────────────────────────────────');
67
+ console.log(`Agent ID: ${response.data.agent_id}`);
68
+ console.log(`Name: ${response.data.name}`);
69
+ console.log(`Created At: ${response.data.created_at}`);
70
+ console.log('─────────────────────────────────────\n');
71
+
72
+ console.log('🔍 Conversation Config:');
73
+ console.log(JSON.stringify(response.data.conversation_config, null, 2));
74
+ console.log('\n');
75
+
76
+ console.log('⚠️ IMPORTANT: Save this Agent ID for making test calls!');
77
+ console.log(` Agent ID: ${response.data.agent_id}\n`);
78
+
79
+ // Save agent ID to a file for easy reference
80
+ const agentIdFile = path.join(__dirname, 'new-agent-id.txt');
81
+ fs.writeFileSync(agentIdFile, response.data.agent_id);
82
+ console.log(`💾 Agent ID saved to: ${agentIdFile}\n`);
83
+
84
+ } catch (error) {
85
+ if (axios.isAxiosError(error)) {
86
+ console.error('❌ API Error:', error.response?.status);
87
+ console.error('Message:', error.response?.data?.detail || error.message);
88
+ if (error.response?.data) {
89
+ console.error('Full error:', JSON.stringify(error.response.data, null, 2));
90
+ }
91
+ } else {
92
+ console.error('❌ Unexpected error:', error);
93
+ }
94
+ process.exit(1);
95
+ }
96
+ }
97
+
98
+ createAgent();