BA

bolna-ai/mcp

Developer tools
2 stars 3 forks Quality 83 Trend 28MIT

Remote MCP server (Streamable HTTP) wrapping the Bolna voice AI REST API (https://api.bolna.ai): 116 tools covering nearly every documented Bolna endpoint, TypeScript, deployed on Vercel via...

Overview

Remote MCP server (Streamable HTTP) wrapping the Bolna voice AI REST API (https://api.bolna.ai): 116 tools covering nearly every documented Bolna endpoint, TypeScript, deployed on Vercel via mcp-handler. — that page has the same connect instructions below with copy-paste buttons for each client. MCP is an open protocol, not Claude-specific — this server works with any MCP-compatible client: Claude, Codex, Cursor, Windsurf, Zed, and others. Endpoint corrections found while verifying tool paths against the live Bolna docs are documented in the comment block at the top of src/tools/index.ts. A directory listing is reviewed as a whole, so every tool on it is surface area to justify. /api/connector/mcp serves the nine tools named in src/tools/directory-surface.ts and nothing else, while /api/mcp keeps growing. Adding a name to that list means adding it to what Anthropic reviews, so do it deliberately. Both routes are built by the same factory in src/lib/mcp-route.

README

Bolna MCP Server

Remote MCP server (Streamable HTTP) wrapping the Bolna voice AI REST API (https://api.bolna.ai): 116 tools covering nearly every documented Bolna endpoint, TypeScript, deployed on Vercel via mcp-handler.

Live at mcp.bolna.ai — that page has the same connect instructions below with copy-paste buttons for each client.

MCP is an open protocol, not Claude-specific — this server works with any MCP-compatible client: Claude, Codex, Cursor, Windsurf, Zed, and others.

Endpoint corrections found while verifying tool paths against the live Bolna docs are documented in the comment block at the top of src/tools/index.ts.

Two endpoints

Endpoint Tools For
/api/mcp all 116 Anyone connecting the server themselves
/api/connector/mcp 9 The Claude connector directory listing

The directory surface is a fixed subset. A directory listing is reviewed as a whole, so every tool on it is surface area to justify. /api/connector/mcp serves the nine tools named in src/tools/directory-surface.ts and nothing else, while /api/mcp keeps growing. Adding a name to that list means adding it to what Anthropic reviews, so do it deliberately. Both routes are built by the same factory in src/lib/mcp-route.ts and share the same tool implementations.

The restriction is applied at registration time, not per call: tools off the list never enter the server’s registry, so they are absent from tools/list and un-callable by name. Prompts are dropped the same way, so the connector answers prompts/list with “method not found” rather than advertising the four on /api/mcp.

Two things also differ on the connector, and only there:

  • No api_key parameter. Every tool on /api/mcp accepts an optional api_key to target another account for one call (see above). It is stripped from both the schema and the incoming arguments on the connector, so it always acts as the OAuth-authenticated user. The strip lives in the same wrapper as the allowlist — no tool implementation is touched.
  • Its own server instructions. SERVER_INSTRUCTIONS describes tools and prompts the connector doesn’t register, so it sends CONNECTOR_INSTRUCTIONS from src/tools/prompts.ts instead.

OAuth is per-surface. RFC 9728 metadata must declare a resource equal to the URL the client connected to, and Claude rejects a mismatch, so a single hardcoded document can’t serve two paths. /api/connector/mcp points at the path-insertion form /.well-known/oauth-protected-resource/api/connector/mcp, served by a catch-all route that answers only for known transport paths. /api/mcp keeps the bare /.well-known/oauth-protected-resource it has always handed out, so already-connected clients are unaffected. Both documents name the same Supabase authorization server, and verifyToken does no audience check of its own — the token is forwarded to api.bolna.ai either way — so the sign-in flow at the two URLs is identical.

Sub-accounts and switching between accounts

Sub-account API keys (format sa-...) work exactly like a main account’s key (bn-...) — connect a separate client/connector with a sub-account’s key as the Bearer token to work entirely within that sub-account.

To switch accounts within a single connected session instead of reconnecting, every tool also accepts an optional api_key argument that overrides the connection’s own credential for just that call. Get a sub-account’s key from list_sub_accounts’ api_key field, then pass it to any tool call to run that call against that sub-account instead of the main account — e.g. “list agents in sub-account X” resolves to calling list_sub_accounts, finding X’s key, then list_agents with that key passed as api_key.

Available tools

116 tools across 17 categories. “Write” tools flagged Destructive modify, remove, or spend money and typically prompt for confirmation in MCP clients that respect tool annotations.

Agents & calls

Tool Type Description
list_agents Read List agents in the account (id, name, status, created_at). Paginated.
get_agent Read Full config of one agent by ID.
create_agent Write Create a new agent. Returns its ID.
update_agent Write, Destructive Patch an existing agent’s name, prompts, welcome message, webhook, or voice settings.
delete_agent Write, Destructive Permanently delete an agent. Irreversible.
stop_agent_queued_calls Write, Destructive Cancel every queued call for an agent.
start_outbound_call Write, Destructive Place a real outbound call from an agent. Spends account balance.
stop_call Write, Destructive Cancel a queued or scheduled call.

Executions

Tool Type Description
list_agent_executions Read Call history for one agent. Paginated, defaults to the last 7 days.
get_execution Read Full details of one call: transcript, status, cost, telephony data.
get_execution_raw_logs Read Raw pipeline logs (transcriber/LLM/synthesizer) for a call.
get_execution_debug Read Everything needed to debug a call, in one compact request: execution, per-turn latency and transcript, logs with delta-encoded LLM requests.
list_batch_executions Read Every call execution within a batch. Paginated.

Batches

Tool Type Description
create_batch Write Create a batch of outbound calls from a list of recipients.
get_batch Read A batch’s status, schedule, and contact counts.
list_batches Read Call batches for one agent.
schedule_batch Write, Destructive Schedule a batch to start calling. Spends account balance.
stop_batch Write, Destructive Halt a running or queued batch.
delete_batch Write, Destructive Permanently delete a batch.

Dispositions (structured call extraction)

Tool Type Description
list_dispositions Read List dispositions, optionally scoped to an agent.
get_disposition Read Retrieve a single disposition.
create_disposition Write Create a disposition linked to an agent.
bulk_create_dispositions Write Atomically create multiple dispositions for one agent.
update_disposition Write, Destructive Update a disposition (may fork a private copy — Bolna’s copy-on-write).
delete_disposition Write, Destructive Permanently delete a disposition.
test_dispositions Read Run an agent’s dispositions against a sample transcript.

Extraction categories

Tool Type Description
list_extraction_categories Read List an agent’s extraction categories with their dispositions.
create_extraction_category Write Create an extraction category (name + model) on an agent.
update_extraction_category Write, Destructive Rename a category or change its model; renames rewrite the category text on its dispositions.
delete_extraction_category Write, Destructive Permanently delete a category and every disposition inside it.

Phone numbers & inbound

Tool Type Description
list_phone_numbers Read Phone numbers on the account.
search_phone_numbers Read Search phone numbers available for purchase.
buy_phone_number Write, Destructive Purchase a phone number. Real recurring charge.
delete_phone_number Write, Destructive Remove a phone number and stop its billing.
setup_inbound_agent Write Route inbound calls on a number to an agent, optionally with an IVR menu.
unlink_inbound_agent Write, Destructive Remove inbound routing from a number.

SIP trunks (bring your own carrier)

Tool Type Description
list_trunks Read SIP trunks on the account, with health, gateways, carrier IPs and numbers.
get_trunk Read Full details of one SIP trunk.
create_trunk Write Create a SIP trunk for your own carrier.
update_trunk Write, Destructive Partially update a trunk’s settings or carrier credentials.
delete_trunk Write, Destructive Permanently delete a trunk with its gateways, carrier IPs and numbers.
add_trunk_gateway Write Add an outbound gateway (the carrier’s SIP host).
remove_trunk_gateway Write, Destructive Remove an outbound gateway.
add_trunk_carrier_ip Write Allow a carrier signalling IP or CIDR to send inbound calls.
remove_trunk_carrier_ip Write, Destructive Stop accepting inbound calls from a carrier IP.
add_number_to_trunk Write Add an E.164 number the carrier routes to the trunk.
remove_number_from_trunk Write, Destructive Remove a number from a trunk.
assign_trunk_number_agent Write, Destructive Set or clear the agent that answers a number’s inbound calls.
list_trunk_calls Read Recent calls on a trunk’s numbers, with SIP codes.
get_trunk_connection_details Read Bolna’s SIP domain, IPs, port, transports and RTP range to configure at the carrier.
start_trunk_test_call Write, Destructive Ring a phone through the trunk with an echo test.
get_trunk_test_call Read State of an outbound test call.
arm_trunk_inbound_test Write Answer the trunk’s next inbound call with an echo test instead of an agent.
get_trunk_inbound_test Read Whether the trunk is armed and how the inbound test went.
disarm_trunk_inbound_test Write, Destructive Cancel an inbound test.

Legacy SIP trunks (deprecated)

Kept for trunks that already exist on the legacy plane; new setups use the SIP trunk tools above.

Tool Type Description
create_sip_trunk Write Create a legacy SIP trunk with gateway and auth config. Use create_trunk instead.
get_sip_trunk Read Full details of a legacy SIP trunk. Use get_trunk instead.
list_sip_trunks Read All legacy SIP trunks on the account. Use list_trunks instead.
update_sip_trunk Write, Destructive Partially update a legacy SIP trunk. Use update_trunk instead.
delete_sip_trunk Write, Destructive Permanently delete a legacy trunk and its gateways/numbers. Use delete_trunk instead.
add_trunk_number Write Add a DID phone number to a legacy trunk. Use add_number_to_trunk instead.
remove_trunk_number Write, Destructive Remove a number from a legacy trunk. Use remove_number_from_trunk instead.
list_trunk_numbers Read Numbers assigned to a legacy trunk. Use get_trunk instead.

Sub-accounts (enterprise)

Tool Type Description
create_sub_account Write Create an isolated sub-account workspace. Requires org admin access.
list_sub_accounts Read All sub-accounts in the organization.
update_sub_account Write, Destructive Update a sub-account’s name or concurrency limits.
delete_sub_account Write, Destructive Permanently delete a sub-account and all its data.
get_sub_account_usage Read Usage and cost breakdown for one sub-account.
get_all_sub_accounts_usage Read Usage and cost breakdown for every sub-account.

Voice & providers

Tool Type Description
list_tts_providers Read TTS providers and models Bolna supports.
list_voices Read Voices available for a TTS provider/model.
list_providers Read Third-party providers configured on the account (secrets masked).
remove_provider Write, Destructive Remove a configured provider by name.

Knowledgebase (RAG)

Tool Type Description
create_knowledgebase Write Create a knowledgebase by scraping a URL. PDF upload isn’t supported here.
get_knowledgebase Read A knowledgebase’s file name, status, and settings.
list_knowledgebases Read All knowledgebases on the account.
delete_knowledgebase Write, Destructive Permanently delete a knowledgebase.

Violations

Tool Type Description
list_violations Read List flagged call violations, optionally filtered by status. Paginated.

Workflows

Multi-step, per-contact automations (call an agent, branch on the outcome, wait, call an API, wait for a callback from your own system, message over WhatsApp, retry, and so on) — distinct from a single agent’s own conversation. A workflow is edited as a draft, then published as an immutable version before it can run.

Tool Type Description
create_workflow Write Create a new (empty) workflow.
list_workflows Read List workflows, optionally filtered by name. Paginated.
get_workflow Read A workflow’s status, settings (webhook header values masked), and full draft/published version history.
rename_workflow Write, Destructive Rename a workflow.
update_workflow_settings Write, Destructive Set, change, or remove the execution webhook (URL and headers) as a JSON merge patch. Takes effect immediately.
test_workflow_webhook Write POST one sample execution webhook to the saved URL and report the receiver’s response.
delete_workflow Write, Destructive Permanently delete a workflow and every version.
get_workflow_draft Read The current editable draft definition and its revision number.
save_workflow_draft Write, Destructive Overwrite the draft’s node graph. Requires the current revision to avoid clobbering concurrent edits.
validate_workflow Read Check the saved draft for errors before publishing.
publish_workflow Write, Destructive Freeze the draft as a new immutable published version.
get_workflow_version Read Retrieve a specific published version’s node graph.
run_workflow Write, Destructive Run a single contact through the latest published version. Places real calls/messages.
list_workflow_node_types Read Every node type the engine supports, with its config parameters.
get_workflow_callback Read A callback node’s URL and signing secret, optionally with the last payload it received.

Workflow campaigns

Runs many contacts through one workflow version as a batch.

Tool Type Description
create_workflow_campaign Write Create a campaign pinned to a workflow version.
list_workflow_campaigns Read List campaigns, optionally filtered by workflow, status, or kind. Paginated.
get_workflow_campaign Read A campaign’s status and totals, plus entry/validation-error breakdowns.
delete_workflow_campaign Write, Destructive Delete an empty draft campaign.
upload_workflow_campaign_entries Write Add contacts to a campaign (CSV/JSON columns beyond the standard fields go in custom_fields).
list_workflow_campaign_entries Read List a campaign’s uploaded contacts. Paginated.
get_workflow_campaign_entries_template Read The CSV header row the campaign’s pinned version expects.
start_workflow_campaign Write, Destructive Start dispatching a campaign’s pending entries. Spends account balance.
pause_workflow_campaign Write, Destructive Pause a running campaign’s dispatching.
resume_workflow_campaign Write, Destructive Resume a paused campaign.
abort_workflow_campaign Write, Destructive Permanently terminate a campaign. Cannot be undone.
list_workflow_campaign_executions Read List a campaign’s per-contact executions. Paginated.
get_workflow_campaign_report Read Aggregated execution/termination/per-node funnel counts.

Workflow executions

A single contact’s run through a workflow, created by run_workflow or a campaign.

Tool Type Description
get_workflow_execution Read Current node, node-by-node history, and recent timeline events.
cancel_workflow_execution Write, Destructive Terminate a running execution.
resend_workflow_webhook Write Queue a finished execution’s original webhook payload again, to the workflow’s current URL and headers.

Graph agents

Node-based voice flows (llm_agent.agent_type: "graph_agent"). Create, edit, and validate the graph, and push events into live calls.

Tool Type Description
create_graph_agent Write Create a graph agent from nodes and edges. The graph is validated first; voice, transcriber, and telephony have defaults.
get_graph_agent Read A graph agent’s nodes, edges, routing settings, and a validation report.
update_graph_agent Write, Destructive Replace the graph, or add/replace/remove nodes and change routing settings, keeping the rest of the agent. Validated before saving.
validate_graph_agent Read Check a graph (or a saved agent) against the graph editor’s rules without saving.
send_graph_agent_event Write Push a named event into a live call; a matching event edge on the current node transitions and the agent speaks.

Account & documentation

Tool Type Description
get_user_info Read Account profile, wallet balance, concurrency limits.
search_docs Read Search the Bolna documentation site for matching pages.
get_doc Read Fetch the full markdown content of a Bolna documentation page.

Not exposed as a tool, all for the same reason — each needs either a raw file upload or a third-party secret as its request body, neither of which maps cleanly to a tool argument or belongs in a chat conversation:

  • POST /providers (add a provider) — takes a third-party credential (e.g. a Twilio auth token)
  • POST /knowledgebase with a PDF file (the URL variant is supported, above)
  • POST /violations/submit — takes an evidence screenshot/document

Install & use

Prerequisite: your own Bolna API key (from the Bolna dashboard). Every client below needs the same two things: the server URL (https://mcp.bolna.ai/api/mcp) and that key as a Bearer token.

Claude Code

One command:

./scripts/connect.sh

or the equivalent by hand:

claude mcp add --transport http bolna https://mcp.bolna.ai/api/mcp \
  --header "Authorization: Bearer " \
  --scope user

or by hand-editing ~/.claude.json (or .mcp.json for a project-scoped copy):

{
  "mcpServers": {
    "bolna": {
      "type": "http",
      "url": "https://mcp.bolna.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer "
      }
    }
  }
}

Claude Desktop

Desktop’s config only understands locally-run (stdio) servers, so reaching a remote HTTP server with a custom header needs the mcp-remote bridge, which runs locally and forwards the header on your behalf. Add this to claude_desktop_config.json:

{
  "mcpServers": {
    "bolna": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp.bolna.ai/api/mcp",
        "--header",
        "Authorization: Bearer "
      ]
    }
  }
}

Restart Claude Desktop after editing the config.

Codex CLI

Reads the key from an environment variable rather than the config file:

export BOLNA_API_KEY=""

codex mcp add bolna \
  --url https://mcp.bolna.ai/api/mcp \
  --bearer-token-env-var BOLNA_API_KEY

Cursor

Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "bolna": {
      "url": "https://mcp.bolna.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer "
      }
    }
  }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "bolna": {
      "serverUrl": "https://mcp.bolna.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer "
      }
    }
  }
}

Zed

Add to settings.json. Zed doesn’t support environment-variable interpolation in headers yet, so the key goes in directly:

{
  "context_servers": {
    "bolna": {
      "url": "https://mcp.bolna.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer "
      }
    }
  }
}

Claude Desktop (extension)

Instead of the mcp-remote bridge above, you can install this as a proper Desktop Extension (.mcpb) — a local, stdio-based build of the same 116 tools, packaged with a manifest so Claude Desktop can install it with one click and prompt you for your API key itself (no config file editing).

Build it from source:

npm run package:mcpb   # bundles src/stdio.ts, packs mcpb/ into bolna-mcp.mcpb

Then double-click bolna-mcp.mcpb, or drag it into Claude Desktop’s Settings → Extensions, and enter your Bolna API key when prompted.

This local build talks directly to api.bolna.ai using only the raw API key path in src/lib/auth.ts — OAuth is specific to the remote server and isn’t used here.

Any other MCP client

Point it at:

URL:     https://mcp.bolna.ai/api/mcp
Header:  Authorization: Bearer 

claude.ai web/mobile

This server now implements real OAuth (via Bolna’s Supabase-backed authorization server), so claude.ai’s own “Add custom connector” flow (Settings → Connectors) should work with just the URL — no manually pasted token needed, since claude.ai handles the login/consent redirect itself the same way Claude Code does. This hasn’t been separately verified on claude.ai web/mobile specifically yet (only Claude Code’s CLI flow has been tested end-to-end so far) — the CLI/config options above remain the proven paths in the meantime.

Try it

After connecting, start a new conversation and ask something like:

  • “List my Bolna agents”
  • “What’s my Bolna wallet balance?”
  • “Call +1… using my [agent name] agent”

Auth

Two ways to connect:

  • OAuth — sign in through Bolna’s own login (Supabase-backed). This is what claude.ai’s custom-connector UI and Claude Code’s Authenticate prompt use automatically; no manual token needed.
  • Raw API key — pass your own Bolna API key as a Bearer token in the Authorization header, per the client examples above.

Either credential is verified before being forwarded to api.bolna.ai — see the comment block at the top of src/lib/auth.ts for how.

For local development, set BOLNA_API_KEY in .env and omit the header — the server falls back to it automatically.

Local dev

npm install
cp .env.example .env   # then fill in BOLNA_API_KEY
npm run dev             # or: vercel dev

The MCP endpoint is served at http://localhost:3000/api/mcp.

Deploy

Deployed under the Bolna AI Vercel team, aliased to mcp.bolna.ai:

vercel deploy --prod --scope bolna-ai

Set BOLNA_API_KEY as a Vercel environment variable only if you want a server-wide fallback for testing; production callers should supply their own key via the Authorization header.

Test with MCP Inspector

npx @modelcontextprotocol/inspector

In the Inspector UI, connect with:

  • Transport: Streamable HTTP
  • URL: http://localhost:3000/api/mcp (or your deployed URL + /api/mcp)
  • Header: Authorization: Bearer (optional locally if BOLNA_API_KEY is set in .env)

Then use the Inspector’s “List Tools” and “Call Tool” panels to exercise each of the 13 core tools with valid and invalid input.

Privacy Policy

See mcp.bolna.ai/privacy.

License

MIT

View the full README on GitHub

Install

npx -y mcp-remote https://mcp.bolna.ai/api/mcp --header Authorization: Bearer <your BOLNA_API_KEY>
New to MCP? Start with the mcpskill.org guide →

Configuration

{ "mcpServers": { "bolna": { "type": "http", "url": "https://mcp.bolna.ai/api/mcp", "headers": { "Authorization": "Bearer <your BOLNA_API_KEY>" } } } }