music-warehouse-mcp
Query years of your own Spotify listening history through an AI agent — a local, stdio, read-only MCP server that proxies a music-warehouse Worker's API, exposing 14 tools (all read-only, idempotent except the live ones).
Find things —
searchmatches artists and songs by name (case-insensitive substring) with all-time play counts, and converts a name into the id needed by the history tools.Raw plays —
get_playsreturns individual stored plays newest-first, with local time, track, artists and album, filterable by date/ISO/epoch window and paged vianext_before.Charts over any range —
top_artistsandtop_trackscount plays between two inclusive local dates (default: last 30 days, max 3,660 days), with song editions folded together.Volume trends —
daily_play_countsgives plays per local day (quiet days as 0) or summed by week (from Monday) or month, with a total.Deep dives on one entity —
artist_historyandtrack_historyreturn all-time plays, estimated minutes, first and last play, plays per month and top songs; the artist one accepts an id, a name (catching imported-export-only artists withid: null) or both.Nostalgia —
on_this_dayshows the most-played songs on this calendar date in each earlier year, with that day's total.Precomputed stats —
get_statreturns one ofon-repeat(last-14-day outliers),rhythm(streaks, plays by hour),top-over-time(per quarter/year),eras(taste before vs. after e.g. a move) oralbums(all-time and per-year).Wrapped —
list_wrapped_rangeslists summarisable finished ranges (each year with plays, plus this year so far), andget_wrappedproduces a Wrapped-style summary: minutes, top artists/songs/albums, biggest day, streak, hour and weekday breakdown, each month's top artist and song, discoveries and a listening age.Live Spotify data —
now_playing,recently_played_live(Spotify's last ≤50 plays, including ones not yet stored, since the warehouse polls every 30 minutes) andspotify_top(Spotify's own top tracks/artists over ~4 weeks, ~6 months or ~1 year). These three need the Worker's Spotify grant and are the only non-idempotent, open-world tools; everything else reads stored rows and keeps working if the grant lapses.Not available — the README advertises 15 tools including
upcoming_concerts(Ticketmaster gigs for your top artists), but that tool is absent from the supplied schema, so it cannot currently be called.
Provides read-only access to a user's Spotify listening history and live Spotify data through a music-warehouse Worker, enabling queries for search, individual plays, top artists and tracks, daily play counts, artist/track history, on-this-day stats, Wrapped-style summaries, now playing, recently played, and Spotify's own top tracks and artists.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@music-warehouse-mcpwhat was I into in spring 2022?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
An MCP server that lets an AI agent (Claude Code, Claude Desktop, Cursor and others) query the Spotify listening history stored by a music-warehouse Worker. The agent answers from your own data, years of it, not Spotify's last 50 plays. It runs locally over stdio and only reads.
This needs your own music-warehouse deployment. If you don't have one yet, start with the warehouse'squick start.
What it does
Ask things like:
"What was I into in spring 2022?"
"When did I first play Shelter?"
"How has my listening changed since I moved?"
and the agent picks the right tools: fifteen of them, all read-only, covering search, plays, top artists and songs over any range, per-artist and per-song history, precomputed stats, Wrapped-style summaries, upcoming concerts, and what's playing now.
Responses are trimmed for an agent: no image URLs or Spotify API links, play times shown in the local zone, Spotify objects cut to name, artists, album and id.
Related MCP server: SpotifyScraper MCP Server
How it works
flowchart LR
A[AI agent] <-->|stdio| M[music-warehouse-mcp]
M -->|"GET /api/* (read token)"| W[music-warehouse Worker]Every tool calls the Worker's /api/* routes with a read-only token. The
Worker does the storage and aggregation; this server only shapes the answers.
Why stdio, not a remote server
Running locally keeps the token on your machine and needs no change to the Worker beyond the read routes. The trade-off is that claude.ai on the web and mobile can't use it: their custom connectors need a remote server with OAuth.
Requirements
A deployed music-warehouse Worker at a version that has
/api/searchand/api/top-tracks(October 2026 or later), and/api/concertsforupcoming_concerts. To sign in with Spotify instead of copying a token, it also needs Spotify sign-in.Node.js 20 or later.
It isn't published to npm; install it from source as below.
Quick start
git clone https://github.com/rcnsh/music-warehouse-mcp && cd music-warehouse-mcp
npm install
npm run login -- --url https://music-warehouse.<you>.workers.dev
claude mcp add --scope user music-warehouse \
-e MUSIC_WAREHOUSE_URL=https://music-warehouse.<you>.workers.dev \
-- node "$PWD/dist/index.js"Then /mcp in Claude Code shows it connected. Each step is explained below.
Setup
1. Build
git clone https://github.com/rcnsh/music-warehouse-mcp && cd music-warehouse-mcp
npm install # also builds dist/2. Get a read token
Sign in with Spotify (easiest). Use the Spotify account that owns the warehouse:
npm run login -- --url https://music-warehouse.<you>.workers.devIt opens your browser (and prints the URL in case it doesn't), and once you
approve, saves a read token for that warehouse to
~/.config/music-warehouse-mcp/tokens.json ($XDG_CONFIG_HOME if set),
readable only by you. The token is listed on the warehouse as
MCP (<hostname>) (see the warehouse's
device tokens); pass
--name to choose another. It expires after 90 days: the tools then say so,
and you run the same command again. The server reads the file on every call,
so a new sign-in needs no restart.
--url defaults to MUSIC_WAREHOUSE_URL. If you install the clone globally
(npm install -g .), the same command is
music-warehouse-mcp login --url ….
Or store a token yourself. On macOS, put the Worker's READ_TOKEN in the
Keychain, under the service music-warehouse-mcp and your Worker's host as the
account. security prompts for it, so it never lands in your shell history:
security add-generic-password -s music-warehouse-mcp -a music-warehouse.<you>.workers.dev -wElsewhere, set MUSIC_WAREHOUSE_TOKEN in the MCP client's config instead (see
Configuration). Either one wins over a signed-in token.
Use a read token, neverADMIN_TOKEN: nothing here needs more.
3. Add it to your client
For every project:
claude mcp add --scope user music-warehouse \
-e MUSIC_WAREHOUSE_URL=https://music-warehouse.<you>.workers.dev \
-- node "$PWD/dist/index.js"Run it from the clone, so $PWD is the right path. Then /mcp in Claude Code
shows it connected. If you run more than one Claude Code config directory
(CLAUDE_CONFIG_DIR), run the command once under each.
They take the same thing as JSON, in their MCP server config:
{
"mcpServers": {
"music-warehouse": {
"command": "node",
"args": ["/absolute/path/to/music-warehouse-mcp/dist/index.js"],
"env": { "MUSIC_WAREHOUSE_URL": "https://music-warehouse.<you>.workers.dev" }
}
}
}A GUI app may not see your shell'sPATH; if it can't start node, give its
absolute path (which node).
4. Check it
MUSIC_WAREHOUSE_URL=https://music-warehouse.<you>.workers.dev npm run smokecalls every tool once against your Worker and prints the start of each
answer. Or explore interactively with npm run inspect.
Configuration
Variable | Required | Meaning |
| yes | The Worker's origin. Must be |
| no | A read token, overriding the Keychain and a signed-in token. |
| no | IANA zone for local dates and times. Defaults to the system's. |
| no | Where |
The token is the first of:
MUSIC_WAREHOUSE_TOKEN.The macOS Keychain entry for the Worker's host (service
music-warehouse-mcp).The token
npm run loginsaved for the Worker's origin. Tokens are saved per origin, so one is only ever sent to the warehouse that minted it.
A missing or expired token doesn't stop the server starting: each tool says how to provide one, and the next call picks it up without a restart. A rejected token (401) names the login command.
Tools
Fifteen tools, all read-only. Dates are YYYY-MM-DD local days in the
configured zone.
Tool | Answers | Worker route |
| Artists and songs by name, with all-time plays. The way in to the history tools. |
|
| Individual plays, newest first, in a window. Pages with |
|
| Plays per artist between two dates. |
|
| Plays per song between two dates, editions folded. |
|
| Ticketmaster gigs in the regions your warehouse watches, for your top artists; |
|
| Plays per day, or summed per week or month, with a total. |
|
| One artist's plays, minutes, first and last play, months, top songs. |
|
| The same for one song, editions folded together. |
|
| Top songs on this date in each earlier year. |
|
|
|
|
| Which ranges |
|
| A Wrapped-style summary of a finished range. |
|
| What's playing right now. |
|
| Spotify's last plays, including ones not stored yet. |
|
| Spotify's own top tracks and artists. |
|
The last three are live and need the Worker's Spotify grant; the rest read stored rows and keep working when it lapses.
When a tool fails, its message says why and what to do: a rejected token names
npm run login, a lapsed grant names npm run authorize in the
music-warehouse repo, a stat still computing is waited out (up to 25 s) before
giving up.
Development
Command | Does |
|
|
| vitest: the client, formatting, sign-in, and every tool over an in-memory MCP connection |
| Type-checks source and tests |
| Calls every tool once against a real Worker (needs |
| Opens the MCP Inspector on |
Tests fake fetch, so they need no Worker. The sign-in test runs the real
loopback listener and plays the browser's redirect itself. npm run smoke is
the end-to-end check against a real one.
Related projects
Project | |
The Worker: records your plays and serves the API | |
Native macOS app for browsing your history | |
music-warehouse-mcp (this repo) | MCP server so AI agents can query your history |
Stats inside the Spotify desktop client | |
Wrapped-style stories for any range, in the browser |
Licence
MIT. See LICENSE.
Available Tools
14 toolsartist_historyOne artist's whole historyARead-onlyIdempotent
An artist's all-time plays, estimated minutes, first and last play, plays per month, and their most-played songs. Counts only plays where they are the primary artist. Give the id from search, or the name (which also catches plays from the imported export), or both.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Spotify artist id | |
| name | No | Artist name, matched case-insensitively |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent semantics, and the description adds a real behavioral constraint not in the structured data: only primary-artist plays are counted, and the name path includes imported-export data. It does not discuss result size or ordering, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with what is returned before how to call it. The output enumeration is dense but every item is a distinct aggregate, so little padding; slightly long but earns its space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 returns and does so explicitly; with 100% schema coverage the parameters are already documented, and usage plus the primary-artist caveat close the remaining gaps. Nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds meaning the schema lacks: that name is case-insensitive-ish matched via the schema and, more importantly, that the name path catches imported-export plays that the id path may miss. That is genuine decision-relevant parameter context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb+resource ('An artist's all-time plays') and enumerates the returned aggregates (minutes, first/last play, plays per month, top songs), which cleanly separates it from track_history and top_artists. The scoping clause 'Counts only plays where they are the primary artist' pins down the resource boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Tells the agent how to supply the inputs (id from search, or name) and gives a decision-relevant nuance: name 'also catches plays from the imported export'. It lacks an explicit when-not/alternative-tool statement, so it stops short of 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
daily_play_countsPlays per day, week or monthARead-onlyIdempotent
How many plays on each local day between two dates, quiet days as 0, optionally summed into weeks (from Monday) or months. Use month or week for spans longer than a few months.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Last day, YYYY-MM-DD; default today | |
| from | No | First day, YYYY-MM-DD; default 29 days ago | |
| group_by | No | Default day |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, closed world), so the bar for extra disclosure is lower, and the description clears it: it discloses that days are "local" (timezone semantics), that empty days are returned as 0 rather than omitted, and that weeks start Monday. These are real behavioral traits not derivable from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core behavior, then the rollup option and its selection rule. No filler and no repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter read-only tool with no output schema, the description conveys the essential shape of the result (a per-day series with zeros) and the rollup behavior. It stops just short of describing response structure or format, but nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds meaning the schema lacks: week buckets begin Monday, day bucketing is on the local calendar day, and week/month exist specifically for long spans. Defaults and formats are already in the schema and are not restated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise aggregation: daily play counts between two dates, with silent days materialized as 0 and optional week/month rollups. That level of specificity clearly separates it from raw-play siblings (get_plays) and ranking siblings (top_tracks, top_artists), so an agent can select it 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use month or week for spans longer than a few months" is concrete, condition-based guidance on granularity choice. It does not name alternative tools or state when this tool should be avoided, so it falls short of the explicit alternatives/exclusions a 5 requires.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_playsIndividual playsARead-onlyIdempotent
Individual stored plays, newest first, with local time, track, artists and album. Give after and before to read a window (newest first within it). If next_before is returned, pass it as before for the next, older page. For counts over a range prefer daily_play_counts or top_artists, which are far cheaper.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Only plays after this: YYYY-MM-DD (local midnight), an ISO datetime, or epoch-ms | |
| limit | No | Default 50 | |
| before | No | Only plays before this: same forms as `after` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and closed-world, so safety is covered. The description adds real behavioral context beyond them: newest-first ordering, local-time values, the next_before pagination contract, and a cost signal relative to aggregate siblings. It stops short of stating default page size or limits (left to schema).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with what is returned, then windowing, then pagination, then routing to cheaper alternatives. Every clause carries information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 earns its place by describing the record contents and the next_before return value needed for paging. Combined with full schema coverage for the three parameters, an agent has everything required to call and iterate this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds meaning beyond the schema by explaining the window semantics of after/before together and tying next_before to the before parameter for paging. It does not restate formats already documented in the schema, which is the right split.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Individual stored plays') plus ordering ('newest first') and returned fields (local time, track, artists, album). It also names the sibling tools that cover the cheaper aggregate case, so an agent can place it against daily_play_counts and top_artists immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-not guidance: 'For counts over a range prefer daily_play_counts or top_artists, which are far cheaper.' It also gives the windowing recipe (after/before) and the pagination recipe (pass next_before as before), 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.
get_statPrecomputed listening statsARead-onlyIdempotent
All-time aggregates, refreshed every few hours. on-repeat: songs and albums played far more than usual in the last 14 days. rhythm: listening streaks and plays by hour. top-over-time: top artists and songs per quarter and per year. eras: how taste changed between the two eras the warehouse is configured with (e.g. before and after a move). albums: most-played albums, all time and per year.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint=false, so the safety profile is covered. The description adds real behavioral context beyond them: the data is precomputed and refreshed only every few hours (staleness) and 'eras' depends on how the warehouse is configured, which an agent cannot learn from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core statement (all-time aggregates, refresh cadence), then a tight value-by-value enumeration with no filler or repetition. Dense but every clause carries information; only minor loss for the run-on final sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 convey what comes back, and defining each stat category does that at a conceptual level. It stops short of describing response shape, grouping, or pagination, but for a read-only aggregate tool with one enum input this is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the single enum parameter's five values are otherwise opaque strings, yet the description defines each one concretely (on-repeat = last-14-day over-play, rhythm = streaks/hourly, top-over-time = per quarter/year, eras = taste shift, albums = all-time/yearly). This is the parameter's documentation in all but schema form.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource ('all-time aggregates' plus five named stat categories), so an agent knows this returns precomputed listening statistics. It does not, however, explicitly distinguish itself from siblings like top_artists, top_tracks, or daily_play_counts, which overlap in subject matter, 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied rather than stated: 'refreshed every few hours' signals this is a cached/aggregate read, contrasting with live siblings like recently_played_live or now_playing, but the description never says when to prefer this over top_artists/top_tracks. No explicit exclusions or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_wrappedWrapped-style summaryARead-onlyIdempotent
A Spotify-Wrapped-style summary of a finished date range: minutes, top artists, songs and albums, biggest day, streak, listening by hour and weekday, each month’s top artist and song, discoveries and a listening age. Use a range from list_wrapped_ranges; others may be refused.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | ||
| from | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and openWorldHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: valid ranges are gated by list_wrapped_ranges and other ranges 'may be refused', which is a precondition an agent would otherwise learn only by failing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, purpose and payload front-loaded, with the enumeration doing real work because there is no output schema. The constraint sentence follows the payload, and nothing is repeated from the name or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description takes on the job of describing return content and does so thoroughly, and it covers the input constraint. The gap is a few details on return shape (ordering, volume of data) and exact accepted range form, which are minor for a read-only, idempotent summary tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the burden falls on the description; it partly compensates by tying 'from'/'to' to ranges produced by list_wrapped_ranges and by requiring a 'finished' range. It never states the expected format or boundary inclusivity, which the pattern alone conveys only implicitly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific, recognizable artifact (a Wrapped-style summary) over a bounded resource (a finished date range) and enumerates exactly what it returns: minutes, top artists/songs/albums, biggest day, streak, per-month leaders, discoveries, listening age. This breadth clearly separates it from narrow siblings like top_artists or top_tracks, so an agent can pick it 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use a range from list_wrapped_ranges; others may be refused' gives an explicit precondition and names the sibling that supplies valid inputs, plus a soft exclusion for unlisted ranges. There is no explicit statement of when a caller should prefer top_artists/search instead for a narrower question, which keeps it 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.
list_wrapped_rangesWrapped ranges availableARead-onlyIdempotent
The date ranges get_wrapped can summarise: each year with plays, and this year so far.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so the safety profile is covered. The description adds real value beyond them by disclosing the exact contents of the returned set (one entry per year with plays, plus a partial current year), which is the key behavioral fact for a zero-argument enumeration tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with zero waste that front-loads the purpose ('the date ranges get_wrapped can summarise') and then the contents. Nothing redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter, no-output-schema listing tool, the description covers what the tool does and what comes back, which is nearly everything an agent needs. It could go one step further by noting the format of the range identifiers consumed by get_wrapped, but the gap is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description usefully explains what the (implicitly returned) range values represent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names the specific resource (date ranges) and explicitly ties it to the sibling get_wrapped, so an agent can distinguish it from the other list/search tools without opening any schema. The scope of what is enumerated (each year with plays, plus this year so far) is concrete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
By naming get_wrapped the description implies this is the discovery step before calling that tool, but it never states that explicitly nor gives any when-not guidance or alternatives. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
now_playingPlaying right nowARead-only
What Spotify is playing right now, live, or null when nothing is. Needs the warehouse's Spotify grant.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already declaring readOnlyHint=true, openWorldHint=true, and idempotentHint=false, the bar is lower, yet the description still adds value by disclosing the null return when nothing is playing and the required Spotify grant. It does not explain rate limits or response shape, but the null semantics and auth requirement are meaningful additions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences with no filler. The core behavior (live now-playing, null fallback) is front-loaded, followed by the auth prerequisite.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, no-output-schema tool, the description covers the essential facts: what it returns, the null case, and the auth grant needed. The main remaining gap is not routing the agent versus the similar recently_played_live sibling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the baseline this scores 4. The description correctly implies no input is needed, and there is nothing further to document.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and state ('What Spotify is playing right now, live') and notes the null case for nothing playing. It distinguishes itself from the playback-history siblings like get_plays and recently_played_live by emphasizing the live, instantaneous snapshot, though it does not name those alternatives explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a prerequisite ('Needs the warehouse's Spotify grant') which is useful context, but offers no explicit guidance on when to choose this over the closely related recently_played_live or get_plays tools. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
on_this_dayOn this day in earlier yearsBRead-onlyIdempotent
The most-played songs on this calendar date in each earlier year, with that day’s total plays.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | YYYY-MM-DD; default today |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and closed-world, so the safety profile is covered. The description adds useful data semantics, per-year grouping and a per-day play total, but says nothing about how many years are returned, ordering, or output shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense sentence with zero filler, front-loading what is returned before the qualifier about totals. Nothing needs trimming or reordering.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter, read-only lookup with no output schema, the description covers purpose and result content adequately. It would be slightly stronger if it hinted at the response shape (e.g. one entry per year) since no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single optional 'date' parameter is documented there with format and default, so the schema does the heavy lifting. The description adds no format or fallback detail beyond 'this calendar date'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and scope: most-played songs on this calendar date for each earlier year, plus that day's play totals. An agent can distinguish it from track_history or daily_play_counts, though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no statement of when this beats track_history/daily_play_counts, and no exclusions. The only usable hint (date defaults to today) lives in the schema rather than the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recently_played_liveRecently played, live from SpotifyARead-only
Spotify's own last plays (at most 50), including ones the warehouse has not stored yet (it polls every 30 minutes). For anything older use get_plays. Needs the Spotify grant.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 10 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnlyHint=true, openWorldHint=true), and the description adds genuinely non-obvious behavior: the warehouse polls every 30 minutes, so results can include plays not yet persisted, and the call depends on a Spotify grant. It does not mention rate limits or ordering, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the resource and the key freshness caveat, then the alternative, then the prerequisite. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still tells the agent what comes back (last plays, capped at 50, possibly unstored), what the freshness semantics are, and what auth is needed. Nothing essential to correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already carries the default (10) and the maximum (50). The description's 'at most 50' largely restates that ceiling, so it adds little semantics beyond the structured field — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Spotify's own last plays, at most 50') and explicitly frames the scope as the live, not-yet-warehoused view. It names sibling get_plays as the contrasting tool, so an agent can distinguish this from every other history tool 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use (recent/live plays not yet stored) and when-not ('For anything older use get_plays'), plus the prerequisite 'Needs the Spotify grant'. Both routing and the auth condition are stated rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchSearch artists and songsARead-onlyIdempotent
Find artists and songs in the stored listening history by name (case-insensitive substring), with all-time play counts. Use this first to turn a name into the id that artist_history and track_history take. An artist with id null is known only from the imported export: pass its name to artist_history instead.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Results per list, default 10 | |
| query | Yes | Part of an artist or song name | |
| artist | No | Only songs whose primary artist name contains this |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: case-insensitive substring matching, that play counts are all-time, and the null-id edge case that signals an export-only artist. It does not discuss result ordering or pagination, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with purpose and matching semantics, then routing guidance, then the edge case. Every sentence carries information an agent needs to pick and call the tool correctly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still conveys the shape of results (matched artists/songs with ids and all-time play counts) and the key null-id case. A bit more on ordering or how the two result lists are returned would make it fully self-contained, but it is complete enough to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so query, artist and limit are already documented in the schema, and the baseline is 3. The description reinforces that matching is a case-insensitive substring on names but adds no syntax, default, or format detail beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (find) and resource (artists and songs in stored listening history) plus the matching semantics (case-insensitive substring) and returned data (all-time play counts). It also distinguishes itself from siblings by naming artist_history and track_history as downstream consumers of the ids it produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to 'use this first' to turn a name into the id that artist_history and track_history take, and gives a clear when-not/alternative branch: an artist with id null is known only from the imported export, so pass its name to artist_history instead. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
spotify_topSpotify's top listsARead-only
Spotify's own top tracks and artists, live. short_term is about 4 weeks, medium_term about 6 months, long_term about a year. For exact counts over any range, use top_artists or get_stat instead. Needs the Spotify grant.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Only one list; default both | |
| limit | No | Default 12 | |
| range | No | Default long_term |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds non-obvious context: 'live' implies real-time, uncached data (consistent with idempotentHint=false), and 'Needs the Spotify grant' flags an authorization prerequisite. Return format and limit behavior remain unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, each load-bearing: identity, range semantics, alternative routing, auth prerequisite. Front-loaded with the tool's identity and no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description covers identity, range meaning, routing and auth. It does not describe the response shape or pagination, but for a small three-parameter read tool with full schema coverage it is close to sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 genuinely extends the schema by defining short_term (~4 weeks), medium_term (~6 months) and long_term (~1 year) — the enum values alone convey none of that. That is real added meaning beyond the structured field.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (Spotify's own top tracks and artists) with the qualifier 'live', and names sibling tools (top_artists, get_stat) as alternatives. It is mostly distinguishable, though the boundary between this and top_tracks/top_artists (whose data it returns) is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: 'For exact counts over any range, use top_artists or get_stat instead.' It also defines the meaning of each range value, which is the key selection criterion. It stops short of saying when NOT to use it relative to top_tracks, but the guidance is concrete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
top_artistsTop artists over a date rangeARead-onlyIdempotent
Play counts per artist between two local dates (inclusive), most played first. Credits every artist on a track. Defaults to the last 30 days. Ranges up to 3,660 days.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Last day, YYYY-MM-DD; default today | |
| from | No | First day, YYYY-MM-DD; default 29 days ago | |
| limit | No | Default 50 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds meaningful behavioral detail beyond annotations: inclusive local dates, a default 30-day window, a 3,660-day max span, and the policy of crediting every artist on a track. It stops short of describing return structure or error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight, front-loaded fragments communicate purpose, ordering, counting semantics, defaults, and range limits. Every sentence earns its place with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description is expected to carry more return-value context. It conveys output ordering and a key counting rule but does not specify the returned fields (e.g., artist name, id, count) or pagination behavior. Those are minor gaps for a straightforward list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value beyond the schema by clarifying that dates are local and inclusive, and by specifying a maximum range of 3,660 days that is not expressed in the schema. It does not add meaning for the limit parameter beyond the schema's stated default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource (play counts per artist), scope (between two local dates, inclusive), ordering (most played first), and notable counting semantics (credits every artist on a track). It clearly distinguishes the output from a simple per-track count, but does not explicitly differentiate this tool from siblings like top_tracks or artist_history.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: retrieve top artists over a date range, with defaults and a maximum span given. However, there is no explicit when-to-use guidance or comparison to alternatives such as top_tracks, artist_history, or search. It leaves the agent to infer the selection context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
top_tracksTop songs over a date rangeARead-onlyIdempotent
Play counts per song between two local dates (inclusive), most played first, with editions of a song (single, album, remaster) folded together. Use this for "my top songs in July" or "most played song last year". Defaults to the last 30 days. Ranges up to 3,660 days.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Last day, YYYY-MM-DD; default today | |
| from | No | First day, YYYY-MM-DD; default 29 days ago | |
| limit | No | Default 20 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only/idempotent profile, and the description adds real behavioral context beyond them: editions are collapsed together, results are sorted by play count, dates are local and inclusive, and the window defaults to 30 days with a 3,660-day cap. It doesn't describe pagination or what a truncated/empty result looks like, so it's not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with what the tool returns and how it aggregates, followed by usage examples and constraints. Every sentence carries information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 reasonably by naming the unit (play counts per song) and ordering. It's complete enough to call correctly, though it could say more about result shape (e.g. fields returned) given no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds semantics the schema lacks: the dates are 'local' and 'inclusive', the default window is the last 30 days, and the maximum span is 3,660 days (the schema's limit field has no such range note). This is meaningful extra meaning on top of a fully documented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('play counts per song'), the ordering ('most played first'), and the aggregation rule ('editions of a song ... folded together'). An agent can distinguish this from top_artists (artists) and track_history (per-track detail) 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete usage examples ('my top songs in July', 'most played song last year') plus the default window and max range, so the agent knows when this tool is the right fit. It never names an alternative to avoid (e.g. track_history or spotify_top), so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
track_historyOne song's whole historyARead-onlyIdempotent
A song's all-time plays, estimated minutes, first and last play, and plays per month, with every edition of it (single, album, remaster) folded together. Takes a track id: use search to find one by name.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Spotify track id |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and closed-world behavior, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: it aggregates across every edition (single, album, remaster) rather than just one track release. It stops short of noting auth or pagination, hence not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loading the return contents before the id requirement. Every clause earns its place, though the parenthetical edition list is slightly dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 return values and does so thoroughly, including the edition-folding semantics. An agent has enough to call it correctly; only minor gaps (auth, whether the id must be exact) remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter is fully documented as 'Spotify track id'. The description restates the type and adds the practical guidance on finding an id via search, but adds no syntax or format detail beyond the schema. Baseline 3 is appropriate for a fully-covered single param.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource and enumerates exactly what it returns (all-time plays, estimated minutes, first/last play, plays per month), plus the edition-folding behavior. It doesn't explicitly distinguish itself from the analogous sibling artist_history, but an agent reading it knows precisely what this tool produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives one routing hint ('use search to find one by name'), which covers how to obtain the required id. It does not say when to prefer this over get_plays, daily_play_counts, or artist_history, so alternative selection is left to inference.
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.
14 tool updates
v0.1.0- First observed
artist_history - First observed
daily_play_counts - First observed
get_plays - First observed
get_stat - First observed
get_wrapped - First observed
list_wrapped_ranges - First observed
now_playing - First observed
on_this_day - First observed
recently_played_live - First observed
search - First observed
spotify_top - First observed
top_artists - First observed
top_tracks - First observed
track_history
TDQS
Scored across 14 tools
Most tools target clearly distinct query types: name search, raw plays, top lists, daily counts, entity histories, Wrapped summaries, precomputed aggregates, and live Spotify state. Some overlap remains between top_artists/top_tracks, get_stat aggregates, get_wrapped, and stored vs live recent plays, but descriptions provide explicit guidance on when to use which.
All names use readable snake_case with no camelCase or chaotic variation. The set is not a strict verb_noun pattern throughout, since many tools are noun phrases like artist_history, now_playing, and spotify_top, but the convention is still predictable and consistent.
Fourteen tools fits comfortably within the ideal 3-15 range for an analytics-style server. Each tool covers a distinct listening-history or Spotify-live query, and there is no excessive filler or fragmentation.
The surface strongly covers read-only listening analytics: search, raw plays, top artists/tracks, daily counts, artist/track histories, on-this-day, Wrapped, precomputed stats, and live Spotify tools. Minor gaps remain, such as no direct per-artist or per-track query over an arbitrary date range beyond top lists, and no metadata/import management, but core workflows are covered.
Maintenance
Related MCP Connectors
The media memory layer for AI agents and their humans. Your AI client gets 29 tools to search your collection, add items, update ratings, preview music, and find patterns across everything you've read, watched, and listened to.
The CWI Discovery Engine is the MCP server for the Cumulative Web Inc music catalog — 28 tools for AI agents: catalog search, track/artist/release lookups, semantic and mood-based sync search, Radio 365 live stream data, playlist pitching, sync-brief submission, airplay requests, featured nominations, label info, events, lyrics, press kits, videos, genres, playlists and recommendations. No authentication required. Free.
Anonymous public tools for Zachary Roth Music. See the published agent boundary before use.
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Related MCP Servers
- AlicenseAqualityDmaintenanceConnects AI assistants to a self-hosted Your Spotify instance and Spotify's Web API for deep listening analytics and playback control. It enables users to query unlimited listening history, generate custom Wrapped summaries, and manage playlists through natural language.18Apache 2.0
- AlicenseBqualityDmaintenanceEnables AI agents to access public Spotify data (tracks, albums, artists, playlists, podcasts) without an API key, including lyrics and podcast transcripts with optional login.281,423 PyPI316MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to securely connect to a user's personal Discogs music collection for mood-aware searching, analytics, and context-aware recommendations via Cloudflare Workers.MIT
- AlicenseAqualityBmaintenanceLets AI assistants answer questions about your Spotify listening history, including taste evolution, top artists, recently played, and playlist analysis.872 npmMIT