---
name: podcasto-agent
description: Operate Podcasto (turns Telegram channels or article URLs into AI-generated podcast episodes) on behalf of a signed-in user via its MCP server. Use this skill whenever the user asks to create, list, update, pause/resume, or check the status of a Podcasto podcast or episode, check their Podcasto credit balance, or connect an agent to their Podcasto account. Also use it to explain how to get a Podcasto personal access token or wire up the Podcasto MCP server in Claude Code, Claude.ai, ChatGPT, or Cursor.
---

# Podcasto Agent

Podcasto turns a Telegram news channel (or a list of article URLs) into a
scripted, narrated podcast episode. This skill drives Podcasto's MCP server as
the signed-in user, inside that user's own plan limits and credit balance —
it never bypasses them.

## Connect first

The MCP server lives at `https://app.podcasto.org/api/mcp`. **Always use the
`app.` host** — the bare `podcasto.org` apex redirects and drops the
`Authorization` header, so a request against it will look like an auth
failure. Two ways to connect:

- **OAuth (Claude.ai, ChatGPT, Cursor)** — add the URL above as a remote MCP
  server in the client's connector settings and complete the consent screen.
  No token to copy; the client handles refresh.
- **Personal access token (PAT)** — the user creates one at
  `https://app.podcasto.org/settings/agent-access`, scoped and optionally
  time-limited, shown once. Then:
  - Claude Code: `claude mcp add --transport http podcasto https://app.podcasto.org/api/mcp --header "Authorization: Bearer pk_..."`
  - Cursor: add to `.cursor/mcp.json`:
    ```json
    {
      "mcpServers": {
        "podcasto": {
          "url": "https://app.podcasto.org/api/mcp",
          "headers": { "Authorization": "Bearer pk_..." }
        }
      }
    }
    ```
  - MCP Inspector: `npx @modelcontextprotocol/inspector`, transport
    "Streamable HTTP", URL above, header `Authorization: Bearer pk_...`.

If tools return 401/403, the token is missing, revoked, expired, or lacks the
scope the tool needs — do not retry with the same token; tell the user.

Full tool reference: `references/tools.md`. Step-by-step flows:
`references/workflows.md`.

## Core loop

1. `get_me` — confirm who you're acting as, their plan, entitlements, and
   credit balance before doing anything else.
2. For a Telegram-sourced podcast, `preview_telegram_channel` first so the
   user sees what will be collected before anything is created.
3. `create_podcast` (scope `podcasts:write`) with the source, title,
   description, target language, and target duration. Mirrors the podcast
   creation form: `contentSource` is `'telegram'` (with `telegramChannel` +
   `telegramHours`) or `'urls'` (with a `urls` array); `language` is the
   source language code, `outputLanguage` the language to narrate in.
4. `generate_episode` (scope `episodes:generate`) — **this spends credits.**
   Tell the user the plan/estimated cost and get an explicit go-ahead before
   passing `confirm: true`. Never call it speculatively "to see what
   happens."
5. Poll `get_episode` (scope `episodes:read`) until `status` is `published`
   or a terminal failure. Don't poll tighter than every ~15-30 seconds, and
   stop after a reasonable number of checks — episode generation can take
   several minutes.

## Guardrails

- **Never call `generate_episode` (or an admin equivalent) without first
  telling the user it spends credits and getting their confirmation.** This
  applies even if the user's prior message implied urgency — confirm the
  specific action, not just the general intent.
- **Never retry a failed generation in a loop.** If `get_episode` reports a
  terminal failure, surface the failure reason (see `references/workflows.md`
  for the error taxonomy) and let the user decide whether to retry.
- **Respect plan limits.** If a tool call fails because of a plan limit
  (podcast count, scheduling interval, duration cap), report the limit
  plainly — do not attempt workarounds (e.g. deleting/recreating podcasts to
  dodge a cap) or claim it's a bug.
- **Never attempt an `admin_*` tool unless the connected token actually has
  the `admin` scope** — check `get_me`'s scopes first. A missing scope is not
  something to work around; it means the action is out of bounds for this
  session.
- **Ownership only.** Every podcast/episode tool operates on podcasts the
  authenticated user owns (or that an admin token can see); don't guess at or
  enumerate other users' IDs.
- Read-only tools (`list_*`, `get_*`) are safe to call freely for
  orientation; every tool with `write`, `generate`, or `admin_*` in its name
  changes state or spends money and should be used deliberately.
