Troubleshooting
The problems below cover most Exotel MCP connection failures. If none apply, capture the client-side MCP logs (see Debug logs) and email hello@exotel.com with the subject MCP server — connection issue.
Server does not appear in the client
- Reload the window or restart the app. MCP servers load once at startup, so changes you make to the config after that are ignored. In Cursor and VS Code, use Developer: Reload Window. In Claude Desktop, fully quit (Cmd+Q) and reopen. In Windsurf and Claude Code, restart the process.
- Check the config path. Cursor uses
~/.cursor/mcp.json(global) or.cursor/mcp.json(project). Claude Desktop uses~/Library/Application Support/Claude/claude_desktop_config.jsonon macOS and%APPDATA%\Claude\claude_desktop_config.jsonon Windows. VS Code uses.vscode/mcp.jsonin your workspace. - Validate the JSON. A single missing comma or unbalanced brace makes the whole file invalid. Run
cat ~/.cursor/mcp.json | jq .(or the equivalent path).
mcp-remote fails to start (Claude Desktop, Claude Code, Windsurf)
- Install Node.js 18 or newer.
mcp-remoteruns throughnpx. Runnode -vin a terminal. If it errors or shows a version below 18, install from nodejs.org and restart your client. - First launch is slow.
npxdownloadsmcp-remoteon first run. Give the client 20-30 seconds. - Clear the auth cache. Run
rm -rf ~/.mcp-authandpkill -f mcp-remote, then restart your client.
401 Unauthorized or "credential error"
- Base64 the token correctly.
tokenmust be base64 ofapi_key:api_token: the literal string with a colon separator and no spaces. Regenerate withecho -n "API_KEY:API_TOKEN" | base64. The-nflag matters; a trailing newline breaks the token. - Escape the JSON. In
mcp.json/claude_desktop_config.json, theAuthorizationvalue is a JSON string, so double quotes inside it must be escaped:"Authorization": "{\"token\":\"...\"}". Or store the JSON in anenvvariable and reference it as${AUTH_HEADER}. - Match the API domain. India-hosted accounts use
https://api.in.exotel.com. Globally-hosted accounts usehttps://api.exotel.com. A mismatch returns401or a "resource not found" error. - Product-scoped errors. A CPaaS credential works only for CPaaS tools. If a VoiceBot tool errors with "credential not configured," you missed the
voicebot_*fields. Callexotel_setup_guideto see which products your header configures.
Tool call fails with "resource not found" or 4xx
- Wrong
account_sid. The SID must match the account that owns the API key. Copy both from the same row of my.exotel.com → Settings → API Settings. from_numberisn't a virtual number on this account. Only numbers you see under my.exotel.com → Numbers can act asfrom_numberorcaller_id. Sub-accounts have their own number pool.- DLT-blocked SMS. SMS to India-registered numbers requires a DLT-approved template and sender ID. Errors return as
500with a DLT reason. Configure templates at my.exotel.com → SMS → Templates first.
Tools list is empty
- Wrong URL. The endpoint is
https://mcp.exotel.com/mcp. Notmcp.exotel.com(no path), and notapi.exotel.com/mcp. A wrong URL usually returns HTML, which the client silently drops. - Wrong transport. The server is Streamable HTTP. If your client asks for SSE-only, wrap it with
mcp-remote(see the Claude Desktop pattern in the Overview).
VoiceBot tools return but calls never dial
Bot-driven outbound calls need three credential sets in the same JSON header:
- VoiceBot credentials (
voicebot_api_key,voicebot_api_token,voicebot_account_id) - Outbound-call credentials (
calls_api_key,calls_api_token,calls_account_id), typically the same as CPaaS - A valid
from_numberfromexotel_voicebot_list_phone_numbers
If any of these is missing, the tool returns a config error before dialing.
CQA ingestion succeeds but analysis stays "pending"
Analysis runs asynchronously against your assignment rules. If no assignment rule matches, the interaction stays queued. Call exotel_cqa_list_assignment_rules to check that an active rule matches the interaction's metadata, then call exotel_cqa_track_job (for batches) or exotel_cqa_get_analysis (for single interactions) again after 30-60 seconds.
Test with curl
If your client can't connect, verify the server directly. Store the JSON in a shell variable first. Do not inline it in the command, and do not paste it into shell history.
AUTH='{"token":"BASE64_OF_APIKEY_APITOKEN","from_number":"YOUR_EXOTEL_NUMBER","caller_id":"YOUR_EXOTEL_NUMBER","account_sid":"YOUR_ACCOUNT_SID","api_domain":"https://api.in.exotel.com","exotel_portal_url":"https://my.exotel.com"}'
curl -sS -N -X POST https://mcp.exotel.com/mcp \
-H "Authorization: $AUTH" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-06-18" \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"initialize",
"params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}
}'
A successful response is a JSON-RPC result naming the server. If you get 401, your Authorization is wrong. If you get 404, your URL is wrong.
Follow up with tools/list to enumerate the tools your credentials expose:
curl -sS -N -X POST https://mcp.exotel.com/mcp \
-H "Authorization: $AUTH" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-06-18" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
Debug logs
- Cursor.
View → Output, choose MCP Logs in the dropdown. - VS Code.
View → Output, choose GitHub Copilot Chat: MCP Servers. - Claude Desktop.
~/Library/Logs/Claude/mcp*.logon macOS. - Claude Code.
~/.claude/logs/and--verboseon the CLI. - Windsurf. Cascade panel → MCP → View Logs.
MCP Inspector
The community MCP Inspector shows tools/list, resources/list, and prompts/list interactively.
npx @modelcontextprotocol/inspector
Choose Streamable HTTP, set URL to https://mcp.exotel.com/mcp, and paste your JSON header into the Authorization field.