# Spotify

> Hermes 通过插件目录中的官方 spotify 插件控制 Spotify——播放、队列、搜索、播放列表、已保存的曲目/专辑以及收听历史——基于 Spotify 官方 Web API 配合 PKCE OAuth 实现。

- 网址：https://funcoding.ai/agents/hermes-agent/user-guide/features/spotify/
- 来源：Hermes Agent 官方文档原文（中文），MIT 许可，同步于 2026-10-11
- 官方原文：https://hermes-agent.nousresearch.com/docs/zh-Hans/user-guide/features/spotify

---
Hermes 通过[插件目录](https://funcoding.ai/agents/hermes-agent/user-guide/features/plugins/)中的官方 **`spotify` 插件**控制 Spotify——播放、队列、搜索、播放列表、已保存的曲目/专辑以及收听历史——基于 Spotify 官方 Web API 配合 PKCE OAuth 实现。该插件由 Nous Research 在 [NousResearch/hermes-official-plugins](https://github.com/NousResearch/hermes-official-plugins/tree/main/spotify) 维护，不属于 Hermes 核心。Token（令牌）存储在 `~/.hermes/auth.json` 中，遇到 401 时自动刷新；每台机器只需登录一次。

与 Hermes 内置的 OAuth 集成不同，Spotify 要求每位用户自行注册一个轻量级开发者应用。Spotify 不允许第三方发布可供所有人使用的公共 OAuth 应用。整个过程大约需要两分钟，`hermes spotify login` 会全程引导你完成。

## 安装

```bash
hermes plugins install spotify
```

插件按 profile 安装。若要在其他 profile 中使用 Spotify，请在该 profile 中同样安装（`hermes -p <profile> plugins install spotify`）。

<div class="callout callout-note">

**从内置 Spotify 的版本升级**

无需任何操作。所有已在使用 Spotify 的 profile（`auth.json` 中存有 Spotify 登录，或 `platform_toolsets` 中列出了 `spotify` 工具集）都会由 `hermes update` 自动从插件目录安装该插件；若该步骤未能运行，则在该 profile 首次启动时安装（遵循 `security.allow_lazy_installs`）。你的登录、`spotify` 工具集和工具名称都保持不变。唯一可见的变化：`hermes auth spotify` 改为 `hermes spotify login`（`hermes auth status spotify` / `hermes auth logout spotify` 改为 `hermes spotify status` / `hermes spotify logout`）；旧写法会打印新命令。若之后移除插件（`hermes plugins remove spotify`），它将保持移除状态。

</div>

## 前提条件

- 一个 Spotify 账号。**免费版**可使用搜索、播放列表、音乐库和活动工具。**Premium 版**才能使用播放控制（播放、暂停、跳曲、定位、音量、添加队列、切换设备）。
- 已安装并运行 Hermes Agent。
- 使用播放工具时：需要一个**活跃的 Spotify Connect 设备**——至少一台设备（手机、桌面端、网页播放器、音箱）上必须打开 Spotify 应用，Web API 才有对象可控制。若无活跃设备，将收到 `403 Forbidden` 并提示"no active device"；在任意设备上打开 Spotify 后重试即可。

## 设置

### 1. 启用工具集

插件的 `spotify` 工具集默认关闭，以避免不需要它的用户在每次 API 调用时额外传输工具 schema。在 `hermes tools` 中启用（选中 `🔌 Spotify` 后保存），或运行：

```bash
hermes tools enable spotify
```

### 2. 登录

```bash
hermes spotify login
```

7 个 Spotify 工具只有在登录后才会提供给 agent。

若未设置 `HERMES_SPOTIFY_CLIENT_ID`，Hermes 会内联引导你完成应用注册：

1. 在浏览器中打开 `https://developer.spotify.com/dashboard`
2. 打印需要粘贴到 Spotify "Create app" 表单中的确切值
3. 提示你输入获得的 Client ID
4. 将其保存到 `~/.hermes/.env`，后续运行时跳过此步骤
5. 直接进入 OAuth 授权流程

授权完成后，token 将写入 `~/.hermes/auth.json` 的 `providers.spotify` 下。当前推理提供商不会改变——Spotify 认证与你的 LLM 提供商无关。

### 创建 Spotify 应用（向导所需内容）

当 dashboard 打开后，点击 **Create app** 并填写：

| 字段 | 值 |
|-------|-------|
| App name | 任意（例如 `hermes-agent`） |
| App description | 任意（例如 `personal Hermes integration`） |
| Website | 留空 |
| Redirect URI | `http://127.0.0.1:43827/spotify/callback` |
| Which API/SDKs? | 勾选 **Web API** |

同意条款并点击 **Save**。在下一页点击 **Settings** → 复制 **Client ID** 并粘贴到 Hermes 提示中。这是 Hermes 唯一需要的值——PKCE 不使用 client secret。

### 通过 SSH / 在无头环境中运行

若设置了 `SSH_CLIENT` 或 `SSH_TTY`，Hermes 在向导和 OAuth 步骤中均会跳过自动打开浏览器。复制 Hermes 打印的 dashboard URL 和授权 URL，在本地机器的浏览器中打开，然后正常操作——本地 HTTP 监听器仍在远程主机的 `43827` 端口运行。你的笔记本浏览器无法直接访问远程回环地址，需要通过 SSH 本地端口转发：

```bash
ssh -N -L 43827:127.0.0.1:43827 user@remote-host
```

关于跳板机/堡垒机设置及其他注意事项（mosh、tmux、端口冲突），请参阅 [OAuth over SSH / Remote Hosts](https://funcoding.ai/agents/hermes-agent/guides/oauth-over-ssh/)。

## 验证

```bash
hermes spotify status
```

显示 token 是否存在以及 access token 的过期时间。刷新是自动的：当任何 Spotify API 调用返回 401 时，客户端会用 refresh token 换取新 token 并重试一次。Refresh token 在 Hermes 重启后仍然有效，只有在你的 Spotify 账号设置中撤销该应用，或运行 `hermes spotify logout` 后才需要重新认证。

## 使用方法

登录后，agent 可访问 7 个 Spotify 工具。你用自然语言与 agent 交流——它会选择正确的工具和操作。为获得最佳效果，agent 会加载一个配套技能，教授规范的使用模式（先搜索再播放、何时不需要预先调用 `get_state` 等）。

```
> play some miles davis
> what am I listening to
> add this track to my Late Night Jazz playlist
> skip to the next song
> make a new playlist called "Focus 2026" and add the last three songs I played
> which of my saved albums are by Radiohead
> search for acoustic covers of Blackbird
> transfer playback to my kitchen speaker
```

### 工具参考

所有会修改播放状态的操作都接受可选的 `device_id` 参数以指定目标设备。若省略，Spotify 将使用当前活跃设备。

#### `spotify_playback`
控制和查看播放状态，以及获取最近播放历史。

| 操作 | 用途 | 需要 Premium？ |
|--------|---------|----------|
| `get_state` | 完整播放状态（曲目、设备、进度、随机/循环） | 否 |
| `get_currently_playing` | 仅当前曲目（204 时返回空——见下文） | 否 |
| `play` | 开始/恢复播放。可选：`context_uri`、`uris`、`offset`、`position_ms` | 是 |
| `pause` | 暂停播放 | 是 |
| `next` / `previous` | 跳曲 | 是 |
| `seek` | 跳转到 `position_ms` | 是 |
| `set_repeat` | `state` = `track` / `context` / `off` | 是 |
| `set_shuffle` | `state` = `true` / `false` | 是 |
| `set_volume` | `volume_percent` = 0-100 | 是 |
| `recently_played` | 最近播放的曲目。可选 `limit`、`before`、`after`（Unix 毫秒） | 否 |

#### `spotify_devices`
| 操作 | 用途 |
|--------|---------|
| `list` | 你账号下所有可见的 Spotify Connect 设备 |
| `transfer` | 将播放切换到 `device_id`。可选 `play: true` 在切换时立即开始播放 |

### Home Assistant 管理的音箱

如果 Home Assistant 管理的音箱本身支持 Spotify Connect（例如 Sonos、Echo、Nest 或其他支持 Connect 的音箱），只要 Spotify 能识别它们，它们就会自动出现在 `spotify_devices list` 中。Hermes 不需要 Home Assistant ↔ Spotify 桥接——Spotify 原生处理设备路由。

通过音箱的显示名称让 Hermes 切换播放（例如"transfer Spotify to the kitchen speaker"），或在脚本中调用 `spotify_devices list` 获取确切的 `device_id` 后传给 `spotify_devices transfer`。若音箱未出现，请在 Spotify 应用或音箱的 Spotify 集成中打开一次，让 Spotify 将其注册为活跃的 Connect 目标。

#### `spotify_queue`
| 操作 | 用途 | 需要 Premium？ |
|--------|---------|----------|
| `get` | 当前队列中的曲目 | 否 |
| `add` | 将 `uri` 追加到队列 | 是 |

#### `spotify_search`
搜索曲库。`query` 为必填项。可选：`types`（`track` / `album` / `artist` / `playlist` / `show` / `episode` 的数组）、`limit`、`offset`、`market`。

#### `spotify_playlists`
| 操作 | 用途 | 必填参数 |
|--------|---------|---------------|
| `list` | 用户的播放列表 | — |
| `get` | 单个播放列表及其曲目 | `playlist_id` |
| `create` | 新建播放列表 | `name`（可选 `description`、`public`、`collaborative`） |
| `add_items` | 添加曲目 | `playlist_id`、`uris`（可选 `position`） |
| `remove_items` | 移除曲目 | `playlist_id`、`uris`（可选 `snapshot_id`） |
| `update_details` | 重命名/编辑 | `playlist_id` + `name`、`description`、`public`、`collaborative` 中的任意项 |

#### `spotify_albums`
| 操作 | 用途 | 必填参数 |
|--------|---------|---------------|
| `get` | 专辑元数据 | `album_id` |
| `tracks` | 专辑曲目列表 | `album_id` |

#### `spotify_library`
统一访问已保存的曲目和专辑。通过 `kind` 参数选择集合类型。

| 操作 | 用途 |
|--------|---------|
| `list` | 分页列出音乐库 |
| `save` | 将 `ids` / `uris` 添加到音乐库 |
| `remove` | 从音乐库移除 `ids` / `uris` |

必填：`kind` = `tracks` 或 `albums`，以及 `action`。

### 功能矩阵：免费版 vs Premium 版

只读工具在免费账号上可用。任何修改播放状态或队列的操作都需要 Premium。

| 免费版可用 | 需要 Premium |
|---------------|------------------|
| `spotify_search`（全部） | `spotify_playback` — play、pause、next、previous、seek、set_repeat、set_shuffle、set_volume |
| `spotify_playback` — get_state、get_currently_playing、recently_played | `spotify_queue` — add |
| `spotify_devices` — list | `spotify_devices` — transfer |
| `spotify_queue` — get | |
| `spotify_playlists`（全部） | |
| `spotify_albums`（全部） | |
| `spotify_library`（全部） | |

## 定时任务：Spotify + cron

由于 Spotify 工具是普通的 Hermes 工具，在 Hermes 会话中运行的 cron 任务可以按任意计划触发播放，无需编写额外代码。

### 早晨唤醒播放列表

```bash
hermes cron add \
  --name "morning-commute" \
  "0 7 * * 1-5" \
  "Transfer playback to my kitchen speaker and start my 'Morning Commute' playlist. Volume to 40. Shuffle on."
```

每个工作日早上 7 点发生的事情：
1. Cron 启动一个无头 Hermes 会话。
2. Agent 读取 prompt（提示词），调用 `spotify_devices list` 按名称找到"kitchen speaker"，然后依次调用 `spotify_devices transfer` → `spotify_playback set_volume` → `spotify_playback set_shuffle` → `spotify_search` + `spotify_playback play`。
3. 音乐在目标音箱上开始播放。总计：一个会话，几次工具调用，无需人工干预。

### 夜间收尾

```bash
hermes cron add \
  --name "wind-down" \
  "30 22 * * *" \
  "Pause Spotify. Then set volume to 20 so it's quiet when I start it again tomorrow."
```

### 注意事项

- **cron 触发时必须存在活跃设备。** 若没有 Spotify 客户端在运行（手机/桌面端/Connect 音箱），播放操作将返回 `403 no active device`。对于早晨播放列表，建议指定一个始终开机的设备（Sonos、Echo、智能音箱），而非手机。
- **任何修改播放状态的操作都需要 Premium**——播放、暂停、跳曲、音量、切换设备。只读 cron 任务（例如定时"发送我最近播放的曲目"）在免费版上可正常使用。
- **cron agent 继承你的活跃工具集。** Spotify 必须在 `hermes tools` 中启用，cron 会话才能看到 Spotify 工具。
- **Cron 任务以 `skip_memory=True` 运行**，不会写入你的记忆存储。

完整 cron 参考：[Cron Jobs](https://funcoding.ai/agents/hermes-agent/user-guide/features/cron/)。

## 退出登录

```bash
hermes spotify logout
```

从 `~/.hermes/auth.json` 中移除 token。若还需清除应用配置，请从 `~/.hermes/.env` 中删除 `HERMES_SPOTIFY_CLIENT_ID`（以及 `HERMES_SPOTIFY_REDIRECT_URI`，如果你设置了的话），或重新运行向导。

若要在 Spotify 侧撤销应用，请访问[已连接到你账号的应用](https://www.spotify.com/account/apps/)并点击 **REMOVE ACCESS**。

## 故障排查

**`403 Forbidden — Player command failed: No active device found`** — 你需要在至少一台设备上运行 Spotify。在手机、桌面端或网页播放器上打开 Spotify 应用，随便播放一首曲目以注册设备，然后重试。`spotify_devices list` 可显示当前可见的设备。

**`403 Forbidden — Premium required`** — 你使用的是免费账号，但尝试执行需要 Premium 的播放操作。请参阅上方的功能矩阵。

**`get_currently_playing` 返回 `204 No Content`** — 当前所有设备上均无内容播放。这是 Spotify 的正常响应，不是错误；Hermes 将其呈现为说明性的空结果（`is_playing: false`）。

**`INVALID_CLIENT: Invalid redirect URI`** — 你的 Spotify 应用设置中的 redirect URI 与 Hermes 使用的不匹配。默认值为 `http://127.0.0.1:43827/spotify/callback`。请将其添加到应用的允许 redirect URI 列表中，或在 `~/.hermes/.env` 中将 `HERMES_SPOTIFY_REDIRECT_URI` 设置为你注册的值。

**`429 Too Many Requests`** — Spotify 的速率限制。Hermes 会返回友好的错误提示；等待一分钟后重试。若持续出现，你可能在脚本中运行了紧密循环——Spotify 的配额大约每 30 秒重置一次。

**`401 Unauthorized` 持续出现** — 你的 refresh token 已被撤销（通常是因为你从账号中移除了该应用，或应用被删除）。重新运行 `hermes spotify login`。

**向导未打开浏览器** — 若你通过 SSH 连接或在没有显示器的容器中运行，Hermes 会检测到并跳过自动打开。复制它打印的 dashboard URL 并手动打开。

## 进阶：自定义 scope

默认情况下，Hermes 会请求所有已发布工具所需的 scope。若需限制访问权限，可覆盖默认值：

```bash
hermes spotify login --scope "user-read-playback-state user-modify-playback-state playlist-read-private"
```

Scope 参考：[Spotify Web API scopes](https://developer.spotify.com/documentation/web-api/concepts/scopes)。若请求的 scope 少于某个工具所需，该工具的调用将以 403 失败。

## 进阶：自定义 client ID / redirect URI

```bash
hermes spotify login --client-id <id> --redirect-uri http://localhost:3000/callback
```

或在 `~/.hermes/.env` 中永久设置：

```
HERMES_SPOTIFY_CLIENT_ID=<your_id>
HERMES_SPOTIFY_REDIRECT_URI=http://localhost:3000/callback
```

Redirect URI 必须在你的 Spotify 应用设置中加入白名单。默认值适用于绝大多数情况——只有在 43827 端口被占用时才需要更改。

## 文件位置

| 文件 | 内容 |
|------|----------|
| `~/.hermes/auth.json` → `providers.spotify` | access token、refresh token、过期时间、scope、redirect URI |
| `~/.hermes/.env` | `HERMES_SPOTIFY_CLIENT_ID`，可选 `HERMES_SPOTIFY_REDIRECT_URI` |
| Spotify 应用 | 由你在 [developer.spotify.com/dashboard](https://developer.spotify.com/dashboard) 管理；包含 Client ID 和 redirect URI 白名单 |
