Apple Podcasts MCP Server & CLI README

The full upstream README, mirrored for reference. Install config, tool schemas, adoption signals and our own overview live on the Apple Podcasts MCP Server & CLI listing page.

Apple Podcasts

Apple Podcasts MCP Server & CLI

License npm YouTube X LinkedIn

Apple Podcasts MCP server and CLI for Claude Code, Codex and AI agents. 32 tools for podcast search, chart rank tracking, listener reviews, RSS feed parsing and validation, on-device transcript search, and Apple Podcasts Connect analytics.

One install gives you both surfaces, the same 32 tools under the same names, reading one array of tool definitions so they cannot drift apart.

It searches Apple's catalog and checks where a show ranks in each country.

It reads listener reviews and parses any podcast's RSS feed.

If you own a show, it pulls your listening numbers too.

Nothing here needs an account, except the owner analytics.

There are 32 tools, and only the five that read your own show's analytics need an account of any kind.

Built and maintained by Navid Moazzez. Built on Slipway, which turns one definition of each tool into the MCP server and the CLI.

Claude Code using the Apple Podcasts MCP server

Two ways to use it

Command line

apple-podcasts-cli runs every tool as a command. Agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal, a script or a cron job:

bash
apple-podcasts-cli                                     # every command, one line each
apple-podcasts-cli status                              # what this server can reach
apple-podcasts-cli get-top-shows --limit 5             # Apple's Top Shows chart
apple-podcasts-cli find-chart-position --show 1200361736 --storefronts us --storefronts gb
apple-podcasts-cli get-reviews --show 1200361736 --storefront gb
apple-podcasts-cli search-library --query "compound interest"
apple-podcasts-cli check-feed --show https://example.com/feed.xml
apple-podcasts-cli find-chart-position --show 1200361736 --json --select best_rank,charted_in
apple-podcasts-cli export-subscriptions --path ~/Desktop/podcasts.opml --confirm
apple-podcasts-cli <command> --help                    # what any command takes

--confirm is the shell spelling of the confirmation the OPML export needs. --json gives JSON, --compact puts it on one line, --select keeps only the fields you name, and --agent turns on all of it for a script. Exit codes are 0 ok, 1 unexpected, 2 usage or a refused write, 3 not found, 4 auth, 5 API, 7 rate limited and 10 nothing configured, so a script branches on the number.

apple-podcasts-cli schema <command> prints the exact JSON Schema an MCP client receives for that tool.

MCP server, for your AI app

apple-podcasts-mcp is what Claude Code, Claude Desktop, Cursor and the rest launch. You never run it by hand:

Terminal
claude mcp add apple-podcasts -- npx -y @thenavidm/apple-podcasts-mcp-cli@latest

In Claude Desktop, the .mcpb extension installs on a double click. Section 4 has every other client.

Then just ask: "where does this show rank in the US, UK and Sweden, and what do its reviews complain about?" The one tool that writes, the OPML export, waits for your approval in the client, as section 11 explains.

Which one

Where you areWhat you can reach
An agent that can run shell commands, like Claude Code or CursorBoth. The CLI is the cheaper one: it costs nothing until you type it
claude.ai, the Claude Desktop chat tab, or a phoneThe server only. There is no shell to run a command in
A terminal, a script, cron or CIThe CLI only. There is no MCP client in a shell

They are the same program reading the same tool definitions, so anything one can do, the other can.

Features

Every tool is both a command and an MCP tool, with the same name. The command is the tool name with dashes.

CapabilityCLI commandMCP tool
What this server can reachapple-podcasts-cli statusstatus
Search the catalogapple-podcasts-cli search-podcasts / search-episodes / get-podcast / get-podcast-episodes / list-genres / resolve-apple-linksearch_podcasts / search_episodes / get_podcast / get_podcast_episodes / list_genres / resolve_apple_link
Charts and ranking, per countryapple-podcasts-cli get-top-shows / get-trending-episodes / find-chart-position / list-storefrontsget_top_shows / get_trending_episodes / find_chart_position / list_storefronts
Listener reviewsapple-podcasts-cli get-reviews / get-review-summaryget_reviews / get_review_summary
RSS feeds and transcriptsapple-podcasts-cli get-feed / get-feed-episode / find-transcripts / check-feedget_feed / get_feed_episode / find_transcripts / check_feed
Research a nicheapple-podcasts-cli get-show-profile / compare-shows / find-similar-showsget_show_profile / compare_shows / find_similar_shows
Your library on this Macapple-podcasts-cli list-subscriptions / search-library / list-recent-episodes / list-saved-episodes / get-library-episode / library-stats / export-subscriptionslist_subscriptions / search_library / list_recent_episodes / list_saved_episodes / get_library_episode / library_stats / export_subscriptions
Analytics for a show you ownapple-podcasts-cli check-analytics-access / get-show-analytics / get-episode-analytics / get-followers / get-analytics-reportcheck_analytics_access / get_show_analytics / get_episode_analytics / get_followers / get_analytics_report
Check your setupapple-podcasts-cli doctornot a tool

All 32 are in section 7.

Contents

#SectionWhat is in it
1What you can ask itReal prompts, not features
2Quick installOne line, no account
3SetupOnly if you want the optional parts
4Connect your clientEvery client, copy and paste
5Check it workeddoctor, and what actually fails
6What it costs to have connectedMeasured in Claude Code, and how to spend less
7ToolsAll 32, grouped by what they reach
8The four sourcesWhy this is not one API
9What Apple actually doesThe traps, learned the hard way
10Your dataWhat is read, and what never leaves
11SafetyShort, because almost nothing writes
12TroubleshootingSymptom to cause
13FAQIncluding what an MCP server is

1. What you can ask it πŸ’¬

  • Where does this show rank in the US, UK and Sweden, and where is it strongest?
  • What are people complaining about in the reviews of my competitor's show?
  • Which episode was that thing about compound interest I heard a while back?
  • Compare these four shows on rank, ratings and how often they publish.
  • Is my podcast feed missing anything Apple requires?
  • What is trending in podcasts right now that is not true crime?
  • Find shows like this one, so I can see who else is in this niche.
  • Which of the shows I follow publish real transcripts I can read?
  • How many people played my episodes last week, and which one won?
  • Export everything I subscribe to as OPML so I can leave Apple Podcasts.

The third one is the point. Apple caches a transcript excerpt for nearly every episode of every show you follow, and nothing surfaces it. On a normal library that is tens of thousands of excerpts of real spoken words sitting on your Mac, searchable, and it answers "where did I hear that" in a way no catalog can.

2. Quick install ⚑

Node 22 or newer. Nothing else.

Terminal
npx -y @thenavidm/apple-podcasts-mcp-cli@latest --version

That is the whole install. npx fetches it on demand, so there is nothing to update later.

For the CLI as a command you or your agent can run anywhere, install it once:

Terminal
npm install -g @thenavidm/apple-podcasts-mcp-cli
apple-podcasts-cli

Most of this server works immediately, with no account. Apple's catalog, its charts, its reviews and every podcast RSS feed are all open. Your own library is read straight off this Mac. Section 3 is only for the parts that need something extra, and you can skip it entirely.

3. Setup πŸ”‘

Nothing here is required. Skip to section 4 and come back when you want one of these.

Reading your own library

Nothing to configure, but macOS may need to be told to allow it.

The Apple Podcasts library lives in a protected group container, so the app running the server needs Full Disk Access:

  1. Open System Settings, then Privacy & Security, then Full Disk Access.
  2. Click + and add the app that launches the server. For Claude Code or Codex that is your terminal (Terminal, iTerm, Ghostty). For Claude Desktop it is Claude itself.
  3. Quit that app completely and reopen it. The permission is only read at launch.

If you would rather this server never read your subscriptions, set APPLE_PODCASTS_LIBRARY=0 and those seven tools disappear from the list entirely.

This group only exists on macOS. On Linux or Windows the other 25 tools work normally.

Apple Podcasts Connect analytics

Only for a show you own and administer. It is the one part with credentials.

  1. Sign in to podcastsconnect.apple.com.
  2. Your vendor number is on the account. It is a numeric id, usually seven or eight digits.
  3. Generate a Reporter access token under the account's Reporter settings. Copy it immediately: Apple shows it once.
  4. Set both as environment variables in your client config, as APPLE_PODCASTS_VENDOR_NUMBER and APPLE_PODCASTS_REPORTER_TOKEN.

The token expires after 180 days and has to be regenerated in Podcasts Connect. Nothing in this server can mint or refresh one. doctor reports whether the token still works, and check_analytics_access lists which vendor numbers it can actually read, which is the fastest way to tell a wrong token from a wrong vendor number.

To revoke it, delete the token in Podcasts Connect. That takes effect immediately.

Have an agent do it

The agent cannot sign in to Apple for you. What it can do is wire up the config and verify it. Paste this into Claude Code, Cursor, or any agent with terminal access:

Code
Set up @thenavidm/apple-podcasts-mcp-cli for me.

1. Add it to my MCP client config, running via `npx -y @thenavidm/apple-podcasts-mcp-cli@latest`.
2. Run `npx -y @thenavidm/apple-podcasts-mcp-cli@latest doctor` and show me the output.
3. If the local library check fails on permissions, tell me exactly which app
   to add to Full Disk Access and stop so I can do it.
4. Do not ask me for Apple Podcasts Connect credentials unless I say I own a
   show. Everything else works without them.

4. Connect your client πŸ”Œ

The long version, every step with what to do when one fails, is in INSTALL.md.

Every block is self-contained. No credentials are needed in any of them; the env block is only for the optional extras from section 3.

Claude Code

Terminal
claude mcp add apple-podcasts -- npx -y @thenavidm/apple-podcasts-mcp-cli@latest

--scope user makes it available in every project rather than the current one.

Claude Desktop

The short way: download the .mcpb extension from the latest release and double-click it. It carries its own dependencies, so there is no config file to edit and nothing to install first. Claude Desktop asks for your country and, only if you own a show, your Apple Podcasts Connect details. For the library tools, give Claude Desktop Full Disk Access (section 3).

The long way, if you would rather edit the config yourself:

1. Open the config file.

In Claude Desktop go to Settings, then Developer, then click Edit Config. That reveals claude_desktop_config.json in your file manager. Open it in any text editor.

To go straight there:

PlatformPath
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json
Linux~/.config/Claude/claude_desktop_config.json

On macOS, from a terminal:

bash
open -e ~/Library/Application\ Support/Claude/claude_desktop_config.json

2. Add the server.

If the file is empty or does not exist, paste this whole thing in:

config.json
{
  "mcpServers": {
    "apple-podcasts": {
      "command": "npx",
      "args": ["-y", "@thenavidm/apple-podcasts-mcp-cli@latest"]
    }
  }
}

If you already have other servers, add only the "apple-podcasts": { ... } part inside your existing "mcpServers", and put a comma after the entry before it. The file has to stay valid JSON. One missing comma or one trailing comma stops every server from loading, not just this one.

Tip Claude Desktop does not inherit your shell PATH. If npx is not found, run which npx in a terminal and use that absolute path as the command.

3. Restart properly.

Quit Claude Desktop completely and reopen it. On macOS closing the window is not enough, use Cmd+Q. On Windows quit it from the system tray. Claude only reads that file at startup.

4. Check it worked.

Look for the tools icon in the message box and click it. You should see apple-podcasts with its tools listed. Then ask it something from section 1.

If nothing appears, Claude Desktop's own log is the fastest way in:

PlatformPath
macOS~/Library/Logs/Claude/mcp-server-apple-podcasts.log
Windows%APPDATA%\Claude\logs\mcp-server-apple-podcasts.log
bash
tail -n 50 ~/Library/Logs/Claude/mcp-server-apple-podcasts.log

Cursor

.cursor/mcp.json in a project, or ~/.cursor/mcp.json for every project. Same JSON shape as Claude Desktop, with the key mcpServers. Then reload the window, or open Settings, MCP, and toggle the server.

Windsurf

~/.codeium/windsurf/mcp_config.json, key mcpServers, same JSON shape. Then reload.

VS Code

.vscode/mcp.json. The key is servers, not mcpServers, and each entry takes a type:

config.json
{
  "servers": {
    "apple-podcasts": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@thenavidm/apple-podcasts-mcp-cli@latest"]
    }
  }
}

Or run MCP: Add Server from the command palette.

Codex CLI

~/.codex/config.toml:

toml
[mcp_servers.apple-podcasts]
command = "npx"
args = ["-y", "@thenavidm/apple-podcasts-mcp-cli@latest"]

Gemini CLI

~/.gemini/settings.json, key mcpServers, same JSON shape as Claude Desktop.

claude.ai on the web

claude.ai runs connectors from Anthropic's cloud rather than your machine, so it needs a public HTTPS URL and cannot run a local command.

Terminal
npx -y @thenavidm/apple-podcasts-mcp-cli@latest --http --port 8000

Host that somewhere with a public HTTPS URL, then in claude.ai: Customize, Connectors, +, Add custom connector. Paste the URL and click Add.

The library tools cannot be hosted. They read the Apple Podcasts database on whatever machine the server runs on, so a hosted instance would serve your subscriptions to every caller. The server refuses to start bound to anything but loopback while the library is enabled. Set APPLE_PODCASTS_LIBRARY=0 to host the 25 public tools.

Set APPLE_PODCASTS_HTTP_TOKEN so the endpoint is not open, and put it behind TLS. GET /health reports the tool count and capability without authentication.

Docker

Terminal
docker build -t apple-podcasts-mcp .
docker run --rm -i apple-podcasts-mcp

The container has no Apple Podcasts library, so it runs the public tools only.

Everything else

Any stdio MCP client takes the same three things: the command npx, the args, and optionally an env block. Zed, Cline and Continue all work.

5. Check it worked 🩺

Terminal
npx -y @thenavidm/apple-podcasts-mcp-cli@latest doctor

It probes each of the four sources separately and names the failing one, rather than leaving you with "the tool errored". It also checks two things this server assumes but cannot guarantee: that the Podcasts database still has the columns it reads, and whether your library holds any usable play data.

Two things account for most failures:

SymptomCause
Server does not appear at allNode is not on the PATH your client sees, or the config JSON is malformed. Run the exact command your client runs, by hand, and read the error
Library checks fail on permissionsFull Disk Access, see section 3. Adding the client is not enough if it launches the server through a terminal

6. What it costs to have connected

Both surfaces are the same program with the same 32 tools. The difference is when the model pays for them. Measured in Claude Code:

CostMCP serverCLI
Every message, with every tool loaded12,700 tokensnothing
Every message, Claude Code's default1,170 tokensnothing
When Apple Podcasts comes upnothing more, or the tools it picks4,320 tokens for SKILL.md, once
20 messages with Apple Podcasts in 1, every tool loaded254,000 tokens4,320 tokens

Claude Code's tool search is on by default: it sends only the tool names and the server instructions, and loads a tool's full definition when the model reaches for it. An app that loads every tool up front pays the first line on every message, whether Apple Podcasts comes up or not. With the skill added, Claude Code also lists its one-line description, about 190 tokens.

To spend less, turn the server off when you are not using it, which in Claude Code is the /mcp panel. APPLE_PODCASTS_LIBRARY=0 takes the 7 library tools off the list. Or install the CLI and add the server on the days it earns its place.

Measured on 2026-10-05 with Claude Code 2.1.286 on Claude Opus 5.5: one short prompt with and without the server connected, once with ENABLE_TOOL_SEARCH=false and once with the default, the difference read from the API's own usage figures. SKILL.md was measured the same way. Other apps and models count tokens a little differently.

Against 1.1.2, measured the same day: every tool loaded costs 12,701 tokens instead of 13,764, tool search the same, and SKILL.md 51 more, because it now says how approval works over MCP and lists every exit code. In Codex 0.159.3 on gpt-6.1-sol, the same task, "find the command that shows where a podcast ranks on Apple's charts across several countries and the flags it requires", read a median of 84,197 input tokens on 2.0.0 against 84,531 on 1.1.2 over the CLI, and 48,263 against 48,262 over MCP, five runs each. Codex prints the tool list from a script and keeps the same share of it on both sides; the part it kept was two tokens longer on 2.0.0 (8,928 against 8,926), which is the whole difference.

7. Tools πŸ› οΈ

32 tools. Everything that reads Apple's catalog takes an optional storefront. Anywhere a show is named, it takes an Apple id or a pasted Apple Podcasts URL, so a link someone sent you works directly.

Start here

ToolWhat it does
statusWhich of the four sources are reachable right now. Local and free
get_show_profileOne show, everything: catalog, rank across markets, review sentiment, publishing cadence, transcripts. The one to reach for
resolve_apple_linkTurn a pasted Apple Podcasts URL into show and episode ids

Catalog

ToolArguments
search_podcastsquery, genre_id, match, limit, storefront
search_episodesquery, limit, storefront
get_podcastshow, storefront
get_podcast_episodesshow, limit, storefront
list_genresstorefront, top_level_only

Charts and ranking

ToolArguments
get_top_showslimit, genre, storefront
get_trending_episodeslimit, storefront
find_chart_positionshow, storefronts[], include_episodes
list_storefrontsnone

Reviews

ToolArguments
get_reviewsshow, storefronts[], sort, limit
get_review_summaryshow, storefronts[], limit

Feeds

ToolArguments
get_feedshow, limit, include_episodes
get_feed_episodeshow, episode, limit
find_transcriptsshow, limit
check_feedshow, limit

Research

ToolArguments
get_show_profileshow, storefronts[], reviews
compare_showsshows[] (2 to 6), storefront, reviews
find_similar_showsshow, limit, storefront

Your library

macOS only. Hidden entirely by APPLE_PODCASTS_LIBRARY=0.

ToolArguments
search_libraryquery, show, include_transcripts, full, limit
list_subscriptionsfollowed_only, limit
list_recent_episodesshow, since_hours, full, limit
list_saved_episodeskind, full, limit
get_library_episodeid
library_statsnone
export_subscriptionspath, followed_only, confirm

Owner analytics

Needs Apple Podcasts Connect credentials. Listed even when unconfigured, so they can tell you what is missing.

ToolArguments
check_analytics_accessnone
get_show_analyticsdate_type, date, worldwide
get_episode_analyticsdate_type, date, worldwide, limit
get_followersdate_type, date
get_analytics_reportreport_type, date_type, date, limit

Resources and prompts

Three resources, so a client can load context without spending a tool call: apple-podcasts://status, apple-podcasts://concepts, apple-podcasts://output-format.

Four prompts: show-teardown, niche-map, what-did-i-hear, feed-checkup.

8. The four sources πŸ“š

Apple Podcasts is not one API. It is four things wearing the same brand, and they differ in who can reach them and what they are good for. This is the single most useful thing to understand about this server.

SourceReachCredentialGood for
Search APIanyonenonediscovery, competitive research
Charts and reviewsanyonenoneranking, audience voice
A show's RSS feedanyonenonethe full backlog, real transcripts
Your local librarythis Macnoneyour own subscriptions and cached transcripts
Podcasts Connecta show you ownvendor number and tokenplays, followers, per-episode consumption

Three of those need nothing at all. That is unusual and it is why this works the moment you install it.

9. What Apple actually does ⚠️

The section that makes this worth more than the API docs it wraps. Everything here was verified against the live services, not recalled.

Storefronts change the answer, silently

The catalog, the charts and the reviews are all per country. The same search in us and se returns different shows in a different order, a show can be published in one market and not another, and its review pool is entirely separate in each.

An empty result in one storefront is not evidence a show does not exist. Every listing here carries the storefront it came from for exactly this reason.

Ranking stops at 100, and there are no genre charts

Apple publishes two charts per storefront: Top Shows, which is follower-weighted and slow, and Trending Episodes, which moves fast and is the better read on what a topic is doing this week. Both cap at 100 and asking for 200 fails.

A genre-scoped chart returns 404. Apple serves one overall chart per country. The genre argument on get_top_shows filters that list, so it gives the charting shows that happen to be in a genre, not that genre's own top 100.

There is also no endpoint for "where does this show rank". Finding a rank means fetching the chart and looking, which is what find_chart_position does, once per storefront.

The Search API answers 200 for failures

A malformed query returns HTTP 200 with an errorMessage field and zero results. Handled by status alone that reads as "nothing matched", and a model told a search found nothing concludes the show does not exist. Every response here is inspected on success, not only on failure.

Rate limiting is real, silent, and has no header

Roughly 20 requests a minute per IP, answered with 403 and an HTML body. No Retry-After, no quota endpoint, no announcement.

Requests are therefore spaced and queued rather than fired in parallel, and responses are cached for five minutes, so asking about six shows fetches the chart once rather than six times. Prefer get_show_profile and compare_shows over calling single tools in a loop.

Transcripts: two kinds, one readable

Feed transcripts are public. <podcast:transcript> in a show's RSS carries a URL to a VTT, SRT or JSON transcript that anything can fetch. find_transcripts lists them. Most shows publish none, which is the show's choice.

Apple's own transcripts are not readable. The ones the app displays are access-controlled, and their CDN refuses unauthenticated requests. What does exist is a short excerpt Apple caches locally for episodes in your library, speaker-tagged and typically a few hundred characters, present for nearly every episode. search_library searches those. It is an excerpt, not the episode, and the tools say so rather than implying otherwise.

Your library holds far more than the app shows

The Podcasts app keeps a Core Data store with every episode of every show you follow: full descriptions, dates, durations, guids and audio URLs, whether or not anything was ever downloaded. On a normally-used library that is tens of thousands of episodes.

Its dates are Core Data timestamps, which are seconds since 2001, not 1970. Read as Unix time, every date in your library lands in 1970.

Play data usually is not there. On a library synced from an iPhone, the playhead and play-count columns are zero on every row. Listening progress is tracked on the device that played the episode and does not reach the Mac. So nothing here can tell you what you have listened to. library_stats reports whether your library actually has usable play data, and the tools decline to infer listening history rather than presenting a zero as a finding.

Podcasts Connect lags, and counts devices

Reporting is one to two days behind, and a request for today returns an error that reads as breakage. Every analytics tool here defaults to three days back.

Listener counts are devices, not people. One person on a phone and a HomePod counts twice, and Apple has no way to collapse them.

The access token expires after 180 days with no refresh path.

10. Your data πŸ”’

There is no server behind this. Your requests go straight from your machine to Apple and to podcast hosts, and nothing is collected or sent anywhere else.

WhatWhere
Your subscriptions and episodesRead from ~/Library/Group Containers/243LU875E5.groups.com.apple.podcasts/, read-only, never written
Apple Podcasts Connect credentialsYour client's config. Never written to disk by this server
Catalog and chart responsesMemory only, for five minutes
OPML exportOnly the path you name, and only once you approve it
Audit logOnly the file you name in APPLE_PODCASTS_AUDIT_LOG

The library database is opened read-only through an immutable URI, which is also why reads work while the Podcasts app is running.

Hosts contacted: itunes.apple.com, rss.marketingtools.apple.com, reportingitc-reporter.apple.com if you configure analytics, and whatever host serves a podcast RSS feed you ask for.

11. Safety πŸ›‘οΈ

Short, because there is almost nothing to guard. There is no Apple Podcasts write API and this server does not invent one. Of 32 tools, 31 only read.

export_subscriptions writes an OPML file and overwrites whatever is at the path, so it waits for your approval. That is the only guard, deliberately: approval on every call would train people and models to approve reflexively, which is worse than not asking.

Over MCP a person approves the export where the client can ask: Claude Code (2.1.246 and later) shows its own prompt, and a client that can show forms asks with an approval form whose one box starts unticked. Each approval is signed, bound to that exact call and works once. Where a client can do neither, the model's confirm: true counts, and it should pass it only when you asked for that export. APPLE_PODCASTS_CONFIRM=model makes confirm: true enough everywhere, for an agent with no person to ask. In a terminal it is --confirm, which --agent never adds.

The control that matters here is privacy rather than damage:

server.ts
APPLE_PODCASTS_LIBRARY=0     # removes all seven library tools from the list
APPLE_PODCASTS_READ_ONLY=1   # removes the OPML export too
APPLE_PODCASTS_AUDIT_LOG=~/.apple-podcasts-mcp/writes.jsonl

Tools disappear from the list rather than erroring when called, because a model cannot call a tool it cannot see.

Prompt injection. Reviews are the most injectable surface here, and "summarize my reviews" is the first thing anyone asks. Review bodies, show notes and transcript excerpts are all fenced with a marker naming them as data before a model reads them, and any attempt to close that fence early is defanged. The server instructions repeat the rule. That framing helps and it is not a guarantee: for an agent working unattended over other people's text, APPLE_PODCASTS_READ_ONLY=1 is the real defense.

12. Troubleshooting πŸ”§

doctor first. It names the failing source and the fix.

SymptomCause
Every library tool fails on permissionsFull Disk Access, on the app that launches the server, then restart it. See section 3
"No Apple Podcasts library at ..."The database is created the first time the Podcasts app runs and follows a show. Set APPLE_PODCASTS_LIBRARY_PATH if yours is elsewhere
Library tools are missing from the listAPPLE_PODCASTS_LIBRARY=0, or you are not on macOS
"Apple is rate limiting this IP"Roughly 20 requests a minute. Wait a minute. Use get_show_profile or compare_shows rather than looping single calls
A search returns nothing for a show you know existsWrong storefront. The show may not be published there. Try storefront: "gb" or wherever it is based
A show is unranked everywhereApple only publishes the top 100 per storefront. Outside that band there is no ranking to report
get_top_shows with a genre looks wrongThere are no genre charts. That argument filters the overall chart
find_transcripts returns nothingThe show publishes none. Apple's own transcripts are not readable by anything outside the Podcasts app
library_stats says no usable play dataNormal on a Mac. Progress is tracked on the device you listen on
Analytics say "no report available"Reporting lags one to two days. Try a date three or four days back
Analytics reject the tokenTokens expire after 180 days. Regenerate it in Podcasts Connect
"will not run without --confirm"Working as intended. Only export_subscriptions does this
claude -p will not exportHeadless Claude Code refuses tools that need a person. Give that agent APPLE_PODCASTS_CONFIRM=model
No approval form appearsThe client cannot show forms, so the model's confirm: true counts, and only for an export you asked for
A piped request gets no answerStdin closed before the answer. The MCP stdio binding stops a server when its input ends; keep stdin open until you read the answer, or use the CLI

13. FAQ ❓

What is an MCP server?

An MCP server is a small program that gives an AI assistant a set of tools. MCP is the open protocol Claude, Cursor, Windsurf, VS Code and others use to talk to them. You install it once, and then you ask questions in plain language instead of calling an API.

What is the CLI?

apple-podcasts-cli is the same program as the MCP server, run as commands. AI agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal, a script or a cron job. Every tool is a command with dashes, so get_top_shows runs as apple-podcasts-cli get-top-shows.

Should I use the MCP server or the CLI?

Use the MCP server in an app with no terminal, like Claude Desktop's chat. Use the CLI anywhere commands run: an agent like Claude Code, Codex or OpenCode, a script or a cron job. The MCP server's tools take up context on every message, and the CLI costs nothing until it runs.

Do I need an Apple developer account?

You do not need one. Nothing in the first 25 tools needs an account of any kind. Only the owner analytics do, and only if you have a show in Apple Podcasts Connect.

Does it work on Windows or Linux?

It works everywhere apart from the library tools. Those read the Apple Podcasts app's database, which only exists on macOS. The other 25 work anywhere.

Can it post, subscribe, or rate a show?

It cannot. Apple publishes no write API for podcasts, so there is nothing to call. This server only reads.

Can it read the transcript of any episode?

It reads only the transcripts a show publishes in its own feed, which find_transcripts lists. Apple's own transcripts are access-controlled and unreadable outside the Podcasts app. For shows you follow, Apple caches a short excerpt locally and search_library searches those.

Can it tell me what I have listened to?

Almost certainly not, and it will say so rather than guess. Listening progress lives on the device you listen on and does not sync to the Mac's copy of the library. library_stats tells you whether yours is an exception.

Why does it ask for Full Disk Access?

It does not ask; macOS refuses without it. The Apple Podcasts library sits in a protected group container. The server opens it read-only and never writes to it. Set APPLE_PODCASTS_LIBRARY=0 if you would rather it never looked.

Does it work with Spotify or other podcast apps?

It covers Apple Podcasts only. Any show's RSS feed can be read regardless of where it is distributed, so get_feed and check_feed are useful either way.

Why are my two storefronts giving different answers?

Because they are different. Apple runs a separate catalog, chart and review pool per country. That is a feature of the data, not a bug, and it is often the most useful thing in it.

Can it write anything without me asking?

One tool writes, the OPML export, and it waits for your approval: Claude Code shows its own prompt, and a client that can show forms asks with one. Where a client can do neither, the model's confirm: true counts. APPLE_PODCASTS_READ_ONLY=1 takes it off the list entirely. Nothing here can post, subscribe or rate, because Apple has no API for any of it.

How do I know it is actually working?

doctor. It probes each of the four sources on its own, the catalog, the charts and reviews, your library and Apple Podcasts Connect, and names the failing one with its fix rather than leaving you to guess.

Is my data sent anywhere?

Nothing is sent anywhere. There is no backend: requests go to Apple and to podcast RSS hosts and nowhere else.

Environment variables

VariableDefaultWhat it does
APPLE_PODCASTS_STOREFRONTusCountry code used when a tool names none
APPLE_PODCASTS_STOREFRONTSus,gb,ca,au,ie,se,de,nlMarkets the cross-market tools sweep
APPLE_PODCASTS_LIBRARY10 removes every local-library tool
APPLE_PODCASTS_LIBRARY_PATHthe app's defaultWhere the Podcasts database is
APPLE_PODCASTS_VENDOR_NUMBERnoneApple Podcasts Connect vendor number
APPLE_PODCASTS_REPORTER_TOKENnoneReporter access token, expires after 180 days
APPLE_PODCASTS_READ_ONLY0Hide the one tool that writes a file
APPLE_PODCASTS_ALLOW_DESTRUCTIVE10 blocks the OPML export
APPLE_PODCASTS_AUDIT_LOGnoneAppend-only log of every attempted write, and who approved it
APPLE_PODCASTS_CONFIRMhumanmodel lets confirm: true alone approve over MCP, for an agent with no person to ask
APPLE_PODCASTS_TOOLSETSalllibrary and the rest: which toolsets are on. APPLE_PODCASTS_LIBRARY=0 turns the library one off
APPLE_PODCASTS_SURFACEfullsearch lists three tools that find, describe and run the rest
APPLE_PODCASTS_TOOL_TIMEOUT_MSnoneGive up on any tool after this long
APPLE_PODCASTS_DEBUG01 prints debug lines on stderr
APPLE_PODCASTS_CACHE_TTL_MS300000How long a fetched response stays reusable
APPLE_PODCASTS_REQUEST_TIMEOUT_MS30000Per-request deadline
APPLE_PODCASTS_MIN_REQUEST_INTERVAL_MS220Spacing between requests, to stay under the limit
APPLE_PODCASTS_MAX_RETRIES3Retries on 5xx and transient errors
APPLE_PODCASTS_USER_AGENTapple-podcasts-mcpUser-Agent sent to Apple and to podcast hosts
APPLE_PODCASTS_ITUNES_HOSThttps://itunes.apple.comOverride the Search API host, for testing
APPLE_PODCASTS_CHARTS_HOSThttps://rss.marketingtools.apple.comOverride the charts host, for testing
APPLE_PODCASTS_REPORTER_HOSThttps://reportingitc-reporter.apple.comOverride the Reporter host, for testing
APPLE_PODCASTS_HTTP_PORT8788For --http
APPLE_PODCASTS_HTTP_HOST127.0.0.1For --http
APPLE_PODCASTS_HTTP_TOKENnoneBearer token for --http. Any address but localhost refuses to start without one
APPLE_PODCASTS_HTTP_ALLOWED_ORIGINSnoneComma-separated browser origins allowed to connect; a page from any other site is refused

Versions

See CHANGELOG.md.

Questions

Run into a problem or have a question? Open an issue and I will help.

About the author

Navid Moazzez is a leading AI business strategist, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life. He creates useful free tools, MCP servers and CLIs that creators and founders can use in their own workflows.

Links

If this is useful, star the repo and come say hi on X.

Dependencies

LibraryLicenseWhat it does
SlipwayApache-2.0The MCP server and the CLI from one definition of each tool, with the write guard
MCP TypeScript SDKApache-2.0The MCP protocol and transports, through Slipway
zodMITTool argument schemas and validation

RSS parsing and SQLite reading are both built in, so there is nothing else to install. The library is read through Node's own node:sqlite where available, falling back to the sqlite3 command that ships with macOS.

License

MIT. Free to use, modify, and share.

Not affiliated with, endorsed by, or connected to Apple Inc.


© 2026 Navid Media. Made with ❀️ by Navid Moazzez.