/phone-conversation
Make conversational phone calls and join Zoom meetings via Twilio + Gemini. Multi-turn AI conversations on the phone on behalf of the user.
Claude Code
$ npx -y skills add sonichi/sutando --skill phone-conversation --agent claude-code
Codex
$ npx skills add sonichi/sutando --skill phone-conversation -a codex -y
Cursor
$ npx skills add sonichi/sutando --skill phone-conversation -a cursor -y
Gemini CLI
$ npx skills add sonichi/sutando --skill phone-conversation -a gemini-cli -y
GitHub Copilot
$ npx skills add sonichi/sutando --skill phone-conversation -a github-copilot -y
OpenCode
$ npx skills add sonichi/sutando --skill phone-conversation -a opencode -y
Windsurf
$ npx skills add sonichi/sutando --skill phone-conversation -a windsurf -y
SKILL.md
phone-conversation.SKILL.mdname: phone-conversation
description: "Make conversational phone calls and join Zoom meetings via Twilio + Gemini. Multi-turn AI conversations on the phone on behalf of the user."
Phone Conversation
Make outbound phone calls and join Zoom meetings where Sutando has a real multi-turn conversation, powered by Gemini.
When to Use
- "Call +14155551234 and ask if they're available for dinner"
- "Call the restaurant and make a reservation for 7pm"
- "Call my dentist and reschedule my appointment"
- "Phone the landlord and ask about the maintenance request"
- "Join my Zoom meeting 1234567890"
- "Dial into the meeting and take notes"
- Any time you need Sutando to have a phone conversation or join a meeting on your behalf
Setup from the chat (only sign-up and the card are manual)
The owner signs up at twilio.com and adds a payment method; everything after that is an API call, so do it for them with `scripts/twilio-setup.py`:
1. Ask for the **Account SID** and **Auth Token** (Twilio console → Account info) and store them: `vault set TWILIO_ACCOUNT_SID …`, `vault set TWILIO_AUTH_TOKEN …`. That is enough for the script: it, `startup.sh`'s phone gate and the phone server itself all resolve the environment (`.env` included) first and the vault when it is empty, so nothing is copied into `.env`. The phone server and its tunnel stay OFF until step 4 has written `TWILIO_PHONE_NUMBER`: the gate asks for all three (SID, token, number), because the server exits without the number and a tunnel to it would be public and dead. 2. `python3 skills/phone-conversation/scripts/twilio-setup.py status` — account type (a **Trial** account cannot buy a number or call unverified numbers; say so and point at https://console.twilio.com/billing), numbers owned, webhook drift. 3. `… numbers --country US --area 415` — list voice-capable numbers; let the owner pick. 4. `… buy +14155551234` — buys it, points its voice webhook at this machine (the running server's tunnel from `GET localhost:3100/health`; else `TWILIO_WEBHOOK_URL`, an operator-set fixed external URL; else `WEBHOOK_BASE_URL`), and writes `TWILIO_PHONE_NUMBER` + `TWILIO_WEBHOOK_PUSHED` (the base it pushed) into `<repo>/.env` in place. It never writes `TWILIO_WEBHOOK_URL`: the server binds that key instead of starting its own tunnel, so a moving ngrok URL recorded there goes stale on the next restart. Then restart the phone server (`startup.sh`). 5. `… set-webhook [BASE]` — re-point an owned number after the tunnel URL moved (`status` says "last pushed to Twilio … run set-webhook" when it did). With `TWILIO_AUTO_WEBHOOK=1` in `.env` the server pushes the tunnel it just bound on every start, so a restart with an unreserved ngrok needs no hand step. That push gives api.twilio.com 10 s per call and logs a skip (`webhook sync skipped … run twilio-setup.py set-webhook`) instead of holding the start; `set-webhook` is the retry. 6. Confirm: `curl localhost:3100/health` shows the tunnel; `status` shows no drift.
Twilio's refusals are printed verbatim (error code + message + more_info link); relay them as they are, the fix is on Twilio's side (upgrade, verify a number, billing).
How It Works
Uses Twilio Media Streams for real-time bidirectional audio, piped to Gemini Live for natural conversation. The caller can interrupt mid-sentence — no waiting for the AI to finish speaking.
1. Call connects → Twilio opens a WebSocket audio stream 2. Audio flows bidirectionally between the caller and Gemini Live 3. Gemini responds in real time, interruptible at any point 4. Full transcript is saved when the call ends
Read more
name: phone-conversation description: "Make conversational phone calls and join Zoom meetings via Twilio + Gemini. Multi-turn AI conversations on the phone on behalf of the user."
Phone Conversation
Make outbound phone calls and join Zoom meetings where Sutando has a real multi-turn conversation, powered by Gemini.
When to Use
- "Call +14155551234 and ask if they're available for dinner"
- "Call the restaurant and make a reservation for 7pm"
- "Call my dentist and reschedule my appointment"
- "Phone the landlord and ask about the maintenance request"
- "Join my Zoom meeting 1234567890"
- "Dial into the meeting and take notes"
- Any time you need Sutando to have a phone conversation or join a meeting on your behalf
Setup from the chat (only sign-up and the card are manual)
The owner signs up at twilio.com and adds a payment method; everything after that is an API call, so do it for them with `scripts/twilio-setup.py`:
1. Ask for the **Account SID** and **Auth Token** (Twilio console → Account info) and store them: `vault set TWILIO_ACCOUNT_SID …`, `vault set TWILIO_AUTH_TOKEN …`. That is enough for the script: it, `startup.sh`'s phone gate and the phone server itself all resolve the environment (`.env` included) first and the vault when it is empty, so nothing is copied into `.env`. The phone server and its tunnel stay OFF until step 4 has written `TWILIO_PHONE_NUMBER`: the gate asks for all three (SID, token, number), because the server exits without the number and a tunnel to it would be public and dead. 2. `python3 skills/phone-conversation/scripts/twilio-setup.py status` — account type (a **Trial** account cannot buy a number or call unverified numbers; say so and point at https://console.twilio.com/billing), numbers owned, webhook drift. 3. `… numbers --country US --area 415` — list voice-capable numbers; let the owner pick. 4. `… buy +14155551234` — buys it, points its voice webhook at this machine (the running server's tunnel from `GET localhost:3100/health`; else `TWILIO_WEBHOOK_URL`, an operator-set fixed external URL; else `WEBHOOK_BASE_URL`), and writes `TWILIO_PHONE_NUMBER` + `TWILIO_WEBHOOK_PUSHED` (the base it pushed) into `<repo>/.env` in place. It never writes `TWILIO_WEBHOOK_URL`: the server binds that key instead of starting its own tunnel, so a moving ngrok URL recorded there goes stale on the next restart. Then restart the phone server (`startup.sh`). 5. `… set-webhook [BASE]` — re-point an owned number after the tunnel URL moved (`status` says "last pushed to Twilio … run set-webhook" when it did). With `TWILIO_AUTO_WEBHOOK=1` in `.env` the server pushes the tunnel it just bound on every start, so a restart with an unreserved ngrok needs no hand step. That push gives api.twilio.com 10 s per call and logs a skip (`webhook sync skipped … run twilio-setup.py set-webhook`) instead of holding the start; `set-webhook` is the retry. 6. Confirm: `curl localhost:3100/health` shows the tunnel; `status` shows no drift.
Twilio's refusals are printed verbatim (error code + message + more_info link); relay them as they are, the fix is on Twilio's side (upgrade, verify a number, billing).
How It Works
Uses Twilio Media Streams for real-time bidirectional audio, piped to Gemini Live for natural conversation. The caller can interrupt mid-sentence — no waiting for the AI to finish speaking.
1. Call connects → Twilio opens a WebSocket audio stream 2. Audio flows bidirectionally between the caller and Gemini Live 3. Gemini responds in real time, interruptible at any point 4. Full transcript is saved when the call ends
My AI Stand — Realtime by Day, Rewriting Itself by Night. Summon my AI superpower. Voice, vision, screen, meetings, calls when I'm engaged. Learns my patterns, ships its own code when I'm not. Runs across my Macs, interacts with people & their Stands.
Other skills on sutando.
More skills from other plugins.
browser-use
Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
Questions about phone-conversation.
- Which coding agents can use phone-conversation?
- phone-conversation installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

