@mindstone/mcp-server-elevenlabs-agents

ElevenLabs Conversational AI MCP server for Model Context Protocol hosts. Inspect and author voice agents, review conversation transcripts and recordings, manage phone-number assignments, place outbound calls, submit or monitor scheduled batch calls, and write to the knowledge base through the ElevenLabs ConvAI API.
Status
- Version: 0.2.1 ยท npm
- Auth: API key (
ELEVENLABS_API_KEY)
- Tools: 31 (configure, agents, agent tools, conversations, phone numbers, outbound calls, batch calls, knowledge base)
- Surface: cloud-api
- Machine-readable:
STATUS.json
Requirements
- Node.js 20+
- npm
- An ElevenLabs API key with Conversational AI access
One-click install

After clicking the button, your host will prompt you to fill: ELEVENLABS_API_KEY.
Manual config for Claude Desktop / Claude Code / Goose / Continue.dev (ElevenLabs Agents)
{
"mcpServers": {
"ElevenLabs Agents": {
"command": "npx",
"args": [
"-y",
"@mindstone/mcp-server-elevenlabs-agents"
],
"env": {
"ELEVENLABS_API_KEY": ""
}
}
}
}
Quick Start
Install & build
cd <path-to-repo>/connectors/elevenlabs-agents
npm install
npm run build
Local
Configuration
Environment variables
ELEVENLABS_API_KEY โ ElevenLabs API key (starts with sk_)
MCP_WORKSPACE_PATH โ optional sandbox root for knowledge-base file uploads
MCP_HOST_BRIDGE_STATE โ optional path to a host bridge state file used for credential management
MINDSTONE_REBEL_BRIDGE_STATE โ backwards-compatible alias for MCP_HOST_BRIDGE_STATE
Host configuration example
{
"mcpServers": {
"ElevenLabs Agents": {
"command": "node",
"args": ["<path-to-repo>/connectors/elevenlabs-agents/dist/index.js"],
"env": {
"ELEVENLABS_API_KEY": "your-api-key"
}
}
}
}
Configuration
configure_elevenlabs_agents_api_key โ Save your ElevenLabs API key
Agents
list_agents โ List voice agents in the workspace
get_agent โ Get one agent, including prompts and nested conversation config
create_agent โ Create a new agent from a user-friendly authoring surface
update_agent โ Partially update one agent via PATCH deep-merge semantics
duplicate_agent โ Duplicate an existing agent before experimenting
delete_agent โ Permanently remove an agent
simulate_conversation โ Test an agent with a simulated user message before telephony work
list_agent_tools โ List webhook/client/system tools available to agents
add_agent_tool โ Add a webhook or client tool to the workspace
Conversations
list_conversations โ List conversations, optionally filtered by agent/date/success
get_conversation โ Get a full conversation transcript and analysis
get_conversation_audio โ Download the conversation recording to a tmp file
submit_conversation_feedback โ Submit like/dislike feedback on a reviewed conversation
Phone numbers
list_phone_numbers โ List configured phone numbers
get_phone_number โ Get one phone number and its label/assignment
import_phone_number โ Import a Twilio or SIP trunk number into the workspace
update_phone_number โ Update one phone number label and/or assigned agent
delete_phone_number โ Permanently remove an imported phone number
Outbound calls
make_outbound_call โ Place one outbound call after resolving the phone-number provider automatically
Batch calls
submit_batch_call โ Submit a multi-recipient batch, optionally scheduled for the future
list_batch_calls โ List recent batch-call jobs in the workspace
get_batch_call โ Inspect one batch job, including per-recipient statuses
cancel_batch_call โ Cancel a queued or scheduled batch job
retry_batch_call โ Retry a previously submitted batch job
Knowledge base
list_knowledge_base_docs โ List knowledge-base documents
get_knowledge_base_doc โ Get one knowledge-base document (metadata + /content body, capped ~50KB)
add_knowledge_base_document โ Add a KB document in text, file, or URL mode
delete_knowledge_base_document โ Delete a KB document, optionally with force
get_knowledge_base_rag_index_status โ Check whether a document is indexed and retrievable
rebuild_knowledge_base_rag_index โ Trigger (re)indexing of a KB document
Security notes
All external text returned by the ElevenLabs API is wrapped in <untrusted-content> envelopes before it reaches the model. This is especially important for conversation transcripts, which can contain attacker-controlled caller speech. Enveloping is deny-by-default: anything that is not a recognised structural value (IDs, enums, timestamps, phone numbers) is wrapped, including responses whose root is a bare JSON value rather than an object.
The same walk runs on every response surface โ agents, conversations, knowledge base, phone numbers, simulations, and outbound/batch calls. No surface carries a list of known prose field names, so a text field added upstream (an agent name, a workflow branch name, a future summary) is enveloped from the day it first appears in a response.
Nor does an unexpected shape route text around the walk. A response whose root is a bare JSON value, a list whose items are bare strings, and a transcript field carrying a string or an object where an array of turns was expected all go through the same deny-by-default walk rather than being returned unchanged.
Because reads come back enveloped, the agent authoring tools strip one envelope from the values they are given. Copying a language, model id, prompt, or advanced_config fragment out of get_agent and back into update_agent therefore stores the original text upstream rather than the envelope around it.
The structural literal exemptions in the walk are path-aware and value-shape-aware, not key-name-based. Inside arbitrary collaborator-authored maps โ webhook request_headers, advanced_config passthroughs, JSON-Schema parameter fragments, and the caller-authored open maps submitted with call initiation (conversation_initiation_client_data, conversation_config_override, custom_llm_extra_body, overrides, which ElevenLabs reflects on the conversation, call, and batch-call surfaces) โ key names are data rather than schema, so no string stays literal there at all: a property named status in a request-header map is collaborator text, not a trusted enum, and is enveloped whatever its value looks like. Because advanced_config is deep-merged into the config body before it is sent upstream, its reflected shape carries no advanced_config ancestor to key off; on the agent and workspace-tool surfaces a string therefore also stays literal only when every ancestor key from the surface root is a known schema position, so a flattened passthrough fragment (for example tool_config.custom.status) is enveloped however structural its key names and value shape look. Elsewhere on trusted paths, a string only stays literal under id/status/role/type keys when it is id/enum-shaped (no whitespace, no : or /, and not phrase-shaped or built from instruction-shaping words โ alphabet shape alone cannot tell an identifier from whitespace-free authored text such as IGNORE_PRIOR_INSTRUCTIONS), under timestamp only when it is ISO-8601-shaped, and under phone-number keys only when it is E.164. Values under credential-shaped keys (token, sid, *_secret, *_password, *_api_key) are replaced with [redacted] instead of being passed on at all, and import_phone_number additionally strips the exact submitted credentials โ the Twilio SID/token pair, and SIP trunk credential values such as a trunk username โ from any success payload or upstream error detail that reflects them.
URLs the connector asks ElevenLabs to dereference server-side must be public https:// addresses. This covers webhook tools via add_agent_tool, URL-mode knowledge-base documents, and every url-keyed string in the agent authoring tools' advanced_config (create_agent / update_agent) โ ElevenLabs fetches custom_llm.url on every conversation turn and dereferences platform_settings webhook URLs, so the merged agent body is validated recursively before any upstream call. Non-HTTP schemes, plain HTTP, embedded credentials, loopback/private/link-local/CGNAT/multicast IP literals (including the cloud-metadata address 169.254.169.254), IPv4-mapped/NAT64/6to4/Teredo and documentation IPv6 ranges, localhost-style hostnames, and single-label hostnames are rejected before any upstream call; trailing root-label dots are stripped before classification, so DNS-equivalent spellings such as localhost. are rejected too. A public hostname can still resolve or redirect to an internal address once ElevenLabs fetches it โ that residual DNS/redirect trust boundary is inherent to server-side dereferencing and is not closed by this validation. add_agent_tool's advanced_config deep-merges last but cannot set first-class fields (type, name, description, expects_response, api_schema.url, api_schema.method), and the merged tool config is revalidated before it is sent.
Outbound numbers are validated in E.164 format before any billing-surface call is sent upstream. Scheduled batches run on ElevenLabs' servers even if the client app is closed, so they should be monitored with list_batch_calls / get_batch_call and stopped with cancel_batch_call when needed.
Licence
FSL-1.1-MIT โ Functional Source License, Version 1.1, with MIT future licence. The software converts to MIT licence on 2030-04-08.