---
title: >-
  Run your call center from Claude: six real workflows on the Sautikit MCP
  server
description: >-
  Connect claude.ai to Sautikit over OAuth and run voice ops in plain language:
  calls, broadcasts, recordings, wallet checks — with money tools gated.
summary: >-
  A working tour of voice operations from Claude: the claude.ai connector
  sign-in, the per-tool approval model, and six workflows from wallet checks to
  broadcast reports and voice-action validation.
date: 2026-07-21T00:00:00.000Z
type: blog
---


## Summary

Sautikit runs a hosted [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude 42 tools over your voice workspace. Add it to claude.ai as a custom connector, sign in with OAuth — no API key — and your call center becomes a conversation: check the wallet, place a call, launch or pause a broadcast, pull a recording, inspect call stats, validate a voice-actions document before you wire it to a number. Anything that spends money stops and asks you first. This post walks each workflow end to end, then covers scoped API keys for editor clients like Claude Code and Cursor.

## The problem this actually solves

A call-center lead's morning is a dashboard tour. Wallet page to check the balance. Campaign page to see how Friday's broadcast finished. Call log to find the complaint call a customer mentioned. Recording player to hear it. Each screen is fine on its own; the tax is the switching, and the translating — turning a CSV report and a ledger into the one sentence your boss asked for.

With the Sautikit connector in claude.ai, that whole loop is one chat. Claude holds the context between steps, so "pull Friday's broadcast report and tell me who to retry" is a single instruction, not four tabs and a spreadsheet.

Two things make this safe enough to hand to an operator rather than a developer. First, every tool wraps the public REST API — same auth, same scopes, same rate limits, same billing, no backdoor. Second, the client keeps a human in the loop: tools that spend money or destroy things are annotated so Claude asks before running them. More on both below.

As of this writing (July 2026), Sautikit is the only voice-first CPaaS we could find with a hosted, OAuth-protected MCP server and live call-event tools. Twilio's hosted MCP server is docs-only — search and retrieval over its API reference, no account actions (per Twilio's MCP docs, July 2026). Telnyx ships a full-featured server, but it installs locally and runs on a raw API key. Infobip hosts remote MCP servers in beta, led by its messaging channels. The pattern itself is well proven outside telephony: Stripe, PayPal, and Square all run hosted MCP servers where consequential actions sit behind confirmation. Voice was the missing column.

## Connect claude.ai to your workspace

The connector flow takes about two minutes:

1. In claude.ai, open **Settings → Connectors** and choose **Add custom connector**.
2. Paste the server URL: `https://mcp.sautikit.com/mcp` (the trailing `/mcp` is required).
3. Click **Connect**. A browser popup opens Sautikit's sign-in — the OAuth 2.1 flow the MCP spec mandates, so no API key ever touches the chat client.
4. Sign in, pick the workspace to connect, and approve the scope groups you want to grant: **Read-only**, **Calls + numbers**, **Agents + broadcasts**, **Account**.
5. Done. Ask Claude for your wallet balance to confirm the handshake.

Grants are yours to inspect and kill: revoke the connection any time under [app.sautikit.com](https://app.sautikit.com) → Settings → Connected apps, and access ends on the next request. Custom connectors are available on every claude.ai plan — Free accounts get one connector; paid plans get more (per Anthropic's support docs, July 2026). On Team and Enterprise plans, an org owner adds the connector under Organization settings first, then each member connects and signs in individually — the connector acts as *you*, with your workspace permissions, not as a shared robot account.

Full setup details, including editor clients, live in the [connect guide](/developers/guides/connect-mcp).

## Approvals: where the human stays in the loop

The first time Claude wants to use a tool, it asks. You can allow it once, or choose **Always allow** for that tool going forward. Anthropic's guidance is to reserve Always allow for tools you would let run unsupervised — and the Sautikit tool set is designed so that split is obvious:

| Keep on "Needs approval" | Safe to "Always allow" |
|---|---|
| `place_call`, `send_agent_call` — dials a real phone | `get_wallet_balance`, `list_wallet_statements` — reads |
| `start_broadcast`, `resume_broadcast` — starts a paying campaign | `list_calls`, `get_call`, `get_call_stats` — reads |
| `claim_number` — debits the wallet for a number | `list_broadcasts`, `get_broadcast_report` — reads |
| `release_number`, `delete_agent`, `delete_webhook` — destructive | `validate_voice_actions` — local check, no API call |

The money-spending tools carry MCP annotations that tell the client to confirm before running, so even a fully-trusted chat stops at "Place this call?" On Enterprise plans, admins can go further and set org-wide per-tool policy — Always allow, Needs approval, or Blocked — so an operator cannot approve an action the organization has ruled out.

Below the client sit harder floors. The wallet is prepaid, so the worst-case blast radius of any conversation is the balance you have loaded — a confirmation slip cannot overdraw KES that is not there. And some things are simply not tools: there is no top-up tool, no API-key-minting tool, no secret-rotation tool. Money-in and identity stay in the dashboard, on purpose.

> 
> 
> Anthropic advises connecting only to MCP servers you trust and reviewing OAuth grants periodically. Treat that advice seriously for every connector, including this one — the confirmation prompts are a seatbelt, not a substitute for knowing whose server you plugged in.
> 
> 

## Six workflows, start to finish

### 1. The morning wallet check

> "What's our balance, what did we spend yesterday, and how much of it was AI minutes?"

Claude calls `get_wallet_balance`, `list_wallet_statements`, and `get_ai_spend`, then does the arithmetic for you. The API returns minor units — a balance of `184530` is KES 1,845.30 — and Claude converts without being asked. If the balance sits below your low-balance threshold, you will hear about it before your callers do.

### 2. Place a call

> "Call +254722000001 from our main line."

`place_call` wraps `POST /v1/calls`: the `from` number must be one your workspace owns, and the tool is money-annotated, so Claude shows you the numbers and waits for a yes. Cost stays legible because billing is per second after connect — a 42-second confirmation call at KES 0.05/sec is KES 2.10. Sautikit pricing (as of 2026-06-30): KES 3/min outbound billed per second, inbound free, KES 100/month ex. VAT (KES 116 incl. VAT) per local Nairobi number — see [/pricing](/pricing) for current rates.

### 3. Launch — and pause — a broadcast

> "Set up a reminder campaign with the payments agent for this contact list, weekdays 9 to 5 Nairobi time, retry no-answers twice."

Claude drafts it with `create_broadcast` (the agent must be published — drafts are rejected with a clear error, which Claude reads and fixes), loads the list with `add_broadcast_contacts` (row-level validation, so one malformed number doesn't sink the batch), and then stops at `start_broadcast` for your confirmation. Later, "pause the reminder campaign" takes effect immediately — pausing costs nothing and needs no approval, while `resume_broadcast` is money-annotated and asks again. When it finishes, `get_broadcast_report` pulls the funnel and Claude turns it into the sentence you need: reached, voicemail, retry-worthy.

### 4. Pull a recording and summarize the call

> "Find yesterday's completed calls from +254733000210 and get me the recording of the longest one."

Claude filters with `list_calls` (status, direction, time range, or a number substring), then `get_call_recording` returns a download link with the duration and size. The link is presigned and expires in 15 minutes — audio never streams through the API — so click through promptly. If the recording has aged past your storage plan's retention window, the tool reports it as expired rather than handing you a dead link; retention windows per plan are on [/pricing](/pricing). For the summary itself, drop the transcript into the same chat — if your flow records with transcription enabled, this step is copy-paste — and ask for a summary, the customer's actual request, and the follow-up owner. That last mile is where the chat model earns its seat: the recording player was never going to write your QA note.

### 5. Inspect call stats

> "How did this week compare to last week on answer rates?"

`get_call_stats` pulls the aggregates; `list_calls` sliced by `status=no_answer,busy,failed` gives Claude the raw material for the "why". Because it is a conversation, the follow-ups are free: "same numbers, outbound only", "which hours had the worst pickup", "draft the note to the team". The tools return data; Claude turns it into decisions.

### 6. Validate voice actions before you wire them

Before you point a number at a new IVR handler, paste the actions document into the chat:

```json
{
  "actions": [
    { "say": { "text": "Habari! Press 1 to confirm your appointment.", "language": "en-KE" } },
    {
      "getDigits": {
        "timeout": 8,
        "numDigits": 1,
        "nested": [{ "say": { "text": "Press 1 to confirm, 2 to reschedule." } }]
      }
    },
    { "say": { "text": "We did not get a selection. Goodbye." } },
    { "hangup": {} }
  ]
}
```

`validate_voice_actions` checks it against the exact schema the runtime enforces — locally, with no API call, no charge, and no scope required. Language models and humans alike love inventing plausible fields (a follow-up URL on `getDigits` is the classic — digits actually come back to your `voice_callback_url` as a `Digits` field), and the validator rejects those at authoring time instead of on a live call. Once it passes, `update_number_routing` points the number at your handler in the same conversation. The full DSL is in the [voice actions reference](/developers/concepts/voice-actions).

## Scoped API keys for editor clients

The claude.ai connector signs in as you, over OAuth. Claude Code, Cursor, VS Code, and Windsurf connect with an API key instead:

```bash
claude mcp add --transport http sautikit https://mcp.sautikit.com/mcp \
  --header "Authorization: Bearer $SAUTIKIT_API_KEY"
```

Mint that key at [app.sautikit.com](https://app.sautikit.com) → Settings → API keys, and scope it to the job. A reporting assistant gets `wallet.read`, `calls.read`, and `recordings.read`. A campaign desk gets `broadcasts.read`, `broadcasts.manage`, and `agents.read` — and nothing that dials ad hoc. The server only advertises the tools your key's scopes cover, so a read-only key produces a genuinely read-only Claude. Agent and broadcast scopes are enforced server-side today — a key without `broadcasts.manage` cannot start a campaign through MCP or the REST API — with enforcement rolling out across the remaining groups. Keys are revocable at any time, and revocation is checked on every request.

That split — OAuth for people in chat, narrow keys for tools in editors — is the same least-privilege posture the broader agent-security guidance keeps converging on: scope the credential, gate the spend below the prompt, keep confirmation on anything consequential.

## Get started

1. [Create a Sautikit workspace](/) and claim a phone number.
2. Top up over **M-Pesa**: KES billing, no card.
3. In claude.ai, add `https://mcp.sautikit.com/mcp` under Settings → Connectors, sign in, and ask Claude for your wallet balance — then ask it to do something real. Full walkthrough on the [MCP page](/mcp) and in the [connect guide](/developers/guides/connect-mcp).

**[Start with Sautikit →](/)** &nbsp;·&nbsp; **[See pricing →](/pricing)** &nbsp;·&nbsp; **[Need SMS, WhatsApp & an agent desk? Helloduty →](https://helloduty.com)**
