mcpField
A
Apple Music Playlist Curator

Apple Music Playlist Curator

本地服务
github.com游戏娱乐22 周前更新

关于 Apple Music Playlist Curator

Apple Music 播放列表策划 MCP 服务,将自然语言描述转为经过目录核验和编排的曲目列表,面向使用 MCP 客户端的听众。由客户端中的 LLM 负责理解语义,服务负责搜索、匹配和账户操作。

主要功能

  1. 01按描述搜索 Apple Music 曲目
  2. 02核验曲目版本与重复项
  3. 03分析播放列表元数据和音频特征
  4. 04按指定叙事边界调整曲序
  5. 05查看最近播放与播放次数
  6. 06创建、编辑和删除播放列表

适用场景

  1. 01按氛围或场景策划播放列表
  2. 02确认候选曲目对应准确录音
  3. 03检查曲目衔接并调整顺序
  4. 04依据播放记录辅助选曲

MCP 相关

通过本地 stdio MCP 服务向客户端提供 Apple Music 搜索、曲目核验、播放列表管理和分析工具。客户端中的 LLM 负责理解策划要求并选择曲目。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"z-han-z-apple-music-playlists": {
"command": "uvx",
"args": [
"apple-music-playlists"
]
}
}
}
启动命令uvx apple-music-playlists

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiapple-music-playlists1.5.0

工具

14

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

Apple Music MCP 策展工具

网易云(NCM)公开预览:简体中文使用说明。

Apple Music MCP — 基于 Apple Music 曲库打造的自然语言歌单

测试 容器 发布 PyPI MCP 注册表 Python 3.10+ 许可证:MIT Glama 质量评分

English | 简体中文 | 繁體中文 | 日本語 | 한국어 | Español | Português do Brasil | Deutsch | Français

为 Apple Music 深度策划歌单:描述一种感觉、场景、年代、聆听目的或声音;你的 Agent 会基于这些信息筛选曲目,并安排播放顺序,打造令人满意的聆听体验。你可以指定任意叙事节拍;如果没有提出此类要求,就不会强加故事弧线。

观看 12 首曲目的策展演示:22 首经过核实的候选曲目,组成一个按明确要求打造的三幕故事,并展示了为什么较低的优化器成本可能让歌单变得更糟。这只是其中一种可能形式,并非默认模板。

纯 Python 标准库——运行无需 pip install,也无需加入 Apple Developer Program。需要 Python 3.10+,支持 Windows / macOS / Linux。

主要接口是本地 am-mcp stdio 服务。MCP 客户端中已运行的语言模型会解读需求并选择候选曲目;本项目负责搜索 Apple Music 曲库、匹配确切曲目并执行账户操作。项目不包含随附模型、LLM API 密钥、艺人列表或固定主题。CLI 仍可用于登录、诊断、脚本编写、审计和高级排序。

  understand  →  curate  →  ground  →  sequence with intent  →  dry-run  →  create

为什么选择这个项目

  • 简述始终聚焦语义。 宿主大模型会直接推理意象、情绪、歌词角度、时代、文化背景、对比,以及每首歌曲的作用。它不会被简化为少数几个由用户提供的滑块,也不会被浓缩成不透明的主题匹配分数。
  • 选曲与排序各自独立。 模型决定哪些歌曲适合入选;测得的 BPM、调性、能量、效价和响度可以用于诊断过渡,或在你指定的节拍范围内优化流畅度——否则不会强加全局曲线。
  • 每个候选都有依据。 在试运行和最终创建之前,目录解析会检查曲目缺失、重复、艺人错误,以及可疑的现场版/重制版。
  • 聆听记录仅作为参考。 重播历史、近期播放记录、日期和播放次数可以为策划提供参考,但不会悄然变成算法对用户品味的定义。
  • 从设计上保护本地隐私。 服务在你的设备上运行;凭据保存在本地应用配置中,不捆绑模型、遥测服务,也不需要额外的大模型 API 密钥。
  • 可移植的 MCP stdio。 适用于 Codex、Claude、Cursor、VS Code/Copilot、Gemini CLI、Windsurf、Cordis/DSH、Harness,以及其他能够启动本地 stdio 服务的客户端。

快速开始

推荐 — 安装 MCP stdio 服务:

pip install apple-music-playlists
am-playlist status
am-playlist login       # one-time Apple ID sign-in

已经在使用 uv?无需永久安装即可运行已发布的软件包:

uvx --from apple-music-playlists am-playlist status
uvx --from apple-music-playlists am-playlist login
uvx --from apple-music-playlists am-mcp

对于 MCP 客户端,符合 Registry 规范的等效配置如下:

{ "mcpServers": { "applemusic": { "command": "uvx",
    "args": ["--from", "apple-music-playlists", "am-mcp"],
    "env": { "PYTHONIOENCODING": "utf-8" } } } }

在客户端中注册 am-mcp。常见的配置形式如下:

{ "mcpServers": { "applemusic": { "command": "am-mcp",
    "env": { "PYTHONIOENCODING": "utf-8" } } } }

接下来描述你想要的结果,而不是实现方式:

创建一个适合深夜驾车的 25 首歌曲播放列表:氛围感强的另类 R&B 和电子乐,主要选自过去十年,不要现场版,结尾要平和。

支持 MCP Prompt 的客户端可以选择 create_playlist_from_description。其他客户端则可以在聊天中发送相同的请求:服务说明和类型化工具会提供相同的工作流:状态 → 候选曲目池 → 目录核验 → 直接比较 → 试运行 → 创建。

从克隆版本开始(无需安装):

git clone https://github.com/Z-Han-Z/apple-music-playlists.git
cd apple-music-playlists

python am_playlist.py status     # auto-fetches the developer token
python am_playlist.py login      # one-time Apple ID sign-in (~6 months validity)

python am_mcp_server.py             # register this absolute script path in the MCP client

安装后,CLI 和 MCP 命令也会添加到你的 PATH 中:

am-playlist status      # the CLI
am-playlist login       # one-time Apple ID sign-in
am-mcp                  # the MCP stdio server

开发时,从克隆版本运行 pip install -e .,即可让修改立即生效,无需重新安装。

凭据设置指南(三种获取用户令牌的方法,包括一种零依赖方法)请参见 SETUP.en.md。


一个真实的策展示例:一台机器梦见自己是人类

这比“给我做一份健身歌单”难得多。需求要求音乐承载剧情,而其中一些约束无法用节奏或情绪滑块来表达:

创作一个由 12 首曲目组成、分为三幕的故事:一台机器在城市中醒来,把关注误认为亲密,提出触碰请求,变得脆弱,并看见黎明。横跨 20 世纪 70 年代末至今的电子音乐和艺术流行乐;每位艺术家只选一首曲目,且仅使用录音室录音;让人声逐渐变得更像人类。结尾必须安静而令人信服,而不只是能量低。

以下运行使用了 2026-09-23 的美国 Apple Music 公共目录。它没有读取或写入私人音乐库。

22 LLM-proposed candidates
└─ 22 catalog matches returned exact title, artist, album, date, ISRC, and version metadata
   ├─ rejected: “Open Eye Signal (Mixed)” — resolved to a 2025 DJ Mix, not the studio cut
   ├─ rejected: “Deeper Understanding (2018 Remaster)” — not the requested original recording
   └─ 12 final selections

Final create dry-run:       12/12 matched; no write performed
Audio-feature coverage:     12/12 usable (100%)
Flow cost, narrative locks: 44.14 → 41.14

下面每个曲目标题都会打开解析器返回的美国目录中的确切录音,因此可以试听这个顺序,而不是只能盲目信任。

幕有依据的顺序这个顺序的作用
I — 启动The Robots — Kraftwerk
Technopolis — Yellow Magic Orchestra
Kid A — Radiohead
先是一个身体,然后是一座城市,接着是一个不稳定的第一人称声音。
II — 欲望Oblivion — Grimes
Digital Witness — St. Vincent
Is It Cold In The Water? — SOPHIE
Touch — Daft Punk & Paul Williams
All Is Full of Love — Björk
公共关注逐渐变成身体风险、蜕变、触碰请求,最终得到回应。
III — 重返Cellophane — FKA twigs
Retrograde — James Blake
Long Road Home — Oneohtrix Point Never
An Ending (Ascent) — Brian Eno
合成外壳失效;退避变成归来,故事最终落在黎明。

有意思的失败发生在排序阶段。仅锁定三幕时,数值优化器将测得的成本从 48.28 降到了 14.88,却把 Retrograde 放在黎明之后,还让 All Is Full of Love 回应一个尚未发生的请求。成本更低,效果却更差。因此,宿主模型添加了语义节拍边界(request → answer、return → dawn),并让 am_optimize_order 只在这些边界内进行局部调整。曲目选择和故事仍由语言判断;BPM、调性、能量和效价只是辅助证据。

最终试运行输入
[
  "The Robots - Kraftwerk",
  "Technopolis - Yellow Magic Orchestra",
  "Kid A - Radiohead",
  "Oblivion - Grimes",
  "Digital Witness - St. Vincent",
  "Is It Cold In The Water? - SOPHIE",
  "Touch - Daft Punk",
  "All Is Full of Love - Björk",
  "Cellophane - FKA twigs",
  "Retrograde - James Blake",
  "Long Road Home - Oneohtrix Point Never",
  "An Ending (Ascent) - Brian Eno"
]

这是常规的 MCP 工作流:宿主模型解读需求,并提出多于所需数量的候选项;am_resolve_candidates 为候选项提供依据;只有在需求需要时,模型才选择曲目并解读其叙事角色;am_optimize_order 可选择检查局部流畅度,但不会跨越语义边界;am_create_playlist(dry_run=true) 则会在写入前核验最终录音。

若要将此工作流与一次性基线进行比较,请使用 examples/ 中六份难度较高的多语言需求和盲听流程。该套件提供可审计的约束,而非预先指定的“正确”歌曲。


包含内容

文件用途
am_playlist.py核心功能:令牌管理、目录搜索、创建 / 编辑 / 删除播放列表、曲目解析
am_mcp_server.py主要的 MCP stdio 服务:一个描述转播放列表提示词,以及 14 个工具
playlist_audit.py元数据审计:长度、艺人集中度、流派、年代、时长、重复项、间奏曲
playlist_flow.py音频特征审计:BPM / 调性 / 响度 / 能量 / 效价、相邻曲目检查、弧线形状
playlist_optimize.py根据测量规则进行模拟退火曲目排序
listening_stats.py聆听历史:最近播放,以及每首曲目 / 专辑 / 艺人的播放次数(Apple Music Replay 后端)
profile_library.py描述性样本画像:测量 BPM / 能量 / 效价分布和相对于样本的象限;它不定义用户的品味
am_library.py你的资料库:分页导出你拥有的所有由目录提供支持的歌曲,并补充 ISRC / 年份 / 流派
build_pool.py聆听证据池:将最近播放与多个 Replay 年份的数据合并,保留日期和播放次数供大模型解读

支持模块:

文件用途
playlist_core.py平台无关的核心功能:Camelot、BPM 折叠、四条相邻规则、六种叙事形状。不导入本项目中的任何内容,也不导入任何第三方内容
am_paths.py平台无关的路径和版本 — 配置与缓存的存放位置
am_meta.py唯一的 catalog_meta 实现(批量目录查询)

所有三个分析模块都可作为库导入:

import playlist_flow, playlist_audit, playlist_optimize

print(playlist_flow.flow_report("My Playlist"))          # -> str
print(playlist_audit.audit_report("My Playlist"))        # -> str
ids, report = playlist_optimize.optimize("stack.json")   # -> (list[str], str)
MCP 工具

标准提示词 create_playlist_from_description 会请求一段自然语言简介,以及可选的名称、曲目数量和回复语言。策展工作由宿主模型完成;这些工具是基于事实的 Apple Music 执行层:

am_status · am_search_songs · am_resolve_candidates · am_list_playlists · am_show_playlist · am_create_playlist · am_add_tracks · am_delete_playlist · am_audit_playlist · am_analyze_flow · am_optimize_order · am_recently_played · am_top_played

am_resolve_candidates 会根据真实目录元数据核实大模型提出的候选曲目池,标记重复项和可疑版本,并且有意不对主题契合度评分。宿主模型会直接将候选曲目与用户的描述进行比较,并说明它们在播放列表中的作用。 am_analyze_flow 会诊断曲目间的衔接;am_optimize_order 可以选择性地优化已选叙事区块内的排序。它绝不会决定哪些歌曲应加入播放列表。

使用 preset/ 中的模板将其挂载到 Cordis Agent 预设中,或通过以下方式将其接入任何其他 MCP 客户端:

{ "mcpServers": { "applemusic": {
    "command": "python", "args": ["/abs/path/am_mcp_server.py"] } } }

Codex、Claude、Cursor、VS Code/Copilot、Gemini CLI、Windsurf、Docker、Cordis/DSH 和 Harness 的完整测试示例见 docs/client-setup.md。

使用以下命令构建非 root 本地容器:

docker build -t apple-music-playlists:1.5.0 .

客户端必须使用 docker run --rm -i 以附加模式运行容器;只挂载应用配置目录和可写缓存,如客户端指南所示。配置目录必须保持可写,以便持久保存令牌刷新结果。切勿将 Apple 凭据打包进镜像。


测试

python -m unittest discover -s tests -v

整套测试完全离线——无需网络,也无需凭据。分为两类:

  • 行为测试:决定什么才「听起来不错」的纯数学逻辑——Camelot 映射、BPM 折算、弧线分类、分别断言每项邻接惩罚、退火确定性,以及分块顺序约束。六种叙事原型都必须被分类为自身。
  • 结构回归测试,每项都对应一个实际发布过的 bug:没有硬编码目录区域、恰好一个 catalog_meta、--storefront 没有非 None 默认值、缓存位于仓库之外、每个 MCP 工具都连接到处理器,以及优化器不导入平台模块。

这些测试很快就证明了自己的价值——它们在几分钟前才写好的文件尚未运行之前,就发现了其中的语法错误。


有意思的部分:音频特征

Apple 的目录 API 完全不提供音频特征——没有速度、调性、响度、能量或效价。Spotify 的 audio-features 端点已于 2024-11-27 停止向新应用开放,AcousticBrainz 则于 2022 年退役。

playlist_flow.py 借助 Apple 确实会返回的 ISRC,通过一条免费且无需密钥的链路填补这一空白:

Apple Music track  ──►  ISRC
                          │
                          ├─► api.reccobeats.com/v1/track?ids=<ISRC>   → track UUID
                          │        └─► /v1/audio-features?ids=<UUID>
                          │                 → tempo, key, mode, loudness, energy, valence,
                          │                   danceability, acousticness, instrumentalness,
                          │                   liveness, speechiness
                          └─ (fallback) musicbrainz.org ISRC lookup

结果会缓存在本地,因此每个播放列表只需支付一次网络开销。

覆盖率会如实报告,不会悄悄丢弃。 每个使用方都会打印一条漏斗,说明每首曲目为何无法测量:

Audio-feature coverage: 1,395/1,581 usable (88%)
  ·  80 tracks have no ISRC — the feature chain cannot start, so changing sources will not help
  · 106 tracks are not in the current source — switch sources or analyse the audio locally

这一区别正是关键所在。没有 ISRC 意味着链路根本无法启动——更换特征来源也无济于事。未在来源中找到则意味着 ISRC 没问题,更换来源(或在本地分析音频)就能解决。把两者都归为「缺少特征」,就会丢掉唯一能告诉你下一步该怎么做的信息。

这比表面看起来更重要:tempo / key / energy / valence 是邻接规则和弧线唯一能据以采取行动的指标,因此覆盖率决定了排序质量的上限。覆盖率为 60% 时,十个位置中有四个从未参与评估——但成本数字看起来仍然很理想。因此,优化器会在成本行上方打印覆盖率,并在低于 90% 时发出警告。


优化器执行的排序规则

根据 docs/ 中收集的研究整理而成——包括一项由 130 位音乐专业人士对专辑进行排序的 PLOS ONE 研究,以及一项关于情绪自适应音乐排序的随机试验。

硬性相邻规则

  • 不允许两首慢速曲目相邻
  • 避免「仅略微变慢」的衔接(速度下降 0–12% 会让较慢的曲目显得拖沓)
  • 相邻曲目在速度和调性上不能同时相似
  • 不允许没有充分理由的大幅 BPM 跳变(>40%);不允许在调性不兼容时出现突兀的能量变化

这四条规则只有一个定义,位于 playlist_core.check_pair() 中,审核和优化器都会调用它。它们过去分别实现了两次,但两份实现并不一致:审核将低于速度第 25 百分位的曲目称为「慢速」,而优化器使用固定的 100 BPM;此外,审核完全没有检查 BPM 跳变规则。这就相当于工具按一套标准诊断、按另一套标准修复——因此,它报告的计数并不可信。

关于「慢速」阈值的说明。 该阈值是绝对值(100 BPM),而非基于数据得出,这是有意为之:优化器在退火过程中会对同一序列进行数千次评估,而百分位阈值会随着排列变化而漂移,导致成本永远无法稳定下来。代价是,速度普遍较慢的播放列表会将每一对相邻曲目都标记出来——这是实际情况,并非排序失败,报告也会对此作出说明。

全局叙事弧线是可选项。 不指定 --arc 时,优化器只考虑局部相邻关系,不会施加情绪或速度轨迹。宿主 LLM 应从简述中理解自由形式的故事,并在各个分组中保留其顺序;只有当用户明确要求某种曲线时,才使用指定预设。

python playlist_optimize.py stack.json --arc cinderella
python playlist_optimize.py --list-shapes
维度目标
valence、energy、loudness仅在明确指定 --arc 时,采用所选原型
tempo倒 U 形——中段较快,仅在明确指定 --arc 时生效

六种可选形状:rags-to-riches、tragedy、man-in-a-hole、icarus、cinderella、oedipus。目标曲线和审核所归类的形状都来自 playlist_core.ARCHETYPES 中的同一张表。审核仍可能报告播放列表与哪种预设相似;但这种诊断并不意味着该预设是推荐方案或排序目标。

明确请求某种预设时,valence / energy / loudness 会遵循其情绪轨迹,而速度则使用单独的倒 U 形目标。不指定 --arc 时,不会应用这两种全局目标。

弧线成本表示与明确请求的特征曲线之间的距离,并不衡量播放列表的好坏。覆盖范围限制了它所能描述的内容;成本较低既不能凌驾于简述要求之上,也不能证明某个序列听起来更好。

优化器会保留你的分组(乐章 / 时代 / 情绪),只在各个分组内部重新排序,因此即使调整响度,也能保留主题结构。移除分组后,优化器就会自由重排——播放列表可以明显变得「更平滑」,但要以牺牲叙事为代价。

真实运行示例:保留分组时,成本从 104.46 降至 19.41;不分组时则降至 1.28。


调试前值得了解的注意事项

  • 即使从未发送 Accept-Encoding,响应也可能经过 gzip 压缩。 将原始字节解码为 UTF-8 会得到乱码,看起来像是空响应正文。(此问题已在 am_playlist.py 中修复。)
  • DELETE 仅适用于 amp-api.music.apple.com。 对播放列表和资料库歌曲执行删除操作时,文档中记录的主机 api.music.apple.com 会返回 401。
  • 不要向 amp-api 发送 x-apple-client-version,否则会导致 500 错误。
  • 创建播放列表时,也会将其中的曲目添加到资料库。 删除播放列表不会将这些曲目移除。
  • BPM 估算存在倍频歧义(同一首曲目可能估算为 90 或 180)。比较前应将数值折叠到 [70,160);否则,“相邻的两首慢歌”会被多报约 4 倍。
  • 切勿将 "Title - Artist" 直接传给目录搜索——你会得到现场版或重制版录音。请使用空格分隔的形式进行搜索,然后再对不同版本进行评分。
  • 在某个商店的搜索中找不到艺人 ≠ 歌曲在该商店不可用。 请通过 ISRC 查找。
  • 只有创建播放列表的客户端才能修改它——这是 Apple 方面的限制。

更多内容请参阅 docs/apple-music-api-notes.md 和 skill/reference.md。


文档

文档内容
SETUP.en.md凭据:有哪些令牌、如何获取每种令牌、安全说明、故障排除
docs/client-setup.md特定客户端的 MCP、Docker、Cordis/DSH、通用运行框架和 Harness Platform 设置
docs/publishing.md仅供维护者使用的 PyPI 和官方 MCP Registry 发布检查清单
docs/apple-music-api-notes.md令牌模型、端点契约、实测 API 行为、7 种自动化方案评估
docs/how-to-build-a-good-playlist.md策展方法:相邻曲目规律、弧线数据、六种叙事形态、ISO 原则
docs/playlist-curation-survey.md已发布策展指南综述(平台规则、DJ 方法、学术研究结果)
docs/evaluation-signals.md大模型原生策展:直接比较候选曲目、目录依据、可读约束,以及为何标量主题评分不应进入关键路径
docs/natural-language-curation-evidence.md关于宽泛音乐意图、参考与请求错误、意图幻觉、可审查的语言特征,以及可复用验证协议的原始研究
examples/可复现的多语言策展评估:六份高难度需求说明、基准协议、可审计证据、隐私规则,以及不提供黄金曲目列表
docs/algorithm-review.md早期启发式方法的审查边界:哪些决策应交由大模型处理,哪些应由确定性算法保留
docs/platform-adapters.md平台适配器边界:哪些部分与平台无关、适配器必须提供什么,以及在不提供 ISRC 的服务上会出现哪些问题
llms.txt简明的 Agent 可读指南,介绍策展边界和最有用的项目文档
skill/Agent 技能:工作流 + 累积的注意事项列表
CHANGELOG.md发布历史,包括不同版本间的行为变化
preset/用于挂载 MCP 服务的 Cordis Agent 预设模板

完整的简体中文指南请参阅 README_ZH_CN.md。


社区

  • 参与贡献 — 开发工作流、架构边界和评审要求
  • 支持 — 提问、报告 Bug 或提出功能建议的渠道
  • 行为准则 — 参与规范和私密举报渠道
  • 安全政策 — 支持的版本和机密漏洞报告方式

许可证

MIT — 详见 LICENSE。

非官方社区工具,与 Apple 无关联,也未获得 Apple 背书。 个人使用时,请使用自己的 Apple Music 账户;并遵守 Apple 的服务条款。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。