mcpField
C
controlling-spotify

controlling-spotify

github.com/oaustegard其他15748 次安装1 天前更新
代码仓库

关于 controlling-spotify

通过 Spotify MCP 服务搜索音乐、管理播放列表并控制播放,适用于希望用自然语言操作 Spotify 的用户。内容涵盖凭据配置,以及播放、曲库和播放列表管理。

主要功能

  1. 01搜索歌曲、专辑、艺人和播放列表
  2. 02控制播放并将音乐加入队列
  3. 03创建播放列表并添加曲目
  4. 04查看播放状态、播放列表和已保存音乐
  5. 05管理已保存专辑

适用场景

  1. 01查找歌曲并开始播放
  2. 02查看当前播放曲目
  3. 03根据搜索结果创建播放列表
  4. 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.md
scripts/
apply-patch.js
get-refresh-token.js
install-mcp-server.sh

详细介绍

控制 Spotify

使用 Spotify MCP Server 控制 Spotify 播放、搜索音乐并管理播放列表,拥有完整的用户账户访问权限。

适用场景

在用户提出以下请求时调用此技能:

  • 在 Spotify 上播放、暂停或跳过音乐
  • 搜索歌曲、专辑、艺术家或播放列表
  • 创建或修改播放列表
  • 查看当前播放的曲目或播放状态
  • 管理 Spotify 音乐库(已保存的曲目、专辑)
  • 将歌曲或专辑加入播放队列

前提条件

重要:此技能需要用户提供凭据。用户必须完成一次性设置:

用户一次性设置
  1. 创建 Spotify Developer Application

  2. 获取 Refresh Token

    • 用户必须在本地运行辅助脚本(参见 references/setup-guide.md)
    • 脚本会将 OAuth 代码交换为长期有效的刷新令牌
    • 刷新令牌将作为凭据保存到技能配置中
  3. 配置凭据

    • 为此技能添加以下三个凭据:
      • SPOTIFY_CLIENT_ID:来自 Spotify Developer Dashboard
      • SPOTIFY_CLIENT_SECRET:来自 Spotify Developer Dashboard
      • SPOTIFY_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

可用工具

读取操作
  1. searchSpotify - 搜索曲目、专辑、艺术家或播放列表

    result = await client.call_tool("searchSpotify", {
        "query": "bohemian rhapsody",
        "type": "track",
        "limit": 10
    })
    
  2. getNowPlaying - 获取当前播放的曲目信息

    result = await client.call_tool("getNowPlaying", {})
    
  3. getMyPlaylists - 列出用户的播放列表

    result = await client.call_tool("getMyPlaylists", {
        "limit": 20,
        "offset": 0
    })
    
  4. getPlaylistTracks - 获取播放列表中的曲目

    result = await client.call_tool("getPlaylistTracks", {
        "playlistId": "37i9dQZEVXcJZyENOWUFo7"
    })
    
  5. getRecentlyPlayed - 获取最近播放的曲目

    result = await client.call_tool("getRecentlyPlayed", {
        "limit": 10
    })
    
  6. getUsersSavedTracks - 获取用户点过赞的歌曲

    result = await client.call_tool("getUsersSavedTracks", {
        "limit": 50,
        "offset": 0
    })
    
播放控制
  1. 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"
    })
    
  2. pausePlayback - 暂停当前播放

    result = await client.call_tool("pausePlayback", {})
    
  3. skipToNext - 跳到下一首曲目

    result = await client.call_tool("skipToNext", {})
    
  4. skipToPrevious - 跳到上一首曲目

    result = await client.call_tool("skipToPrevious", {})
    
  5. addToQueue - 将曲目/专辑加入播放队列

    result = await client.call_tool("addToQueue", {
        "uri": "spotify:track:6rqhFgbbKwnb9MLmUQDhG6"
    })
    
播放列表管理
  1. createPlaylist - 创建新的播放列表

    result = await client.call_tool("createPlaylist", {
        "name": "My Workout Mix",
        "description": "High energy tracks",
        "public": False
    })
    
  2. addTracksToPlaylist - 将曲目添加到现有播放列表

    result = await client.call_tool("addTracksToPlaylist", {
        "playlistId": "3cEYpjA9oz9GiPac4AsH4n",
        "trackUris": [
            "spotify:track:4iV5W9uYEdYUVa79Axb7Rh",
            "spotify:track:6rqhFgbbKwnb9MLmUQDhG6"
        ]
    })
    
专辑操作
  1. getAlbums - 获取专辑详情

    result = await client.call_tool("getAlbums", {
        "albumIds": ["4aawyAB9vmqN3uQ7FjRGTy"]
    })
    
  2. getAlbumTracks - 获取专辑中的曲目

    result = await client.call_tool("getAlbumTracks", {
        "albumId": "4aawyAB9vmqN3uQ7FjRGTy"
    })
    
  3. 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 客户端

解决方案:指导用户:

  1. 在任意设备(网页、桌面或移动设备)上打开 Spotify
  2. 开始播放内容(可立即暂停)
  3. 再次尝试播放命令
“需要 Premium”

原因:用户使用的是 Spotify Free 账户

解决方案:播放控制需要 Spotify Premium。免费账户只能使用搜索和读取操作。

MCP 服务无法启动

原因:缺少依赖项或安装不正确

解决方案:

# Re-run installation script
bash scripts/install-mcp-server.sh

最佳实践

  1. 播放前务必先搜索 - 不要假定 URI,先搜索内容
  2. 检查播放状态 - 使用 getNowPlaying 确认设备是否可用
  3. 妥善处理错误 - 操作失败时提供有用的提示信息
  4. 批量操作 - 添加多首曲目时,使用单次调用并传入数组
  5. 遵守速率限制 - 批量操作时添加延迟

参考资料

安全

此技能需要敏感凭据。请确保:

  • 凭据安全地存储在技能配置中
  • 切勿在回复用户时泄露凭据
  • 切勿记录凭据
  • 用户了解自己随时可以撤销访问权限

详细的安全最佳实践请参阅 references/setup-guide.md。

评论

支持 Markdown