Skip to main content

miragea-podcast: open-source AI podcast generator (NotebookLM-style two-host audio from any URL, PDF or topic)

miragea-podcast banner: two AI hosts, Alex and Sam, with waveforms, and the files the tool writes: MP3 with chapters, SRT/VTT transcript, chapters JSON, show notes and a Podcasting 2.0 RSS feed

miragea-podcast is an open-source (MIT) AI podcast generator that turns a web page, PDF, text file or plain topic into a finished two-host (or up to six-voice panel) podcast episode. Your AI agent or any LLM writes a natural conversation script, and miragea-podcast voices each host with a distinct cloned or saved voice through the Miragea voice API. It then mixes real turn-taking (interruptions, overlaps, laughs, pauses) and writes an MP3 with ID3 chapters, SRT/VTT/JSON transcripts, show notes and a Podcasting 2.0 RSS feed. It ships as a CLI, an MCP server (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf) and an Agent Skill. It needs no GPU, no local TTS model and no second LLM key when an agent writes the script.

Listen to the demo episode (MP3, 85 s) · Watch it with captions (MP4) · Read the script · PyPI

Animated preview of the demo episode: a waveform moves while burned-in captions show Alex and Sam talking about earworms

Contents

Quick start

# 1. Install (Python 3.10+ and ffmpeg)
pipx install miragea-podcast          # or run without installing: uvx miragea-podcast ...

# 2. Add your Miragea API key (create one at https://miragea.ai/workspace/api)
export MIRAGEA_API_KEY=...
miragea-podcast doctor                # free check: key, network, ffmpeg

# 3. Free dry run with placeholder tones (no credits, no network)
miragea-podcast make examples/earworms.md --preview

# 4. The real episode: one voice per host, cloned from public samples
miragea-podcast make examples/earworms.md --intro-music chime --outro-music chime \
  --host "Alex=https://example.com/alex.wav|Exact words spoken in alex.wav." \
  --host "Sam=https://example.com/sam.wav|Exact words spoken in sam.wav."

Or straight from a source, if you have an OpenAI-compatible LLM key (PODCAST_LLM_API_KEY, PODCAST_LLM_BASE_URL, PODCAST_LLM_MODEL):

miragea-podcast create https://en.wikipedia.org/wiki/Earworm --minutes 5 --style deep-dive \
  --host "Alex=..." --host "Sam=..."

Using Claude Code, Codex or Cursor instead? You don't need an LLM key at all: the agent writes the script. Agents can also add the general Miragea integration with: Install https://miragea.ai/skills/miragea-audio/install.md.

How it works

Pipeline diagram: 1 Source (URL, PDF, text or topic), 2 Script written by your agent or any LLM, 3 Plan that validates speakers, tags and voices and estimates credits for free, 4 Voices generated by the Miragea API with one cloned voice per host in parallel, 5 Mix with turn-taking, overlaps, interruptions, music and a -16 LUFS master, producing publish-ready MP3, transcripts, chapters, show notes and RSS

  1. Source. extract / read_source pulls readable text from HTML pages, PDFs, TXT and Markdown, and skips navigation and scripts.
  2. Script. One brief (prompt, script_guide) tells any writer the exact format, the word target (150 words per minute) and the delivery tags. Six styles are built in: deep-dive, debate, interview, explainer, news-brief and panel.
  3. Plan (free). It parses the script, gives each speaker a distinct voice, maps English tags such as [laughs] to the labels Miragea accepts, drops unsupported tags with a warning, splits long turns at sentence boundaries and estimates credits.
  4. Voices. Segments are generated in parallel, and each request carries a deterministic idempotency key and a local cache. If a run stops halfway, run the same command again: finished segments are reused and nothing is billed twice.
  5. Mix and publish. It trims silence, keeps natural gaps, starts [interrupts] and [overlap] turns early so voices really overlap, adds optional intro/outro music, masters to -16 LUFS (the usual podcast target), embeds ID3 chapters and the transcript, then writes every companion file.

Real demo output

Everything below came from one real run of examples/earworms.md (207 words, 2 hosts, 3 chapters, 15 voice requests). No numbers were edited.

Terminal capture of the real miragea-podcast make run: plan line with 2 speakers and 207 words, 15 segments voiced, mixing and mastering, then the MP3 path, an 84.898 second duration, three chapters at 0, 22 and 50 seconds, and an empty warnings list

Waveform of the real 85-second demo MP3 with yellow chapter markers for Cold open, Why it happens, and How to make it stop

Files in examples/output/:

File What it is
why-songs-get-stuck-in-your-head.mp3 The episode: 128 kbps MP3 with ID3 title, chapters (CHAP/CTOC), transcript (USLT)
.srt / .vtt / .txt Speaker-labelled transcript for YouTube, players and show notes
.transcript.json Podcasting 2.0 JSON transcript
.chapters.json Podcasting 2.0 chapters (Apple Podcasts, Pocket Casts, Podverse, Fountain)
.shownotes.md Title, summary, hosts and timestamped chapters
.episode.json / .rss-item.xml Metadata and a ready-made <item> for your feed

As a check, we sent the finished MP3 back through Miragea speech recognition, and it returned the script word for word apart from one homophone ("cereal" heard as "serial").

The two demo voices are cloned from short CMU ARCTIC recordings (speakers slt and bdl; free for any use, Copyright 2003 Carnegie Mellon University).

Use it from Claude, Cursor or any MCP client

The MCP server exposes 7 tools: read_source, script_guide, list_voices, list_tags, plan_podcast, create_podcast, build_feed. It also has one prompt, make_podcast. The agent writes the script itself, so it needs no LLM key.

Claude Code

claude mcp add miragea-podcast -e MIRAGEA_API_KEY=<your-key> -- uvx --from miragea-podcast miragea-podcast-mcp

Claude Desktop, Cursor, Windsurf (claude_desktop_config.json, ~/.cursor/mcp.json, ...)

{
  "mcpServers": {
    "miragea-podcast": {
      "command": "uvx",
      "args": ["--from", "miragea-podcast", "miragea-podcast-mcp"],
      "env": { "MIRAGEA_API_KEY": "<your-key>" }
    }
  }
}

miragea-podcast config vscode (or cursor, windsurf, claude-desktop, claude-code) prints the exact snippet. Then ask: "Turn https://example.com/article into a 5-minute two-host podcast, with Alex and Sam."

Use it as an Agent Skill

skills/ai-podcast/SKILL.md teaches Claude Code, Codex, Cursor and other SKILL.md-aware agents the whole workflow: read, brief, write, plan, make, publish. It is also part of the miragea-skills collection:

npx skills add https://codeberg.org/miragea-voice/miragea-skills.git

Script format

---
title: Why Is the Ocean Salty?
description: Two hosts untangle a question every kid asks.
language: en
---

## Cold open
Alex: [excited] Okay, I learned something wild this week.
Sam: [chuckles] You say that every week.
Alex: Rain slowly dissolves minerals out of rocks—
Sam: [interrupts] Wait, so the salt starts on land?
Alex: [overlap] On land!
[pause 0.6s]

## Where the salt goes
Sam: Rivers carry those minerals to the sea...
  • Name: text is one turn. ## Heading starts a chapter. 2 to 6 speakers.
  • Delivery tags go right before the words they colour: [laughs], [chuckles], [sighs], [gasps], [whispers], [excited], [surprised], [shouts], [clears throat] and more (miragea-podcast tags). *laughs* and (laughs) work too.
  • [interrupts] and [overlap] change timing as well as delivery: the turn starts before the other voice has finished.
  • [pause 1.5s] inserts silence. JSON scripts ({"chapters": [{"title", "turns": [{"speaker", "text"}]}]}) are accepted too.

Voices

Each speaker gets their own voice in one of three ways:

Spec Meaning
--host "Alex=actor:ID" A voice saved in your Miragea account (miragea-podcast voices)
--host "Alex=Emma" A saved voice by name
--host "Sam=https://host/sam.wav|exact words in the sample" Zero-shot clone from a public sample (10 to 30 s of clean speech). Adding the transcript after | gives the best match.

Options can follow after ;, for example Sam=actor:123;speed=1.05. A TOML file works too (--hosts-file hosts.toml). Only clone voices you have the right to use.

CLI reference

Command What it does Credits
doctor Checks key, API, ffmpeg, saved voices free
voices, tags Lists saved voices and delivery tags free
extract SOURCE Prints the text pulled from a URL/PDF/file free
prompt SOURCE Prints the script-writing brief plus source, for any LLM free
write SOURCE -o script.md Writes a script with an OpenAI-compatible LLM LLM only
plan script.md --host ... Validates and estimates free
make script.md --host ... Produces the episode (--preview is free) yes
create SOURCE --host ... write + make yes
feed DIR --base-url ... Builds feed.xml from a folder of episodes free
mcp, config CLIENT Runs the MCP server / prints client config free

Useful flags: --style, --minutes, --cast "Name=role", --model expressive|standard, --intro-music FILE|chime, --outro-music, --cover art.jpg, --max-credits N, --gap 0.32, -o DIR, --json.

Environment: MIRAGEA_API_KEY (required), MIRAGEA_BASE_URL (default https://miragea.ai/v1), MIRAGEA_OUTPUT_DIR, MIRAGEA_DEFAULT_MODEL, MIRAGEA_CONCURRENCY (1-8).

Publish as a real podcast (RSS)

# upload ./episodes to any static host (S3, R2, GitHub/Codeberg Pages, Netlify), then:
miragea-podcast feed ./episodes --base-url https://cdn.example.com/show \
  --title "Curious Minutes" --author "You" --image https://cdn.example.com/show/art.jpg --email you@example.com

The feed is RSS 2.0 with iTunes tags and Podcasting 2.0 podcast:transcript, podcast:chapters and podcast:person. Submit its URL to Apple Podcasts, Spotify for Creators or the Podcast Index. Preview episodes are never published.

How it compares

miragea-podcast NotebookLM Audio Overviews podcastfy open-notebook
Open source Yes (MIT) No Yes (Apache-2.0) Yes (MIT)
Edit the script before voicing Yes, plain Markdown No (prompt steering only) Yes (transcript file) Partly
Choose or clone host voices Any saved or cloned voice per host Fixed voices Depends on TTS provider Depends on TTS provider
Interruptions and overlapping speech Yes ([interrupts], [overlap]) Yes No (turns play one after another) No
Chapters, SRT/VTT, RSS feed Yes, all built in No Transcript only No
MCP server + Agent Skill Yes No No No (has its own API)
Keys needed Miragea only (agent writes the script) Google account LLM key + TTS key LLM key + TTS key + database
Runs without a GPU Yes n/a (hosted) Yes with cloud TTS Yes with cloud TTS

Comparison as of November 2026, based on each project's public docs. Corrections are welcome via issues.

FAQ

How do I make a podcast from a PDF with AI?

Run miragea-podcast prompt paper.pdf --minutes 8. Paste the brief into any LLM (or let your agent read it), save the script, then miragea-podcast make script.md --host ... --host .... With an LLM key set, miragea-podcast create paper.pdf --host ... --host ... does it in one step.

Is there an open-source NotebookLM Audio Overview alternative?

Yes. miragea-podcast produces the same two-host "deep dive" format, but you can read and edit the script, pick or clone each host's voice, set the length and style, and you get chapters, transcripts and an RSS feed.

Can I use my own voice as one of the hosts?

Yes. Record 10 to 30 seconds of clean speech, upload it somewhere public (a direct file URL), and pass --host "Me=https://.../me.wav|the exact words you said".

How do I add an AI podcast tool to Claude Desktop or Cursor?

Add the MCP config shown above, restart the client and ask for an episode. The agent calls read_source, writes the script with script_guide, checks it with plan_podcast and renders it with create_podcast.

How long can an episode be?

script_guide accepts up to 90 minutes. Long turns are split at sentence boundaries automatically, and runs are resumable, so long episodes are practical.

How much does an episode cost?

plan prints a credit estimate before anything is spent, and --max-credits refuses to run above your limit. Tags, plans, previews and cached re-runs are free. See miragea.ai for current plans.

Does it support languages other than English?

The script format and mixing are language-agnostic. Set language: in the front matter and write the script in that language. Subtitles handle CJK width correctly.

Why is the voice generation not local?

Local multi-speaker TTS needs a GPU, large models and fragile dependencies, and those are the most common issues in similar projects. Cloud voices from one API mean pipx install and an API key are all you need.

Troubleshooting

Symptom Fix
MIRAGEA_API_KEY is not set Create a key at https://miragea.ai/workspace/api and export it (or put it in the MCP env block)
synthesis_failed Check that each reference URL is public and returns the audio file directly (curl -I URL), then rerun the same command: finished segments are reused
ffmpeg not found brew install ffmpeg, sudo apt install ffmpeg or winget install ffmpeg
Tag ignored warning That tag isn't offered on the chosen model; miragea-podcast tags lists the valid ones
over_budget The estimate exceeded --max-credits; nothing was spent

Development

git clone https://codeberg.org/miragea-voice/miragea-podcast.git && cd miragea-podcast
uv venv && uv pip install -e '.[dev]'
pytest            # 36 tests, offline: the Miragea API is mocked with httpx.MockTransport; needs ffmpeg
ruff check .
python docs/make_images.py   # re-render README images and the demo video from examples/output

Project layout: src/miragea_podcast/ (script.py parser and segmenter, voices.py, tags.py, synth.py parallel cached synthesis, mix.py timeline, mastering and ID3 chapters, subtitles.py, rss.py, sources.py, server.py MCP, cli.py), skills/ai-podcast/, examples/, tests/.

License

MIT. Demo voices are derived from CMU ARCTIC (free for any use). "NotebookLM" is a trademark of Google LLC; this project is not affiliated with Google.

Metadata

Release files for miragea-podcast 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for miragea-podcast 0.1.0
File Size Uploaded Provenance Actions
miragea_podcast-0.1.0.tar.gz 4.9 MB Without provenance Details for miragea_podcast-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for miragea-podcast 0.1.0
File Interpreter ABI Platform Actions
miragea_podcast-0.1.0-py3-none-any.whl Python 3 none any Details for miragea_podcast-0.1.0-py3-none-any.whl

Total release size: 4.9 MB

Release files / miragea_podcast-0.1.0.tar.gz

Download URL miragea_podcast-0.1.0.tar.gz
Size 4.9 MB
Tags Source
SHA-256 checksum
How to use checksums
84b0b528405c5595cf044e86211484adbc9373259bbee310b39ae62bbc5e1a78
BLAKE2b-256 checksum
How to use checksums
ebdf65b7bbd0991ba7c95047c2a51f5e6afa23be6af7f5913641138542af45dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / miragea_podcast-0.1.0-py3-none-any.whl

Download URL miragea_podcast-0.1.0-py3-none-any.whl
Size 60.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd74849f8a55b86ec9c4f54f17a4e70e8bfd622165b15263e23a988521886d0e
BLAKE2b-256 checksum
How to use checksums
c58f5c35d501aa5d652b5e2b04d9a6f435cc385519eb2cfafbaac831e87a1a5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for miragea-podcast 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page