Skip to main content
Glama

apple-podcasts-mcp

Owner-side Apple Podcasts analytics for AI agents: plays, followers, and per-episode listening, over the Apple Podcasts Connect Reporter protocol. Read-only.

npm version License: Apache 2.0 Node Glama score Podcast X


An MCP server for the analytics Apple shows the person who owns the show: how many plays an episode got, how far into it people got, and whether the follower count is moving. That data lives behind Apple Podcasts Connect and the Reporter service, and it is not in Apple's public catalog API.

Nothing here has been checked against a live Apple account. The protocol is implemented from Apple's Reporter documentation and tested against fixtures written by hand. No request this server sends and no response it parses has been confirmed on the wire. If you run it against a real vendor number, an issue saying what came back is the most useful thing you can send.

You need an Apple Podcasters Program membership to use this at all. Reporter identifies you by a vendor number, and a vendor number is issued as part of the vendor relationship that Program enrollment creates. A standard free Podcasts Connect account does not have one: its Account → Details page shows an account UUID, which is a different identifier and will not work here. Enrollment costs an annual fee and requires a legal entity with tax and banking details. See Availability of Apple Podcasts features.

If you are not enrolled, there is nothing to configure and this server cannot help you — read your numbers in the Analytics section of Podcasts Connect instead.

Read-only. Reporter only reads. Nothing this server does can change a show, an episode, or an account.

What this does not do

This is not the iTunes Search / public catalog API. It does not look up shows by name, read public charts, fetch artwork, or return reviews and ratings. The other "Apple Podcasts" MCP servers I have looked at wrap the public catalog, which needs no credentials. This one needs your vendor number and your access token, and in exchange it returns your own listening data.

It also does not cover:

  • Subscriptions and revenue. Reporter has apSubscriptionsSales and friends. This server does not wrap them.

  • Anything before you had a Podcasts Connect account. Reporter reports on what Apple recorded for your vendor number.

  • Today. Apple publishes on a one-to-two day lag, so ranges default to ending two days back.

  • Downloads. Apple reports plays and listeners, which are not downloads. If you want download counts, use a hosting or prefix analytics source such as op3-mcp.

Related MCP server: Open Podcast Prefix Project (OP3) MCP Server

Tools

Tool

What it returns

apple_podcasts_check_access

Whether the token works, which vendor numbers it can read, and the token expiry when Apple returns one. No listening data.

apple_podcasts_summary

Show-level plays, unique listeners, engaged listeners, and followers over a date range, per period and totalled. Listener counts are devices, not people — see What the metrics mean.

apple_podcasts_episodes

Per-episode plays and listener counts over a date range, rolled up across periods and ranked.

apple_podcasts_followers

Follower value per period across a range, with the change over the window.

There is deliberately no "fetch the raw report" tool. Reporter returns one report per date, each with a row per episode and, in the non-worldwide variants, a row per storefront per episode. A month of that is tens of thousands of rows, and handing it to an agent verbatim is how you spend a context window on tab-separated text.

Every tool takes an explicit date range and a cap:

  • max_periods limits how many Reporter calls a single tool call makes. Hard cap 31. Reporter has no range query — one date is one HTTP round trip — so this is a rate-limit guard, not a formality. A range wider than the cap is truncated to the most recent periods, and the response says so with rangeTruncated.

  • limit on apple_podcasts_episodes caps returned rows at 50.

  • Ranges default short: 7 days for Daily, 7 weeks for Weekly, 6 months for Monthly. Each default is sized to fit inside the default max_periods of 7, so a call with no dates returns a whole window rather than a truncated one.

What the metrics mean

Apple's numbers are not headcounts. Podcasts Connect Analytics aggregates "listening and viewing completion rates from unique devices" (Apple), so a listener is a device. One person with a phone and a CarPlay head unit can be two.

  • Plays — times someone pressed play on an episode.

  • Unique listeners — devices that played more than zero seconds.

  • Engaged listeners — devices that played at least 20 minutes or 40% of an episode. That is Apple's threshold for depth. It is not a completion rate, and 40% of an episode is not finishing it.

  • Followers — a level, not a flow. See About the column names for why this one needs care.

Setup

1. Get your vendor number and access token

Both come from the Reporter side of Apple Podcasts, which requires an Apple Podcasters Program membership — see the note at the top. A free Podcasts Connect account has neither.

Enrolled accounts get their vendor number and access token through Apple's Reporter tooling, documented in the Reporter User Guide. Reporter's generateToken command issues the access token; viewToken shows the current one and its expiry.

Two constraints from Apple's documentation that will bite you:

  • One active token per Apple Account. Generating a new token immediately expires the previous one. If anything else uses Reporter on this account — another tool, a colleague, a dashboard you set up last year — generating a token here silently breaks it, and the failure looks exactly like expiry.

  • Token management is not meant to be automated. Apple states these commands "are not intended for automated use and access may be rate limited," so do not script rotation.

The Settings page this section used to point at does not exist. An earlier version of these instructions said to find the vendor number and generate an access token under Podcasts Connect → Settings. Podcasts Connect has no Settings page. Its Account section has People, API Keys, and Details, and none of them carries a vendor number. Those instructions were written from Apple's documentation and never checked against the product.

The API Keys page there is a different feature and not a substitute: Apple states an API key "allows your hosting provider to publish shows and episodes to Apple Podcasts on your behalf, but they will not have access to your listening analytics." Generating one grants this server nothing, and a key cannot be modified to add services after it is created.

2. Build it

Published on npm. The config blocks below use npx, which fetches it on first run; no clone required.

git clone https://github.com/conorbronsdon/apple-podcasts-mcp.git
cd apple-podcasts-mcp
npm install
npm run build

3. Configure your MCP client

Claude Code

Add to your .mcp.json:

{
  "mcpServers": {
    "apple-podcasts": {
      "command": "npx",
      "args": ["-y", "@conorbronsdon/apple-podcasts-mcp"],
      "env": {
        "APPLE_PODCASTS_ACCESS_TOKEN": "your-access-token",
        "APPLE_PODCASTS_VENDOR_ID": "87654321"
      }
    }
  }
}

Codex CLI

Add to ~/.codex/config.toml:

[mcp_servers.apple-podcasts]
command = "npx"
args = ["-y", "@conorbronsdon/apple-podcasts-mcp"]
env = { APPLE_PODCASTS_ACCESS_TOKEN = "your-access-token", APPLE_PODCASTS_VENDOR_ID = "87654321" }

Claude Desktop

Same block as Claude Code, in claude_desktop_config.json.

The server starts without credentials so a client can list its tools. Each tool call then fails with a message telling you which variable is missing.

If your token can read more than one account

APPLE_PODCASTS_ACCOUNT_ID is optional and most setups do not need it. Set it when Reporter answers with code 214, "this token has access to more than one account; specify an account number" — Reporter will not pick one for you, so every call fails until you name it.

"env": {
  "APPLE_PODCASTS_ACCESS_TOKEN": "your-access-token",
  "APPLE_PODCASTS_VENDOR_ID": "87654321",
  "APPLE_PODCASTS_ACCOUNT_ID": "2011425"
}

It is an environment variable rather than a tool argument because it is part of the credential, not part of a question: it does not vary between calls, and putting it in every tool's schema would spend context on an argument almost no one sets. Leave it unset if you have one account — Reporter rejects an empty account field, so the server omits it entirely rather than sending a blank. apple_podcasts_check_access echoes back the account number in use.

3. Verify

Ask your assistant: "Check my Apple Podcasts access." That runs apple_podcasts_check_access, which proves the token works and shows whether your vendor number is one the token can read — the two failures that look identical from the outside.

Token rotation, every 180 days

Apple Reporter access tokens expire 180 days after you generate one. This is the thing that will break your setup, and it will break it silently: the server keeps starting, the tools keep listing, and every call starts failing.

When a token expires, tools return:

Apple Reporter error (123) on Sales.getReport: Access token is expired. Reporter tokens
last 180 days. Generate a new one in Apple Podcasts Connect > Settings > Access Token and
update APPLE_PODCASTS_ACCESS_TOKEN.

To rotate:

  1. Issue a new token with Reporter's generateToken, per the Reporter User Guide.

  2. The old one stops working the moment the new one exists, so do this when you can update the config in the same sitting.

  3. Replace APPLE_PODCASTS_ACCESS_TOKEN wherever you set it, and restart the MCP client so it picks up the new environment.

Rotation is account-wide, not per-application. Apple allows one active token per Apple Account. Anything else on the account that talks to Reporter will start failing the moment you rotate here, with the same code 123 this server reports. If more than one thing needs Reporter access, they have to share a token and rotate together.

Two things worth doing when you set this up:

  • Run apple_podcasts_check_access and note the tokenExpires date if Apple returns one. Not every account gets an expiry back from Sales.viewToken; when it does not, the response says so and you should track the date yourself.

  • Put a calendar reminder at day 170. Rotation is 30 seconds of work; discovering it expired mid-analysis is not.

Expiry (code 123) and a rejected token (code 124) are separate error types here, because the fix is different: one means rotate, the other means you pasted it wrong.

Worked example

You: How did the show do on Apple last week, and which episodes carried it?

The assistant runs two calls.

apple_podcasts_summary with period: "Daily", start: "2026-07-24", end: "2026-07-30":

{
  "reportType": "apShowListeningWorldwide",
  "period": "Daily",
  "requestedRange": { "start": "20260724", "end": "20260730" },
  "periodsReturned": 7,
  "totals": { "plays": 8940, "uniqueListeners": 5620, "engagedListeners": 3810 },
  "totalsNote": "Totals sum the flow metrics (plays, listeners, time listened) across periods. Followers is a level, not a flow, so it is reported per period in the series and is deliberately absent from totals.",
  "series": [
    { "date": "20260724", "rows": 1, "metrics": { "plays": 1204, "followers": 9430 } },
    { "date": "20260725", "rows": 1, "metrics": { "plays": 1530, "followers": 9512 } }
  ],
  "resolvedColumns": { "plays": "Plays", "followers": "Followers" }
}

Then apple_podcasts_episodes over the same range, sort_by: "engagedListeners", limit: 5:

{
  "totalEpisodes": 43,
  "returned": 5,
  "sortedBy": "engagedListeners",
  "episodes": [
    { "episodeId": "1000712346", "episodeName": "What evals actually measure",
      "plays": 830, "uniqueListeners": 635, "engagedListeners": 530 }
  ]
}

engagedListeners is the interesting one. Plays counts starts; engaged listeners counts the devices that got at least 20 minutes or 40% into the episode. An episode that leads on plays and trails on engagement got clicked, not heard.

(Values above are illustrative. Column names come from your account's report — see the next section.)

About the column names

Apple does not publish the column layout for the podcast listening reports, and has renamed columns between report versions. So this server does not hardcode column names. Each metric resolves through an alias table (src/tsv.ts), and every response reports:

  • resolvedColumns — which column each metric actually matched in your report.

  • unmappedColumns — columns present in the report that matched nothing known.

If Apple renames a column, apple_podcasts_summary and apple_podcasts_episodes return a schemaNote alongside the unmapped name, not a quiet zero. If you see a metric you care about sitting in unmappedColumns, open an issue with the column name and it goes in the alias table.

The same caution applies to followers. Apple's follower column has been both a running total and a per-period count. apple_podcasts_followers returns resolvedColumn, change (latest minus first), and sumAcrossPeriods, and tells you which to read for which case rather than guessing on your behalf.

Errors

Reporter is not REST. It answers most failures with a numeric code in the body, frequently under HTTP 200, so a client that trusts the status code will parse an error envelope as a report. This server checks the body. Codes map to typed errors (src/errors.ts):

Error

Reporter code

Means

TokenExpiredError

123

The 180-day clock ran out. Rotate.

TokenInvalidError

124, 125, 132, HTTP 401/403

Token missing, malformed, or rejected.

VendorError

200, 300

The vendor number is not one this token can read. Run apple_podcasts_check_access.

AccountError

214, 215

The token reaches several Apple accounts and Reporter will not choose, or the account number given is wrong. Set APPLE_PODCASTS_ACCOUNT_ID.

NoDataError

209, 211, 213

Valid request, no report for that period. Routine — reports lag, and quiet periods produce nothing.

RateLimitError

117, HTTP 429/503

Apple is throttling or reports are delayed. Narrow the range.

BadRequestError

201–208

Bad report type, date type, or combination.

ReporterError

anything else

Base class, also used for network failures.

NoDataError is handled rather than raised when it happens mid-range: the date is recorded under missingPeriods and the rest of the range still returns. A range that comes back completely empty gets an explanation, not a page of zeros.

A range that produces no Reporter dates at all is a separate answer. Weekly reports are keyed to the Sunday that ends the week, so a Monday-to-Friday Weekly range contains no report date and nothing is sent to Apple. The response says that, rather than blaming Apple's publishing lag for a request that was never made.

Protocol notes

Reporter takes an HTTP POST with a single form-encoded field, jsonRequest, holding a JSON document with the token and a bracketed command:

POST https://reportingitc-reporter.apple.com/reportservice/sales/v1
Content-Type: application/x-www-form-urlencoded

jsonRequest={"accesstoken":"...","version":"2.2","mode":"Robot.XML",
             "queryInput":"[p=Reporter.properties, Sales.getReport, 87654321,apShowListeningWorldwide,Summary,Daily,20260728]"}

Version 2.2 matters: token-based auth (generateToken) requires Reporter 2.2 or later, and an older version string gets the token rejected. Successful reports come back gzipped (Content-Type: application/a-gzip) as tab-separated text with one header line and no quoting.

When APPLE_PODCASTS_ACCOUNT_ID is set, an account field joins the same JSON document. It is left out when unset: Reporter treats an empty account as an error rather than as "no preference".

Apple's own client is a Java jar. This server reimplements the wire protocol directly, so there is no JVM anywhere in the dependency tree. Apple's reference: Reporter User Guide.

Development

git clone https://github.com/conorbronsdon/apple-podcasts-mcp.git
cd apple-podcasts-mcp
npm install
npm run build
npm test

Run locally:

APPLE_PODCASTS_ACCESS_TOKEN=... APPLE_PODCASTS_VENDOR_ID=... npm start

Tests stub fetch and run against hand-built fixtures in src/__tests__/fixtures/. No test touches Apple. Read the provenance comment at the top of the fixtures file before treating its column names as Apple's schema: the fixtures pin the parsing, aggregation, date, and error paths, which is what they exist for. They were written to match Apple's documented response shape, not captured from an account, and neither was the reference implementation this was ported from.

Releasing

.github/workflows/publish.yml publishes on a version bump using npm Trusted Publishing. Trusted Publishing is configured per package on npmjs.com, so the first publish has to be done by hand (npm publish --access public) or with a granular access token. Until the package exists and this repository is registered as its trusted publisher, the workflow runs and fails at the publish step. The workflow header has the steps.

Contributing

Issues and pull requests welcome. Three things are especially useful, in order:

  • Anything at all from a live account. No response this server parses has been verified against real Apple data — the implementation reads Apple's documentation and the tests run on fixtures. If you point it at a real vendor number, say what happened, working or not. That is the gap nothing else here closes.

  • Column names from a real account. If a metric you care about shows up in unmappedColumns, post the column name. It cannot be derived from public documentation.

  • A Reporter code this server maps badly. Include the code and Apple's message.

Keep the read-only contract, and keep new tools bounded — an explicit range and a row cap, no raw dumps.

About

Built and maintained by Conor Bronsdon. I host the Chain of Thought podcast, which covers AI infrastructure, developer tools, and how practitioners actually use this stuff. I built this because Apple has the listening data that matters for a show and the only supported way to get it was a Java jar and a spreadsheet.

Companion tools:

  • op3-mcp: OP3 download analytics — geography, apps, per-episode downloads. Downloads where this covers plays.

  • Transistor-MCP: the Transistor.fm MCP server. Episodes, transcripts, hosting-side counts.

  • podcastindex-mcp: the Podcast Index MCP server, search by person or topic, trending shows, feed health.

  • podcast-benchmark: benchmark your show against peers on public signals.

  • ai-tools-for-creators: a curated list of AI skills and MCP servers for people who ship ideas for a living.

More at chainofthought.show and on X.


Disclaimer

This is an independent personal project, not affiliated with, sponsored by, or endorsed by Apple Inc. All views expressed are my own.

License

Apache-2.0

Available Tools

4 tools
apple_podcasts_check_accessA

Verify the configured Apple Podcasts Connect credentials and list the vendor numbers this access token can read. Run this first, and run it whenever another tool reports an auth failure: Reporter access tokens expire 180 days after they are generated, and the failure looks like a permissions problem rather than an expiry. Returns no listening data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations, the description fully discloses behavioral traits: returns no listening data, and provides critical context about token expiry (180 days) and how failures manifest. This goes beyond basic description to help agents diagnose issues.

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

Conciseness5/5

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

Two sentences, front-loaded with the core action, followed by usage guidance and return behavior. Every sentence provides value without redundancy. Efficient and well-structured.

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 a simple check tool with no output schema, the description covers purpose, usage timing, return contents, and an important expiration caveat. It is self-contained and sufficient for an agent to invoke correctly.

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?

No parameters exist, so schema coverage is trivially 100%. The description adds no param details because there are none. Baseline for 0 params is 4, and the description appropriately clarifies the tool takes no input.

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?

The description clearly states the tool's purpose: verify credentials and list vendor numbers. It uses specific verbs ('verify', 'list') and identifies the resource (Apple Podcasts Connect credentials, access token). This distinguishes it from sibling tools that likely return data summaries or episode lists.

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

Usage Guidelines5/5

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

Explicitly instructs when to run: 'Run this first, and run it whenever another tool reports an auth failure'. This provides a clear trigger condition and implies it should precede other tools. Though it doesn't name alternatives, the context of auth failure makes the choice unambiguous.

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

apple_podcasts_episodesA

Per-episode listening from Apple Podcasts Connect over a date range: plays, unique listeners, and engaged listeners for each episode, rolled up across the range and ranked. Answers 'which episodes held attention on Apple'. Apple aggregates from unique devices, so these are device counts, not headcounts, and an engaged listener is a device that played at least 20 minutes or 40% of an episode — a depth threshold, not a completion. Takes an explicit date range and a row cap; both are required to keep the response bounded.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoEnd of the range, YYYY-MM-DD (or YYYY-MM for Monthly). Defaults to 2 days ago, because Apple publishes reports on a lag.
limitNoMax episodes to return, ranked by sort_by. Default 10, cap 50.
startNoStart of the range, YYYY-MM-DD (or YYYY-MM for Monthly). Defaults to 7 days back for Daily, 7 weeks for Weekly, 6 months for Monthly — each sized to fit the default max_periods of 7.
periodNoReporter period. Daily and Weekly take YYYY-MM-DD dates; Monthly takes YYYY-MM. Weekly dates are Apple's week-ending Sundays.Daily
sort_byNoWhich metric ranks the episodes. Default plays.plays
worldwideNoUse the worldwide episode report instead of the per-storefront one. Per-storefront repeats every episode once per country, which is far more rows for the same totals.
max_periodsNoHow many periods to fetch, cap 31. Reporter has no range query, so each period is a separate call to Apple and a wide range will hit their throttle. Default 7. Ranges longer than this are truncated to the most recent periods.

TDQS

A4.4/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden and excels: it discloses that Apple aggregates by unique devices (device counts not headcounts), explains the engaged listener threshold (20 minutes or 40%), and notes the bounded response requirement. This is rich behavioral context beyond the schema.

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

Conciseness5/5

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

The description is appropriately concise—four sentences, each earning its place: purpose, use case, metric semantics, and response-boundary constraint. It is front-loaded and contains no fluff or repetition.

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

Completeness4/5

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

The rich schema combined with the description covers purpose, metrics semantics, and constraints well. There is no output schema, but the description implies output structure (ranked episodes). Minor ambiguity about 'required' params (schema shows defaults) leaves a small gap, preventing a 5.

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

Parameters3/5

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

Schema description coverage is 100%, with all 7 parameters well-documented. The description adds rationale for date range and limit (bounded response) but does not substantially enhance per-parameter meaning beyond what the schema already provides, so the baseline of 3 is appropriate.

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?

The description clearly states the tool provides per-episode listening metrics (plays, unique listeners, engaged listeners) over a date range, rolled up and ranked. It uses specific verb and resource (Apple Podcasts Connect episodes) and is well differentiated from siblings like summary and followers by focusing on episode-level attention.

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?

The description gives context on when to use this tool ('Answers which episodes held attention on Apple') and implies differentiation from siblings (summary, followers). However, it does not explicitly name alternatives or state exclusions, so it stops short of full guidance.

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

apple_podcasts_followersA

Follower trend for the show on Apple Podcasts over a date range: one value per period plus the change across the window. Use it for 'is my Apple following growing'. Read the resolvedColumn field in the response before interpreting the numbers: Apple's follower column has been both a running total and a per-period count, and which one you get changes what 'change' means.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoEnd of the range, YYYY-MM-DD (or YYYY-MM for Monthly). Defaults to 2 days ago, because Apple publishes reports on a lag.
startNoStart of the range, YYYY-MM-DD (or YYYY-MM for Monthly). Defaults to 7 days back for Daily, 7 weeks for Weekly, 6 months for Monthly — each sized to fit the default max_periods of 7.
periodNoReporter period. Daily and Weekly take YYYY-MM-DD dates; Monthly takes YYYY-MM. Weekly dates are Apple's week-ending Sundays.Daily
max_periodsNoHow many periods to fetch, cap 31. Reporter has no range query, so each period is a separate call to Apple and a wide range will hit their throttle. Default 14. Ranges longer than this are truncated to the most recent periods.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full burden. It discloses a key behavioral nuance: 'Read the resolvedColumn field in the response before interpreting the numbers: Apple's follower column has been both a running total and a per-period count, and which one you get changes what 'change' means.' It also mentions output structure (one value per period plus change) and implicitly that it's a read operation.

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

Conciseness5/5

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

The description is three tightly written sentences. The first sentence states purpose and output, the second gives a use case, and the third warns about interpreting the data. No wasted words; front-loaded and easy to parse.

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

Completeness4/5

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

There is no output schema, so the description must compensate. It explains the data shape (one value per period plus change) and the critical resolvedColumn caveat. It could be more explicit about the response structure, but for a trend tool this is sufficient. The schema fills in parameter behavior, and the description covers the essential interpretation pitfall.

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

Parameters3/5

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

The input schema provides 100% coverage with detailed descriptions for all four parameters, including defaults, date formats, and truncation behavior. The description adds no parameter-specific guidance, but the schema already does the heavy lifting, so a baseline of 3 is appropriate.

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?

The description clearly states the tool's function: 'Follower trend for the show on Apple Podcasts over a date range: one value per period plus the change across the window.' It specifies the resource (follower trend) and scope (over a date range), distinguishing it from sibling tools like apple_podcasts_summary and apple_podcasts_episodes.

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?

The description gives an explicit use case: "Use it for 'is my Apple following growing'." This tells the agent when to choose this tool. However, it does not name alternative tools or provide exclusion criteria, so it misses the 'when-not-to-use' aspect.

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

apple_podcasts_summaryA

Show-level listening summary from Apple Podcasts Connect over a date range: plays, unique listeners, engaged listeners, and followers, per period and totalled. Apple aggregates listening from unique devices, so listener counts are devices, not people, and an engaged listener is a device that played at least 20 minutes or 40% of an episode. This is the owner-side data Apple's hosting APIs do not expose. Use it for 'how is the show doing on Apple' questions. Keep the range short; each period is a separate call to Apple.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoEnd of the range, YYYY-MM-DD (or YYYY-MM for Monthly). Defaults to 2 days ago, because Apple publishes reports on a lag.
startNoStart of the range, YYYY-MM-DD (or YYYY-MM for Monthly). Defaults to 7 days back for Daily, 7 weeks for Weekly, 6 months for Monthly — each sized to fit the default max_periods of 7.
periodNoReporter period. Daily and Weekly take YYYY-MM-DD dates; Monthly takes YYYY-MM. Weekly dates are Apple's week-ending Sundays.Daily
worldwideNoUse the worldwide report (one row per period) instead of the per-storefront report (one row per storefront). Worldwide is smaller and is what you want unless you need geography.
max_periodsNoHow many periods to fetch, cap 31. Reporter has no range query, so each period is a separate call to Apple and a wide range will hit their throttle. Default 7. Ranges longer than this are truncated to the most recent periods.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden and does so excellently. It discloses that Apple counts unique devices rather than people, defines an engaged listener precisely (20 minutes or 40% of an episode), and warns that each period is a separate API call to Apple with throttling implications. These are non-obvious behavioral facts essential for correct use.

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

Conciseness5/5

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

Four tight sentences: state what it does, define key metrics, give usage context, and warn about API behavior. No filler or repetition; every sentence earns its place and the most important information is front-loaded.

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?

Despite having no output schema, the description tells the caller what to expect in return (metrics per period plus totals) and gives necessary caveats (device-based counting, engaged listener threshold, Apple's lag, range limits). For a read-only reporting tool with a fully specified input schema, this is complete enough to invoke correctly.

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?

The input schema already covers 100% of parameters with detailed descriptions, so the baseline is 3. The description adds value by explaining why 'keep the range short' (each period is a separate call) and by defining what the returned listener metrics actually mean, which clarifies the data behind the parameters. It doesn't describe each parameter individually, but the schema already does that.

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?

The description opens with 'Show-level listening summary from Apple Podcasts Connect' and enumerates exactly which metrics are returned (plays, unique listeners, engaged listeners, followers) and how they are aggregated (per period and totalled). This clearly distinguishes it from siblings like apple_podcasts_episodes and apple_podcasts_followers by scope and content.

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?

The description gives a direct usage cue: 'Use it for "how is the show doing on Apple" questions.' It also notes that this is owner-side data not exposed by hosting APIs. However, it does not explicitly mention when NOT to use it or name alternative sibling tools, so it falls short of the top tier.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedapple_podcasts_check_access
    • First observedapple_podcasts_episodes
    • First observedapple_podcasts_followers
    • First observedapple_podcasts_summary

TDQS

A4.6/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: check_access verifies credentials, summary provides show-level metrics, episodes provides per-episode metrics, and followers provides follower trends. There is no overlap or ambiguity between them.

Naming Consistency5/5

All tool names follow the consistent pattern 'apple_podcasts_<resource>', making it highly predictable and easy to understand the target of each call. Even though 'check_access' uses a verb-noun structure, it fits the same prefix convention.

Tool Count5/5

With just 4 tools, the server is tightly scoped to the core analytics operations needed for Apple Podcasts Connect: access verification, show summary, episode breakdown, and follower trends. Each tool earns its place with no redundancy.

Completeness5/5

The tool set covers the primary analytics surface for a podcast show on Apple: overall performance, per-episode performance, and audience growth. The access check tool ensures credential management, and the provided date-range and row-cap parameters cover typical use cases. No obvious gaps for the stated domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers