关于 controlling-spotify
通过 Spotify MCP 服务搜索音乐、管理播放列表并控制播放,适用于希望用自然语言操作 Spotify 的用户。内容涵盖凭据配置,以及播放、曲库和播放列表管理。
主要功能
- 01搜索歌曲、专辑、艺人和播放列表
- 02控制播放并将音乐加入队列
- 03创建播放列表并添加曲目
- 04查看播放状态、播放列表和已保存音乐
- 05管理已保存专辑
适用场景
- 01查找歌曲并开始播放
- 02查看当前播放曲目
- 03根据搜索结果创建播放列表
- 04查看最近播放或已保存的曲目
MCP 相关
安装并连接 Spotify MCP 服务,通过其工具搜索音乐、控制播放、访问曲库和管理播放列表。需要 Spotify 凭据;播放控制还要求 Premium 账户和活跃设备。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ oaustegard/ claude-skills --skill controlling-spotify安装后在 Claude Code 中输入/controlling-spotify确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/setup-guide.mdscripts/apply-patch.jsget-refresh-token.jsinstall-mcp-server.sh详细介绍
控制 Spotify
使用 Spotify MCP Server 控制 Spotify 播放、搜索音乐并管理播放列表,拥有完整的用户账户访问权限。
适用场景
在用户提出以下请求时调用此技能:
- 在 Spotify 上播放、暂停或跳过音乐
- 搜索歌曲、专辑、艺术家或播放列表
- 创建或修改播放列表
- 查看当前播放的曲目或播放状态
- 管理 Spotify 音乐库(已保存的曲目、专辑)
- 将歌曲或专辑加入播放队列
前提条件
重要:此技能需要用户提供凭据。用户必须完成一次性设置:
用户一次性设置
-
创建 Spotify Developer Application
- 前往 https://developer.spotify.com/dashboard/
- 创建应用并记下 Client ID 和 Client Secret
- 添加重定向 URI:
http://127.0.0.1:8888/callback
-
获取 Refresh Token
- 用户必须在本地运行辅助脚本(参见
references/setup-guide.md) - 脚本会将 OAuth 代码交换为长期有效的刷新令牌
- 刷新令牌将作为凭据保存到技能配置中
- 用户必须在本地运行辅助脚本(参见
-
配置凭据
- 为此技能添加以下三个凭据:
SPOTIFY_CLIENT_ID:来自 Spotify Developer DashboardSPOTIFY_CLIENT_SECRET:来自 Spotify Developer DashboardSPOTIFY_REFRESH_TOKEN:来自辅助脚本的输出
替代方式:也可以通过 Project Knowledge 文件提供凭据。确保文件包含具有上述键的
.env样式代码块。 - 为此技能添加以下三个凭据:
没有这些凭据,此技能将无法运行。 如果缺少凭据,请按照 references/setup-guide.md 中的详细说明引导用户完成设置。
MCP 服务安装
必须在计算环境中安装 Spotify MCP Server。使用提供的安装脚本,该脚本会负责克隆、修补和构建服务。
# Run the installation script
bash scripts/install-mcp-server.sh
MCP 服务配置
配置 MCP 客户端以连接 Spotify MCP server。请注意用于支持从 Project Knowledge 获取凭据的逻辑。
from mcp import Client
import asyncio
import re
# 1. Try to get credentials from skill configuration
env_vars = {
"SPOTIFY_CLIENT_ID": credentials.get("SPOTIFY_CLIENT_ID"),
"SPOTIFY_CLIENT_SECRET": credentials.get("SPOTIFY_CLIENT_SECRET"),
"SPOTIFY_REFRESH_TOKEN": credentials.get("SPOTIFY_REFRESH_TOKEN")
}
# 2. If missing, look in Project Knowledge / Context for .env style block
if not all(env_vars.values()):
# Heuristic: Scan context/files for VAR=VALUE patterns
# (Pseudo-code: Implement based on available context access)
pass
# Server configuration
mcp_config = {
"command": "node",
"args": ["/home/claude/spotify-mcp-server/build/index.js"],
"env": env_vars
}
# Initialize client
async def initialize_spotify_mcp():
client = Client()
await client.connect_stdio(
mcp_config["command"],
mcp_config["args"],
mcp_config["env"]
)
return client
可用工具
读取操作
-
searchSpotify - 搜索曲目、专辑、艺术家或播放列表
result = await client.call_tool("searchSpotify", { "query": "bohemian rhapsody", "type": "track", "limit": 10 }) -
getNowPlaying - 获取当前播放的曲目信息
result = await client.call_tool("getNowPlaying", {}) -
getMyPlaylists - 列出用户的播放列表
result = await client.call_tool("getMyPlaylists", { "limit": 20, "offset": 0 }) -
getPlaylistTracks - 获取播放列表中的曲目
result = await client.call_tool("getPlaylistTracks", { "playlistId": "37i9dQZEVXcJZyENOWUFo7" }) -
getRecentlyPlayed - 获取最近播放的曲目
result = await client.call_tool("getRecentlyPlayed", { "limit": 10 }) -
getUsersSavedTracks - 获取用户点过赞的歌曲
result = await client.call_tool("getUsersSavedTracks", { "limit": 50, "offset": 0 })
播放控制
-
playMusic - 开始播放曲目/专辑/艺术家/播放列表
# Play by URI result = await client.call_tool("playMusic", { "uri": "spotify:track:6rqhFgbbKwnb9MLmUQDhG6" }) # Or by type and ID result = await client.call_tool("playMusic", { "type": "track", "id": "6rqhFgbbKwnb9MLmUQDhG6" }) -
pausePlayback - 暂停当前播放
result = await client.call_tool("pausePlayback", {}) -
skipToNext - 跳到下一首曲目
result = await client.call_tool("skipToNext", {}) -
skipToPrevious - 跳到上一首曲目
result = await client.call_tool("skipToPrevious", {}) -
addToQueue - 将曲目/专辑加入播放队列
result = await client.call_tool("addToQueue", { "uri": "spotify:track:6rqhFgbbKwnb9MLmUQDhG6" })
播放列表管理
-
createPlaylist - 创建新的播放列表
result = await client.call_tool("createPlaylist", { "name": "My Workout Mix", "description": "High energy tracks", "public": False }) -
addTracksToPlaylist - 将曲目添加到现有播放列表
result = await client.call_tool("addTracksToPlaylist", { "playlistId": "3cEYpjA9oz9GiPac4AsH4n", "trackUris": [ "spotify:track:4iV5W9uYEdYUVa79Axb7Rh", "spotify:track:6rqhFgbbKwnb9MLmUQDhG6" ] })
专辑操作
-
getAlbums - 获取专辑详情
result = await client.call_tool("getAlbums", { "albumIds": ["4aawyAB9vmqN3uQ7FjRGTy"] }) -
getAlbumTracks - 获取专辑中的曲目
result = await client.call_tool("getAlbumTracks", { "albumId": "4aawyAB9vmqN3uQ7FjRGTy" }) -
saveOrRemoveAlbumForUser - 保存/移除专辑
result = await client.call_tool("saveOrRemoveAlbumForUser", { "albumIds": ["4aawyAB9vmqN3uQ7FjRGTy"], "action": "save" })
工作流示例
示例 1:播放用户喜爱的歌曲
# 1. Search for the song
search_result = await client.call_tool("searchSpotify", {
"query": "user's favorite song name",
"type": "track",
"limit": 1
})
# 2. Extract track URI from results
track_uri = search_result["tracks"][0]["uri"]
# 3. Play the track
await client.call_tool("playMusic", {
"uri": track_uri
})
示例 2:按音乐流派创建播放列表
# 1. Search for tracks in genre
search_result = await client.call_tool("searchSpotify", {
"query": "genre:rock year:2020-2024",
"type": "track",
"limit": 20
})
# 2. Create new playlist
playlist_result = await client.call_tool("createPlaylist", {
"name": "Modern Rock Mix",
"description": "Recent rock tracks",
"public": False
})
# 3. Extract track URIs
track_uris = [track["uri"] for track in search_result["tracks"]]
# 4. Add tracks to playlist
await client.call_tool("addTracksToPlaylist", {
"playlistId": playlist_result["id"],
"trackUris": track_uris
})
示例 3:显示正在播放的内容
# Get current playback state
now_playing = await client.call_tool("getNowPlaying", {})
# Format and display
print(f"Now Playing: {now_playing['track']['name']}")
print(f"Artist: {now_playing['track']['artists'][0]['name']}")
print(f"Album: {now_playing['track']['album']['name']}")
print(f"Progress: {now_playing['progress_ms']} / {now_playing['duration_ms']} ms")
重要说明
需要 Spotify Premium
播放控制操作(播放、暂停、跳过、加入队列)需要 Spotify Premium。读取操作(搜索、获取播放列表、查看曲目)可使用免费账户。
需要活动设备
要使播放命令生效,用户必须拥有一个活动的 Spotify 会话(网页播放器、桌面应用、移动应用),且有可用设备。如果没有活动设备,播放命令将会失败。
速率限制
Spotify API 有速率限制(通常为每分钟 180 次请求)。对于批量操作,请设置适当的延迟或分批处理。
令牌安全
- 刷新令牌授予对用户 Spotify 账户的完全访问权限
- 切勿记录或泄露刷新令牌
- 按照密码的安全级别保护刷新令牌
- 用户可以在 https://www.spotify.com/account/apps/ 撤销令牌
URI 格式
Spotify 使用以下格式的 URI:
- 曲目:
spotify:track:ID - 专辑:
spotify:album:ID - 艺术家:
spotify:artist:ID - 播放列表:
spotify:playlist:ID
大多数工具接受 URI,也接受单独的 type + id 参数。
故障排除
“未找到 Spotify 配置”
原因:缺少环境变量
解决方案:确认凭据已正确配置:
import os
print(os.getenv("SPOTIFY_CLIENT_ID")) # Should not be None
print(os.getenv("SPOTIFY_CLIENT_SECRET")) # Should not be None
print(os.getenv("SPOTIFY_REFRESH_TOKEN")) # Should not be None
“没有活动设备”
原因:当前没有正在运行或处于活动状态的 Spotify 客户端
解决方案:指导用户:
- 在任意设备(网页、桌面或移动设备)上打开 Spotify
- 开始播放内容(可立即暂停)
- 再次尝试播放命令
“需要 Premium”
原因:用户使用的是 Spotify Free 账户
解决方案:播放控制需要 Spotify Premium。免费账户只能使用搜索和读取操作。
MCP 服务无法启动
原因:缺少依赖项或安装不正确
解决方案:
# Re-run installation script
bash scripts/install-mcp-server.sh
最佳实践
- 播放前务必先搜索 - 不要假定 URI,先搜索内容
- 检查播放状态 - 使用
getNowPlaying确认设备是否可用 - 妥善处理错误 - 操作失败时提供有用的提示信息
- 批量操作 - 添加多首曲目时,使用单次调用并传入数组
- 遵守速率限制 - 批量操作时添加延迟
参考资料
- 设置指南:
references/setup-guide.md - API 文档:https://developer.spotify.com/documentation/web-api/
- MCP 规范:https://modelcontextprotocol.io/
安全
此技能需要敏感凭据。请确保:
- 凭据安全地存储在技能配置中
- 切勿在回复用户时泄露凭据
- 切勿记录凭据
- 用户了解自己随时可以撤销访问权限
详细的安全最佳实践请参阅 references/setup-guide.md。