Skip to main content
Glama

OP3 MCP

Stars License npm Downloads YouTube X LinkedIn

OP3 sits in front of the audio file, so it counts every download whatever app made it.

That is why its numbers differ from Apple's or Spotify's, which each report only their own listeners.

22 tools, including unique listeners, retention cohorts and episode benchmark curves that OP3's own API does not expose.

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

Two ways to use it

Command line

op3-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:

npm install -g @thenavidm/op3-mcp-cli
op3-cli                                   # every command
op3-cli op3-global-app-share --agent
op3-cli op3-get-show --identifier https://feeds.example.com/show.xml
op3-cli op3-show-downloads --help
op3-cli which listener retention          # find the command for a task

Every command reads OP3's public data, so nothing asks for --confirm. --agent is JSON on one line for scripts and agents, and --select a,b.c keeps only the fields you name.

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

MCP server, for AI agents

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

claude mcp add op3 -- npx -y @thenavidm/op3-mcp-cli

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

Related MCP server: Claude Stats MCP

Contents

  1. What you can ask it

  2. Quick install

  3. Setup

  4. Connect your client

  5. Check it worked

  6. What it costs to have connected

  7. Tools

  8. Reading the numbers

  9. Your data

  10. Troubleshooting

1. What you can ask it 💬

  • How many downloads did my podcast get this month?

  • How many actual people is that, not downloads?

  • Are my listeners coming back, or is it a new audience every month?

  • Is this week's episode tracking ahead or behind my usual?

  • Where in the world is my audience, down to the state?

  • Which podcast apps do my listeners use, and is that unusual?

  • Compare my show against these three others.

  • What day and hour do most downloads happen?

  • Which of my episodes share the same listeners?

  • OP3 shows nothing for my feed. What is wrong?

The one that is impossible without this server is the second. Every podcast analytics dashboard reports downloads. A download is an app fetching a file, not a person, and one listener whose app re-requests across three days counts three times. OP3's raw rows carry a privacy-preserving per-listener hash, so unique listeners, returning listeners and retention can be computed from them. None of OP3's own aggregated endpoints expose that, and this server does.

2. Quick install ⚡

Node 22 or newer. Nothing else.

npx -y @thenavidm/op3-mcp-cli@latest --version

That is the whole install. npx fetches it on demand, so there is nothing to update later: with @latest, a new version reaches you the next time your client starts the server.

To build from source instead:

git clone https://github.com/thenavidm/op3-mcp-cli.git
cd op3-mcp
npm install
npm run build
npm test
node dist/index.js --version

3. Setup 🔑

You can skip this. The server works with no credential at all, because OP3 publishes a shared preview token and that is what it falls back to. It is rate limited and OP3 can withdraw it, so get your own before relying on it.

Have an agent do it

The agent cannot sign in to OP3 for you. What it can do is walk you through it and wire up the config.

Paste this into Claude Code, Cursor, or any agent with terminal access:

Help me set up the OP3 MCP server.

1. Open https://op3.dev/api/keys and tell me what to click to create an
   API key and its bearer token.
2. Stop and wait for me to paste the token back.
3. Add the server to my MCP client config with that token as OP3_TOKEN.
4. Run the doctor command and tell me whether it worked.

Or do it yourself

  1. Go to op3.dev/api/keys.

  2. Create an API key and copy its bearer token.

  3. Set it as OP3_TOKEN in your client config, as in section 4.

You do not need to own a podcast. The token reads public OP3 data, which covers every show that has the OP3 prefix on its feed.

To revoke

Delete the key at op3.dev/api/keys. It stops working immediately.

If you want your own show in here

Your podcast needs the OP3 prefix on its episode audio URLs. That is a change to your feed, not to this server, and it is documented at op3.dev/setup. Until a listener downloads an episode through the prefix, OP3 has no data for your show and neither does this.

4. Connect your client 🔌

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

OP3_TOKEN is optional in every block below. Leave it out to use OP3's preview token.

Claude Code

claude mcp add op3 \
  -e OP3_TOKEN=your-token \
  -- npx -y @thenavidm/op3-mcp-cli@latest

Add --scope user to make it available in every project rather than just this 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. It asks for an OP3 token, which is optional.

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

Platform

Config path

macOS

~/Library/Application Support/Claude/claude_desktop_config.json

Windows

%APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "op3": {
      "command": "npx",
      "args": ["-y", "@thenavidm/op3-mcp-cli@latest"],
      "env": { "OP3_TOKEN": "your-token" }
    }
  }
}

Tip Claude Desktop does not inherit your shell PATH. If npx is not found, use the absolute path from which npx.

Quit Claude Desktop completely and reopen it.

claude.ai on the web

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

Run the server over HTTP:

npx -y @thenavidm/op3-mcp-cli@latest --http --port 8000

Host it somewhere with a public HTTPS URL, then in claude.ai go to Customize, Connectors, +, Add custom connector, paste the URL and click Add.

On Team and Enterprise plans an owner adds it first under Organization settings, Connectors, then each member enables it under Customize, Connectors.

It binds to 127.0.0.1 by default, which is all a tunnel or a proxy on the same machine needs. To accept connections from outside the machine, set OP3_HTTP_HOST=0.0.0.0 together with OP3_HTTP_TOKEN, a bearer token every request must send: without one, the server refuses to listen beyond this machine.

Cursor

.cursor/mcp.json, same JSON shape as Claude Desktop, key mcpServers.

Windsurf

~/.codeium/windsurf/mcp_config.json, key mcpServers.

VS Code

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

{
  "servers": {
    "op3": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@thenavidm/op3-mcp-cli@latest"],
      "env": { "OP3_TOKEN": "your-token" }
    }
  }
}

Codex CLI

~/.codex/config.toml:

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

[mcp_servers.op3.env]
OP3_TOKEN = "your-token"

Gemini CLI

~/.gemini/settings.json, key mcpServers.

Everything else

Any stdio MCP client takes the same three things: the command npx, the args, and the env block.

Docker

docker build -t op3-mcp .
docker run --rm -i -e OP3_TOKEN=your-token op3-mcp

5. Check it worked 🩺

npx -y @thenavidm/op3-mcp-cli@latest doctor

It tests the token against the cheapest OP3 endpoint, tests the raw query endpoints separately because they fail for their own reasons, and prints the settings in force.

Symptom

Cause

doctor says the token was rejected

The key was deleted at op3.dev/api/keys, or OP3_TOKEN has a stray space

Every show lookup returns not found

The podcast does not have the OP3 prefix on its feed. Run op3_verify_prefix

Rolled-up tools work, raw ones time out

The window is too wide. Narrow it, or raise OP3_REQUEST_TIMEOUT_MS

Numbers do not match the OP3 dashboard

Rolled-up figures lag by about a day. Check the asof field

npx not found in Claude Desktop

Desktop does not inherit your shell PATH. Use the absolute path

6. What it costs to have connected

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

MCP server

CLI

Every message, with every tool loaded

9,000 tokens

nothing

Every message, Claude Code's default

1,000 tokens

nothing

When OP3 comes up

nothing more, or the tools it picks

3,400 tokens for SKILL.md, once

20 messages with OP3 in 1, every tool loaded

180,000 tokens

3,400 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 OP3 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. Or install the CLI and add the server on the days it earns its place.

Measured on 2026-10-05 against 1.2.2, 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 the same way) and Codex 0.159.3 on gpt-6.1-sol:

Cost

1.2.2

2.0.0

Claude Code, every tool loaded, every message

9,784

9,031

Claude Code's default, tool search, every message

1,030

1,026

SKILL.md, read once

3,384

3,424

Codex over the CLI, one task, median of five

84,242

61,677

Codex over MCP, the same task, median of five

78,381

78,341

The task was "find the command that compares listener retention between two periods, and the flags it requires". Every tool loaded costs less because each tool no longer repeats $schema, additionalProperties and an execution block. Over the CLI, every 1.2.2 run read the general help, the command list and the command's help, three requests that each carry the conversation so far; which answers with the command's help when one command fits well ahead of the rest, so 4 of five 2.0.0 runs needed two. Over MCP, Codex answered from the tool list without calling a tool, and read about 40,000 input tokens in one run of five on each version and about 78,000 in the rest. SKILL.md costs 40 more because it lists which and exit code 1. Other apps and models count tokens a little differently, and tool-list characters divided by four are not API usage.

7. Tools 🛠️

Every tool is a read. Nothing here changes anything.

Finding a show

Tool

Does

op3_resolve_show

Any identifier to an OP3 show uuid. Takes a feed URL and encodes it for you

op3_get_show

Show title, uuid, podcast guid, stats page, optionally the episode list

op3_list_episodes

Episodes with OP3 episode ids and publication dates, searchable by title

Downloads, from OP3's rolled-up data

Fast. Prefer these whenever they answer the question.

Tool

Does

op3_show_downloads

Monthly downloads, the week-by-week breakdown, and the weekly average

op3_episode_downloads

Downloads at 1, 3, 7 and 30 days after publication, plus all-time

op3_compare_shows

Several shows ranked side by side, in one request

Audience, from the raw rows

The tools OP3's own API cannot give you.

Tool

Does

op3_audience_summary

Unique listeners against downloads, and the ratio between them

op3_new_vs_returning

First-time against repeat listeners, over a baseline you choose

op3_listener_retention

Cohort carry-over between two periods, as two separate rates

op3_episode_overlap

Which episodes share an audience, and how much

Where and how

Tool

Does

op3_geography

Downloads and listeners by continent, country, region, metro or timezone

op3_app_share

Podcast apps, over any window rather than OP3's fixed three months

op3_device_breakdown

All four dimensions at once: agent type, app, device type, device

op3_global_app_share

App market share across every show OP3 measures

op3_benchmark_apps

This show against that global mix, indexed so 100 is average

Over time

Tool

Does

op3_download_trend

Downloads and listeners by day, week or month, with a growth rate

op3_listening_patterns

Hour of day and day of week, in UTC

op3_episode_curve

One episode against the show's median at the same age

Discovery and setup

Tool

Does

op3_recent_transcripts

Episodes across OP3 that carry a podcast:transcript tag

op3_verify_prefix

Whether OP3 is receiving downloads for a feed, and what is wrong if not

op3_query_downloads

Raw download rows, every filter OP3 offers. The escape hatch

op3_query_hits

Raw request log across OP3. A verification surface, not an analytics one

8. Reading the numbers 📊

The part worth more than the upstream API docs. All of it was found by probing the live API, because OP3's OpenAPI document declares no response schemas.

A download is not a person. It is an app fetching a file. Podcast analytics across the industry quotes downloads, and a show with a loyal audience whose apps re-request looks larger than a show with more actual listeners. op3_audience_summary gives both numbers and the ratio.

Episodes are not comparable on totals. An older episode has had longer to accumulate downloads. op3_episode_curve compares at equal age against the show's own median, and excludes episodes younger than the horizon from that median so a three-day-old episode does not drag a thirty-day comparison down.

App share on its own says almost nothing. Nearly every show's biggest app is Apple Podcasts, because Apple is around 38% of all podcast listening. A show at 40% Apple is under-indexed. op3_benchmark_apps divides by the global share so the number means something.

bots does more than add bots. With it off, OP3 applies its published download calculation, which deduplicates repeat requests. With it on you get raw request rows. On one probe the same window returned 213 against 345, and only 79 of the difference were bot rows.

Rolled-up figures lag about a day. They carry an asof date. That is why they will not match a live dashboard exactly.

An empty episode list is normal for a small show. OP3's daily rollup has not covered it yet. The show-level total may still be there.

Metro codes are US-only. They are a US broadcast concept. Use level=region for a worldwide breakdown.

Raw download rows come back oldest first. OP3 offers no way to reverse that on this endpoint, so a limit takes the earliest rows in the window. Narrow the window to see recent activity rather than raising the limit.

Some shows cannot be filtered by episode. OP3 derives the episode id from the episode audio URL, so a host that regenerates those URLs leaves historical rows carrying ids that no longer appear in the feed. Checked across three shows, two matched exactly and one had no overlap at all. op3_episode_curve detects this and says so rather than returning silent zeros.

The raw endpoints are scans, not indexes. Two rows took 2790ms when probed. Cost grows with the window. The server pages with a continuation token, caps what it will pull, and labels any result that was cut short, because a truncated result presented as complete makes every rate computed from it wrong.

9. Your data 🔐

There is no backend. The server runs on your machine, talks to op3.dev, and stores nothing on disk.

Responses are cached in memory for five minutes so an agent asking several questions about one show does not pay for the same scan repeatedly. That cache dies with the process. Set OP3_CACHE_TTL_MS=0 to disable it.

Per-listener identifiers never leave the server. OP3's raw row carries audienceId and hashedIpAddress. Both are aggregated over inside the process and stripped from anything returned. Every audience figure is a count, a rate or a distribution.

This is deliberate. OP3 exists to be a privacy-preserving analytics service, and a wrapper that streamed stable per-listener keys into a model context would undo that. op3_query_downloads can emit a shortened, non-reversible label if you need to tell rows apart by listener, and it is off by default.

Third-party text. Show and episode titles come from arbitrary RSS feeds. Anyone can publish a podcast, so that text is attacker-controlled and reaches the model inside a tool result. The server neutralises fence-breaking and tells the model in its instructions to treat it as data. That raises the cost of an injection rather than removing it. The real reason the blast radius is small is that this server is read-only and reaches nothing but OP3.

Settings

Variable

Default

Does

OP3_TOKEN

preview token

Your bearer token from op3.dev/api/keys

OP3_API_KEY

unset

Accepted as an alias for OP3_TOKEN

OP3_REQUEST_TIMEOUT_MS

45000

Per-request deadline

OP3_MIN_REQUEST_INTERVAL_MS

150

Spacing between requests

OP3_MAX_RETRIES

3

Retries on 429 and 5xx

OP3_MAX_ROWS

50000

Cap on rows any one analysis pulls

OP3_MAX_PAGES

40

Cap on continuation pages

OP3_CACHE_TTL_MS

300000

Response cache lifetime, 0 disables

OP3_USER_AGENT

op3-mcp

Sent on every request

OP3_BASE_URL

https://op3.dev/api/1

OP3 API root, leave alone unless you proxy it

OP3_HTTP_PORT

8787

Port for --http

OP3_HTTP_HOST

127.0.0.1

Bind address for --http; anything but this machine needs OP3_HTTP_TOKEN

OP3_HTTP_TOKEN

none

Require this bearer token on HTTP requests

OP3_HTTP_ALLOWED_ORIGINS

none

Comma-separated browser origins allowed to call --http; a page from any other site is refused

OP3_SURFACE

full

search lists three tools that find, describe and run the rest

OP3_TOOL_TIMEOUT_MS

none

Give up on any tool after this long

OP3_DEBUG

0

1 prints debug lines on stderr

10. Troubleshooting 🔧

Run doctor first. It names the problem in one command.

npx -y @thenavidm/op3-mcp-cli@latest doctor

Symptom

Cause and fix

"OP3 has nothing at /shows/..."

The show has no OP3 prefix on its feed. Run op3_verify_prefix, then op3.dev/setup

Downloads are zero but the show exists

The prefix was added recently and nothing has come through. Widen the lookback

Every row is a bot

The prefix works but no listener has downloaded yet

A tool times out

The window is too wide for a scan. Narrow it or raise OP3_REQUEST_TIMEOUT_MS

A result says it was truncated

A cap stopped the pull. Narrow the window, or raise OP3_MAX_ROWS

op3_episode_curve returns zeros with a warning

The host regenerates episode URLs, so episode ids do not line up. Show-level tools still work

Rate limited on the preview token

It is shared. Get your own at op3.dev/api/keys

FAQ ❓

An MCP server is a standard way to give an AI assistant tools it can actually call. Model Context Protocol is the agreement they speak, so any MCP client connects to any MCP server. This one exposes 22 read-only tools over OP3.

op3-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 op3_show_downloads runs as op3-cli op3-show-downloads.

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.

It does not. The token reads public OP3 data, which covers every show that has the prefix on its feed.

You do not need an account, though you should get a token. Without one the server uses OP3's shared preview token, which is rate limited.

It works with any podcast whose feed carries the OP3 prefix, whoever hosts it.

Those report only their own listeners. OP3 sits in front of the audio file, so it sees every download regardless of app.

It does not. OP3's API is read-only and so is this.

It does not. Per-listener identifiers are aggregated inside the server and stripped from every response.

The raw endpoints are scans. Cost grows with the window. The rolled-up tools answer in milliseconds; prefer them.

It works over the HTTP transport, which needs a public HTTPS URL. See section 4.

With @latest in the install line, the next published version reaches you the next time your client starts the server.

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

Library

License

What it does

Slipway

Apache-2.0

The MCP server and the CLI from one definition of each tool

MCP TypeScript SDK

Apache-2.0

The MCP protocol and its transports, through Slipway

zod

MIT

Tool argument schemas and validation

Nothing else. The OP3 client, the pagination, the aggregation and the time handling are all built in.

License

MIT. Free to use, modify, and share.

Not affiliated with, endorsed by, or connected to the Open Podcast Prefix Project.


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

Available Tools

22 tools
op3_app_shareApp shareA
Read-onlyIdempotent

Which podcast apps a show's audience uses, over any window you choose, with unique listeners alongside downloads. Prefer this over OP3's built-in app query when the window matters, because OP3's own endpoint is locked to the last three calendar months. Listener share is the more honest column: an app that re-requests files inflates its download share without representing more people.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end. Defaults to now.
topNoHow many apps to return.
botsNoInclude known bots. Off by default.
startNoWindow start, e.g. -30d. Defaults to -30d.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the bar is lower, yet the description adds real operational context: the three-calendar-month restriction on the competing endpoint and why download share can be inflated by re-requesting apps. It does not discuss pagination, rate limits, or how the two metrics are computed, so not a full 5.

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?

Three sentences, zero filler, and front-loaded: purpose first, then the routing rule versus the alternative, then the interpretation caveat. Each sentence earns its place by changing how an agent would call or read the tool.

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?

With no output schema, the description carries some return-value burden and does name the two core columns (listener share, download share) and the windowing behavior. It stops short of describing the response shape, output format, or how windows outside the default are validated, leaving a small gap.

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%, so every parameter (identifier, start, end, top, bots) is already documented in the schema, establishing the baseline of 3. The description only alludes generally to 'any window you choose' and adds no per-parameter syntax or default detail beyond the schema.

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?

States a specific verb+resource ('which podcast apps a show's audience uses'), the scope ('any window you choose'), and the returned metrics ('unique listeners alongside downloads'). It is clearly distinguishable from the global/aggregate siblings such as op3_global_app_share and op3_benchmark_apps.

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 names the alternative ('OP3's built-in app query') and the exact condition that selects this tool over it ('when the window matters, because OP3's own endpoint is locked to the last three calendar months'). It also guides interpretation, telling the agent that listener share is the more honest column versus inflatable download share.

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

op3_audience_summaryAudience summaryA
Read-onlyIdempotent

Unique listeners against downloads for a show over any window. This is the number OP3's own dashboard and every rolled-up endpoint cannot give you: how many people, not how many requests. Read downloadsPerListener as the key figure, near 1 means each download is a distinct person, well above 1 means apps re-requesting the same file and every download number you see elsewhere is inflated by that factor.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end, same formats as start. Defaults to now.
botsNoInclude downloads from known bots. Off by default, which matches how OP3's own download counts are computed.
startNoWindow start. A relative value like -30d, -8w or -3m, a date like 2026-08-01, or an ISO timestamp. Defaults to -30d. Wider windows are slower: this reads raw rows, not a rollup.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so the bar is lower. The description adds genuine interpretive context the annotations cannot: how to read downloadsPerListener, that values near 1 mean distinct people, and that higher values mean re-requests that inflate download counts elsewhere. It doesn't cover pacing/cost beyond the schema's note about raw rows.

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

Conciseness4/5

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

Purpose is front-loaded in the first clause and every sentence carries information. The second sentence is long and slightly rhetorical ("the number OP3's own dashboard ... cannot give you"), which costs a little tightness but not clarity.

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?

With no output schema, the description must carry return-value meaning, and it does explain the key figure (downloadsPerListener) and its interpretation. It leaves the rest of the response shape unspecified, but for a read-only summary over a well-documented schema it is largely complete.

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%, so all four parameters are already documented in the schema (window formats, bots default, identifier types, slowness warning). The description adds no parameter-level detail beyond what the schema carries, so the baseline of 3 applies.

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?

States a specific verb+resource+scope: unique listeners vs downloads for a show over any window, and explicitly distinguishes the result from what other rolled-up endpoints return. An agent can tell this apart from op3_show_downloads and op3_query_downloads without opening a schema.

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?

Strong implicit routing: it says this is what the dashboard and every rolled-up endpoint cannot give you, telling the agent to reach for it when it needs people rather than requests. It stops short of naming the specific sibling to use instead (e.g. op3_show_downloads) when raw download counts are wanted.

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

op3_benchmark_appsBenchmark appsB
Read-onlyIdempotent

A show's app mix against OP3's global mix, with an index where 100 means exactly average. This is the tool that turns app share into something actionable. A show can be 40% Apple Podcasts and be under-indexed, because Apple is around 38% globally, so raw share hides the real story. Over-indexed apps are where this audience is unusual and where it can be reached deliberately.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end. Defaults to now.
botsNoInclude known bots. Off by default.
startNoWindow start for the show side, e.g. -30d. Defaults to -30d.
min_shareNoIgnore apps below this percentage of the show's downloads. Without a floor, one download from an obscure app reports as a huge over-index.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so safety is covered. The description adds genuine interpretive context about what the index means and why min_share exists, but it says nothing about the shape or size of the returned result, pagination, or how many apps come back. With annotations carrying the safety profile, a 3 is appropriate.

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

Conciseness3/5

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

The description is four sentences and opens with the mechanics, which is reasonable, but 'This is the tool that turns app share into something actionable' is filler, and the 40% Apple Podcasts example is illustrative padding rather than operational detail. Roughly half the text earns its place.

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?

With no output schema, the description carries the burden of explaining what the returned index means, and it does that well (100 = exactly average, raw share can mislead). Parameters are fully covered by the schema. It is largely complete for this tool, with only the output structure left implicit.

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%, so all five parameters (identifier, start, end, bots, min_share) are already documented in the schema, including the min_share rationale. The prose adds no syntax, format, or default information beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific comparison: a show's app mix versus OP3's global mix, producing an index where 100 = average. That is a clear verb+resource an agent can act on. It does not, however, name or contrast itself with the obvious siblings op3_app_share and op3_global_app_share, so sibling differentiation is left to inference.

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

Usage Guidelines3/5

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

It implies when the tool matters ('over-indexed apps are where this audience is unusual and where it can be reached deliberately'), which is interpretive guidance rather than routing guidance. There is no explicit statement of when to use this over op3_app_share, nor any exclusion or precondition. Usage is implied, not specified.

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

op3_compare_showsCompare showsA
Read-onlyIdempotent

Compare several shows side by side on monthly downloads and weekly average, ranked. OP3 accepts many shows in one request, so this is one call rather than several. Useful for benchmarking a show against others in its category, or for tracking a portfolio of shows at once.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifiersYesTwo to twenty shows, each as a uuid, podcast:guid or feed URL. Anything that is not already a uuid costs one extra lookup.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/openWorld and non-destructive, so the safety profile is covered. The description adds a genuinely useful behavioral fact not in the structured fields: OP3 accepts many shows per request, so comparison is one call rather than N.

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?

Three tight sentences, front-loaded with what it does and what it returns, followed by the batching rationale and use cases. No filler or restatement of the name.

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?

For a no-output-schema, one-param read tool, the description covers purpose, metrics returned, ranking, and use cases. It could say more about the response shape (per-show rows vs aggregate), but it 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.

Parameters3/5

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

Schema description coverage is 100% for the single parameter, including the 2–20 limit and the uuid/podcast:guid/feed URL formats, so the schema does the heavy lifting. The description's 'many shows in one request' only echoes the batching already documented in the schema.

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?

States a specific verb (compare), resource (shows), and the exact metrics compared (monthly downloads, weekly average) with the ranking behavior called out. An agent can distinguish this from op3_show_downloads (single show) or op3_benchmark_apps without opening a schema.

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?

Gives clear use cases: benchmarking a show against category peers and tracking a portfolio at once. It does not explicitly name the single-show alternative (op3_show_downloads) as the when-not path, but the multi-show framing implicitly excludes it.

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

op3_device_breakdownDevice breakdownA
Read-onlyIdempotent

How a show is consumed, across all four dimensions OP3 records: agentType (app, browser, bot), agentName (the specific app), deviceType (mobile, computer, tablet, smart speaker) and deviceName (Apple iPhone, Android Phone). One call returns all four, which is what you want for a picture of the audience rather than a single ranked list.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end. Defaults to now.
topNoHow many entries per dimension.
botsNoInclude known bots. Worth turning on here specifically, since agentType is the dimension that shows how much bot traffic a feed attracts.
startNoWindow start, e.g. -30d. Defaults to -30d.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.

TDQS

A4.1/5.0
Behavior3/5

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

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds useful context that all four dimensions arrive in one call, but says nothing about result volume, ordering, or how the bot filter interacts with agentType beyond what the schema already states.

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

Conciseness4/5

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

Two sentences, front-loaded with the resource and dimensions, and the payoff ('one call returns all four') lands before the qualifier. Slightly dense in the enumeration, but no sentence is filler.

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?

For a read-only analytics call with no output schema but full param documentation, the description covers the what, the return shape (four dimensions at once), and an implied use case. Nothing critical is missing for correct invocation.

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?

Schema description coverage is 100%, setting a baseline of 3. The description goes beyond the schema by decoding what agentType, agentName, deviceType and deviceName actually mean with concrete example values, which the raw enum-less parameters do not convey on their own.

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?

States a specific verb-and-resource outcome ('how a show is consumed') and enumerates the four dimensions it returns (agentType, agentName, deviceType, deviceName), so the agent knows exactly what comes back. It also implicitly separates itself from single-dimension siblings by noting it returns all four 'rather than a single ranked list.'

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 line 'which is what you want for a picture of the audience rather than a single ranked list' gives a clear situational cue and implicitly contrasts with the narrower siblings (op3_app_share, op3_geography). It stops short of naming an explicit alternative to use instead, so it never reaches when/when-not territory.

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

op3_download_trendDownload trendA
Read-onlyIdempotent

A show's downloads and unique listeners over time, bucketed by day, week or month, with a growth rate and the peak period. Growth compares the two halves of the window rather than first period against last, because podcast downloads are weekly-seasonal enough that comparing endpoints is close to noise.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end. Defaults to now.
botsNoInclude known bots. Off by default.
startNoWindow start, e.g. -90d, -12w, 2026-01-01. Defaults to -30d.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.
granularityNoBucket size. Use week or month for windows longer than a couple of months.day

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive/open-world, so the safety profile is covered. The description adds genuinely non-obvious behavioral detail: how growth is computed (halves of the window, not endpoint-to-endpoint) and why (weekly seasonality), which materially affects how an agent should interpret the output.

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

Conciseness4/5

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

Two front-loaded sentences: the first states the output, the second justifies the growth methodology. Every clause earns its place, though the seasonality rationale is somewhat verbose relative to the tool-selection job the description is doing.

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?

With no output schema, the description carries the return-value burden and does so: downloads, unique listeners, growth rate, and peak period. Combined with 100%-covered params and full annotations, an agent has everything needed to call and interpret this tool without opening anything else.

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%, including the accepted identifier formats, relative date syntax, bots default, and granularity guidance, so the baseline is 3. The description's 'bucketed by day, week or month' restates the enum without adding syntax, format, or constraint detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the exact resource and shape of the analysis: a show's downloads and unique listeners over a window, bucketed by day/week/month, plus growth rate and peak period. That specificity implicitly separates it from aggregate siblings like op3_show_downloads or op3_episode_downloads, but no sibling is named, so an agent still has to infer the boundary.

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

Usage Guidelines2/5

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

There is no explicit when-to-use, when-not-to-use, or alternative tool callout, despite several overlapping siblings (op3_show_downloads, op3_query_downloads, op3_episode_downloads). The only usage hint — 'use week or month for windows longer than a couple of months' — lives in the schema for granularity, not in the description.

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

op3_episode_curveEpisode curveA
Read-onlyIdempotent

How one episode is tracking against the show's own median at the same age. Returns cumulative downloads by day after publication alongside the median across comparable episodes, plus a verdict. This is the only fair way to judge a recent episode: total downloads always favour older episodes because they have had longer to accumulate. Only episodes at least as old as the horizon go into the median, so a three-day-old episode does not drag a thirty-day comparison toward zero.

ParametersJSON Schema
NameRequiredDescriptionDefault
botsNoInclude known bots. Off by default.
episode_idYesThe OP3 episode id, a 64-character hash from op3_list_episodes or op3_get_show with include_episodes.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.
horizon_daysNoHow many days after publication to chart. 30 is the industry convention.
compare_episodesNoHow many other episodes form the median. More is steadier and slower.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive and open-world, so safety is covered. The description adds real behavioral value beyond that: it discloses the return shape (cumulative downloads by day, median, verdict) and the median's inclusion rule (only episodes at least as old as the horizon qualify), which is non-obvious logic an agent could not infer.

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

Conciseness4/5

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

The core purpose is front-loaded in the first sentence, followed by return contents and rationale. It runs a bit long with three sentences and the final clause is dense, but each sentence carries distinct information, so nothing is pure padding.

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?

With no output schema, the description must carry the return-value burden, and it does describe the key outputs (cumulative curve, median, verdict) and the median's construction rule. It omits some details like the verdict's possible values or output format, but it is sufficient for an agent to call the tool 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?

Schema coverage is 100%, so the baseline is 3, but the description earns above baseline by explaining how horizon_days and compare_episodes behave conceptually — the horizon gate on median membership and the trade-off between steadier and slower comparisons. It adds interpretive meaning rather than merely restating the schema.

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 states a specific verb and resource — tracking one episode's cumulative downloads against the show's own median at the same age — and frames it as a comparison tool, which cleanly separates it from siblings like op3_episode_downloads or op3_show_downloads that report raw totals. An agent can identify the tool's distinct job without opening the schema.

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?

It gives clear guidance on when to reach for this tool — judging a recent episode fairly — and explains why raw total downloads are the wrong lens. However, it never names the alternative tools (e.g. op3_episode_downloads) an agent should avoid, so routing is inferred rather than explicit.

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

op3_episode_downloadsPer-episode download counts for a show's recent episodesA
Read-onlyIdempotent

Per-episode download counts for a show's recent episodes: downloads in the first 1, 3, 7 and 30 days after publication, plus all-time. Use it to compare how episodes performed at equal age. Note that an empty result is normal for a small or new show, it means OP3's daily rollup has not covered it yet rather than that there is no data.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoHow many episodes to return, newest first.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the bar is lower. The description adds genuinely useful operational context: an empty result means OP3's daily rollup hasn't covered the show yet, not that data is absent. It doesn't discuss latency, rate limits, or refresh cadence.

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?

Three sentences, all front-loaded with the metric list first, then the use case, then the empty-result caveat. Nothing is redundant with the title or schema.

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?

With no output schema, the description compensates by naming the return metrics and the empty-result case, which is what an agent most needs. Minor gaps remain around per-episode fields returned and result ordering, though ordering is in the schema.

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% and both parameters (identifier formats, limit default/max, newest-first ordering) are fully documented in the schema. The description adds no syntax or format detail beyond that, so the baseline 3 applies.

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?

States a specific verb+resource (per-episode download counts for a show's recent episodes) and enumerates the exact metrics returned (1, 3, 7, 30-day and all-time). This distinguishes it from show-level siblings like op3_show_downloads and the flexible op3_query_downloads without opening either schema.

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?

"Use it to compare how episodes performed at equal age" gives a clear selection criterion, and the empty-result note preempts a common misuse (treating no data as an error). It stops short of naming an explicit alternative for show-level or raw download queries, so no when-not routing.

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

op3_episode_overlapWhich episodes share an audienceA
Read-onlyIdempotent

Which episodes share an audience. For each pair of a show's busiest episodes, reports shared listeners, a symmetric similarity, and the share of the smaller episode's audience that also heard the other. Read the smaller side's share first: for one big episode and one small one the symmetric number is always near zero, while the smaller side's share tells you whether a spike brought genuinely new people or just gave the existing audience another download.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end, same formats as start. Defaults to now.
botsNoInclude downloads from known bots. Off by default, which matches how OP3's own download counts are computed.
startNoWindow start. A relative value like -30d, -8w or -3m, a date like 2026-08-01, or an ISO timestamp. Defaults to -30d. Wider windows are slower: this reads raw rows, not a rollup.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.
top_episodesNoHow many of the busiest episodes to compare. Pairs grow quadratically, so 6 gives 15 pairs and 15 gives 105.

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so safety is covered. The description adds genuinely non-obvious analytical behavior: that the symmetric similarity is misleading for skewed pairs and the smaller side's share is the decisive read. That interpretation context is real value beyond the annotations.

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

Conciseness4/5

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

Front-loaded with the purpose in one sentence, then a second sentence covering returns and interpretation. It is longer than minimal but each clause (shared listeners, symmetric similarity, smaller-side share, spike interpretation) carries information an agent needs.

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?

With no output schema, the description competently documents the three returned values and how to interpret them. It does not mention default window or bot handling, but those are fully covered by the schema, so the remaining gap is small.

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 coverage is 100%, so window, bots, identifier and top_episodes are fully documented in the schema itself. The description only alludes to 'busiest episodes', which maps loosely to top_episodes, adding no format or syntax detail beyond the schema.

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?

Names a specific analysis (pairwise audience overlap among a show's busiest episodes) and enumerates the three metrics returned: shared listeners, symmetric similarity, and smaller-side share. This is clearly distinguishable from siblings like op3_episode_downloads (single-episode volume) and op3_compare_shows (cross-show comparison).

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

Usage Guidelines3/5

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

Usage is implied rather than stated: the guidance about 'one big episode and one small one' tells the agent the tool fits asymmetric episode pairs, but nothing says when to prefer this over op3_listener_retention, op3_new_vs_returning, or op3_episode_downloads. No explicit alternatives or exclusions are given.

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

op3_geographyGeographyA
Read-onlyIdempotent

Where a show's downloads come from, at whichever level you ask for: continent, country, region (state or province), metro area, or timezone. Reports downloads and unique listeners side by side for each place, because one enthusiastic listener in a small market otherwise looks like a market. Region and metro are qualified by country, so Illinois and Israel do not merge.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end. Defaults to now.
topNoHow many places to return. The rest are folded into otherCount rather than dropped.
botsNoInclude downloads from known bots. Off by default.
levelNoGranularity. country is the usual answer. region is states and provinces. metro is a US-centric DMA code and is mostly empty outside the US.country
startNoWindow start, e.g. -30d, -8w, 2026-08-01. Defaults to -30d.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/openWorld/non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: it reports downloads and unique listeners side by side, and explains that region/metro are qualified by country so same-named places don't merge.

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

Conciseness4/5

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

Three sentences, front-loaded with the core purpose, and the market-size rationale for dual metrics earns its place. Slightly conversational but no filler that obscures the operative facts.

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?

No output schema exists, so the description carries the return-value burden and does so by naming the two reported metrics per place. It omits pagination/otherCount handling and default window behavior, but those are already documented in the schema.

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?

Schema coverage is 100%, so the baseline is 3. The description adds rationale the schema lacks — why two metrics are returned together, and why region/metro results are country-scoped — which helps the agent interpret level choices rather than just enumerate them.

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?

Opens with a specific verb+resource ('Where a show's downloads come from') and enumerates the exact geographic levels available, which cleanly separates it from siblings like op3_audience_summary or op3_device_breakdown. An agent can identify the tool's job without opening the schema.

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 frames the tool as answering at whatever granularity you request and lists the five levels, giving clear context for when each is appropriate. It does not name a sibling alternative or state exclusions, so it stops short of a 5.

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

op3_get_showLook up a show on OP3A
Read-onlyIdempotent

Look up a show on OP3: its uuid, title, podcast guid and public stats page. Set include_episodes to also get the episode list with OP3 episode ids, titles and publication dates. Episode ids from here are what the episode-level tools filter on.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYesThe show, as any of: an OP3 show uuid (32 hex characters), a podcast:guid (the dashed UUID from the feed's <podcast:guid> tag), or the RSS feed URL itself. A plain feed URL is fine, it gets encoded for you.
episode_limitNoCap on episodes returned when include_episodes is true. Newest first.
include_episodesNoInclude the episode list. Off by default because a long-running show returns hundreds.

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so safety is covered. The description adds useful context the annotations lack: that include_episodes is off by default because long-running shows return hundreds of episodes, i.e. a payload-size warning, plus the id-chaining contract for episode-level tools.

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

Conciseness4/5

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

Three sentences, front-loaded with the core lookup, then the optional expansion, then the downstream chaining note. Every sentence carries information, though the include_episodes clause partially repeats the schema's own description of that flag.

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?

With no output schema, the description compensates by naming the returned fields (uuid, title, podcast guid, stats page) and the shape of the episode list (ids, titles, publication dates). It is nearly complete for a lookup tool; only the form of the 'public stats page' value is left implicit.

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%, so identifier, episode_limit and include_episodes are already fully documented in the schema. The description only restates the include_episodes behavior ('also get the episode list'), adding no syntax or format detail beyond what the schema provides. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb (look up) and resource (a show) and enumerates what comes back: uuid, title, podcast guid and public stats page. That is well beyond a restatement of the name. It does not explicitly distinguish itself from the sibling op3_resolve_show, which is the one nearby tool an agent could confuse it with.

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?

It tells the agent to set include_episodes when the episode list is needed, and states that 'Episode ids from here are what the episode-level tools filter on' – a genuine routing hint toward the episode-level siblings. It does not say when to prefer op3_resolve_show or op3_list_episodes instead, so the guidance is clear but not exhaustive.

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

op3_global_app_shareGlobal app shareA
Read-onlyIdempotent

Podcast app market share across every show OP3 measures, over the last thirty days. This is the industry benchmark, not one show's numbers, and it is useful on its own for questions about the podcast app landscape. Can be narrowed to a single device to see which apps dominate on, say, an Apple iPhone.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_agentNoRestrict to the device inferred from a raw user agent string.
device_nameNoRestrict to one device, e.g. 'Apple iPhone'. Device names come from op3_device_breakdown.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint and non-destructive, so safety is covered. The description adds meaningful behavior beyond that: a fixed 30-day window, an all-shows aggregation scope, and the ability to narrow to a single device.

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

Conciseness4/5

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

Three sentences, front-loaded with scope and time window, each carrying information. 'It is useful on its own' is slightly padded but not wasteful.

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?

Discloses the fixed time window, the aggregation scope, and device narrowing, and the schema fully documents the two optional params. Without an output schema, a brief note on the return shape (app names + share percentages) would round it out.

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%, so both optional params are already documented in the schema. The description adds only mild context about what narrowing by device reveals, so the baseline of 3 applies.

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?

States a specific verb+resource+scope: 'Podcast app market share across every show OP3 measures, over the last thirty days.' It also explicitly distinguishes itself from a per-show tool ('not one show's numbers'), which is critical given the sibling op3_app_share.

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?

Gives clear usage context ('useful on its own for questions about the podcast app landscape') and contrasts with per-show data. It stops short of naming the alternative tool (op3_app_share or op3_benchmark_apps), so the routing is implied rather than explicit.

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

op3_listener_retentionCohort carry-over between two periodsA
Read-onlyIdempotent

Cohort carry-over between two periods: how much of the earlier period's audience showed up again in the later one. Returns two rates that answer different questions. retentionRate is the share of the old audience that came back, which measures whether the show holds people. carryOverShare is the share of the new period that is old faces, which measures whether the show is growing or recycling. A show can score well on one and badly on the other.

ParametersJSON Schema
NameRequiredDescriptionDefault
botsNoInclude downloads from known bots. Off by default, which matches how OP3's own download counts are computed.
later_endNoEnd of the later period. Defaults to now.
cohort_endNoEnd of the earlier period, and the start of the later one. Defaults to -30d.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.
cohort_startNoStart of the earlier period. Defaults to -60d.

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, openWorld, and non-destructive, so safety is covered. The description adds meaningful domain context beyond the structured fields: it explains that the tool returns TWO rates with distinct interpretations and clarifies what each is a share of, which helps the agent reason about results rather than just the operation.

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

Conciseness4/5

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

Purpose is front-loaded in the first clause, followed by parallel definitions of the two rates. Four sentences, each carrying interpretive weight, with no filler. Slightly longer than strictly necessary but every sentence earns its place.

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?

With no output schema, the description properly carries the burden of explaining return values, and it does so clearly for both metrics. The remaining gap is the lack of sibling routing and any note on empty-cohort behavior, but for a read-only analytics tool it is essentially complete.

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%, so the schema fully documents all five parameters including the period defaults. The description mentions 'two periods' generically but adds no syntax, format, or reconciliation detail (e.g., how cohort_end relates to later_end), so the baseline of 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource and analysis (cohort carry-over between two periods) and even names the two output metrics, retentionRate and carryOverShare, so the agent knows exactly what this computes. However, it never differentiates from close siblings like op3_new_vs_returning, which likely cover adjacent territory, so it stops short of a 5.

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

Usage Guidelines3/5

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

It explains what each rate measures and that a show can score well on one and badly on the other, which implies interpretive use. But it gives no explicit when-to-use guidance, no exclusions, and no routing to alternatives such as op3_new_vs_returning or op3_audience_summary.

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

op3_listening_patternsListening patternsA
Read-onlyIdempotent

When downloads happen, by hour of day and day of week, in UTC. Useful for choosing a publication slot. Read it as request timing rather than listening behavior: a podcast app's scheduled background refresh fires on the app's schedule, not when a person pressed play, so the peaks partly reflect app defaults.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end. Defaults to now.
botsNoInclude known bots. Leave off: bot traffic is often scheduled hourly and will flatten the pattern.
startNoWindow start, e.g. -30d. Defaults to -30d.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, openWorld, non-destructive), so the bar is lower. The description adds genuine interpretive context the annotations cannot: that the data is request timing rather than true listening, and that app background-refresh defaults inflate certain peaks. That caveat materially affects how an agent should present the result. It stops short of 5 only because it says nothing about aggregation/window limits beyond what the schema already notes.

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?

Three sentences, front-loaded with what the tool returns, then the use case, then the critical caveat. Every sentence earns its place; nothing is redundant with the schema or annotations.

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?

With no output schema, the description carries the burden of describing the return shape, and it does so (hour-of-day and day-of-week buckets, UTC). It is complete enough to call and interpret correctly. It could say more about output structure (counts vs. relative shares) but nothing essential is missing.

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% — identifier, start, end, and bots are all documented in the schema, including the rationale for leaving bots off. The description adds no parameter-level information beyond that, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states precisely what is returned — download timing broken down by hour of day and day of week, in UTC — which is a specific verb+resource+granularity statement. It also resolves the mismatch between the tool name ('listening patterns') and what it actually measures. It does not explicitly name the sibling it differs from (e.g. op3_show_downloads or op3_download_trend), so it falls short of a 5.

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

Usage Guidelines3/5

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

'Useful for choosing a publication slot' gives one concrete use case, which is more than a bare description. However, there is no guidance on when NOT to use it or which sibling tool answers a related question (e.g. total downloads vs. time-of-day distribution). Usage is implied rather than delineated.

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

op3_list_episodesList episodesA
Read-onlyIdempotent

List a show's episodes with their OP3 episode ids, titles and publication dates, newest first. Use it to find the episode id for a specific episode before asking anything episode-level. Episode titles come from the publisher's RSS feed and are third-party text.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoHow many episodes to return, newest first.
searchNoCase-insensitive substring match on the episode title, applied before the limit.
identifierYesThe show, as any of: an OP3 show uuid (32 hex characters), a podcast:guid (the dashed UUID from the feed's <podcast:guid> tag), or the RSS feed URL itself. A plain feed URL is fine, it gets encoded for you.

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so safety is fully covered. The description's only genuinely new behavioral detail is the provenance warning that episode titles are third-party RSS text (a mild injection caution); the newest-first ordering merely restates the schema. Adequate but not rich beyond the annotations.

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?

Three tight sentences, zero padding, with the core purpose and ordering front-loaded before the usage hint and the provenance caveat. Every sentence carries information an agent needs.

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?

With no output schema, the description does the necessary work by naming the returned fields and sort order. It does not mention pagination or whether a limit truncation is signalled, a minor gap for a list tool with a 500-item cap, but otherwise complete.

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 three parameters documented (identifier formats, limit default/max, case-insensitive substring search applied before limit). The description adds no parameter detail beyond the schema, so the baseline 3 is correct.

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?

States a specific verb and resource ('List a show's episodes') and enumerates the returned fields (OP3 episode ids, titles, publication dates) plus ordering (newest first). This clearly separates it from siblings like op3_get_show (show metadata) and op3_episode_downloads (metrics), so an agent can pick it without opening a schema.

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?

Gives an explicit when-to-use: resolve an episode id before calling anything episode-level, which correctly routes the agent toward this tool as a prerequisite step. It does not, however, name an alternative for the aggregate-analytics case or state exclusions, so it falls short of the 5 bar.

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

op3_new_vs_returningNew vs returningA
Read-onlyIdempotent

Split a show's listeners in a window into first-time and returning, by comparing against a longer baseline period immediately before it. Answers whether a show is reaching new people or serving the same audience repeatedly. The baseline length matters: a short baseline calls a monthly listener new, so it defaults to four times the window and both sizes are reported so you can judge the answer.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end, same formats as start. Defaults to now.
botsNoInclude downloads from known bots. Off by default, which matches how OP3's own download counts are computed.
startNoWindow start. A relative value like -30d, -8w or -3m, a date like 2026-08-01, or an ISO timestamp. Defaults to -30d. Wider windows are slower: this reads raw rows, not a rollup.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.
baseline_multiplierNoHow many window-lengths of history to treat as the baseline. Higher is more accurate and slower. 4 means a 30-day window is compared against the 120 days before it.

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare read-only, idempotent, non-destructive behavior, and the description adds useful context beyond that: the default baseline multiplier and why it matters, that both sizes are returned, and that wider windows read raw rows and are therefore slower. No contradiction with annotations.

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

Conciseness4/5

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

Four compact sentences, front-loaded with what the tool computes before the caveat about baseline length. Every sentence carries information; only the final clause slightly restates the reporting behavior.

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?

With no output schema, the description does tell the agent that both the first-time and returning sizes are returned, which is the key shape information. It leaves the exact response structure unspecified, but for a read-only analytical tool with full schema coverage this is nearly complete.

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?

Schema coverage is 100%, so baseline is 3; the description still adds interpretive value by motivating baseline_multiplier's default (a short baseline mislabels a monthly listener as new) and reinforcing the multiplier semantics. It does not add format detail for start/end/identifier beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific analysis: splitting a show's listeners in a window into first-time vs returning via comparison against a prior baseline. The framing ('reaching new people or serving the same audience repeatedly') conceptually separates it from a retention-style metric, though it never names a sibling tool to route against.

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?

Explains the question this answers and adds guidance on the key tradeoff (baseline length changes what counts as 'new'). It does not explicitly say when to prefer this over op3_listener_retention or op3_audience_summary, so the routing decision is left partly implicit.

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

op3_query_downloadsRaw download rows for a show, with every filter OP3 offersA
Read-onlyIdempotent

Raw download rows for a show, with every filter OP3 offers. This is the escape hatch for questions the aggregating tools do not cover. Prefer op3_show_downloads, op3_audience_summary, op3_geography or op3_app_share when they can answer the question, because raw rows are slow to fetch and expensive to reason over. Rows come back oldest first and OP3 offers no way to reverse that on this endpoint, so the limit takes the earliest rows in the window: to see recent activity, narrow the window with start rather than raising the limit. Per-listener identifiers are removed from the output.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end. Defaults to now.
botsNoReturn raw request rows instead of OP3's deduplicated download count. This adds bot traffic and also switches off OP3's download calculation, so the row count rises for reasons beyond bots. Off by default, which matches every other download figure OP3 reports.
limitNoRows to return. Kept low on purpose: these rows are wide and fill a context window fast.
startNoWindow start, e.g. -24h, -7d, 2026-08-01. Defaults to -30d.
episode_idNoRestrict to one episode, by its 64-character OP3 episode id.
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.
include_listener_keysNoInclude a shortened, non-reversible listener label so rows can be told apart by listener. The full audienceId and hashedIpAddress are never returned either way.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already cover readOnly/idempotent/non-destructive, and the description adds non-obvious behavior the annotations cannot: rows return oldest-first with no reversal option, limit therefore takes the earliest rows, raw rows are costly, and per-listener identifiers are stripped from output. These are exactly the traits an agent needs before calling.

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?

Front-loaded with purpose, then exclusions, then the ordering/limit caveat, then the privacy note. Every sentence carries distinct, decision-relevant information with no filler.

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?

For a wide raw-row endpoint with no output schema, it covers ordering, scoping, cost and PII removal well, which is most of what matters. The one gap is that it never indicates what columns or fields the raw rows actually contain, leaving the agent to discover the row shape blind.

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?

Schema coverage is 100% and the schema itself explains bots, limit and include_listener_keys well, so the baseline is 3. The description adds meaning the schema does not: the coupling between start and limit (limit takes the earliest rows in the window) and the privacy consequence of the listener-key parameter. It does not restate parameter formats, which 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?

States a specific verb+resource ('raw download rows for a show') and positions itself precisely as the escape hatch beyond the aggregating tools. It names four sibling tools it is not, so an agent can route correctly without opening any schema.

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?

Explicit when-to-use-vs-alternatives: prefer op3_show_downloads, op3_audience_summary, op3_geography or op3_app_share when they suffice, with the reason (raw rows are slow to fetch and expensive to reason over). It also gives the correct workaround for recent activity (narrow with start rather than raising limit), which is real operational guidance.

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

op3_query_hitsQuery hitsA
Read-onlyIdempotent

Raw request rows from OP3's redirect log, across every show unless filtered by url. This is the lowest level OP3 exposes and it is a verification surface rather than an analytics one: it shows individual requests including user agents, byte ranges and the edge that served them. For questions about a specific show's performance, use the show tools instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoWindow end. Defaults to now.
urlNoFilter by episode URL. Supports a trailing wildcard for a starts-with match, which is how you scope this to one show or one host.
limitNoRows to return.
startNoWindow start, e.g. -1h, -24h. Defaults to -1h, because this is a firehose across all shows.
newest_firstNoSort most recent first.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description still adds real behavioral value beyond that: it discloses that this is the lowest-level surface OP3 exposes and enumerates what a row contains (user agents, byte ranges, serving edge). It does not discuss volume/rate behavior, which is the only gap.

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?

Three sentences, front-loaded with what the tool returns, then its role, then the routing rule. Every sentence carries distinct information with no restatement of the title or schema.

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?

There is no output schema, and the description compensates by describing the shape of the returned rows (individual requests, user agents, byte ranges, edge). Combined with the 100%-covered input schema and the safety annotations, an agent has everything needed to call and interpret this tool.

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%, so the schema already documents all five parameters including the wildcard url behavior and the default time window. The description's 'unless filtered by url' duplicates the schema rather than extending it, so the baseline 3 applies.

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?

States a specific verb+resource ('raw request rows from OP3's redirect log') and immediately scopes it ('across every show unless filtered by url'). It also positions the tool against the analytics siblings by calling itself a 'verification surface rather than an analytics one', so an agent can distinguish it without opening a schema.

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 says when to use this (low-level verification, individual requests) versus when not to ('For questions about a specific show's performance, use the show tools instead'). Both the use case and the alternative are named, leaving nothing to inference.

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

op3_recent_transcriptsRecent transcriptsA
Read-onlyIdempotent

Recently published episodes across all of OP3 that carry a podcast:transcript tag, newest first. Use it to find podcasts whose episodes are machine-readable, which is the shortlist worth building on for anything that needs to read transcripts rather than count downloads. Returns podcast guids you can pass straight to the show tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoHow many episodes to return, newest first.
resolve_showsNoLook each podcast guid up to add the show title and uuid. Costs one request per distinct show, so leave it off for large limits.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive, open-world. The description adds return-format context (podcast guids that feed the show tools) and ordering (newest first), plus the resolve_shows cost note. It doesn't state rate limits or pagination, but adds useful behavior beyond the annotations.

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

Conciseness4/5

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

Three tight sentences, front-loaded with the resource and scope before the usage guidance. Every sentence contributes, though the final sentence is a mild restatement of the return value already implied by the tag/guid framing.

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?

No output schema, but the description explains what is returned (newest-first episodes with podcast guids usable by the show tools). Annotations cover the safety profile. Combined with 100% schema coverage, an agent has enough to call it correctly, though return field detail is thin.

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%, so both parameters are already well documented. The description connects the returned guids to the show tools, which hints at the resolve_shows use case, but does not add syntax or defaults beyond the schema. Baseline 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?

States a specific verb+resource+scope: recently published episodes across all of OP3 carrying a podcast:transcript tag, newest first. This clearly distinguishes it from the sibling download/audience tools, which the description explicitly contrasts against ("read transcripts rather than count downloads").

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?

Provides clear when-to-use context: find podcasts with machine-readable episodes, the shortlist for anything that needs to read transcripts. It contrasts the use case against download-counting siblings, but doesn't name a specific alternative tool the way the top-tier example does, so it stops short of explicit routing.

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

op3_resolve_showTurn any podcast identifier into an OP3 show uuidA
Read-onlyIdempotent

Turn any podcast identifier into an OP3 show uuid. Accepts a show uuid, a podcast:guid, or an RSS feed URL, and reports which kind it recognized. Use this first when you have a feed URL and need the uuid every other tool wants. If this fails, the show most likely does not have the OP3 prefix on its feed, which means OP3 has no data for it at all.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYesThe show, as any of: an OP3 show uuid (32 hex characters), a podcast:guid (the dashed UUID from the feed's <podcast:guid> tag), or the RSS feed URL itself. A plain feed URL is fine, it gets encoded for you.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description adds genuinely useful context: it reports which identifier kind was recognized, and it explains what a failure implies (the feed lacks the OP3 prefix, so OP3 has no data). This failure-mode disclosure goes beyond the annotations.

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?

Three short sentences, front-loaded with the core purpose, then usage ordering, then failure interpretation — every sentence earns its place with zero redundancy.

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?

No output schema exists, so the description wisely notes that the response reports which identifier kind was recognized. For a single-param resolver with full annotation coverage this is nearly complete, though it could say more about the returned uuid payload shape.

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% and the schema already documents the three accepted identifier forms with format detail (32 hex chars, dashed GUID, URL). The description restates the same three forms at a coarser level, adding little beyond the schema. Baseline 3 applies.

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?

States a specific transformation ('turn any podcast identifier into an OP3 show uuid') and enumerates the accepted identifier kinds, so the agent knows exactly what the tool does. It is clearly distinct from siblings like op3_get_show (which presumably consumes a uuid) and op3_verify_prefix.

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?

'Use this first when you have a feed URL and need the uuid every other tool wants' gives an explicit ordering and trigger condition relative to siblings. It also explains the failure case (no OP3 prefix, hence no data), which is strong guidance, but it does not name a specific alternative tool to try instead.

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

op3_show_downloadsA show's headline download numbersA
Read-onlyIdempotent

A show's headline download numbers: downloads in the last 30 days, the week-by-week breakdown over the last four weeks, and the weekly average. This is the fast answer to 'how many downloads does my show get' and should be preferred over the raw query tools whenever it can answer the question. Excludes bots. Updated once a day.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYesAn OP3 show uuid, a podcast:guid, or the show's RSS feed URL.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already cover read-only/idempotent/non-destructive semantics, so the bar is lower; the description adds genuinely new behavior: bot exclusion and once-a-day refresh, both of which affect how an agent should interpret and trust the numbers. It does not cover pagination or error behavior, but for an aggregate read this is solid.

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?

Three tight sentences: what it returns first, then the routing rule, then the behavioral caveats. Every sentence carries information and nothing is padded.

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?

There is no output schema, so the description must describe the return payload, and it does so concretely (last 30 days, four-week weekly breakdown, weekly average). Combined with annotations and a fully documented parameter, an agent has everything needed to call and interpret it.

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% and the single identifier parameter is fully documented (uuid, podcast:guid, or RSS URL) in the schema. The description adds no further parameter meaning, so the baseline 3 applies.

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?

States a specific resource (a show's headline download numbers) and enumerates exactly what is returned: 30-day downloads, four-week week-by-week breakdown, and weekly average. This clearly distinguishes it from siblings like op3_episode_downloads, op3_download_trend, and op3_query_downloads.

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?

Explicitly says it 'should be preferred over the raw query tools whenever it can answer the question,' which gives a positive selection rule and names the alternative category. It stops short of naming specific sibling tools or stating when this tool is NOT sufficient (e.g. custom date ranges).

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

op3_verify_prefixVerify prefixA
Read-onlyIdempotent

Check whether OP3 is actually receiving downloads for a show, and say what is wrong when it is not. Run this first whenever the numbers are zero or a show cannot be found. It separates the three cases that look identical from the outside: the prefix was never added to the feed, it was added but no download has come through yet, or it is working and the answer is genuinely a small number.

ParametersJSON Schema
NameRequiredDescriptionDefault
lookbackNoHow far back to look for any request at all.-7d
identifierYesThe show, as a uuid, podcast:guid, or RSS feed URL. A feed URL is the most useful input here, because the failure being diagnosed is usually that OP3 has never seen that feed.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds genuine behavioral value beyond that: it explains that the tool actively diagnoses and reports what is wrong, and enumerates the three distinct states it disambiguates. Output format specifics are still absent, but the diagnostic behavior is well disclosed.

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

Conciseness4/5

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

Three sentences, front-loaded with the purpose, then the routing trigger, then the disambiguation detail. Tight and every sentence carries information, though the third sentence is somewhat elaborate for the point it makes.

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?

With no output schema, the description should convey what comes back; it does so at the level of outcomes (one of three cases plus a diagnosis of what is wrong). Annotations cover safety and the schema covers both parameters, so the remaining gap — the exact shape of the returned diagnosis — is minor.

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%, including a detailed note that a feed URL is the most useful identifier because the failure is usually that OP3 has never seen the feed. The description reinforces the feed/prefix framing but adds no syntax or format detail beyond the schema, so the baseline 3 applies.

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 states a specific verb and resource — checking whether OP3 is receiving downloads for a show — and frames the tool as a diagnostic rather than an analytics query, which cleanly separates it from siblings like op3_show_downloads or op3_query_downloads. It even names the failure modes it distinguishes, so an agent knows exactly what question this tool answers.

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?

"Run this first whenever the numbers are zero or a show cannot be found" gives an explicit, actionable trigger condition, plus the implicit converse that it is not the tool to reach for during normal analysis. It does not name alternative sibling tools for adjacent cases (e.g. op3_resolve_show for identifier resolution), so it falls short of a full when/when-not/alternatives statement.

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. 22 tool updatesv2.0.0
    • Changedop3_app_share2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_audience_summary2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_benchmark_apps2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_compare_shows2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_device_breakdown2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_download_trend2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_episode_curve2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_episode_downloads2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_episode_overlap2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_geography2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_get_show2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_global_app_share2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_list_episodes2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_listener_retention2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_listening_patterns2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_new_vs_returning2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_query_downloads2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_query_hits2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_recent_transcripts2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_resolve_show2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_show_downloads2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedop3_verify_prefix2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
  2. 22 tool updatesv1.1.0
    • First observedop3_app_share
    • First observedop3_audience_summary
    • First observedop3_benchmark_apps
    • First observedop3_compare_shows
    • First observedop3_device_breakdown
    • First observedop3_download_trend
    • First observedop3_episode_curve
    • First observedop3_episode_downloads
    • First observedop3_episode_overlap
    • First observedop3_geography
    • First observedop3_get_show
    • First observedop3_global_app_share
    • First observedop3_list_episodes
    • First observedop3_listener_retention
    • First observedop3_listening_patterns
    • First observedop3_new_vs_returning
    • First observedop3_query_downloads
    • First observedop3_query_hits
    • First observedop3_recent_transcripts
    • First observedop3_resolve_show
    • First observedop3_show_downloads
    • First observedop3_verify_prefix

TDQS

A4.1/5.0

Scored across 22 tools

Disambiguation5/5

Each tool targets a distinct analytical dimension (downloads, unique listeners, geography, apps, devices, retention, overlap, raw rows), and the descriptions explicitly say when to prefer one over another. The few superficially similar tools (op3_show_downloads vs op3_query_downloads vs op3_episode_downloads, or op3_app_share vs op3_benchmark_apps vs op3_global_app_share) are clearly differentiated by scope and intent.

Naming Consistency5/5

All 22 tools use a consistent snake_case verb_noun pattern uniformly prefixed with op3_. No camelCase, no mixed conventions, and the names read predictably.

Tool Count4/5

22 tools is on the heavier side but justified by a genuinely broad analytics domain spanning downloads, listeners, geography, apps, devices, retention, and raw verification surfaces. Each tool earns its place rather than being redundant.

Completeness5/5

The surface covers the full analytic lifecycle: identifier resolution, show/episode metadata, aggregate metrics, audience composition, breakdowns, trends, cohort retention, raw escape hatches, and a diagnostic verification tool. No obvious dead ends for the stated podcast-analytics purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Connects Google Analytics 4 data to Claude, Cursor and other MCP clients, enabling natural language queries of website traffic, user behavior, and analytics data with access to 200+ GA4 dimensions and metrics.
    10
    2,495 PyPI
    242
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides statistical analysis and usage tracking for Claude Code, enabling users to query daily/monthly stats, compare users, analyze trends, detect anomalies, and generate usage reports through natural language.
    1
    -
  • A
    license
    B
    quality
    A
    maintenance
    Enables querying Rybbit Analytics data directly through MCP-compatible clients like Claude Code. It provides tools for monitoring website statistics, user sessions, error logs, funnels, and performance metrics via natural language.
    43
    42 npm
    4
    MIT