关于 hum
hum 是可由编码 Agent 通过 MCP 控制的浏览器音乐播放器,音乐在 hum 浏览器标签页中播放。它整合歌曲搜索、情绪电台、Spotify 链接导入、同步歌词,以及无需账户的曲库和可选加密同步。
主要功能
- 01搜索歌曲并导入 Spotify 链接
- 02情绪电台与自动播放混音
- 03同步歌词和喜欢的歌曲
- 04免账户曲库同步与备份
- 05Agent 控制播放与音量
适用场景
- 01编码时播放音乐
- 02启动符合心情的背景电台
- 03通过编码 Agent 控制播放
- 04在设备间同步音乐曲库
MCP 相关
MCP 服务让兼容的 Agent 控制浏览器标签页中运行的 hum 播放器:播放歌曲、启动电台、导入 Spotify 链接、切歌、调节音量,并查询当前歌曲和歌词行。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
hum
聆听所有已发行的歌曲,免费畅享;播放器带来如同置身于专辑封面灯光营造的房间般的体验。
- 搜索任意歌曲,或粘贴 Spotify 歌单、专辑或曲目链接(也可以在任意位置按 ⌘V)。
- 点按一个电台,它就会一直播放相应氛围的音乐。
- 歌词与音乐同步、无限自动播放混音、收藏歌曲,还能分享歌曲链接。
- 无需账号,也无需密钥。你的音乐库保存在浏览器中;借助同步,无需账号也能在不同设备间同步。
播放通过 YouTube 官方嵌入式播放器进行,因此广告和版税照常运作,艺人也能获得报酬。
运行
一条命令(Node 18+)。启动 hum 并在浏览器中打开:
npx github:anzal1/hum
从克隆的仓库运行:
node server.js
Docker(家用服务器、VPS、NAS):
docker build -t hum . && docker run -p 3737:3737 hum
免费部署到线上
hum 由一组静态文件和一个小型函数组成,因此适合 Cloudflare Workers 的免费套餐:静态文件数量不限,每天还包含 100,000 次搜索。
- **一键部署:**使用
/developers.html上的 Deploy to Cloudflare 按钮,或访问https://deploy.workers.cloudflare.com/?url=https://github.com/anzal1/hum - 从此文件夹部署:
npx wrangler deploy
Vercel 也可使用(api/ 和 vercel.json 已就绪),但其免费套餐仅供非商业用途。
已测试:node server.js、从打包的 tarball 运行 npx、Docker,以及 Cloudflare 自带的本地运行时(npx wrangler dev)。四种方式下的所有路由均有响应。
同步你的资料库
你的喜欢内容、播放列表和历史记录通常只保存在一个浏览器中,因此清除网站数据会导致它们丢失,而在第二台设备上则会从空白开始。同步无需账户、电子邮件或登录即可解决这个问题。
使用方法。 打开主页,找到 你的资料库,按下 同步,然后选择 开启同步。你会获得一个类似 W6R1-BA1V-1BME-RGNM-GRTQ-X2PG-J8EG 的代码和一个复制按钮。在另一台设备(或本地 hum)上,按下 同步,选择 使用同步代码,然后输入代码。校验和会在操作开始前检查是否有拼写错误。关闭同步会在该设备上停止同步,并保留该设备上的资料库。同一面板中的 导出资料库 和 导入 会生成一个可在任何地方恢复的 JSON 备份;导入会将内容添加到现有资料中,绝不会替换它们。
同步内容。 liked、playlists、recent,以及存在时的 taste 和 variants 值。音量、随机播放、当前队列和布局按设备分别保存。
工作原理。
- 代码由浏览器生成,包含 128 位随机数据(外加 8 位校验和)。
- WebCrypto 使用 HKDF 将其转换为两个互不相关的内容:记录 ID 和 AES-256-GCM 密钥。密钥绝不会离开页面。
- 资料库会经过压缩和加密,然后作为一个数据块发送。服务器能看到 ID、密文、数据大小和更改时间,但看不到代码、密钥或任何歌曲名称。数据块还与其 ID 绑定,因此无法将其替换到另一个 ID 下。
- 拉取时会合并而非覆盖:喜欢内容和播放列表会取并集,播放列表以最新编辑为准,删除操作会以墓碑形式同步,因此仍保留旧副本的设备不会撤销删除;历史记录按播放时间合并(保留 30 条),
taste则取每个计数器和时间戳的最大值。绝不会为了腾出空间而丢弃本地数据。 - 更改后约 5 秒会推送,且每 30 秒最多推送一次。hum 会在加载时、窗口获得焦点时,以及页面可见期间每分钟拉取一次,且频率不会超过每分钟一次。每次写入都会注明其所依据的版本;如果另一台设备先完成写入,hum 就会拉取、合并并重试。
隐私与限制。
- 任何拥有代码的人都可以读取和更改你的资料库;代码丢失后无人能够找回。请将其保存在密码管理器中。
- 为了运行同步,代码会存储在浏览器的 localStorage 中(键
hum:sync),因此任何能访问你的浏览器配置文件的人都能看到它。关闭同步会将其移除。 - 关闭同步不会删除服务器上的加密副本。没有代码,它只是一段无法读取的乱码。
- 服务器能看到某个 ID 是否存在以及写入时间。它可以拒绝服务或提供较早的密文,但无法读取或伪造你的数据。
- 数据块上限为 512 KB(由于经过压缩,大约可存储 5,000 首喜欢的歌曲);服务器每 10 秒接受每个 ID 一次写入。
本地 hum 和网站共用一个资料库。 它们属于不同源,因此无法共用浏览器存储,但本地服务器(node server.js、npx github:anzal1/hum)默认会将 /api/sync 转发到 https://hum.anzalabidi.dev/api/sync。在两处输入相同的代码,它们就会保持同步。代理只会传递密文。
| 变量 | 作用 |
|---|---|
HUM_SYNC_URL | 要转发到的同步服务器,例如你自己的 Worker:https://hum.you.workers.dev/api/sync。 |
HUM_SYNC=off | 此本地服务器不启用同步。此时面板只提供导出和导入。 |
在 Cloudflare D1 上自托管同步。 同步需要绑定为 SYNC 的 D1 数据库。未绑定数据库时,各路由会返回 501,页面只提供导出和导入,其他一切照常运行。
npx wrangler d1 create hum-sync # copy the database_id it prints
# add to wrangler.jsonc, at the top level:
# "d1_databases": [{ "binding": "SYNC", "database_name": "hum-sync", "database_id": "<yours>", "migrations_dir": "migrations" }]
npx wrangler d1 migrations apply hum-sync --remote
npx wrangler deploy
env.production 下方的代码块使用的是官方网站的数据库;请保留它或替换为你自己的数据库。若要在本地试用:npx wrangler d1 migrations apply hum-sync --local && npx wrangler dev --local。该表每个资料库对应一行:migrations/0001_blobs.sql 中的 blobs(id, data, version, updated)。
将 hum 嵌入你的应用
只需添加一个脚本标签,即可在任何页面添加悬浮播放器:
<script src="https://YOUR-HUM-HOST/embed.js" data-station="lofi beats"></script>
然后通过代码控制它:hum.play('Blinding Lights')、hum.station('deep focus')、hum.playlist(spotifyUrl)、hum.pause()、hum.next()、hum.volume(60)、hum.on('state', fn)。也可以直接使用 iframe:widget.html?station=lofi 和 postMessage({ hum: 'play', query })。在线演示见 /developers.html。
在你的编码 Agent 中
hum 适用于任何支持 MCP 的 Agent。你的 Agent 就是遥控器,音乐则在 hum 浏览器标签页中播放。它可以播放歌曲、启动电台、导入 Spotify 链接、切歌、调节音量,还能告诉你正在播放什么,精确到当前唱到的歌词。需要 Node 18+。
claude mcp add --scope user hum -- npx -y -p github:anzal1/hum hum-mcp
VS Code:
code --add-mcp '{"name":"hum","type":"stdio","command":"npx","args":["-y","-p","github:anzal1/hum","hum-mcp"]}'
Claude Desktop(一键扩展)、Cursor(安装链接)、Codex、Gemini CLI、Windsurf、Zed、Copilot CLI、opencode、Cline、Kiro、Amp、Goose 和 Continue 均见 docs/agents.md。
从终端使用
安装一次后,需要时这些命令会启动 hum 并为你打开它。
npm i -g github:anzal1/hum
hum play blinding lights # a song or artist
hum station lofi beats # an endless mix
hum playlist <spotify link>
hum pause | resume | toggle | next | prev
hum vol 40
hum duck # lower the music; hum unduck brings it back
hum now # title, artist, progress and the line being sung
hum now --line 会为状态栏打印一行简短状态;hum 未运行时则不输出任何内容:♪ Amazing Grace · Judy Collins · I once was lost, but now I am found。它不会启动 hum,约 30 ms 即可返回。hum now --json 适用于脚本。
在 tmux 中(~/.tmux.conf):
set -g status-right '#(hum now --line)'
set -g status-interval 2
在 Claude Code 中(~/.claude/settings.json):
"statusLine": { "type": "command", "command": "hum now --line" }
其他程序都可以向本地远程服务发送 POST 请求;它只监听 127.0.0.1,且只接受 JSON:
curl -X POST localhost:3737/api/remote -H 'content-type: application/json' -d '{"cmd":"station","mood":"lofi"}'
播放始终通过 YouTube 自带的播放器在 hum 窗口中进行,因此请保持窗口打开。终端充当遥控器和显示器。HUM_PORT 用于指定其他端口,HUM_NO_OPEN=1 则阻止其打开浏览器。
工作原理
| 部件 | 来源 |
|---|---|
| 搜索、歌曲元数据、自动播放混音 | YouTube Music 的公开 Web API,由 api/_core.js 调用 |
| 播放 | YouTube IFrame Player API,按规则要求始终保持可见 |
| 歌词 | LRCLIB,由浏览器直接调用 |
| Spotify 导入 | 该播放列表的 Spotify 公开嵌入页面 |
| 颜色 | 在浏览器中从封面提取,并通过 WebGL 着色器绘制 |
如果某首歌的主要上传版本拒绝在 YouTube 之外播放,hum 会悄悄尝试下一个最佳上传版本。
带实时灵动岛的桌面应用
desktop/ 是一款小型 Electron 应用:hum 在独立窗口中运行,另有一个岛状界面覆盖在 MacBook 的刘海上。紧凑的岛状界面环绕刘海(左侧封面,右侧音频条);悬停时,它会下拉展开为迷你播放器,显示正在唱的歌词、进度和控件。在 Windows 和没有刘海的 Mac 上,它会悬浮在屏幕顶部中央。岛状界面通过 BroadcastChannel 与播放器通信,因此同一网站的任何窗口都可以控制它。
cd desktop && npm install && npm start # uses https://hum.anzalabidi.dev
cd desktop && npm run dev # uses your local server on :3737
在浏览器中,按 N 即可在页面内打开同样的岛状界面。
弹出式迷你播放器
按 P 或点击弹出按钮,播放器就会移入一个始终置顶的小窗口(通过 Document Picture-in-Picture 在 Chrome 和 Edge 中实现)。在切歌时,Chrome 也可以自动打开它。关闭窗口后,播放会在同一秒的位置回到页面中。
为你推荐
你导入的每个播放列表和每个电台都有“原版 / 为你推荐”切换选项。“为你推荐”会保留相同的歌曲,但根据你听完、跳过和点赞的歌曲调整排序,并从播放列表之外穿插几首发现的新歌,标记为“为你推荐的新歌”。首次会推荐 3 首;每个新的一天你打开它时,最多再添加 3 首,且新增歌曲永远不会超过列表的 30%。跳过两次的新歌会永久移除。播放过几首歌曲后,主页会新增“为你打造”一栏,展示你最常播放歌曲的变体。
所有计算都在浏览器中基于你自己的收听记录完成,并存储在 localStorage 的 taste 和 variants 键下。你的口味数据会留在设备上;唯一的请求是为发现新歌而对少数歌曲进行的常规电台查询。相关规则位于 public/taste.js。
分享链接
歌曲链接的格式为 /s/<id>。聊天应用和社交网站会显示歌曲本身的封面和标题;点击后会直接进入播放器。默认预览图片为 public/og.jpg,由 og/og.html 生成。部署后,请将 public/index.html 中的 og:image 设置为你的完整域名,因为有些爬虫会忽略相对路径。
测试
test/e2e.js 是一套端到端测试,包含 100 项检查,涵盖所有搜索路径、按钮、滑块、开关、列表操作、键盘快捷键、小组件、分享页面、遥控器、「为你推荐」的口味规则和同步(密钥派生、加密与解密、错误代码验证失败、每条合并规则,以及两台设备通过模拟服务器达成一致)。这套测试可在 Chromium 中通过;编写时,前 52 项检查也已在 Firefox 和 WebKit(Safari 的引擎)中通过。将测试文件放在应用旁边(cp test/e2e.js public/__e2e.js),启动应用,按一次播放,然后在控制台中运行:
(await import('/__e2e.js')).run().then((r) => console.table(r))
按键
| 按键 | 功能 |
|---|---|
/ 或 ⌘K | 搜索 |
Space | 播放或暂停 |
← → | 快进或快退 5s |
Shift + ← → | 上一首或下一首 |
L | 歌词 |
Q | 接下来播放 |
S | 随机播放 |
M | 静音 |
P | 弹出迷你播放器 |
N | 缺口模式 |
值得了解的限制
- YouTube 的规则要求播放器保持可见,且不能在后台播放,因此手机锁屏时音乐会停止。桌面设备、平板电脑和电视不受影响。
- 导入 Spotify 播放列表时,只会导入前 100 首歌曲。
- 搜索和混音使用 YouTube Music 的非官方 Web API,该 API 可能会随时变更。
- YouTube 可能会在播放器中显示广告。hum 不会也不应屏蔽广告。通常,在同一浏览器中登录 YouTube Premium 的用户不会看到广告。
- 新标签页需要先点击一次,浏览器才会允许播放声音。之后,Agent 和小组件 API 均可自由播放。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。