KaiCalls

Connect KaiCalls to Claude, ChatGPT, Grok, Manus & every MCP client

Connect KaiCalls to the AI assistant you already use, and it can read your calls, transcripts, leads, and voicemails, and manage your account on your behalf. Install the published KaiCalls app in ChatGPT, or paste one URL — https://www.kaicalls.com/api/mcp — into Claude, Grok, Manus, Gemini, Perplexity, Mistral, Cursor, VS Code / GitHub Copilot, or Windsurf.

That URL is a remote Model Context Protocol (MCP) server, so any MCP-capable client works — but you don't need to know that to use it. This page is the exhaustive per-client reference; if you only want the shortest path for the one assistant you use, the setup walkthrough ranks them by how much work each one takes.

At a glance

MCP server URL
https://www.kaicalls.com/api/mcp
ChatGPT app
KaiCalls in the ChatGPT app directory (published, no setup needed)
Transport
Streamable HTTP (POST JSON-RPC 2.0)
Auth
OAuth 2.1 (authorization code + PKCE S256, refresh tokens, Dynamic Client Registration) for hosted chat clients; or a KaiCalls API key (kc_live_…) Bearer token for developer/CLI clients.
Scopes
26 scopes across agents, approvals, billing, calls, emails, evals, events, knowledge, leads, numbers, products, sms, support, webhooks, workspaces. Each tool's required scope is listed in the table below.
Discovery
/.well-known/mcp.json, /.well-known/mcp/server-card.json, /.well-known/oauth-protected-resource

Get an API key (for Bearer-token clients) from the dashboard. For OAuth-based clients you approve the KaiCalls consent screen during setup — no key to paste.

For a no-OAuth MCP setup, create a key with agents:read and calls:read. Add calls:write only for trusted clients that should be allowed to place real outbound calls.

Direct MCP clients can send the key as Authorization: Bearer kc_live_.... Gateways that collect API keys separately can send the same key as X-KaiCalls-API-Key: kc_live_....

Claude (Claude.ai & Desktop)

  1. Add KaiCalls to Claude (one click). Claude opens its Add custom connector box with the name and URL already filled in. Check them and press Add. If you'd rather do it by hand, open Settings → Connectors → Add custom connector and paste https://www.kaicalls.com/api/mcp.
  2. Sign in with your KaiCalls account and approve the access Claude asks for.
  3. Enable the tools you want. To start safely, enable read-only tools first and add make_call once you're ready to place calls.

Watch the setup walkthrough

On Team and Enterprise plans, an organization owner adds the connector first under Organization settings → Connectors (or uses this one-click owner link); members then connect it from their own Connectors settings. Claude connects from Anthropic's cloud, so the KaiCalls server being publicly reachable is already taken care of.

For Claude Code, install the same remote server from a terminal:

bash
claude mcp add --transport http --scope user kaicalls https://www.kaicalls.com/api/mcp claude mcp list

If Claude Code shows kaicalls - Needs authentication, start an interactive Claude Code session, run /mcp, select kaicalls, and choose authenticate. That opens the KaiCalls OAuth flow and stores the token in Claude.

To skip OAuth and use a static KaiCalls API key instead, pass the Bearer header when you add the server:

bash
claude mcp add --transport http --scope user kaicalls-api https://www.kaicalls.com/api/mcp \ -H "Authorization: Bearer kc_live_xxxxx" claude mcp list

A read-only key should use agents:read and calls:read. Include calls:write only if Claude Code should be able to use make_call.

Claude's OAuth callback (claude.ai/api/mcp/auth_callback) is already allowlisted by the KaiCalls authorization server.

ChatGPT (published app or Developer Mode)

Option 1 — Install the KaiCalls app (recommended, all plans)

KaiCalls is a published, OpenAI-approved app in the ChatGPT directory. This is the fastest path — no developer settings required, and it works on every ChatGPT plan, including Free.

  1. Open the KaiCalls app listing in ChatGPT (or search for "KaiCalls" in the ChatGPT app directory).
  2. Click Connect and sign in with your KaiCalls account.
  3. Approve the permissions and pick the business to connect. Then just ask — "List my recent calls" — or @-mention KaiCalls in a conversation.

On ChatGPT Business, Enterprise, and Edu workspaces an admin must enable the app first under Workspace settings → Apps.

Option 2 — Add the MCP server in Developer mode (paid plans)

  1. Enable Settings → Security and login → Developer mode (also reachable via the connectors/apps settings under Advanced).
  2. Add a connector with the KaiCalls URL https://www.kaicalls.com/api/mcp.
  3. Sign in with your KaiCalls account when prompted.

ChatGPT always signs in through your KaiCalls account; it does not accept pasted API keys. Its connector callback pattern is allowlisted on the KaiCalls authorization server. Write actions — like placing an outbound call — always ask for confirmation before running.

Meta Muse (Facebook) & Muse Code

Meta Muse (by Facebook / Meta) for macOS, iOS, Android, and the Muse Code CLI agent natively support Model Context Protocol (MCP) remote servers over streamable HTTP.

Meta Muse for Mac

  1. Open Meta Muse on macOS, go to Settings (⌘,) → Connectors (or Tools), and click Add MCP Server.
  2. Enter Server Name: KaiCalls.
  3. Enter Server URL: https://www.kaicalls.com/api/mcp.
  4. Sign in with your KaiCalls account when prompted and select the business you want Muse to manage.
  5. Review permissions. Meta's Sentinel guardrail will prompt you for confirmation before executing any sensitive write actions, like placing an outbound call.

Muse Code (Terminal)

In Muse Code or your terminal workspace, add the KaiCalls server:

bash
muse mcp add --transport http kaicalls https://www.kaicalls.com/api/mcp

For headless runs or CI environments, pass a KaiCalls API key directly as Authorization: Bearer kc_live_….

Claude Code

Add the connector once from the CLI, then authenticate:

bash
claude mcp add --transport http kaicalls https://www.kaicalls.com/api/mcp # then, inside Claude Code: /mcp

To share it with a repo instead of your user profile, add --scope project — that writes a .mcp.json your teammates pick up automatically:

json
{ "mcpServers": { "kaicalls": { "type": "http", "url": "https://www.kaicalls.com/api/mcp" } } }

For headless runs (CI, cron, a container with no browser to complete OAuth in), skip the interactive sign-in and pass a KaiCalls API key instead: claude mcp add --transport http kaicalls https://www.kaicalls.com/api/mcp --header "Authorization: Bearer kc_live_…"

OpenAI Codex

Add KaiCalls to ~/.codex/config.toml:

toml
[mcp_servers.kaicalls] url = "https://www.kaicalls.com/api/mcp"

Or add it from the CLI with codex mcp add kaicalls --url https://www.kaicalls.com/api/mcp. Codex completes the OAuth sign-in on first use.

Codex's support for remote (streamable-HTTP) MCP servers is version-dependent. If your build only accepts local command servers, or the entry above is ignored, bridge to it with mcp-remote:

toml
[mcp_servers.kaicalls] command = "npx" args = ["-y", "mcp-remote", "https://www.kaicalls.com/api/mcp"]

For non-interactive runs, set a KaiCalls API key as a bearer header rather than relying on the browser OAuth flow.

Provisioning many accounts from a coding agent

Agencies and MSPs are the main reason to attach KaiCalls to a coding agent rather than a chat client: the agent can read your own client roster and set each one up. With the connector attached, a single instruction covers the whole job —

Read clients/roster.yaml. For every client without a kaicalls_number,
create a secretary using the prompt in templates/intake.md, buy a local
number in their area code, attach it, point the webhook at our staging
endpoint, and write the number back to the roster.

That runs create_agent, search_available_numbers, buy_number, attach_number, and set_webhook per client. Two related patterns worth knowing:

  • Keep prompts in git. update_agent_config deploys a change, list_config_versions and rollback_config are the undo — every deploy is hashed and versioned, so reverting is a real operation rather than a re-edit.
  • Test in CI. run_eval executes the saved voice scenarios for an agent, so a reworded greeting can't silently break the booking flow. Gate the merge on it.

For a first-time buyer who has no account yet, point the agent at the narrowed setup endpoint https://www.kaicalls.com/api/mcp/acquisition instead — same auth, restricted to the tools that take someone from no account to a number that answers.

VS Code & GitHub Copilot

Add an entry to .vscode/mcp.json (workspace) or your user settings:

json
{ "servers": { "kaicalls": { "type": "http", "url": "https://www.kaicalls.com/api/mcp" } } }

VS Code triggers the OAuth flow on first use. For non-interactive setups, pass a Bearer token instead via a headers entry ("Authorization": "Bearer kc_live_…").

Cursor

One click — add KaiCalls to Cursor. Cursor opens with the connector prefilled; approve it and sign in.

Or add it by hand to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):

json
{ "mcpServers": { "kaicalls": { "url": "https://www.kaicalls.com/api/mcp" } } }

Cursor handles the OAuth handshake automatically. You can also add an "headers": { "Authorization": "Bearer kc_live_…" } block to use a static API key.

Windsurf

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

json
{ "mcpServers": { "kaicalls": { "serverUrl": "https://www.kaicalls.com/api/mcp" } } }

Reload Cascade's MCP servers, then authorize KaiCalls when prompted.

Mistral Le Chat

  1. A workspace admin opens Settings → Connectors → Add MCP connector.
  2. Enter the KaiCalls connector URL https://www.kaicalls.com/api/mcp. Le Chat detects the rest automatically.
  3. Sign in with your KaiCalls account, then share the connector with your team as needed.

xAI Grok

  1. Go to grok.com/connectors and click New Connector, then select Custom.
  2. Enter the KaiCalls connector URL https://www.kaicalls.com/api/mcp.
  3. Sign in with your KaiCalls account when Grok prompts you — or, for an unattended setup, paste an API key as a Bearer header Authorization: Bearer kc_live_….
  4. Grok discovers the KaiCalls tools automatically. Allowlist the ones you want (start with read-only tools).

Grok connects from xAI's cloud, and the KaiCalls connector is already publicly reachable over HTTPS — there is nothing to expose or tunnel from your own machine. Grok Business / Enterprise admins can manage connectors org-wide from the same connector management surface.

Manus

  1. Create a KaiCalls API key in the dashboard (Settings → API Keys). For a safe start, scope it to agents:read and calls:read.
  2. In Manus, open Settings → Integrations → Custom MCP Servers → Add Server.
  3. Enter a server name (e.g. KaiCalls), the server URL https://www.kaicalls.com/api/mcp, and your API key (kc_live_…) as the Bearer token.
  4. Manus tests the connection and lists the KaiCalls tools alongside its built-in integrations. Try "List my recent KaiCalls calls" to confirm.

Add calls:write to the key only if Manus should be able to place real outbound calls with make_call.

Google Gemini (app & CLI)

In the consumer Gemini app, custom MCP connectors are available inside Gemini Spark: open Settings & help → Connected Apps on gemini.google.com and paste https://www.kaicalls.com/api/mcp into Add a custom app link (personal Google accounts, web-first; then available on mobile too).

For the Gemini CLI, add the server from a terminal:

bash
gemini mcp add --transport http kaicalls https://www.kaicalls.com/api/mcp \ --header "Authorization: Bearer kc_live_xxxxx"

Omit the header to use OAuth instead — the CLI discovers the KaiCalls authorization server automatically on the first 401 and walks you through sign-in.

Perplexity

  1. Open Settings → Connectors → Add Connector → Custom MCP.
  2. Enter a name, the server URL https://www.kaicalls.com/api/mcp, and the transport (Streamable HTTP).
  3. Choose sign-in (OAuth) or an API key, then complete it with your KaiCalls account.

Enterprise admins can share the connector org-wide; member-added connectors may be disabled by default.

Smithery

KaiCalls is listed on Smithery. Install from that listing or publish the remote server yourself with the canonical MCP URL.

For a self-managed Smithery deployment, add a config schema so Smithery prompts users for a KaiCalls API key and forwards it as a header:

bash
smithery mcp publish "https://www.kaicalls.com/api/mcp" -n @kaicalls/kaicalls \ --config-schema '{"type":"object","properties":{"kaiCallsApiKey":{"type":"string","title":"KaiCalls API Key","description":"Create a KaiCalls API key with agents:read and calls:read. Add calls:write only if this Smithery connection may place outbound calls.","x-from":{"header":"x-kaicalls-api-key"},"x-to":{"header":"X-KaiCalls-API-Key"}}},"required":["kaiCallsApiKey"]}'

Smithery can list the public tool catalog without credentials. Add the config schema above so users can save a KaiCalls API key for authenticated tools/call requests.

Developer clients (Z.ai, Hermes, OpenClaw)

KaiCalls also works with developer/agent runtimes that consume MCP servers. For Z.ai, reference it as an MCP tool source in a chat/completions request:

json
{ "tools": [ { "type": "mcp", "server_label": "kaicalls", "server_url": "https://www.kaicalls.com/api/mcp", "transport_type": "streamable-http", "allowed_tools": ["list_recent_calls", "get_transcript"], "headers": { "Authorization": "Bearer kc_live_…" } } ] }

Hermes Agent (~/.hermes/config.yaml) and OpenClaw (openclaw mcp add kaicalls --url https://www.kaicalls.com/api/mcp) both accept the same URL with either an Authorization header or auth: oauth. Start with read-only tools and enable outbound/write tools explicitly.

Connected? Try your first question.

Ask your assistant: "List my recent calls." It should answer with the calls Kai took for your business. If your client asks for an API key instead of a sign-in, make one on the API keys page, then paste it into the client.

The full tool list and the technical details are below.

Public code

The public SDK, plugin, WordPress source, n8n, and MCP connector repos live under the KaiCalls GitHub organization. The approved WordPress plugin installs from WordPress.org. The private product repository stays private; these repos contain the code and metadata intended for developers, answer engines, and connector directories.

Available tools

Every client below exposes the same tool inventory. Read-only tools are safe to enable broadly; make_call places real outbound phone calls, so treat it as a write / external-effect action and enable it deliberately.

ToolDescriptionScopeType
request_human_approvalAsk a named principal for a specific decision using the provisioned voice approval channel. Requires restricted approvals:write, a configured callback host and signing secret. Returns dispatch status; the signed callback carries the decision and evidence. No approval is implied by dispatch. SMS-only delivery is unavailable.approvals:writeWrite / external effect
connect_agentConnect an external agent to a business and its signed event outbox. Requires current business admin membership, an assigned Kai agent, and agents:write, sms:write, webhooks:write. New SMS/WhatsApp conversations route to the external agent; explicit handoffs win. Grants no additional permissions and does not activate unregistered channels. Use a stable idempotency_key; replacements require expected_revision. The signing secret is returned only for a non-replayed connect. External realtime voice and email execution are not connected by this operation.agents:writeWrite / external effect
get_agent_connectionDiscover the external agent connection, signed webhook configuration, scoped API operation catalog, channel readiness and remaining runtime requirements. Requires agents:read, sms:read and webhooks:read. Configuration does not prove delivery or recipient consent.agents:readRead-only
disconnect_agentDisconnect the external agent and disable its webhook atomically. Requires current business admin membership and agents:write, sms:write, webhooks:write. Pass the stored expected_revision. Inherited conversations return to Kai; explicit handoffs remain.agents:writeWrite / external effect
get_lsa_account_reportRead the authorized advertiser's live Google Local Services aggregate account report, including actual spend, currency and charged lead totals. Requires linked manager-account access. Dates are calendar dates inclusive at both ends. Source may lag by 30 minutes. Connected phone calls means duration over 30 seconds; responsiveness is the previous 90 days. This is not signed-case revenue or lead-rating reporting.calls:readRead-only
get_lsa_setupInspect Google LSA account selection and sync freshness, with setup steps. Saved configuration never proves a live workflow. Cloud-project production access is not shown here; Google Cloud reports it.calls:readRead-only
sync_lsaSync an explicitly selected connected LSA advertiser. Requires current business admin role. Syncing runs lead ingestion, and existing business speed-to-lead configuration may contact the new leads it finds.agents:writeWrite / external effect
list_lsa_leadsList synced Google LSA leads, charge and credit states, source IDs and rating details. The returned LSA lead id identifies the lead in LSA commands; the separate lead_id field links to the CRM.calls:readRead-only
get_lsa_conversationsRead the latest 200 synced Google LSA conversation events for an LSA lead, including customer and advertiser messages. History is as current as the last sync.calls:readRead-only
get_lsa_reportReport LSA lead counts, types, observed statuses, ratings and credit counts for an explicit UTC window (start inclusive, end exclusive). Includes sync freshness and completeness. Removed unrated leads are counted separately because they cannot be rated here. Financial amounts, signed cases and response-time metrics are unavailable in this source and cannot be derived from counts.calls:readRead-only
send_lsa_replySend an authorized text reply inside an existing Google LSA message lead through the Ads API. This contacts the customer. Requires current business admin role and a stable idempotency_key. A retry with the same key is deduplicated; pending/unknown writes are blocked. Provider acceptance does not prove customer delivery. Attachments are unsupported.sms:writeWrite / external effect
rate_lsa_leadSubmit an authorized, truthful Google LSA quality survey and return Google's actual bonus-credit decision. This is not a guaranteed refund or the retired manual dispute workflow. Requires admin role and a stable retry key. Each rating is a per-lead survey answer based on that lead, not a bulk dissatisfaction claim. The reason must match the positive/negative rating; OTHER requires a comment. Neutral takes no reason.calls:writeWrite / external effect
agency_profile_bootstrapRegisters a new agency for the signed-in user and makes them its owner, using the given brand and support details. Requires a signed-in user session with a verified email; an API key cannot create an agency. Repeating it for an agency that already exists does not create a second one.workspaces:writeWrite / external effect
agency_profile_updateReplaces the agency brand, support details and requested commercial mode. Requires an agency owner or admin and the current profile revision; a stale revision is rejected. It does not change any published offer.workspaces:writeWrite / external effect
agency_profile_inviteCreates a staff invitation for an email address with the admin, operator or reader role and returns a one-time invite link that expires in 7 days. Requires an agency owner or admin; only the owner can invite an admin. It sends no email; the returned link is delivered by whoever created the invite.workspaces:writeWrite / external effect
agency_profile_accept_inviteJoins the agency using the token from an invite link. The signed-in user must have a verified email that matches the invited address, and the invite must be unexpired and not revoked. Accepting the same invite again is a no-op.workspaces:writeWrite / external effect
agency_profile_revoke_inviteCancels a pending staff invitation so its link can no longer be used. Requires an agency owner or admin. It does not remove anyone who already accepted; revoke_member does that.workspaces:writeWrite / external effect
agency_profile_assignGives an active agency staff member access to one client business with the admin or member business role. Requires an agency owner or admin who can manage that client; only the owner can assign an admin staff member. Assigning an existing assignment again changes nothing.workspaces:writeWrite / external effect
agency_profile_unassignRemoves a staff member's agency assignment to one client business, and removes the business membership if this assignment created it. Requires an agency owner or admin; only the owner can unassign an admin. It does not remove the person from the agency.workspaces:writeWrite / external effect
agency_profile_revoke_memberRemoves a staff member from the agency: revokes their membership, all their client assignments, their accepted invites and every API key issued to them through the agency. Requires an agency owner or admin; only the owner can remove an admin, and the owner cannot be removed.workspaces:writeWrite / external effect
agency_profile_issue_keyCreates a new API key for yourself in this agency, limited to the requested scopes, and returns the secret once. Readers cannot get write scopes, only the agency owner can get billing:write, and a delegated key cannot issue a key broader than itself. Each call creates another key (up to 20 active per user).workspaces:writeWrite / external effect
agency_offer_saveCreates a new offer draft, or replaces an existing draft when offerId and its current revision are given. Requires an agency owner or admin. Saving changes only the draft; clients see nothing until it is published.workspaces:writeWrite / external effect
agency_offer_previewBuilds the publishable manifest and sales kit for an offer draft and returns its fingerprint and revision for publishing. Requires an agency owner or admin. It saves nothing and fails if a package release, variant or claim is not supported.workspaces:writeRead-only
agency_offer_publishPublishes the previewed offer as a new immutable version and returns its enrollment link. Requires an agency owner or admin, plus the fingerprint and revision from preview; partner-billed offers also need billing collection to be ready. Publishing the same fingerprint again returns the existing version.workspaces:writeWrite / external effect
agency_offer_archiveArchives an offer so it can no longer be published or used for new enrollments. Requires an agency owner or admin and the current offer revision. Existing installations are not removed.workspaces:writeWrite / external effect
agency_enrollment_start_self_serviceStarts a business owner's own enrollment in a published agency offer, using the business name and intake facts. Requires a signed-in user session with a verified email and an idempotency key; the same key replays the same session. Nothing is installed until the owner approves and finishes.workspaces:writeWrite / external effect
agency_enrollment_finish_self_serviceCompletes a self-service enrollment after the owner has approved the current intake: creates the client business and queues its package installations, which later configure the business's voice agent. Only the owner who started it can finish it. Repeating it returns the recorded result.workspaces:writeWrite / external effect
agency_enrollment_owner_saveLets the client owner replace the intake facts on their own enrollment link. Requires the owner who claimed the link and the session's current revision. Saving clears any earlier owner approval, so the owner must approve again.workspaces:writeWrite / external effect
agency_enrollment_createCreates an enrollment session for 1-50 existing or new clients against a published offer version and returns one owner approval link per new client. Requires an agency owner, admin or operator with access to each existing client, and an idempotency key; a replay returns the session without the links. It sends no email and installs nothing.workspaces:writeWrite / external effect
agency_enrollment_saveReplaces the client entries of an uncommitted enrollment session. Requires the session creator (or an agency owner/admin) and the current session revision. Saving revokes all outstanding owner approval links for the batch, so owners must be sent new links.workspaces:writeWrite / external effect
agency_enrollment_previewChecks every client in the batch for missing facts, owner approval and payer conflicts, and returns what enrolling would install, with the fingerprint and approval IDs needed to enroll. Requires an agency owner, admin or operator. It records the preview on the session but installs nothing.workspaces:writeWrite / external effect
agency_enrollment_enrollCommits the previewed batch: creates new client businesses, records owner approvals and queues package installations for every ready client; installations later configure each client voice agent. Requires an agency owner, admin or operator who created the session, its idempotency key, and the fingerprint and revision from preview. Clients that are not ready are reported with their next step instead of being installed.workspaces:writeWrite / external effect
agency_enrollment_claim_ownerLinks the signed-in client owner to their enrollment link using its token. The user's verified email must match the owner email on the link. It approves nothing.workspaces:writeWrite / external effect
agency_enrollment_approve_ownerRecords the client owner's approval of the exact offer and intake facts on their enrollment link. Requires the owner who claimed the link, the session's current revision and its fingerprint. It does not enroll; the agency still enrolls the batch.workspaces:writeWrite / external effect
agency_enrollment_rotate_owner_linkIssues a new owner link for a client in the batch and invalidates the old one, clearing any earlier claim and approval. Requires the session creator (or an agency owner/admin) and the link's current revision. It sends nothing; the returned link is delivered by whoever re-issued it.workspaces:writeWrite / external effect
agency_enrollment_revokeRevokes an enrollment session and all of its owner links so nothing more can be approved or enrolled from it. Requires the session creator or an agency owner/admin. Installations that were already enrolled are not removed.workspaces:writeWrite / external effect
agency_installation_preview_route_receiptReturns the evidence that a real call reached the client's voice line and produced a delivered lead notification, with a fingerprint for acknowledgement. Only for voice intake installations whose training is complete, and only the client owner who received that notification can view it. It changes nothing.workspaces:writeRead-only
agency_installation_approve_route_receiptRecords the client owner acknowledging the route test receipt they reviewed. Requires the client owner who received the notification and the fingerprint from preview_route_receipt. It does not place any call.workspaces:writeWrite / external effect
agency_installation_preview_handoffReturns the staff handoff for an installation with a fingerprint for approval. Requires client membership or agency assignment to the client. It changes nothing.workspaces:writeRead-only
agency_installation_approve_handoffRecords the client owner approving the exact staff handoff they reviewed. Requires the client owner and the fingerprint from preview_handoff.workspaces:writeWrite / external effect
agency_installation_resolve_updateChooses, for each conflicting setting in a proposed package update, whether to keep the client's current value or use the package value, and saves the resolved update. Requires the client owner and the update's fingerprint; client facts cannot be overridden this way. It does not apply the update, and the resolved version needs fresh owner approval.workspaces:writeWrite / external effect
agency_installation_run_scenariosRun approved verification scenarios for an existing client installation at its expected revision using voice agent compute under existing entitlement. Requires current assigned client authority, current owner approval and evals:write. Saves test evidence and can incur irreversible usage charges; a new request key can run and charge again. Makes no real customer calls.workspaces:writeWrite / external effect
agency_installation_owner_previewShows the client owner the exact intake facts and voice script prepared for their business, with the hashes needed to approve each. Only the client owner can view it, and only after the agency prepared a complete preview. It changes nothing.workspaces:writeRead-only
agency_installation_approveRecords the client owner approving either the intake facts or the voice script they reviewed. Requires the client owner and the matching hash from owner_preview. It does not install anything by itself.workspaces:writeWrite / external effect
agency_installation_revoke_approvalWithdraws one of the client owner's earlier approvals. Requires the client owner. Work that depends on that approval waits until it is approved again.workspaces:writeWrite / external effect
agency_installation_pausePauses an installation so its package setup and scheduled package work stop. Requires agency write access to the client or the client owner, and the current revision. It does not delete anything; use retry to queue it again.workspaces:writeWrite / external effect
agency_installation_retryRe-queues an installation so setup runs again, clearing its last error; setup configures the client's voice agent. Requires agency write access to the client or the client owner, and the current revision.workspaces:writeWrite / external effect
agency_installation_exportReturns the installation release, intake facts, approved script, staff sheet and checks for handoff or records. Requires client membership or agency assignment to the client. It changes nothing.workspaces:writeRead-only
agency_installation_preview_offboardShows what offboarding would stop and what it keeps (phone number, sender, connections, billing plan and history), with a fingerprint for approval. Only the client owner can view it. It changes nothing.workspaces:writeRead-only
agency_installation_offboardStarts offboarding: stops the package's jobs, revokes its future automation authority and turns off its scheduled reports. Requires the client owner, accepted set to true and the fingerprint from preview_offboard. The phone number, connections, billing plan and history are kept.workspaces:writeWrite / external effect
agency_installation_preview_updatePrepares a proposed update to a newer published offer version, or a rollback to an earlier installation revision, and lists any conflicts with client changes. Requires agency write access to the client or the client owner. It saves the proposal for review but does not apply it; client facts are always kept.workspaces:writeWrite / external effect
agency_installation_approve_updateRecords the client owner approving the updated script of a proposed update. Requires the client owner, the updateId and its fingerprint. It does not apply the update.workspaces:writeWrite / external effect
agency_installation_apply_updateApplies an approved update and re-queues setup, which replaces the client's live voice agent configuration. Requires agency write access or the client owner, a resolved update with no open conflicts, fresh owner approval, and (unless this client is the canary) an active canary on the same release. Applying an already-applied update changes nothing.workspaces:writeWrite / external effect
agency_installation_opt_into_canaryMarks the client's installation as a canary, so it can receive package updates before other clients of the same agency. Requires the client owner and accepted set to true. It applies no update by itself.workspaces:writeWrite / external effect
agency_report_generateGenerate and save an activity report snapshot for an existing client installation at its expected revision. Requires current client membership and agency access. Queues report email for due owner-approved subscriptions to existing verified client members and advances their schedule; queued does not mean delivered.workspaces:writeWrite / external effect
agency_report_configureSets the weekly or monthly activity report email schedule for an installation and replaces the previous recipient list. Requires the client owner; recipients must be verified members of the client's business. The first report is sent by the scheduled job, not by this call.workspaces:writeWrite / external effect
agency_billing_retry_collectionRetries payment of an existing open wholesale invoice with the agency's verified payment method. Requires the agency owner and a ready collection method; a paid invoice is reported, not charged again. Settlement is confirmed later by the payment provider.billing:writeWrite / external effect
agency_billing_record_adjustmentRecord an already-issued provider credit note or debit invoice against an existing agency billing line. Platform finance operators only: requires the existing admin key and wildcard scope; agency owner status is insufficient. Verifies exact provider receipt, currency and amount before recording bookkeeping. Creates no invoice, payment or subscription.billing:writeWrite / external effect
agency_billing_set_planPuts a partner-created client on an agency-billed plan, or stops it when plan is null. Requires the agency owner who is also a client admin; starting a plan needs accepted terms and a ready collection method. Stopping parks the client service, which detaches its phone numbers from the voice agent under the existing parking policy.billing:writeWrite / external effect
agency_billing_set_automatic_collectionTurns monthly automatic collection of wholesale charges on or off under the accepted terms. Requires the agency owner and accepted terms; it cannot be turned off while any client is on an active partner plan. It charges nothing by itself.billing:writeWrite / external effect
agency_billing_publish_termsPublishes a new set of wholesale commercial terms (discount, grace days, document and start date) for one agency, or for all agencies when partnerId is null. Platform commercial operators only. Each call publishes another version; agencies must still accept it.billing:writeWrite / external effect
agency_billing_accept_termsAccepts published wholesale terms for the agency and applies their discount. Requires the agency owner, and the terms must be in effect and apply to this agency. It charges nothing and doesn't set up payment.billing:writeWrite / external effect
agency_billing_setup_collectionCreates the agency's customer record at the payment provider if needed and returns a hosted link where the owner adds a payment method. Requires the agency owner and accepted terms. It charges nothing, and the method is ready only after the provider confirms it.billing:writeWrite / external effect
agency_billing_freeze_periodCalculates and locks the wholesale statement for one closed calendar month (UTC) from the agency's billable client intervals. Requires the agency owner. Freezing the same month again returns the same period; it does not charge.billing:writeWrite / external effect
agency_billing_collectCreates and finalizes the payment provider invoice for a frozen billing period and charges the agency's verified payment method automatically. Requires the agency owner and a verified collection method. Repeating it reuses the same invoice instead of charging twice.billing:writeWrite / external effect
agency_care_preview_reviewShows the exact review-request text, sender number and recipients for customers with a completed service, with a fingerprint for approval. Requires the client owner, the sms:write scope, and an SMS review installation where Kai is confirmed as the review tool. It sends nothing and saves nothing.workspaces:writeRead-only
agency_care_prepare_reviewSaves the approved review-request texts as a draft campaign and reserves the listed customers. Requires the client owner, the sms:write scope, accepted set to true and the fingerprint from preview_review. It sends nothing; launch_review sends it.workspaces:writeWrite / external effect
agency_care_launch_reviewLaunches the approved review-request campaign, queuing text messages to the listed customers from the business number. Requires the client owner, the sms:write scope, accepted set to true and the fingerprint from preview_review. A campaign that is already sending can't be launched again.workspaces:writeWrite / external effect
agency_support_acknowledgeMarks an agency incident as acknowledged and assigns its follow-up to you. Requires an agency owner, admin or operator. It does not resolve the incident; recovery is confirmed separately.workspaces:writeWrite / external effect
agency_support_measureRecords time spent or money for one client (setup, support, fulfillment, provider cost or retail receipt) with a note. Requires an agency owner, admin or operator with write access to that client. Each call adds a new record.workspaces:writeWrite / external effect
agency_support_complete_exerciseSave completion evidence for a named operational exercise on an existing client installation. Requires current assigned client authority. Replaces any previous proof reference and completion time for that exercise; does not prove live customer delivery.workspaces:writeWrite / external effect
get_agency_workspaceRead assigned installations, grouped support incidents, accepted billing evidence (also billing:read), or inventory one authorized client's saved facts and actual channel readiness. Suggestions and unknowns remain explicit.workspaces:readRead-only
request_extra_numberReserve an exact pool number and request an owner-only browser review of its recurring extra-line price. Requires numbers:write and billing:write. It never charges included or prepaid capacity; included allocation goes through attach_number. This tool does not approve payment or prove activation.billing:writeWrite / external effect
get_extra_number_statusRead an owner-authorized extra-number request. Billing, assignment and live activation are distinct. Unknown checkout or provider outcomes retain the original request and number, so no replacement purchase is needed or started.numbers:readRead-only
retry_setupReconcile database pointers for an existing imported signup phone reservation. Owner-only, entitlement-checked, single-flight and idempotent. Never creates agents, buys numbers, changes provider routing or sends messages. PBX, missing imports, and stale claims return review blockers. Reusing the same key reads or replays the outcome; a failed request is held for review before a new key is accepted. Ready means database agreement, not activation.numbers:writeWrite / external effect
get_setup_recovery_statusRead an owner-authorized setup recovery request by its business and idempotency key. Running requests are never automatically stolen, including stale requests. A ready receipt does not prove live activation.numbers:readRead-only
make_callPlace an outbound call through a KaiCalls AI agent: call back a customer who previously called this business, give the owner a voice preview, or call on the owner's behalf (a landlord, clinic, pharmacy, school or utility) with the task in context. For a customer callback, pass the existing lead_id and callback goal in context. Kai verifies the business's inbound-call consent for the exact destination; a verified callback can go directly to a cell phone without connecting the owner. Contact existence alone is not callback permission, and opt-outs still block calls. A call never proves inbound routing or advances activation. report_language sets the language the result is reported in, and Kai then confirms exact details for that reader; Kai speaks call_language (English by default) on the phone. A new account's first call to a US or Canada business line is free; after that the account needs a plan. Kai calls businesses, not personal cell phones, on a free call. An idempotency_key makes the request safely retryable.calls:writeWrite / external effect
check_call_statusCheck the status of a call by its ID, and any question Kai is waiting on (pending_question)calls:readRead-only
answer_call_questionSend the person's answer to a live call's pending_question, or decline. Send only what they said; answered once.calls:writeWrite / external effect
join_callJoin a live errand call. take_over connects the person's own phone; listen returns a signed-in dashboard link.calls:writeWrite / external effect
list_recent_callsList recent calls for the authenticated businesscalls:readRead-only
get_transcriptGet the transcript and summary of a completed callcalls:readRead-only
share_call_exampleOwner only: publish a finished errand call as a redacted transcript example (no audio, business shown as a category). Call once for a preview, show it, then confirm with its preview_hash.calls:writeWrite / external effect
unshare_call_exampleOwner only: take a shared call example down.calls:writeWrite / external effect
get_call_recordingGet the real call recording URL for a call so reviewers can listen to the voice/audio instead of relying only on the transcript.calls:readRead-only
list_agentsList the KaiCalls agents on the authenticated account. Shows whether this business already has a secretary answering its calls.agents:readRead-only
get_business_infoRead back what a business already has: profile details, how many agents are configured, and recent call volume. This shows whether a business number that answers missed calls already exists. When the business has no working phone line yet, `next_step` names the tool that sets one up.agents:readRead-only
get_operational_settingsRead the business-level operational setup of a live account: staff alert recipients, SMS/email alert flags, escalation rules, textable send-link entries, and assigned agent voice/model/greeting metadata.agents:readRead-only
configure_staff_alertsSave business-owned staff alert recipients and post-call escalation rules. Saving settings does not prove provider delivery or owner receipt; activation notification proof is tracked separately.agents:writeWrite / external effect
get_activation_statusRead current call readiness and persisted private-test proof for one accessible business. Only a currently entitled owner with a coherent assigned number gets the existing private-test setup link. Missing entitlement, incomplete setup or stale sessions do not authorize a call. It cannot assert or advance proof. A completed private test is separate from customer-route coverage; forwarding is optional and does not define whether the assigned phone works.agents:readRead-only
confirm_notification_destinationAPPROVAL-GATED. Save the owner-approved phone number (SMS) or email address where KaiCalls sends the owner the result of their first test call, for the exact active activation session. Once that test call's record is ready, KaiCalls sends a real text or email to that destination through its messaging provider; saving the destination alone is not proof anything was delivered. Replaces any destination saved earlier for the session.agents:writeWrite / external effect
retry_activation_notificationAPPROVAL-GATED. Send the owner's activation notification again, as a real text or email through KaiCalls' messaging provider, for the exact active activation session. Only retries a channel whose last attempt failed or has waited long enough; an attempt whose outcome is unknown is never blindly resent. Requires a new idempotency_key.agents:writeWrite / external effect
choose_customer_routeAPPROVAL-GATED. After private-test proof is complete, save forwarding, published_number, both, or testing. This unlocks the command center but does not claim customer coverage; selected customer routes remain pending until independently verified. Forwarding is optional; testing keeps the existing private-test result without connecting a customer route.numbers:writeWrite / external effect
configure_textable_linksCreate or repair the business_links entries used by the send_link/send_sms tools. These entries let callers receive booking, directions, cancellation, sister-location, or service-specific links by text without raw URLs in the voice prompt.agents:writeWrite / external effect
configure_agent_business_rulesSafely add or replace a named operational rules section inside an agent inbound prompt, then route the prompt patch through the governed agent.patch broker. It covers cross-business handoffs, callback language, alert promises, and client-specific operating rules, and leaves the rest of the prompt unchanged.agents:writeWrite / external effect
list_leadsList leads for the authenticated business, with optional status/source/agent filters. Includes the latest AI lead score when available.calls:readRead-only
get_leadGet full details for a single lead by ID, including the latest AI lead score and explanation.calls:readRead-only
list_voicemailsList recent voicemails for the authenticated business, including transcripts and recording URLs.calls:readRead-only
list_sms_messagesRead SMS and WhatsApp message evidence for accessible businesses (sms:read), including provider message ID, carrier status, delivery/failure timestamps and failure code. Filter by business_id, conversation or direction. Provider acceptance is not delivery; delivered_at and carrier status record delivery. Mirrors GET /api/v1/sms/messages; uses offset pagination.sms:readRead-only
list_campaignsList outbound call campaigns for the authenticated business.calls:readRead-only
create_campaignCreate an outbound call campaign (cadence + lead batch) and optionally launch it immediately. Launching queues calls for the orchestrator; existing TCPA/consent gating still applies at dial time. Requires admin role on the business.calls:writeWrite / external effect
launch_call_campaignStart or resume an existing outbound call campaign so Kai begins calling its leads. Needs campaign_id and agent_id (an agent assigned to the same business), the calls:write scope and an admin role in the business. Queues the campaign's pending calls within its call windows; real people get phone calls once it runs. A queued result does not mean any call was answered or completed. pause_call_campaign stops it. Not for email campaigns.calls:writeWrite / external effect
pause_call_campaignPause an outbound call campaign. Stops its queued and scheduled calls and cancels pending call attempts; a call already in progress may finish. Leads are kept and the campaign can be resumed later with launch_call_campaign. Needs campaign_id, the calls:write scope and an admin role in the business. Pausing an already paused campaign changes nothing.calls:writeWrite / external effect
list_workflow_templatesList the cadence/campaign workflow templates KaiCalls can run (standard, aggressive, nurture, custom), including each template's retry interval, defaults (call windows, days, attempts), and a ready-to-use cadence_config example. The cadence_config examples match the shape create_campaign accepts, including multi-step sequences with launch=true. Static catalog — no per-business state.calls:readRead-only
get_analyticsGet a dashboard summary (lead counts by status, conversion rate, call volume and duration, top agents, and business outcomes by type) over a recent time window.calls:readRead-only
upsert_leadCreate a new lead or update existing leads for the authenticated business, routed through the governed leads API (business access-checked, usage-logged, and audited). To create one, pass `lead` with at least one of name/phone/email plus optional status/source/notes/agent_id/etc. To update, pass `updates`: an array of { id, ...fields } for one or many existing leads (status, name, phone, email, notes, address, city, state, zip). Updates are access-checked per row and report partial success.leads:writeWrite / external effect
send_smsSend a text from an agent's phone line through the governed messaging API. Provide from_agent_id, to, and message. For the immediate confirmation a customer just requested on a booking form, add purpose: booking_confirmation, the form's actual sms_consent: true, and idempotency_key; this records service consent and allows the requested confirmation after hours. Booking alerts to this business's active admin phone use purpose: booking_alert and idempotency_key. Explicit opt-outs, content controls and rate limits remain enforced. Use dispatch_policy: queue_if_needed to defer ordinary messages outside their allowed window. Optionally link lead_id; it must belong to this business and match the recipient phone.sms:writeWrite / external effect
update_agent_configEdit an agent's live runtime configuration — greeting/first message, inbound or SMS prompt, voice, language model, max call duration, and call-transfer settings — routed through the governed update broker so every change keeps the consent + audit trail (a versioned config snapshot and change history). Every write here is reversible: get_change_history and list_config_versions list what changed, and rollback_config undoes it. Mutating changes need an idempotency_key. When the business owner or an admin is signed in through this connector, their own changes apply immediately. High-impact live changes made with an API key or on someone else's behalf queue for the owner's review instead (the owner is notified with a review link). configure_agent_business_rules edits a single named operational-rules section.agents:writeWrite / external effect
request_emergency_addressSet the emergency (E911) service address for one of the business's phone numbers with the phone carrier, so a 911 call from that line reaches the right dispatcher. Needs phone_number, the full street address and disclosure_acknowledged true after the owner reads the 911 notice, plus the owner's confirmed approval. Replaces any address on file for that number. Returns needs_user_input, needs_approval, pending_approval, executed, denied or unsupported; only executed means the change was made.numbers:writeWrite / external effect
request_transcript_webhookCreate or update a webhook that receives the business's completed-call events (which can include transcripts) at a URL the business controls. Needs webhook_url and the owner's confirmed approval because call data leaves KaiCalls. A new webhook's signing secret is returned once. Returns needs_user_input, needs_approval, pending_approval, executed, denied or unsupported; only executed means the change was made.webhooks:writeWrite / external effect
request_agent_updateChange a live agent's name, greeting, prompts, voice, model, call length or call transfer through the approval-gated path, for changes made on the owner's behalf that need a recorded approval. Needs agent_id, at least one field to change and the owner's confirmed approval. Callers hear the change on their next call. Direct edits by the owner go through update_agent_config. Returns needs_user_input, needs_approval, pending_approval, executed, denied or unsupported; only executed means the change was made.agents:writeWrite / external effect
request_number_purchaseBuy a specific available phone number for the business from the phone carrier, with the owner's confirmed approval. The carrier bills the number to the business right away. Available numbers come from search_available_numbers. Optionally connects it to agent_id. Returns needs_user_input, needs_approval, pending_approval, executed, denied or unsupported; only executed means the change was made.numbers:writeWrite / external effect
request_config_rollbackPut a live agent back on a saved earlier version of its configuration (listed by list_config_versions), with the owner's confirmed approval. Replaces the current live configuration; callers hear the restored version on their next call. Needs agent_id and version_number or version_id. Returns needs_user_input, needs_approval, pending_approval, executed, denied or unsupported; only executed means the change was made.agents:writeWrite / external effect
join_meetingSend Kai into a Zoom, Google Meet, Microsoft Teams or Webex meeting by its link. Kai joins under the agent name, takes notes, and emails the owner a summary when the meeting ends. If the meeting has a waiting room, the host must admit Kai. In the default listen mode it answers out loud when someone says its name and counts against the plan's monthly meeting minutes (a business whose plan includes none gets its first hour free, once); avatar mode joins with a talking video face and counts one avatar meeting. Mirrors POST /api/v1/meetings.agents:writeWrite / external effect
get_meetingList the meetings Kai was sent into (newest first), or one meeting by id with its live status, minutes used and summary, plus the plan's remaining meeting minutes this month. Mirrors GET /api/v1/meetings.agents:readRead-only
leave_meetingHave Kai leave a video meeting it is in, or stop trying to join one. Kai drops out of the live call for everyone in it and stops taking notes; this cannot be undone, and joining again takes a new join_meeting request. Notes taken so far are kept and can be read with get_meeting. Mirrors DELETE /api/v1/meetings.agents:writeWrite / external effect
get_usageList recent API usage events (endpoint, method, status code, cost) for the caller's account. Mirrors GET /api/v1/usage.events:readRead-only
list_plansRead the canonical public KaiCalls plan catalog, monthly USD prices and allowances. Does not select a plan, create checkout, or change billing.billing:readRead-only
get_checkout_statusRead a Stripe-verified subscription checkout receipt for a business you own. Requires business_id and session_id from checkout. Confirmed billing does not prove agent, number, or call activation; get_activation_status reports setup proof. This tool never creates checkout or retries provisioning.billing:readRead-only
send_messageSend one message to a business's customer on the channel you choose: a text (sms) from one of the business's agent lines, or a WhatsApp message from its connected WhatsApp number. The same consent, Do-Not-Call, quiet-hours and rate gates as the dashboard apply, and a refusal says which one. sms needs from_agent_id; whatsapp needs a number the owner connected to WhatsApp (pass from when there is more than one) and a customer who messaged that number in the last 24 hours. Email is not sent here; draft_email_campaign drafts a campaign the owner reviews and approves. business_id is required when the account has more than one business. The result reports that the provider accepted the message, not that it was delivered.sms:writeWrite / external effect
request_email_senderSet up a sending address for a business's email campaigns on a domain the business controls (for example mail.example.com). Registers the domain with the email delivery provider and returns the DNS records the owner must add where the domain is hosted. May replace an existing reply address, enabled state and sending limit, and may provision provider inbound routing, inbox and webhook. Sends no email. The sender becomes ready on its own once the records verify; check_email_sender re-checks now. Needs an admin of the business. Campaign email only goes from the business’s own verified sending domain, to customers with recorded email permission who are not on the do-not-email list, within the daily amount the business’s Kai level allows.emails:writeWrite / external effect
check_email_senderRe-check a sending domain's DNS records with the email delivery provider now and replace its saved verification proof; may finish provider inbound routing, inbox and webhook setup. Returns what is still missing; an empty list means the sender is ready. Sends no email. Any member of the business may check.emails:writeWrite / external effect
record_email_consentRecord that existing customers gave the business permission to email them, with evidence_ref saying where that permission came from. Pass lead_id and email for one customer, or emails for up to 200. Addresses that are not existing customers are skipped and listed. Sends no email. Needs an admin of the business. Each record states that the owner holds that permission.emails:writeWrite / external effect
revoke_email_consentTake back email permission for existing customers so no campaign can email them. Pass lead_id and email for one customer, or emails for up to 200, with evidence_ref saying why. Needs an admin of the business.emails:writeWrite / external effect
draft_email_campaignSave an email campaign for the owner to review: a subject, a plain-text body, the customers to email (lead_ids, each with recorded email permission) and the verified sender. Returns the campaign id and the fingerprint of this exact revision. Sends nothing; the owner approves it with approve_email_campaign and it only goes out after launch_email_campaign. Needs an admin of the business. Campaign email only goes from the business’s own verified sending domain, to customers with recorded email permission who are not on the do-not-email list, within the daily amount the business’s Kai level allows.emails:writeWrite / external effect
approve_email_campaignThe business owner approves one exact revision of a drafted email campaign, named by campaign_id and the fingerprint returned by draft_email_campaign or get_email_campaign. A changed draft has a new fingerprint and needs a new approval. Sends nothing; launch_email_campaign queues it. Business owner only.emails:writeWrite / external effect
launch_email_campaignQueue an owner-approved email campaign for sending to real customers, within its daily limit. Business owner only. Emails cannot be unsent once delivered; cancel_email_campaign stops what has not gone out yet. A queued result is not proof any email was delivered. Campaign email only goes from the business’s own verified sending domain, to customers with recorded email permission who are not on the do-not-email list, within the daily amount the business’s Kai level allows.emails:writeWrite / external effect
cancel_email_campaignStop an email campaign so nothing more is sent from it. Emails already delivered stay delivered. Needs campaign_id and the fingerprint of its current revision. Business owner only.emails:writeWrite / external effect
get_email_campaignRead a business's email campaigns: its sending addresses and their setup readiness, recent campaigns with status, revision fingerprint and outcome counts, and the customers who can be emailed (recorded consent, not on the do-not-email list). Pass campaign_id for one campaign, or sender_id for the DNS records that sending address's domain needs. Read-only; any member of the business can read.emails:readRead-only
set_conversation_ownerSet who answers a customer's text conversation. owner 'ai' (the default): Kai replies. 'human': Kai stays quiet and the business owner answers. 'external': Kai stays quiet and the business's own system answers; it receives the sms.received webhook and replies with send_message or POST /v1/messages. With external_reply_timeout_seconds (external only, 60 to 86400), Kai answers a message nothing replied to in that time. Messages are always stored and sms.received always fires. Pass conversation_id for one conversation, or phone for every conversation the business has with that customer. Re-sending the same owner changes nothing.sms:writeWrite / external effect
get_business_verificationRead tenant-scoped business-verification document references, pending/approved/rejected staff-review states and secure upload requirements. No file bytes, storage paths, signed URLs or tax identifiers. Uploads happen on the secure owner page, by an admin; rejected documents can be corrected and uploaded again. Internal staff verification is separate from carrier registration. Reviewer notes are returned as staff-written data.workspaces:readRead-only
submit_text_registrationReserved submission contract; execution is currently unavailable and returns submission_unavailable without filing. Shared durable reservation and unknown-outcome reconciliation across dashboard, checkout and cron are prerequisites. Preparation and status are handled by get_text_registration and save_text_registration_details. Saving corrected details does not resubmit existing rejected provider objects: operator reconciliation is required. Another entry point or a new paid registration would duplicate the filing. It accepts no tax identifiers, credentials, file contents or legal attestations. Owner membership and billing:write required.billing:writeWrite / external effect
get_text_registrationRead where a business stands on its own carrier registration for business texting: saved details (never the EIN; only whether one is on file), payment, filing stage, whether sales texts are allowed, and the one next step. In MCP, `known` excludes fields the canonical flow still requires the owner to confirm; `suggestions` preserves those nonprivate values and available provenance. `missing` is the ordered outstanding field-question list, with missing_value or confirmation_required reasons; `next_question` is its first item. `question_progress` counts field questions including next, not website screens. Website screens group several fields and may include a private identity step; unequal counts can be valid. The MCP presentation separates configured registration/enrollment from recipient-specific sending permission and delivery, which remain not_checked. A null own registration does not prove an enrolled platform route cannot text; configured lines do not prove a send is authorized. Dashboard/API presentation is unchanged. Read-only.billing:readRead-only
save_text_registration_detailsSave a business's legal name, entity type, industry, website, address, authorized contact and what it will text (service only, or service and sales) for its own carrier registration. Business owner only. Each field holds an answer from the owner; anything omitted is filled from what is already on file (see get_text_registration `known`). Answers can be saved one at a time: answers given so far are kept, and while questions remain the result lists `saved_steps`, `missing` and `next_question`. The owner can finish here or on the registration page. Never takes the EIN: the owner types it on the registration page returned as setup_url. Each saved answer replaces the value on file for that field. Refused once a filing is already with the carriers. Charges nothing and files nothing.billing:writeWrite / external effect
start_text_registration_checkoutCreate the payment link for a business's own carrier registration (a one-time filing fee plus a monthly campaign fee). Business owner only, and only once the details and the EIN are saved. Returns checkout_url for the owner to open and pay; nothing is charged by this tool, and filing starts only after payment. A checkout_url means neither payment nor filing. On a plan that includes registration there is nothing to pay: the tool sends it to the carriers straight away and returns included_in_plan and filed true instead of a link, so that path requires confirm_submission true, which records that the owner reviewed and confirmed the saved details and external submission. Submission is not carrier approval. The tool takes no EIN, document contents, credentials or legal attestations.billing:writeWrite / external effect
set_branded_caller_idFile the business name that landlines show when the business's number calls out (caller ID name). Included with the business's own text registration once it is paid; charges nothing. Business owner only. The name must be at most 15 characters, start with a letter, and use only letters, numbers, periods, commas and spaces (get_text_registration returns a suggestion in branded_caller_id.suggestedName). Files with the carriers once the business profile is approved; review then takes a day or two and carriers show it within 72 hours. US local numbers only. The result confirms the filing, not that the name is showing on calls.billing:writeWrite / external effect
create_customer_workspaceCreate a new KaiCalls account for a business, owned by the business owner's own email address. It lets a partner or helper set up KaiCalls for a business owner. The account starts without a plan or phone number: the result includes a link the owner opens themselves to choose a plan and add their card, and the line is set up only after they pay. This tool charges nothing. By default the caller is added as an admin of the new account so they can continue setup (get_setup_checklist lists the steps); join_as_admin false skips that. partner_code credits a referring partner and does not apply to a partner's own account. Fails, creating nothing, if the email already has a KaiCalls account.workspaces:writeWrite / external effect
set_up_businessOptional line customization: sets the business name and greeting Kai answers with, as the owner requested. Not required to make calls, and never changes payment, usage or fraud limits. Extra business details are optional; no business-qualification questionnaire is needed. An existing business greeting is left unchanged.workspaces:writeWrite / external effect
get_setup_checklistRead where one business stands on setup: plan, phone number, texting registration, WhatsApp, call and lead alerts, connected mailbox for follow-up email, and email campaign sender. Each step has a state (done, in_progress, needs_owner, needs_action or unavailable) and one next action: either the tool that moves it forward, or the page the owner must open for steps only they can do, such as paying, typing their EIN or signing in to Facebook or Google. Read-only; changes nothing and contacts no one.workspaces:readRead-only
connect_whatsappGet the one link a business owner opens to put WhatsApp on their KaiCalls number. They sign in to Facebook as an admin of the business's Meta Business account and verify the number; the business owns its WhatsApp account. Uses the business's oldest KaiCalls line unless phone_number names another of its lines. Returns the same link while it is still valid (up to 3 days). Owner or admin only. Creates nothing billable and connects nothing by itself: get_whatsapp_status reports the connection after the owner finishes, and WhatsApp is not connected until it says so.sms:writeWrite / external effect
get_whatsapp_statusCheck whether WhatsApp is connected on a business's KaiCalls number, read live from the carrier. Connected only once the number is verified for WhatsApp; otherwise says whether the owner's link is still waiting, expired or failed.sms:readRead-only
get_channel_statusRead customer channel setup. Phone calls report configured number resources only: state configured or needs_setup, with canSend/canReceive null because operational availability is unknown. SMS has state not_checked and null send/receive flags; shared_setup_state retains the existing configuration summary, not recipient-specific permission. Registration detail requires billing:read; this SMS-scope summary reads no new billing details. Other channels retain their existing states and flags. private_test_readiness checks owner-private call setup only when the token also has agents:read; otherwise it is not_checked with reconnect scope guidance. Private testing does not establish customer coverage or outbound call permission, which remain not_checked. Email includes separate managedEmail campaign sender readiness; a connected mailbox does not prove campaign approval or delivery. Read-only; changes nothing.sms:readRead-only
get_trust_levelRead one business's KaiCalls trust level (Sprout, Verified, Trusted, Pro, Partner): the current level, the steps to the next one with progress, what each level unlocks, today's outbound calls and texts against current effective account limits, and any hold. Badge progress does not itself establish higher call or text caps. focus 'ladder' explains every level; focus 'level' with level explains one. Read-only: returns saved standing or computes missing/stale standing without saving it or sending notifications. recheck_trust_level recomputes and saves current standing. Levels are earned, never set: no tool can raise one.agents:readRead-only
recheck_trust_levelRecompute one business's KaiCalls trust level now from its live account activity (card on file, paid bills, days active, real customer calls) and save the result, the same recheck the dashboard runs, for example right after the owner adds a card. Returns the same view as get_trust_level plus whether the level moved up or down. Requires current business membership. Replaces the saved derived state, may record level-change history and may email the current owner when standing changes. It can only reflect what the account has earned; it never sets or raises a level by request.agents:readWrite / external effect
get_balanceGet plan terms and usage for accessible businesses. No-card trials report 25 lifetime minutes, zero price and no overage; paid plans report the mapped subscription price and billing-cycle usage. Answered-call allowance usage is the raw billable call count, matching dashboard and right-sizing. A separate weighted count is informational only, not allowance consumption or right-sizing. Phone allowance includes purchased extra lines. A balance does not prove activation or inbound routing. Mirrors GET /api/v1/balance; unavailable billing data returns an error.billing:readRead-only
create_checkoutCreate, or reuse, a secure payment page hosted by Stripe where the business owner pays for a KaiCalls plan from list_plans with their own card. Needs business_id, plan_id and an idempotency_key: retrying with the same key returns the same page, and choosing a different plan needs a new key. This tool charges nothing; only the owner can pay, by opening the page themselves. It never proves payment or that the phone line is live: get_checkout_status reports payment for the returned session_id.billing:writeWrite / external effect
list_numbersList phone numbers assigned to the accessible business(es), with capability and compliance flags. Assignment does not prove a successful inbound test or customer coverage. get_activation_status reports current readiness and private-test proof. Forwarding is an optional customer route. Mirrors GET /api/v1/numbers.numbers:readRead-only
get_phone_flowRead how calls ring on the business's hosted phone system: which cells and desk phones ring, for how many seconds, and whether after-hours callers go straight to Kai. Reconciled from the phone system on every call. Mirrors POST /api/v1/phone-system action=get_flow. Returns 409 when the hosted phone system is not set up for this business.numbers:readRead-only
update_phone_flowReplace how calls ring on the business's hosted phone system with a full phone flow: { version: 1, hours: { mode: 'always' | 'business_hours', afterHours: 'kai' }, ring: { members: [{ kind: 'cell', phone: E.164, label, requirePressOne } | { kind: 'desk_phone' | 'user', userId, label }], timeoutSeconds: 5-120 }, overflow: 'kai' }. Applied idempotently (only real differences are written); every member passes the forwarding-loop guard; business_hours mode derives the schedule from the business hours already on file. Because it replaces the whole flow, the input is the full flow as get_phone_flow returns it, with changes applied. Mirrors POST /api/v1/phone-system action=save_flow.numbers:writeWrite / external effect
set_up_phone_systemTurn the business's number into a hosted phone system: Kai is installed as extension 700, the owner's mobile joins the list of phones to ring first, and calls reach Kai when nobody picks up. Idempotent and resumable — a re-run reuses everything already created and reports it under `reused`. Needs a complete US street address on file (the emergency-services and tax location) and the owner's mobile: when either is missing the tool fails with `code` missing_address or missing_owner_mobile plus `required_field` and `next_action` naming exactly what is missing, which business_address or owner_mobile accepts. Returns the status shape (existing setup IDs, extension and the phone-system line) and `next_step`, the owner's next action in one line (forward your line here / dial 700 from any office phone). Mirrors POST /api/v1/phone-system action=provision.numbers:writeWrite / external effect
get_phone_system_statusRead saved phone-system configuration: extension, resource IDs (never secrets), assigned line, and agreement. phone_system_configuration.configuration_allows_calls means provisioned resources plus a permitting agreement only; it does not verify calls can connect. ready_for_calls is null because operational availability is unknown. private_test_readiness uses the existing owner-private call setup authority only with agents:read; otherwise not_checked. Customer coverage and outbound call permission remain not_checked. This read differs from the shared phone-system API configuration flag and changes nothing.numbers:readRead-only
add_team_phoneAdd a teammate's (or the owner's) cell to the phones that ring before Kai answers. Idempotent — a cell already listed is reported as already included. Owners and admins are also registered on the admin roster, so calling the business line from that cell reaches the admin secretary; a member only rings. The business's own forwarded-from office line is refused (forwarding_loop) because ringing it would bounce the call straight back. Requires the phone system to be set up first (set_up_phone_system). Mirrors POST /api/v1/phone-system action=add_ring_group_member.numbers:writeWrite / external effect
list_conversationsList SMS conversation threads (counterparty timeline metadata) for the authenticated business, most recent first. Mirrors GET /api/v1/sms/conversations.sms:readRead-only
get_conversationGet a single SMS conversation thread by ID. Mirrors GET /api/v1/sms/conversations?id=.sms:readRead-only
get_webhookList the configured outbound webhook(s) for a business, including supported event types. Mirrors GET /api/v1/webhooks.webhooks:readRead-only
set_webhookCreate or update a business outbound webhook (URL + subscribed events). Returns a webhook secret on first creation only. Mirrors POST /api/v1/webhooks.webhooks:writeWrite / external effect
delete_webhookRemove a business outbound webhook by ID. Mirrors DELETE /api/v1/webhooks.webhooks:writeWrite / external effect
list_evalsList canned mock-conversation eval scenarios for an agent (or all accessible agents). Mirrors GET /api/v1/evals.evals:readRead-only
run_evalRun a saved test scenario against one of the business's agents and grade the agent's replies: pass eval_id for one scenario, or agent_id for every scenario saved for that agent (see list_evals). The test is a simulated text conversation with the agent's current live configuration; no phone call is placed, no customer is contacted and the agent's configuration is not changed. Each run uses paid voice-agent provider capacity and is recorded with its result. Returns pass or fail per scenario with the grader's reasons. Mirrors POST /api/v1/evals/run.evals:writeWrite / external effect
list_voicesList the curated, credential-free voice catalog (id, display name, accent, language, gender, sample URL) used to configure agent voices. Mirrors GET /api/v1/voices.agents:readRead-only
create_agentCreate a new KaiCalls agent — the secretary that answers this business’s calls (the live voice agent plus KaiCalls records) — with a system prompt, greeting, voice, and model. Mirrors POST /api/v1/agents. Every subsequent mutation to this agent is versioned (assistant_config_versions) and reversible via rollback_config — history is listed by get_change_history / list_config_versions. Compliance: KaiCalls automatically applies state-aware AI-disclosure and consent handling to every agent it provisions, and flags high-risk business categories for extra review.agents:writeWrite / external effect
attach_numberAssign a phone number already in the KaiCalls registry pool to a business (and optionally route it directly to an agent). Does NOT purchase a new number; search_available_numbers and buy_number handle purchases. Mirrors POST /api/v1/phone-numbers.numbers:writeWrite / external effect
set_owner_phoneSaves the owner's own mobile number on the business record (the number Kai texts whenever it takes a call for the owner) so Kai can ring it first and so activation/forwarding follow-ups can reach a human — connecting a number alone does not prove the owner can be reached. In the acquisition flow this step comes before search_available_numbers and buy_number (#2086). US numbers only; normalized to E.164 and rejected if it cannot be validated as a US mobile/landline number. When ring_first is true (default), also configures ring-first routing so calls hit this cell before overflowing to the secretary — the same path used at signup. declined=true, in place of owner_phone, records a caller who declines to give a number as an inquiry: a KaiCalls lead, with no provisioned business or number.agents:writeWrite / external effect
detach_numberRelease a phone number from a business back to the unassigned registry pool. Mirrors DELETE /api/v1/phone-numbers.numbers:writeWrite / external effect
search_available_numbersSearch the carrier for phone numbers available to purchase (live number inventory). Mirrors GET /api/v1/phone-numbers/search. In the acquisition flow this follows set_owner_phone, which saves a reachable owner number or records a decline.numbers:readRead-only
buy_numberRequest a real phone-number purchase. This is APPROVAL-GATED: the carrier bills immediately on execution, so the tool only prepares a request for authenticated owner review. Caller-supplied human_confirmed, dashboard_session, or system_policy fields never authorize execution. Returns the stored request and a review URL for the owner; while approval is pending, no number has been purchased. Existing entitlement and carrier reservation checks still apply. Mirrors POST /api/v1/phone-numbers/purchase via numbers.purchase. In the acquisition flow this follows set_owner_phone, which saves a reachable owner number or records a decline.numbers:writeWrite / external effect
list_knowledgeList agent knowledge base entries for a business. Mirrors GET /api/v1/knowledge.knowledge:readRead-only
upsert_knowledgeCreate a new agent knowledge base entry, or update one when `id` is provided. Mirrors POST /api/v1/knowledge. Creating requires title, content, and content_type.knowledge:writeWrite / external effect
list_productsList a business's agent product catalog. Mirrors GET /api/v1/products.products:readRead-only
upsert_productCreate a new product row, or update one when `id` is provided. Mirrors POST /api/v1/products. Creating requires name and business_id. Pass `quantity` to set/update inventory.products:writeWrite / external effect
list_config_versionsList an agent's hashed, redacted assistant config version history (rollback lineage included). Pass `version` to fetch one version's full redacted config_snapshot instead of the list. Mirrors GET /api/v1/agents/versions.agents:readRead-only
get_change_historyList an agent's recent config-change audit trail (change_type, change_source, old/new value, timestamp) from admin_change_history — the same record the admin_get_change_history voice tool reads over the phone. Every mutation KaiCalls makes to an agent (via update_agent_config, configure_agent_business_rules, the admin call-in secretary, or the dashboard) is logged here and reversible with rollback_config.agents:readRead-only
rollback_configRequest a rollback to a prior assistant_config_versions snapshot. This changes live greeting, voice, prompt and model settings. When the business owner or an admin is signed in through this connector, the rollback applies immediately; otherwise authenticated owner review of the exact stored request is required (the owner is notified with a review link). Caller-supplied authority fields never authorize execution. Targets are listed by list_config_versions and get_change_history; a pending request returns its review URL for the owner. The agent.config.rollback executor preserves version recording and secret exclusion after trusted approval.agents:writeWrite / external effect
list_observability_eventsList a business-scoped timeline of compact call-runtime events and redacted integration-delivery attempts. Mirrors GET /api/v1/observability-events and uses bounded keyset pagination.events:readRead-only
list_tool_execution_logsList per-call voice-agent tool execution traces — outcome, latency, timeout, and a redacted result preview for each routed tool call. Mirrors GET /api/v1/tool-execution-logs. Answers "did this tool call actually work".events:readRead-only
list_subscription_historyList plan/price change history from subscription_change_history — the billing analogue of admin_change_history, written from the Stripe webhook and the right-size apply job. Mirrors GET /api/v1/subscription-history.billing:readRead-only
list_overage_chargesList the idempotent overage-minutes ledger from billing_overage_charges (legacy per-minute-overage tiers only — 2026 plans carry no overage). GET /v1/balance/get_balance only returns an aggregate; this returns the underlying per-period ledger rows. Mirrors GET /api/v1/overage-charges.billing:readRead-only
list_rightsize_recommendationsList per-period auto-right-size decisions from plan_rightsize_recommendations, including the dry_run -> notified -> (kept | applied | superseded) lifecycle. Answers "is this business about to get right-sized". Mirrors GET /api/v1/rightsize-recommendations.billing:readRead-only
report_issueReport a problem with your KaiCalls agent, phone number, billing, or account. Saves the report to your change history and notifies KaiCalls support so a person can follow up on anything broken or not working as expected.support:writeWrite / external effect

Using the tools well

Recommended first read-only flow

Start with get_business_info, then list_agents, then list_recent_calls. Use returned IDs for check_call_status and get_transcript.

Structured results

Tool definitions advertise outputSchema, and tool responses include human-readable text plus machine-readable structuredContent containing stable fields such as call IDs, agent IDs, status, counts, pagination metadata, and error details. tools/list is public metadata for clients and directories; tools/call enforces authentication and scope checks before returning account data or taking action.

Pagination

list_recent_calls and list_agents accept limit and offset. If structuredContent.has_more is true, call the same tool again with offset set to structuredContent.next_offset.

Outbound calls

make_call places a real phone call. Clients should ask for explicit user confirmation, show the destination number and agent, and only call it with a token that has calls:write.

OAuth callback URLs (native clients)

Dynamic Client Registration (POST /api/oauth/register) accepts either callback mechanism a desktop MCP client offers:

  • A private-use URI scheme per RFC 8252 §7.1 — e.g. cursor://anysphere.cursor-mcp/oauth/callback or vscode://….
  • A loopback HTTP listener per RFC 8252 §7.3 — http://localhost:PORT/… or http://127.0.0.1:PORT/… on any port.
  • Any https:// callback, for hosted/web clients.

Plain http:// callbacks to non-loopback hosts, and script-capable schemes (javascript:, data:, blob:, file:, vbscript:), are rejected with invalid_client_metadata.

Verify with MCP Inspector

Before wiring up a client, confirm the server with the official inspector:

bash
npx @modelcontextprotocol/inspector # Transport: Streamable HTTP # URL: https://www.kaicalls.com/api/mcp # tools/list works without auth; run OAuth or add an API key before tools/call

You can also confirm the advertised inventory with curl https://www.kaicalls.com/.well-known/mcp.json.

Troubleshooting first setup

Client says "Needs authentication"

The URL is installed correctly, but you have not signed in yet. Open the client's connector manager and authenticate KaiCalls. In Claude Code, run /mcp inside an interactive session and choose KaiCalls.

Sign-in works, but the business you expected isn't there

Each connection is scoped to one business, chosen during sign-in. If you belong to several, pick the right one on the consent screen — to reach another, connect again and choose that one. If the account you signed in with has no business yet, that is not a dead end: sign-in walks you through creating one, including your phone number, and returns you to your assistant already connected. Seeing no business you recognise usually means you signed in with a different KaiCalls login than the one the business belongs to.

Bearer token clients get 401

Use a KaiCalls API key that starts with kc_live_ and pass it as Authorization: Bearer kc_live_.... MCP gateways may pass the same key as X-KaiCalls-API-Key: kc_live_.... Pasting the key into the URL or using a dashboard session cookie will not work.

A tool returns "Missing required scope"

Recreate the API key or reconnect OAuth with the needed scope. Read-only setup needs agents:read and calls:read; outbound calls also need calls:write.

Frequently asked questions

What is the KaiCalls MCP server?

It is the single URL — https://www.kaicalls.com/api/mcp — that connects your KaiCalls account to an AI assistant such as Claude, ChatGPT, Grok, or Manus. Once it is added, that assistant can read your KaiCalls calls, leads, voicemails, and analytics, and — with your permission — place outbound calls or update how Kai answers your phone, all scoped to one business you approve. MCP is the Model Context Protocol, the open standard that URL speaks; you do not need to know anything about it to use it.

How do I connect KaiCalls to ChatGPT?

The fastest way is the published KaiCalls app: open the KaiCalls listing in the ChatGPT app directory (chatgpt.com/plugins), click Connect, and sign in with your KaiCalls account. Alternatively, on a paid ChatGPT plan you can enable Developer mode and add https://www.kaicalls.com/api/mcp as a custom connector, then sign in the same way. ChatGPT signs you in through your own KaiCalls account — there is no API key to paste.

How do I connect KaiCalls to Claude?

In Claude (web or desktop), open Settings → Connectors → Add custom connector, paste https://www.kaicalls.com/api/mcp, and approve the KaiCalls sign-in screen. In Claude Code, run: claude mcp add --transport http kaicalls https://www.kaicalls.com/api/mcp and authenticate with /mcp. On Team and Enterprise plans an organization owner adds the connector first.

How do I connect KaiCalls to Grok?

Go to grok.com/connectors, click New Connector, choose Custom, and enter the KaiCalls MCP server URL https://www.kaicalls.com/api/mcp. Complete the sign-in when prompted — Grok supports OAuth or an API-key header. Grok then discovers the KaiCalls tools and makes them available in conversations.

How do I connect KaiCalls to Manus?

In Manus, open Settings → Integrations → Custom MCP Servers → Add Server. Enter a name (for example, KaiCalls), the server URL https://www.kaicalls.com/api/mcp, and a KaiCalls API key (kc_live_…) as the Bearer token. Create the key at kaicalls.com/dashboard/settings/api-keys. Manus tests the connection and lists the KaiCalls tools next to its built-in integrations.

Do I need an API key to connect?

Usually not. Hosted chat assistants (ChatGPT, Claude, Grok, Gemini, Mistral, Perplexity) sign you in with your normal KaiCalls account — you approve a consent screen and pick a business, with no key to paste. Developer tools (Claude Code, Cursor, VS Code, Windsurf, Manus) can instead use a KaiCalls API key sent as Authorization: Bearer kc_live_…, created in the KaiCalls dashboard under Settings → API Keys.

What can a connected AI assistant access, and is it safe?

Each connection is scoped to exactly one business that you pick on the KaiCalls consent screen, with explicit permission scopes. Read-only tools (calls, transcripts, leads, voicemails, analytics) are separate from write tools; placing a real outbound call requires the calls:write scope and client-side confirmation. You can revoke a connection at any time from your KaiCalls account.

How do I connect KaiCalls to Meta Muse?

In Meta Muse for Mac, open Settings → Connectors → Add MCP Server. Enter name KaiCalls and the server URL https://www.kaicalls.com/api/mcp. Sign in to your KaiCalls account and pick your business. For Muse Code (CLI), run: muse mcp add --transport http kaicalls https://www.kaicalls.com/api/mcp.

Which AI clients work with the KaiCalls MCP server?

Any client that supports remote MCP servers over streamable HTTP: ChatGPT (published app or Developer mode), Claude and Claude Code, Meta Muse (Mac and Muse Code), xAI Grok, Manus, Google Gemini (Spark custom apps and the Gemini CLI), Perplexity, Mistral Le Chat, Microsoft Copilot Studio, VS Code and GitHub Copilot, Cursor, Windsurf, Smithery, and developer runtimes like Z.ai, Hermes, and OpenClaw.

Questions? Email support@kaicalls.com or see the Agent Discovery reference for the raw protocol details.