Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
},
"metadata": {
"description": "Phone skills for voice tasks (restaurant booking first). Need: Telnyx KYC + one US number, xAI team with ZDR off, API keys, Voice Agent Builder.",
"version": "0.4.2"
"version": "0.4.3"
},
"plugins": [
{
Expand Down
20 changes: 13 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,27 @@ Need: Telnyx KYC + US DID + Telnyx key; xAI team **ZDR off** + that team’s key

### 1. Call identity — ask in chat, wait

Do **not** silently keep defaults. “Set this up” is not consent to these. Show this card and wait for a reply. **Do not ask for destination countries** — those live on Telnyx (step 6).
Do **not** silently keep PhoneZero. “Set this up” is not a spoken name. **Always ask** what Agent Name the callee should hear, and wait. PhoneZero is an example they may choose, not a default you apply without a reply. **Do not ask for destination countries** — those live on Telnyx (step 6).

```
Call settings (defaults — change any now)
Call settings — reply before we continue

1. Spoken name the callee hears: PhoneZero
“Hello, this is {name}…” — keep PhoneZero, or set your name / an alias.
1. Spoken name (required): what should the callee hear after “Hello, this is …”?
Your name, an alias, or PhoneZero — you pick. Do not skip.

2. AI disclaimer in the opener: ON
2. Always use that name on later calls in this Bot?
Yes → remember it (session + memory if available) and do not re-ask.
No → ask again before every call.

3. AI disclaimer in the opener: ON
ON → “…{name}, an automated assistant, calling on a recorded line…”
OFF → omit “, an automated assistant,”
You may turn this OFF.
```

Keep their answers in session and put them on each `phonezero-task` (`spoken_name`, `disclose_ai`). Do **not** put name or disclose on the Configure / Edit Values card. If they turn disclaimer OFF and the Builder agent already exists, re-paste `prompts/voice-agent.md` once with `{disclosure_clause}` empty — that paste is the only way to change a baked prompt. Per-call they may still pick a different spoken name.
Keep their answers in session and put the name on each `phonezero-task` (`spoken_name`, `disclose_ai`). Do **not** put name or disclose on the Configure / Edit Values card. If they turn disclaimer OFF and the Builder agent already exists, re-paste `prompts/voice-agent.md` once with `{disclosure_clause}` empty — that paste is the only way to change a baked prompt.

Before **every later call**, ask the Agent Name again unless they already said to always use one. Then reuse it and show it as Spoken as on the plan.

### 2. Uninstall the wrong plugin

Expand Down Expand Up @@ -122,7 +128,7 @@ xAI: `list_phone_numbers` → `register_byo_number` if the DID is not `byo_trunk

### 8. Calls

You already have SID, TeXML id, From, spoken name, disclose, and the Telnyx destination list. Read `phonezero-runtime` (plan-first, two attempts, `succeeded` / `booked` only with a live-person confirmation in the transcript). Match a shipped skill, or **interview into a `phonezero-task`** — do not ask them to paste a `SKILL.md` or write `~/.cursor/skills`. Owner setup-test to **their own confirmed number** may skip the hours guard — restaurants may not. The call plan must show Spoken as and only dial countries on that Telnyx whitelist. Per-call they may still override the spoken name. If they ask to save the shape as a template, pick memory or `put_template` and say where it went.
You already have SID, TeXML id, From, disclose, and the Telnyx destination list. **Ask the Agent Name** before the call plan unless they already said to always use the same name. Read `phonezero-runtime` (plan-first, two attempts, `succeeded` / `booked` only with a live-person confirmation in the transcript). Match a shipped skill, or **interview into a `phonezero-task`** — do not ask them to paste a `SKILL.md` or write `~/.cursor/skills`. Owner setup-test to **their own confirmed number** may skip the hours guard — restaurants may not. The call plan must show Spoken as and only dial countries on that Telnyx whitelist. If they ask to save the shape as a template, pick memory or `put_template` and say where it went.

On explicit yes, in this order — do not resolve SID again:

Expand Down
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,25 @@ You were pointed at `https://github.com/function1st/PhoneZero`. Drive the UI. Do
- Do **not** take keys in chat. Do **not** `source ~/.phonezero/env`. Do **not** run `scripts/provision.sh` here.
- Do **not** search the Telnyx MCP catalog for `whoami` or `/v2/whoami`. Those are not tools. SID is `list_billing_groups` (step 6).
- Do **not** treat “no Grok xAI *package*” as “cannot upload.” Add/use the PhoneZero xAI MCP (step 5).
- Do **not** silently keep PhoneZero / AI-disclaimer ON. Ask (step 1) and wait.
- Do **not** silently keep PhoneZero as the spoken name. Always ask the Agent Name (step 1, and before each later call unless they said always use one).
- Do **not** collect destination countries as a PhoneZero setting. They live on the Telnyx outbound voice profile (step 6).

### 0. Vendor gate

Need: Telnyx KYC + US DID + Telnyx key; xAI team **ZDR off** + that team’s key; Builder at [console.x.ai](https://console.x.ai) unless they already said xAI is set up. If missing, stop.

### 1. Ask in chat — name and AI disclaimer (wait)
### 1. Ask in chat — Agent Name and AI disclaimer (wait)

Do **not** keep defaults silently. Show this and wait. **Do not ask for countries** — those are Telnyx (step 6).
**Always ask** the spoken name. Do not apply PhoneZero without a reply. **Do not ask for countries** — those are Telnyx (step 6).

```
Call settings (defaults — change any now)
1. Spoken name: PhoneZero
2. AI disclaimer: ON (you may turn this OFF)
Call settings — reply before we continue
1. Spoken name (required): what the callee hears after “Hello, this is …”
2. Always use that name on later calls? (yes = remember; no = ask every call)
3. AI disclaimer: ON (you may turn this OFF)
```

Write answers into Edit Values / xAI env. If they turn disclaimer OFF and Builder already exists, re-paste the prompt once with `{disclosure_clause}` empty.
Keep answers in session / each `phonezero-task`. Do **not** put the name on Edit Values. If they turn disclaimer OFF and Builder already exists, re-paste the prompt once with `{disclosure_clause}` empty. Before every later call, ask the name again unless they said to always use one.

### 2. Uninstall Cursor PhoneZero if it is installed

Expand Down Expand Up @@ -86,7 +87,7 @@ If app **PhoneZero** already has an outbound voice profile attached and the DID

### 8. First call

Plan-first. Show Spoken as. Only dial countries on the Telnyx profile whitelist. On yes: `put_task` (or `put_booking` alias; wait processed) → `calls_accounts_texml_calls` with the session ids → poll `retrieve_calls_accounts_texml_calls` → `retrieve_recordings_json_calls_accounts_texml_recordings_json` → `transcribe` → classify → `delete_booking` (live brief only). Keep the Telnyx recording. Do not paste the audio URL. Owner setup-test to their own confirmed number may skip the hours guard. Custom task: interview into a `phonezero-task` ([docs/SKILLS.md](docs/SKILLS.md)). If they say save as a template, pick memory or `put_template` and tell them where it went.
Plan-first. Ask the Agent Name unless they said always use one. Show Spoken as. Only dial countries on the Telnyx profile whitelist. On yes: `put_task` (or `put_booking` alias; wait processed) → `calls_accounts_texml_calls` with the session ids → poll `retrieve_calls_accounts_texml_calls` → `retrieve_recordings_json_calls_accounts_texml_recordings_json` → `transcribe` → classify → `delete_booking` (live brief only). Keep the Telnyx recording. Do not paste the audio URL. Owner setup-test to their own confirmed number may skip the hours guard. Custom task: interview into a `phonezero-task` ([docs/SKILLS.md](docs/SKILLS.md)). If they say save as a template, pick memory or `put_template` and tell them where it went.

---

Expand Down Expand Up @@ -148,7 +149,7 @@ This sample ships with:

- **Destinations:** whichever Telnyx outbound voice profile is attached to the PhoneZero TeXML app (`whitelisted_destinations`; default `US` only when PhoneZero **creates** a new profile). Name and country list are the user’s. Mission Control → Voice → Outbound voice profiles.
- **AI disclosure:** default **on** in each task (`disclose_ai`) and in the one-time Builder paste
- **Spoken name:** `PhoneZero`
- **Spoken name:** Grok always asks (unless they said always use one). Cursor default `PhoneZero`.
- **Recording:** dual-channel Telnyx recording on every call; the opener says the call is on a recorded line
- **Hours / attempts:** runtime + skill defaults (see [`plugins/phonezero/skills/phonezero-runtime/SKILL.md`](plugins/phonezero/skills/phonezero-runtime/SKILL.md))

Expand Down
4 changes: 2 additions & 2 deletions docs/SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The Telnyx MCP cannot run until `TELNYX_API_KEY` is saved as a plugin variable.

After any update: re-enter **every** required field on the Configure card (a field left blank is cleared on save — see step 9) and start a **new** conversation (existing chats do not pick up a newly installed or updated plugin).

**Grok Bot** (point at `https://github.com/function1st/PhoneZero` and say *set this up*): the Bot follows [AGENTS.md](../AGENTS.md) **Grok Bot — set this up**. It must ask spoken name and AI disclaimer ON/OFF. Destination countries are the Telnyx voice-profile whitelist (not a PhoneZero field). Do not Customize → + Add this repo as the Cursor plugin. Add Telnyx as HTTP MCP `https://api.telnyx.com/v2/mcp` with `Authorization: Bearer` in the MCP form. Add/use the PhoneZero xAI stdio MCP. Resolve SID via `list_billing_groups` (not `whoami`). Do not click Authenticate.
**Grok Bot** (point at `https://github.com/function1st/PhoneZero` and say *set this up*): the Bot follows [AGENTS.md](../AGENTS.md) **Grok Bot — set this up**. It must **always ask** the Agent Name (and whether to always use it) plus AI disclaimer ON/OFF — do not silently keep PhoneZero. Destination countries are the Telnyx voice-profile whitelist (not a PhoneZero field). Do not Customize → + Add this repo as the Cursor plugin. Add Telnyx as HTTP MCP `https://api.telnyx.com/v2/mcp` with `Authorization: Bearer` in the MCP form. Add/use the PhoneZero xAI stdio MCP. Resolve SID via `list_billing_groups` (not `whoami`). Do not click Authenticate.

If none of those are available on Cursor IDE: `"telnyx": {"command":"npx","args":["-y","@telnyx/mcp"],"env":{"TELNYX_API_KEY":"${env:TELNYX_API_KEY}"}}`. A masked secret card alone does **not** authenticate an MCP.

Expand All @@ -56,7 +56,7 @@ To add a country (e.g. Japan): change that Telnyx whitelist in Mission Control,
| `TELNYX_API_KEY` | plugin variable (secret) | A | Env for Telnyx stdio MCP (`npx @telnyx/mcp`). Never in chat. |
| `PHONEZERO_FROM_NUMBER` | plugin variable | A | Telnyx US DID (E.164): outbound caller ID and SIP bridge target (`sip:{PHONEZERO_FROM_NUMBER}@sip.voice.x.ai;transport=tls`). |
| `XAI_API_KEY` | plugin variable (secret) | A | From a team with **ZDR off**. Injected into the PhoneZero xAI MCP only (Files, collections, STT, phone-numbers). Not in the agent shell. |
| Spoken name / disclose | per-task (`phonezero-task.json`) | chat | `spoken_name` and `disclose_ai`. Default PhoneZero / true. Not on the Configure card. `{disclosure_clause}` is pasted once into the Builder prompt. |
| Spoken name / disclose | per-task (`phonezero-task.json`) | chat | `spoken_name` and `disclose_ai`. Grok always asks the name unless they said always use one. Cursor default PhoneZero / true. Not on the Configure card. `{disclosure_clause}` is pasted once into the Builder prompt. |
| Destinations | Telnyx voice profile on the PhoneZero TeXML app | Telnyx | `whitelisted_destinations` of whatever profile is attached (`outbound.outbound_voice_profile_id`). Any name, any country list. Mission Control → Voice → Outbound voice profiles. Not a PhoneZero plugin variable. |
| `TELNYX_ACCOUNT_SID` | resolved in session | B | TeXML REST account SID. MCP: `list_billing_groups` → `data[].organization_id` (no `whoami` tool). Developer curl: `GET /v2/whoami` → `data.organization_id`. Not on the Configure card. |
| `PHONEZERO_TEXML_APP_ID` | resolved in session | B | TeXML application SID. Not on the Configure card. |
Expand Down
2 changes: 1 addition & 1 deletion plugins/phonezero-grok/.grok-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "phonezero-grok",
"displayName": "PhoneZero (Grok)",
"version": "0.4.2",
"version": "0.4.3",
"description": "Grok Bot: phone skills (restaurant first). Telnyx hosted HTTP + PhoneZero xAI stdio. Edit Values for keys. Do not click Authenticate on Telnyx.",
"author": {
"name": "Function1st"
Expand Down
5 changes: 3 additions & 2 deletions plugins/phonezero-grok/commands/setup-phone-calling.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ description: Grok Bot — ask name / AI disclaimer, then wire Telnyx HTTP + xAI

You are a computer-use agent. Run **Grok Bot — set this up** in repo-root `AGENTS.md` (same steps in `README.md`) **in order**. Do not install Cursor PhoneZero. Do not click Authenticate. Do not take keys in chat.

After the vendor gate, **ask in chat and wait** before wiring. Do not silently keep defaults:
After the vendor gate, **ask in chat and wait** before wiring. **Always ask** the Agent Name (spoken name). Do not silently use PhoneZero.

- Spoken name (default PhoneZero) — what the callee hears
- Spoken name (required) — what the callee hears. PhoneZero is an example they may pick, not a default you apply without a reply.
- Always use that name on later calls? If yes, remember it and do not re-ask. If no, ask again before every call.
- AI disclaimer ON or OFF — they may turn it OFF

**Do not ask for destination countries.** Read them from Telnyx after the HTTP MCP is proven: the outbound voice profile **attached to the PhoneZero TeXML app** (any name) → `whitelisted_destinations`. `list_outbound_voice_profiles` with **no name filter**; pick the id on that TeXML app. Show the actual name + codes. That setting is Telnyx Mission Control → Voice → Outbound voice profiles. PATCH only if they ask to add or remove countries. Do not give legal advice.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: Grok Bot PhoneZero setup when pointed at https://github.com/functio
Computer-use. Drive the UI. Do these steps **in order**. Same playbook: repo-root [README.md](../../../../README.md) and [AGENTS.md](../../../../AGENTS.md). After ids are in session: [plugins/phonezero/skills/phonezero-runtime/SKILL.md](../../../phonezero/skills/phonezero-runtime/SKILL.md) and the matching phone skill (or interview a custom `phonezero-task` — do not ask for a `SKILL.md` paste).

1. **Not** Cursor + Add. **Not** Authenticate. **Not** keys in chat. **Not** `source ~/.phonezero/env`. **Not** `scripts/provision.sh`.
2. Vendor gate, then **ask in chat and wait** — spoken name and AI disclaimer ON/OFF only. Do **not** ask for destination countries.
2. Vendor gate, then **ask in chat and wait** — Agent Name (required; do not silently use PhoneZero) and whether to always use that name, plus AI disclaimer ON/OFF. Do **not** ask for destination countries. Before every later call, ask the name again unless they said to always use one.
3. HTTP MCP: `https://api.telnyx.com/v2/mcp` + `Authorization: Bearer` in the form. Edit Values: keys + From only. Name / disclose stay in chat.
4. `list_api_endpoints` — real list or stop. “6 tools” proves nothing. There is **no** MCP tool named `whoami`.
5. If `put_task` / `put_booking` is missing: add stdio `xai` from [`plugins/phonezero/mcp.json`](../../../phonezero/mcp.json) with **real** env (not `${…}`). Then `get_call_config` + `ensure_collection`. If they said xAI is already set up, do not open the Builder. Ignore the wizard number. If they turned disclaimer OFF and Builder already exists, or the agent still searches `phonezero-booking.json`, re-paste `prompts/voice-agent.md` and `prompts/end_call.md` once.
Expand Down
2 changes: 1 addition & 1 deletion plugins/phonezero/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "phonezero",
"displayName": "PhoneZero",
"version": "0.4.2",
"version": "0.4.3",
"description": "Phone skills for voice tasks (restaurant booking first). Need: Telnyx KYC + one US number, xAI team with ZDR off, API keys, Voice Agent Builder. Then /setup-phone-calling.",
"author": {
"name": "Function1st"
Expand Down
2 changes: 1 addition & 1 deletion plugins/phonezero/scripts/xai-mcp.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ async function handle(msg) {
ok(id, {
protocolVersion: params?.protocolVersion || "2024-11-05",
capabilities: { tools: {} },
serverInfo: { name: "phonezero-xai", version: "0.4.2" },
serverInfo: { name: "phonezero-xai", version: "0.4.3" },
});
return;
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/phonezero/skills/book-restaurant/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Read `phonezero-runtime` for Setup, preconditions, plan-first, hours hard cap, d
| Restaurant-local hours when hours unknown | 10:30–20:30 restaurant-local (user TZ if unknown) | user-stated hours |
| Window if they said “around 7” | propose preferred ± 30–60 min + ranked in-window slots | user-supplied window |
| Calendar offer after `succeeded` | offer ~90 minutes | skip |
| Spoken name | PhoneZero | per-call (`spoken_name` in the brief) |
| Spoken name | Cursor: PhoneZero. **Grok: ask every call** unless they said always use one. | per-call (`spoken_name` in the brief) |

## Collect

Expand Down
2 changes: 1 addition & 1 deletion plugins/phonezero/skills/confirm-business-hours/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Collect who to call and what we need confirmed. No OpenTable step. Hand off to [
| Callback | E.164. Default to the user's phone; confirm it. |
| Expected hours (optional) | What we think the hours are, or a specific question (“open Saturday?”, “today’s holiday hours?”). |

Spoken name defaults to PhoneZero; override per call. Fail closed if there is no business or no number after one clarifying turn.
Spoken name: Cursor defaults PhoneZero; **Grok always asks** unless they said to always use one. Fail closed if there is no business or no number after one clarifying turn.

## Call plan

Expand Down
Loading