Apple Music MCP
Provides tools for interacting with an Apple Music account, including reading listening history, heavy rotation, recommendations, Replay summaries, library playlists, searching the catalog, and safely creating playlists and appending tracks with duplicate checks.
Click on "Install 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., "@Apple Music MCPWhat's my top artist this month?"
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.
Apple Music MCP on Cloudflare
A remote Model Context Protocol (MCP) server that lets an AI agent safely work with one Apple Music account. It runs as a Cloudflare Worker, stores authorization and observed listening history in Cloudflare D1, and uses only Apple’s official MusicKit and Apple Music API surfaces.
The server can:
Read indefinitely retained observed history by presets or an exact custom date range.
Read heavy rotation and personalized Apple Music recommendations.
Read official Apple Music Replay summaries.
List library playlists and their tracks.
Search the Apple Music catalog.
Create playlists and append tracks, with duplicate checks and dry-run support.
Build observed listening summaries and rankings by track, artist, album, or genre.
Keep collecting recently played history every five minutes without an agent calling the MCP.
Deployment model
Each deployment connects to one Apple Music account and keeps its data in that deployer's own Cloudflare D1 database. MCP requests require POKE_MCP_API_KEY, and the browser setup flow requires SETUP_TOKEN. Nothing in the repository grants access to an existing deployment, Apple account, or listening history.
Related MCP server: Apple Music MCP Server
How it works
flowchart LR
Client["MCP client or AI agent"] -->|"Bearer API key"| Worker["Cloudflare Worker"]
Worker -->|"Developer token + encrypted user token"| Apple["Apple Music API"]
Worker --> D1["Cloudflare D1"]
Setup["Browser setup page<br/>MusicKit authorization"] --> Worker
Cron["Cloudflare cron<br/>every 5 minutes"] --> Worker
D1 --> History["Observed listening history<br/>analytics state<br/>audit log"]The Worker signs short-lived Apple developer tokens using the configured Media Services private key. The browser setup page uses MusicKit to obtain the account’s music user token, which is encrypted with AES-GCM before being stored in D1.
Cloudflare’s scheduled handler fetches Apple’s latest 30 played tracks every five minutes. It compares consecutive snapshots and stores the newly observed prefix, allowing repeated tracks to become separate observed events.
MCP tools
The server currently exposes 14 tools.
Tool | Capability | Important inputs |
| Check Apple credentials, account connection, token age, and storefront. | None |
| Page through D1-backed history from any observed timeframe. |
|
| Read Apple Music heavy rotation, similar to “On Repeat.” |
|
| Read personalized recommendation groups. |
|
| Read official latest-year Replay totals and top content. | None |
| List library playlists and whether each is editable. |
|
| Read tracks from a library playlist. |
|
| Search songs, albums, artists, playlists, or music videos in the user’s storefront. |
|
| Create a new library playlist. |
|
| Safely resolve, preflight, deduplicate, and append up to 100 tracks. |
|
| Manually refresh the observed listening ledger. |
|
| Inspect ledger coverage and recent ingest runs. | None |
| Build SQL-side observed totals and top items for any timeframe. |
|
| Rank tracks, artists, albums, or genres for any timeframe. |
|
Recently played query examples
Request the first 20 songs observed during the last 30 days:
{
"preset": "30d",
"limit": 20
}Request a custom Mountain Time range:
{
"start": "2026-08-01T00:00:00-06:00",
"end": "2026-08-15T00:00:00-06:00",
"limit": 50
}Request all observed history:
{
"preset": "all_time",
"limit": 50
}Presets are today, 24h, 7d, 30d, 90d, ytd, last_year, and all_time. Use either one preset or a custom inclusive start and optional exclusive end; custom timestamps must include Z or a UTC offset. Calendar presets default to America/Denver, with an optional IANA timeZone override.
History responses are deliberately bounded to 200 tracks and default to 50. When coverage.hasMore is true, pass the returned nextCursor; it carries the original fixed range so rolling presets cannot shift between pages. Summary and ranking tools aggregate inside D1 and do not return or load the full event ledger.
Playlist write behavior
The write surface is intentionally conservative:
The server can create a playlist.
It can append tracks to an editable library playlist.
It compares up to 10 catalog candidates per requested song and verifies title, artist, and version.
It rejects unintended remixes, live recordings, covers, and other variants.
It reports unresolved and ambiguous requests instead of silently substituting or dropping them.
It checks the current playlist and the incoming batch for duplicate catalog IDs.
By default, one unresolved or ambiguous request blocks the entire write;
allowPartial: truerequires an explicit decision to skip questionable songs.dryRun: trueresolves and deduplicates tracks without changing Apple Music and should be used before large or important writes.A completed write is read back with bounded retries. If Apple has accepted the append but its eventually consistent library read has not caught up, the tool reports
pending_apple_propagationrather than incorrectly claiming verification failed.It does not remove tracks, reorder tracks, insert at a position, edit playlist metadata, or delete playlists.
Listening-history accuracy
Apple’s recently played endpoint is not a historical export. It returns at most 30 tracks and does not include a play timestamp.
Consequently:
History cannot be backfilled retroactively.
observedAtis estimated within the five-minute interval in which the Worker first detected a song.If all 30 upstream slots change between polls, the collector flags a possible coverage gap.
Every observed listen event is retained indefinitely; no automatic event-expiration query exists.
Existing event rows and their raw payloads remain untouched. Future events keep normalized per-play data and reference a content-addressed raw payload version, so identical JSON is stored once while every changed version remains recoverable.
Any timeframe is incomplete unless the collector has actually covered that entire period without an upstream polling gap.
apple_music_replay_summaryis the correct tool for authoritative latest-year Replay totals.
Prerequisites
You need:
Node.js and npm.
A Cloudflare account with Workers and D1 access.
An Apple Developer account with permission to create Media IDs and Media Services keys.
An Apple Music subscription for the account being connected.
An MCP client that supports remote Streamable HTTP servers.
In the Apple Developer portal:
Register a Media ID under Certificates, Identifiers & Profiles.
Enable the Apple Music/MusicKit service for that identifier.
Create a Media Services private key associated with the Media ID.
Download the
.p8private key immediately; Apple does not allow it to be downloaded again.Record the key ID and Apple Developer team ID.
Fresh Cloudflare setup
These steps create an independent deployment in your Cloudflare account.
1. Install dependencies and sign in
npm install
npx wrangler login2. Create Cloudflare storage and local configuration
Copy the public configuration template:
cp wrangler.example.toml wrangler.tomlCreate the OAuth KV namespace:
npx wrangler kv namespace create OAUTH_KVCopy the returned namespace ID into the OAUTH_KV entry in your local wrangler.toml.
Create the D1 database:
Create a database:
npx wrangler d1 create apple-music-mcpCopy the returned database ID into wrangler.toml:
[[d1_databases]]
binding = "DB"
database_name = "apple-music-mcp"
database_id = "<YOUR_D1_DATABASE_ID>"
migrations_dir = "migrations"Apply the schema:
npx wrangler d1 migrations apply apple-music-mcp --remoteThe migrations create:
auth_tokensfor the encrypted Apple music user token.configfor authorization state and the cached storefront.listen_eventsfor indefinitely retained normalized listening events.track_resource_versionsfor content-addressed Apple payload versions, deduplicating identical future metadata while preserving every distinct payload and linking it to the listen event.analytics_statefor snapshot comparison state.analytics_ingest_runsfor collector health and coverage.audit_logfor MCP read and write activity.
3. Configure Worker secrets
Set all six secrets interactively:
npx wrangler secret put POKE_MCP_API_KEY
npx wrangler secret put SETUP_TOKEN
npx wrangler secret put TOKEN_ENCRYPTION_KEY
npx wrangler secret put APPLE_TEAM_ID
npx wrangler secret put APPLE_KEY_ID
npx wrangler secret put APPLE_PRIVATE_KEYSecret meanings:
Secret | Purpose |
| Bearer token required for every |
| Protects the browser-based |
| Encrypts the Apple music user token stored in D1. Use a strong random value and preserve it for the lifetime of the stored token. |
| Apple Developer team identifier used as the developer-token issuer. |
| Identifier of the Media Services private key. |
| Full PKCS#8 contents of the downloaded |
Generate strong random values for the first three secrets with a password manager or a command such as:
openssl rand -base64 32Never commit these values. The project ignores work/, .wrangler/, .dev.vars, and the local wrangler.toml deployment configuration.
4. Validate and deploy
npm test
npm run typecheck
npx wrangler d1 migrations apply apple-music-mcp --remote
npx wrangler deploy --dry-run
npm run deployApply migrations before deploying a Worker version that references a new table. Migrations 0003_indefinite_history.sql and 0004_resource_versions.sql create the compact resource archive and replacement history index; they do not update or delete any listen_events rows or existing inline raw payloads.
The deploy output prints the Worker URL. The MCP endpoint is that URL plus /mcp.
5. Authorize Apple Music
Open:
https://<YOUR_WORKER>.workers.dev/setup?setup_token=<SETUP_TOKEN>Select Authorize Apple Music and complete Apple’s prompt. The setup page sends the resulting music user token directly to the Worker, which encrypts it before saving it in D1.
Apple does not issue a refresh token for this flow. If Apple access later expires, open the same setup URL and authorize again. In practice, this may be needed roughly every six months.
6. Verify the connection
Configure an MCP client with:
URL:
https://<YOUR_WORKER>.workers.dev/mcpAuthorization header:
Bearer <POKE_MCP_API_KEY>Transport: Streamable HTTP
Then call apple_music_status. A healthy connection reports:
{
"appleCredentialsConfigured": true,
"connected": true,
"storefront": "us"
}For Poke, the existing project used:
npx poke@latest mcp add https://<YOUR_WORKER>.workers.dev/mcp \
-n "Apple Music" \
-k "<POKE_MCP_API_KEY>"The Worker also exposes /sse for clients that still use the older endpoint name.
Local development
The complete service can run on one machine without deploying a Worker or creating Cloudflare storage. It still uses Wrangler's local workerd runtime and simulated D1/KV bindings, so this is the same Worker architecture running locally rather than a separate Node server.
1. Install and configure
git clone https://github.com/jordanlein/apple-music-mcp.git
cd apple-music-mcp
npm install
cp .dev.vars.example .dev.varsEdit .dev.vars with three strong random values and your Apple Team ID, Media Services key ID, and full .p8 private key. Keep this file private; it is ignored by Git.
Apply the migrations to Wrangler's local D1 instance:
npm run db:migrate:localLocal D1, KV, and authorization state persist under .wrangler/state, as described in Cloudflare's local data documentation. Back up that directory if the observed history matters; deleting it resets the local service.
2. Start and authorize
Start the local Worker with its scheduled-test route enabled:
npm run dev:localOpen this URL, substituting the SETUP_TOKEN from .dev.vars:
http://localhost:8787/setup?setup_token=<SETUP_TOKEN>Authorize Apple Music, then configure the MCP client with:
URL:
http://localhost:8787/mcpAuthorization:
Bearer <POKE_MCP_API_KEY>Transport: Streamable HTTP
The MCP client must run on the same machine unless you deliberately expose the port over a trusted LAN or secure tunnel. Do not forward port 8787 publicly without TLS and access controls.
3. Keep collecting history
Cloudflare Cron Triggers do not automatically fire inside a local Wrangler development session. While npm run dev:local is running, trigger one collection pass with:
curl -fsS 'http://127.0.0.1:8787/__scheduled?cron=%2A%2F5+%2A+%2A+%2A+%2A'For continuous history, configure the host's scheduler to make that request every five minutes and keep both the machine and Wrangler process running. The collector can only observe the latest Apple window, so downtime can create permanent gaps. Cloudflare documents the same route in its local Cron Trigger testing guide.
Cloudflare deployment or local machine?
Consideration | Cloudflare deployment | Local machine |
Availability | Always-on remote HTTPS endpoint; best chance of uninterrupted five-minute collection. | Available only while the computer, network, and Wrangler process are running. |
History storage | Managed D1 plus a scheduled Worker; data lives in the deployer's Cloudflare account. | Simulated D1/KV under |
Access | Works with remote MCP clients from anywhere using the bearer key. | Loopback-only by default; remote access needs deliberate networking, TLS, and firewall work. |
Cost and limits | Subject to Cloudflare plan quotas and possible usage charges as history and queries grow. | No hosted Cloudflare usage, but consumes local power, disk, and uptime. Apple API limits still apply. |
Secret isolation | Worker secrets are managed separately from the encrypted D1 token. |
|
Maintenance | Cloudflare runs the process and Cron Trigger; deployments and schema migrations remain the owner's job. | The owner runs the process, scheduler, backups, updates, and recovery. |
Best fit | The recommended mode for durable indefinite history and remote agents. | Privacy-focused experimentation, development, or an always-on trusted home server. |
Neither mode can backfill plays from before collection began. Both require internet access to Apple Music, and both are single-user per deployment.
Useful project commands:
npm test
npm run typecheck
npm run dev:local
npm run db:migrate:local
npx wrangler deploy --dry-run
npx wrangler tailComparison with other Apple Music MCP servers
This project is optimized for a remote agent that needs durable, queryable listening history and conservative playlist writes. Many other Apple Music MCPs optimize instead for controlling a local Music app or providing the widest possible playback and library surface.
The comparison below reflects the projects' published READMEs as checked on August 31, 2026; those projects may change.
Project | Architecture and Apple access | Strengths | Main tradeoff versus this project |
This project | Remote Streamable HTTP on Cloudflare, or local | Indefinite observed-event ledger, preset/custom timeframes, stable pagination, SQL analytics, official Replay, five-minute collection, encrypted token storage, and guarded create/add playlist writes. | No playback, queue, volume, rating, removal, or playlist-deletion controls; requires an Apple Developer MusicKit key. |
Local Python MCP with native Music.app, Apple API, Safari, and Chrome engines. | Broadest control surface of this set: playback, Up Next, ratings, folders, library management, and cross-platform browser/API modes. | More local/browser integration and a larger trust surface; its README does not describe a durable timestamped history ledger or Cloudflare-hosted remote endpoint. | |
Local Python/FastMCP server controlling Music.app through AppleScript on macOS. | Very simple installation and direct playback/library control without Cloudflare or Apple API credentials. | macOS-only, must run beside Music.app, and does not claim remote hosting, personalized Apple API data, Replay, or persistent history analytics. | |
Local Node stdio server using the documented Apple Music API and browser MusicKit authorization. | Catalog, library, recommendations, recently played, and straightforward playlist creation/addition using official API credentials. | Local client process with current recently-played results only; its README does not describe continuous collection, an indefinite ledger, custom timeframes, or SQL analytics. | |
Local Rust server using an Apple developer token. | Small, focused catalog search and Apple Music deep-link generation. | Catalog-oriented only; no music-user authorization, personal library, recommendations, playlist writes, Replay, or history ledger is documented. |
There are also projects that obtain web-player credentials through browser automation. They can avoid an Apple Developer membership or unlock controls absent from Apple's public API, but they rely on undocumented web behavior and token-capture flows. This project intentionally stays on Apple's documented API and MusicKit authorization surfaces.
Choose this project when remote access, long-running history collection, exact timeframes, and bounded analytics matter most. Choose a local Music.app MCP when immediate playback control and zero cloud setup matter more. Choose a broader hybrid MCP when playback, queue, ratings, deletion, and cross-platform browser control outweigh the operational simplicity of a narrower API surface.
Routes
Route | Access | Purpose |
| Public | Small JSON service descriptor. |
|
| Primary MCP Streamable HTTP endpoint. |
|
| Compatibility endpoint using the same MCP handler. |
|
| Browser MusicKit authorization page. |
| Setup state | Receives and encrypts the authorized Apple music user token. |
/setup accepts its token as ?setup_token=... or as a Bearer token. MCP endpoints accept only the configured Bearer API key.
Operations and troubleshooting
Check deployment and database state
npx wrangler whoami
npx wrangler d1 migrations list apple-music-mcp --remote
npx wrangler secret listUse the MCP tools apple_music_status and apple_music_analytics_status for application-level health.
apple_music_analytics_status reports indefinite retention, total event coverage, and the count of archived resource-payload versions. Monitor D1 storage and rows read in the Cloudflare dashboard as the all-time ledger grows. Pagination and timestamp indexes keep sequence queries bounded; summary and ranking queries aggregate in SQL.
Apple Music is disconnected
Open the protected setup URL and authorize again. If the setup page says Apple credentials are missing, confirm that APPLE_TEAM_ID, APPLE_KEY_ID, and APPLE_PRIVATE_KEY exist as Worker secrets.
MCP returns Unauthorized
Confirm the client sends:
Authorization: Bearer <POKE_MCP_API_KEY>The setup token does not grant MCP access, and the MCP API key does not replace the Apple account authorization.
History is shorter than expected
The collector cannot retrieve plays from before it started. Confirm the five-minute cron is deployed and call apple_music_analytics_status to inspect recent ingest runs. The Apple endpoint can also lose coverage if more than 30 tracks move through its window between polls.
Raw HTTP testing returns Not Acceptable
The MCP transport expects both supported response types:
Accept: application/json, text/event-streamNormal MCP clients set this automatically.
Security notes
Apple’s
.p8key, MCP API key, setup token, and encryption key belong in Cloudflare secrets, notwrangler.toml.The Apple music user token is encrypted before storage with AES-GCM.
The setup flow uses a random state value checked by the Worker before accepting a token.
Read and write tool activity is recorded in
audit_log; an optionalX-Poke-User-Idrequest header is included when supplied.Playlist changes are append-oriented and deliberately exclude destructive operations.
Losing
TOKEN_ENCRYPTION_KEYmakes the stored Apple token unreadable. Changing it requires reauthorizing Apple Music.
Project structure
src/
index.ts Worker routes, MCP authentication, and scheduled handler
mcp.ts MCP tool definitions and input validation
apple.ts Apple Music API client and developer-token signing
analytics.ts D1 collection, paged history queries, and SQL-side statistics
timeframe.ts Preset/custom ranges and timezone-aware calendar boundaries
recent-history.ts Snapshot diffing and opaque history cursor logic
storage.ts Token, config, and audit persistence
setup.ts Browser MusicKit authorization flow
crypto.ts ES256 signing and AES-GCM encryption
format.ts Compact MCP response formatting
types.ts Worker and Apple API types
migrations/ D1 schema migrations
test/ Snapshot, timeframe, pagination, matching, and metadata tests
wrangler.local.toml Local-only simulated D1/KV configuration
wrangler.example.toml Public Worker, D1, KV, variables, and cron template
wrangler.toml Local deployment configuration (ignored by Git)Platform and API references
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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.
Connect AI agents to bank accounts, transactions, balances, and investments.
Analyze and manage Apple Ads from your AI assistant with RevenueCat insights and safety controls.
OAuth 2.1 short-link tools for AI agents with scoped tokens, approvals, audit logs, and revocation.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables AI assistants to control Spotify playback, manage playlists, search music, and access listening history. Requires Spotify Premium and uses secure OAuth 2.0 with PKCE authentication.13109MIT
- FlicenseNot gradedqualityDmaintenanceIntegrates Apple Music with MCP clients to search the global catalog, manage personal playlists, and access library data. It enables users to perform actions like creating playlists, adding tracks, and viewing recommendations through natural language commands.1
- AlicenseNot gradedqualityDmaintenanceConnects Claude Code to Apple Music using only your Apple ID, without needing a developer account. Enables access to recently played, playlists, search, recommendations, and playlist creation.12MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to control Spotify playback, search music, manage playlists and library, and access user listening insights via the Spotify Web API.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jordanlein/apple-music-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server