podcast_generator
Converts markdown podcast scripts into spoken-word audio files, using
voxport's KokoroDirectTTS for
local, offline-capable text-to-speech. No API key, no per-use cost, and
your scripts never leave your machine.
podcast-generator: converts scripts from the command line.- Drop-folder mode: a Windows scheduled task converts whatever lands in
an inputs folder (cloud-synced, if you like), controlled from the small
Podcast Watch app (
podcast-watch). podcast-generator-mcp: an MCP server, so Claude Desktop or another MCP client can write, queue and convert podcasts for you.
This README is a quick start. See MANUAL.md for the full guide: script-writing conventions, complete CLI reference, the voice catalog, and troubleshooting.
Installation
Requires Python 3.10+. The command line works anywhere Kokoro does; the Podcast Watch app and scheduled drop-folder mode are Windows-only.
pip install podcast-generator # command line and Podcast Watch
pip install "podcast-generator[mcp]" # plus the MCP server
A virtual environment is recommended. This pulls in Kokoro and torch
(about 2 GB) through voxport[kokoro]. Check the install:
podcast-generator --version
Not installed for you:
- ffmpeg: needed for MP3 output unless your
soundfile/libsndfile build has native MP3 support. Put it onPATH. WAV output needs neither. - Kokoro model weights and spaCy's
en_core_web_sm: downloaded automatically on the first run. On a firewalled machine, see "Offline use" in the manual.
From a source checkout
git clone https://github.com/brienalkire/podcast_generator.git
cd podcast_generator
python -m venv .venv
.venv\Scripts\activate # Windows (bash: source .venv/bin/activate)
pip install -e ".[mcp]" pytest
Working on voxport at the same time? Clone it next to this repo and run
pip install -e "../voxport[kokoro]" afterwards.
Where things live
Settings and the default folders live in one home folder:
| Install | Home folder |
|---|---|
pip install |
podcast_generator in your Documents folder |
| Source checkout | the repo folder |
| Either | PODCAST_GENERATOR_HOME, if you set that environment variable |
It holds .env (settings), inputs/ (scripts waiting to be converted),
outputs/ (finished audio), script_archive/ (converted scripts, and
failed/ for ones that didn't convert), and generator.log.
The three folders can point anywhere. Use the Podcast Watch app, or set
PODCAST_INPUTS_DIR, PODCAST_OUTPUTS_DIR and PODCAST_ARCHIVE_DIR in
.env (see
.env.example).
Pointing them at a cloud-synced folder (Sync.com, Dropbox, OneDrive) lets
you drop a script in from any device and get the audio back the same way.
Usage
Writing a script
A script is a markdown file. Plain paragraphs are spoken. Headers,
**Key:** value metadata lines, horizontal rules, and italic-only lines
are stripped, so you can label sections and add notes without them being
read aloud:
# My Episode Title
**Voice:** af_heart
## OPENING
Welcome back to the show. Today we're talking about...
## CLOSING
That's all for this episode. Thanks for listening.
---
*Source: some-article.com, September 2026.*
Only the two paragraphs are spoken. An italic-only line after the prose starts ends the script, and everything after it is dropped. Keep those lines for trailing notes. See the manual for the full rules.
Running it
podcast-generator # batch: every script in inputs/
podcast-generator --voice af_heart --speed 1.1 # batch, overriding voice and speed
podcast-generator my-script.md --format wav --output episode01.wav # one file
Batch mode (no file argument) converts every .md script in the inputs
folder and writes <script-name>.mp3 to the outputs folder. The first run
creates the inputs folder if it doesn't exist. Each script that converts
successfully moves into the archive folder, so re-running doesn't
reprocess it. A script that fails moves to <archive folder>/failed/ with
a .error.txt note, so it isn't retried forever.
Single-file mode converts just the named file. --output only applies
here.
| Option | Meaning |
|---|---|
--voice VOICE |
Kokoro voice for the whole run. Overrides a script's **Voice:** line. Default af_heart. |
--speed FLOAT |
Speaking rate (default 1.0; 0.9 slower, 1.1 faster). |
--format {mp3,wav} |
Output format (default mp3). |
--output PATH |
Output file (single-file mode only). |
--lang CODE |
Accent override; normally inferred from the voice name. |
--version |
Print the version and exit. |
Voice precedence: --voice, then the script's **Voice:** line, then
af_heart.
Drop-folder mode and the Podcast Watch app (Windows)
Running podcast-generator with no arguments on a schedule is watch
mode: each run converts whatever is new in the inputs folder and archives
it. A run with nothing to do exits almost immediately, and only one
conversion runs at a time.
The Podcast Watch app sets this up and controls it:
podcast-watch # open the app
podcast-watch --shortcut # add a "Podcast Watch" shortcut to your desktop
- Set up watch registers a Windows scheduled task,
PodcastGeneratorWatch, for your user (no admin rights). It runs the converter withpythonw.exe, so no window flashes up; output goes togenerator.login the home folder. - Turn ON / Turn OFF enables or disables it; Check every sets the interval (5 to 60 minutes).
- When this app opens can always turn the watch on or off when you open the window.
- Folders picks the inputs, outputs and archive folders.
To remove the task: Unregister-ScheduledTask -TaskName PodcastGeneratorWatch
in PowerShell. On macOS or Linux, schedule podcast-generator with cron or
a similar tool instead.
Using it from Claude Desktop (MCP)
podcast-generator-mcp is an MCP server,
so an AI app such as Claude Desktop can make podcasts directly: write a
script, queue it, convert it, and check on it, all from the chat. It runs
locally and uses the same folders and .env as everything else.
-
Install it somewhere that stays put. A uv or pipx tool install works well:
uv tool install "podcast-generator[mcp]"(
pipx install "podcast-generator[mcp]"is the same. A virtual environment works too, as long as you don't delete it.) -
Print the Claude Desktop config for that install:
podcast-generator-mcp --configIt gives the command's full path, which Claude Desktop needs because it doesn't see your shell's
PATH. -
In Claude Desktop, open Settings → Developer → Edit Config, merge that
"podcast-generator"entry intomcpServers, and fully quit and restart Claude Desktop (on Windows, quit from the system tray). It then appears in the chat box's connectors menu.
See the manual for checking it's installed, example requests, the tools, and upgrading (quit Claude Desktop first).
License
MIT. See LICENSE.
Metadata
Release files for podcast-generator 0.3.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| podcast_generator-0.3.4.tar.gz | 44.1 kB | With provenance | Details for podcast_generator-0.3.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| podcast_generator-0.3.4-py3-none-any.whl | Python 3 | none | any | Details for podcast_generator-0.3.4-py3-none-any.whl |
Total release size: 73.6 kB
Release files / podcast_generator-0.3.4.tar.gz
| Download URL | podcast_generator-0.3.4.tar.gz |
|---|---|
| Size | 44.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5fbeb8cb22bebbdfdecdd30fe16751f2a82ec3a861299444210d3e873e2a6dbd
|
|
BLAKE2b-256 checksum How to use checksums |
db4fd487cc89e762da6897d046750487222ff9d23f9428d4352af09749f61805
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logRelease files / podcast_generator-0.3.4-py3-none-any.whl
| Download URL | podcast_generator-0.3.4-py3-none-any.whl |
|---|---|
| Size | 29.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ab2b2db07561a75357b3b968da9c10125cb352a222d5d3e9b005ebc5cd022029
|
|
BLAKE2b-256 checksum How to use checksums |
b50417f35998a87a639bd718be9e3038ebdaa33020c1a648ae068dfdf344fed5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logSecurity for podcast-generator 0.3.4
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.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for podcast_generator-0.3.4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logA 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.