Skip to main content
Glama

Play long audio

play_audio
Destructive

Bigger and longer audio goes here. Calls the human and plays a recording to them as a phone call: a podcast, a long narration you rendered, a voice memo, music. source is a link (YouTube, SoundCloud, a podcast page, or a direct .mp3/.m4a/.wav/.ogg/.flac/... link) or the audio_id of a file uploaded with curl --data-binary @file.m4a "https://callmemcp.com/audio?to=<number>&filename=file.m4a" (up to 300 MB / 3 hours, kept for a day). The voice says your intro, the title and the length, then asks if they want to listen now; on a yes the file plays as plain sound (no voice model) until it ends or they hang up. Returns once they answer the offer: status "playing" (they said yes), "completed" with listened:false (no, or nothing), or missed/declined. poll_result later reports listened_s and finished. Use call for text under ~2000 characters. language ("tr", "de") is the language of your intro; the offer and the call's own lines follow it.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "source": "<source>"
    },
    "name": "play_audio"
  }
}

Input Schema

NameRequiredDescriptionDefault
toNoThe human's 10-digit Call Me number, from My Number in the app (not a regular phone number). Local clients read it from ~/.aiphone/config.json user_number. In a host without file access, reuse a number given earlier in this chat, but do not claim it is saved across chats. Omit it only to get setup_required with the download links.
introNoSpoken before the offer, up to 500 characters: what this is and why they might want it.
titleNoThe recording's title. Empty uses the title read from the link.
voiceNoWho speaks, female first (default "bella"). female: bella, sarah, jessica, matilda, laura, alice (british), lily (british); neutral: river; male: roger, eric, chris, brian, will, liam, bill, george (british), daniel (british), charlie (australian). "female" or "male" picks the first of that kind. Your choice sticks for this session's later calls until you pass another; empty keeps it, or else uses the voice the person chose in their app.
sourceYesA link (YouTube, SoundCloud, a podcast page, or a direct .mp3/.m4a/.wav/.ogg/.flac link) or the audio_id of an uploaded file.
languageNoThe language you are speaking, e.g. "tr", "pt-BR" or "Turkish". The call's own short lines (thanks, goodbye) follow it. Empty means English, or on `say` keeps the current one.
from_labelNoWho is calling, shown on their phone and spoken: e.g. "Claude on my laptop".Someone's AI
session_tokenNoA session_token from an earlier result, to stay in that thread. Omit on first contact.

Output Schema

NameRequiredDescriptionDefault
fromNoYour own agent number. Never call or text it.
nextNoWhat to do next when the call has not settled.
openNoTrue while the line stays up for say or hang_up.
turnNoIndex of the answer within a conversation.
titleNoplay_audio: the recording's title.
statusYes"completed" (answered), "ringing" or "in_call" (not settled: poll_result), "missed", "declined", "ended", "hanging_up", "playing" (play_audio), or "setup_required" when no number was given.
call_idNoPass to poll_result, say and hang_up.
audio_idNoplay_audio: the recording that was offered.
finishedNoplay_audio: whether they heard it to the end.
languageNoLanguage code the recognizer heard, information only.
listenedNoplay_audio: whether they chose to listen.
duration_sNoplay_audio: its length in seconds.
listened_sNoplay_audio: seconds they listened.
transcriptNoWhat the human said; empty if they only listened.
audio_errorNoplay_audio: why the recording could not be played.
language_nameNoThat language's name.
session_tokenNoReuse in later calls and texts to stay in one thread.
said_while_waitingNoWhat they said while you were thinking.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / voice
      Added value: +{
      +  "default": "",
      +  "description": "Who speaks, female first (default \"bella\"). female: bella, sarah, jessica, matilda, laura, alice (british), lily (british); neutral: river; male: roger, eric, chris, brian, will, liam, bill, george (british), daniel (british), charlie (australian). \"female\" or \"male\" picks the first of that kind. Your choice sticks for this session's later calls until you pass another; empty keeps it, or else uses the voice the person chose in their app.",
      +  "title": "Voice",
      +  "type": "string"
      +}
  2. Changed8 schema fields changed
    • addedInput schema / properties / from_label / description
      Added value: +"Who is calling, shown on their phone and spoken: e.g. \"Claude on my laptop\"."
    • addedInput schema / properties / intro / description
      Added value: +"Spoken before the offer, up to 500 characters: what this is and why they might want it."
    • addedInput schema / properties / language / description
      Added value: +"The language you are speaking, e.g. \"tr\", \"pt-BR\" or \"Turkish\". The call's own short lines (thanks, goodbye) follow it. Empty means English, or on `say` keeps the current one."
    • addedInput schema / properties / session_token / description
      Added value: +"A session_token from an earlier result, to stay in that thread. Omit on first contact."
    • addedInput schema / properties / source / description
      Added value: +"A link (YouTube, SoundCloud, a podcast page, or a direct .mp3/.m4a/.wav/.ogg/.flac link) or the audio_id of an uploaded file."
    • addedInput schema / properties / title / description
      Added value: +"The recording's title. Empty uses the title read from the link."
    • addedInput schema / properties / to / description
      Added value: +"The human's 10-digit Call Me number, from My Number in the app (not a regular phone number). Local clients read it from ~/.aiphone/config.json user_number. In a host without file access, reuse a number given earlier in this chat, but do not claim it is saved across chats. Omit it only to get setup_required with the download links."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "additionalProperties": true,
      +  "properties": {
      +    "audio_error": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "play_audio: why the recording could not be played.",
      +      "title": "Audio Error"
      +    },
      +    "audio_id": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "play_audio: the recording that was offered.",
      +      "title": "Audio Id"
      +    },
      +    "call_id": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "Pass to poll_result, say and hang_up.",
      +      "title": "Call Id"
      +    },
      +    "duration_s": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "play_audio: its length in seconds.",
      +      "title": "Duration S"
      +    },
      +    "finished": {
      +      "anyOf": [
      +        {
      +          "type": "boolean"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "play_audio: whether they heard it to the end.",
      +      "title": "Finished"
      +    },
      +    "from": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "Your own agent number. Never call or text it.",
      +      "title": "From"
      +    },
      +    "language": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "Language code the recognizer heard, information only.",
      +      "title": "Language"
      +    },
      +    "language_name": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "That language's name.",
      +      "title": "Language Name"
      +    },
      +    "listened": {
      +      "anyOf": [
      +        {
      +          "type": "boolean"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "play_audio: whether they chose to listen.",
      +      "title": "Listened"
      +    },
      +    "listened_s": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "play_audio: seconds they listened.",
      +      "title": "Listened S"
      +    },
      +    "next": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "What to do next when the call has not settled.",
      +      "title": "Next"
      +    },
      +    "open": {
      +      "anyOf": [
      +        {
      +          "type": "boolean"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "True while the line stays up for say or hang_up.",
      +      "title": "Open"
      +    },
      +    "said_while_waiting": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "What they said while you were thinking.",
      +      "title": "Said While Waiting"
      +    },
      +    "session_token": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "Reuse in later calls and texts to stay in one thread.",
      +      "title": "Session Token"
      +    },
      +    "status": {
      +      "description": "\"completed\" (answered), \"ringing\" or \"in_call\" (not settled: poll_result), \"missed\", \"declined\", \"ended\", \"hanging_up\", \"playing\" (play_audio), or \"setup_required\" when no number was given.",
      +      "title": "Status",
      +      "type": "string"
      +    },
      +    "title": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "play_audio: the recording's title.",
      +      "title": "Title"
      +    },
      +    "transcript": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "What the human said; empty if they only listened.",
      +      "title": "Transcript"
      +    },
      +    "turn": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "Index of the answer within a conversation.",
      +      "title": "Turn"
      +    }
      +  },
      +  "required": [
      +    "status"
      +  ],
      +  "title": "CallResult",
      +  "type": "object"
      +}
  3. Added

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With destructiveHint and openWorldHint already declared, the description adds real context: the size/duration cap (300 MB / 3 hours), one-day retention, the consent flow (voice offers, playback starts only on a yes), and the exact terminal statuses including missed/declined. It does not mention cost, rate limits, or whether a rejected call can be retried, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but nearly every sentence carries operational detail, and the call flow is narrated in order. The opening line "Bigger and longer audio goes here" is a weak, context-dependent opener that delays the actual purpose by a sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter outbound-call tool with an output schema, it covers the lifecycle end to end: what is said, when the call returns, what each status means, and how to follow up with poll_result. Nothing an agent needs in order to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, yet the description still adds meaning: what forms `source` may take (YouTube/SoundCloud/podcast page/direct file), how to obtain an audio_id via the curl upload command, and that `language` governs the intro and the call's own lines. `to`, `session_token` and `voice` are left entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Calls the human and plays a recording to them as a phone call" is a specific verb + resource with an explicit example list (podcast, narration, voice memo, music). It also names the sibling it is not: "Use `call` for text under ~2000 characters."

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a concrete selection rule against `call` (short text vs. long audio) and points to `poll_result` for listening progress, so the routing decision is clear. It never states when not to place a call at all, nor how this differs from `say`, which keeps it from a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.