cubesugar-music
A NAS music library downloader shell that aggregates multiple sources, writes ID3 tags, and exposes MCP tools for AI agents to search, download, and manage music.
README
🎵 方糖音乐 (cubesugar-music)
NAS 音乐库下载壳子 — 配合 Navidrome / Plex / Emby / Subsonic 等自托管音乐服务器,提供壳子 + 多源聚合 + MCP 协议,让你下载的歌曲能正确写 ID3 tag、被播放器识别。
⚠️ 重要声明
本项目不内置任何插件。 支持 LX Music 插件格式(用户自行导入)。
- 用户需要自行通过 Web UI 导入或下载到
sources/目录 - 本项目仅提供:
- ✅ 壳子(HTTP API + 数据库 + 队列)
- ✅ 多源聚合上游
- ✅ MCP 协议(供 AI Agent 接入)
- ✅ ID3 tag 写入(Navidrome 识别用)
- ✅ 批量歌单导入
- ✅ 4 层防重
- ✅ 本地音乐库索引
- ❌ 不内置任何音源插件
✨ 核心功能
| 功能 | 说明 |
|---|---|
| 🔍 跨源搜歌 | 默认走多源聚合 |
| 📦 插件支持 | 支持 LX Music 插件格式,通过 Web UI 导入(Node VM 沙箱执行) |
| 📥 下载队列 | 2 worker 后台线程,原子抢任务,音质降级(hires → master → atmos → flac24bit → flac → 320k → 128k) |
| 🎵 批量歌单 | 歌单 URL 一键导入,自动跳过已下载/已存在任务 |
| 🚫 4 层防重 | ①文件系统 ②数据库精确 ③文件模糊匹配 ④本地索引库 |
| 🎼 本地索引 | 自动扫描下载目录建立索引,存 PostgreSQL,跨源跨 ID 查重 |
| 🆔 ID3 tag | 下载后自动写 FLAC Vorbis Comments / MP3 ID3v2 — Navidrome/Plex 直接识别 |
| 🔌 MCP 服务 | 10 个工具供 Claude / Hermes / Cursor 等 AI Agent 接入(SSE 模式 + 30 天 token) |
| 🌙 主题切换 | 白天/夜间双主题,CSS 变量切换,localStorage 持久化 |
| 🔑 用户管理 | JWT 鉴权、修改密码、退出登录 |
🏗️ 架构
┌─ Web UI (浏览器/外网)
│ ├─ 登录页 (admin/admin)
│ ├─ 搜索/下载/任务
│ └─ 设置 (插件导入 / 音乐库 / MCP / 服务状态)
│
├─ MCP (Claude/Hermes AI Agent 接入, SSE 模式)
│
├─ REST API (8765 端口)
│
└─ Backend
├─ upstream 多源聚合 (公开 API)
├─ PostgreSQL 5 表
├─ Worker threads × 2 (原子抢任务, FOR UPDATE SKIP LOCKED)
├─ 插件 (Node VM 沙箱) — 需用户自行导入
└─ 4 层防重 + ID3 tag 自动写入
🚀 快速开始
方式 1: Docker Compose (推荐)
git clone https://github.com/fangtang0206/cubesugar-music.git
cd cubesugar-music
# 配置环境变量 (可选)
export PG_PASSWORD=your_secure_password
export JWT_SECRET=$(openssl rand -hex 32)
export DOWNLOAD_DIR=/path/to/music # 默认 ./music
# 启动 (首次会构建镜像,需要 2-3 分钟)
docker compose up -d
# 等 30 秒让服务起来
curl http://127.0.0.1:8765/api/health
# → {"status": "ok", "runtime": "ok", "upstream": "ok", "postgres": "ok", "worker_running": true}
# 打开 Web UI
open http://127.0.0.1:8765/
# 默认账号: admin / admin (登录后立即修改!)
端口占用:
- 8765 (Web UI + API)
- 8098 (Node runtime)
- 54321 (PostgreSQL)
如有冲突,修改 docker-compose.yml 里的端口映射。
方式 2: 直接运行 (开发)
# 1. 准备 PostgreSQL
psql -U root -c "CREATE DATABASE fangtang_music"
# 2. 安装依赖
pip3 install mutagen psycopg[binary]
# 3. 启动 Node runtime
cd node-runtime && node server.js &
# 4. 启动主服务
cd app && python3 server.py
🔌 导入 LX Music 插件
项目不内置任何插件。支持 LX Music 插件格式(.js 文件),首次使用需要导入:
通过 Web UI
- 登录 → 右上角 ⚙ 设置 → 📦 插件 tab
- 填入插件 JS 文件的 URL → 点击"URL 导入"
- 或下载到本地 → 用"文件上传"按钮
通过文件系统
# 复制插件 JS 到 sources 目录
cp /path/to/plugin.js /vol1/1000/docker/cubesugar-music/sources/
# 重启服务 (或点 Web UI 刷新)
推荐插件来源
重要提醒:
- 插件上游 API 可能失效(Cloudflare 拦截、KEY 过期等),多源聚合已能覆盖大部分歌曲
- 导入前请检查插件代码安全性
⚙️ 配置
环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
PORT |
8765 |
HTTP 服务端口 |
DOWNLOAD_DIR |
/vol2/1000/music |
下载目录(host 路径, 必须可写) |
SOURCES_DIR |
/vol1/1000/docker/cubesugar-music/sources |
插件目录(需用户填充) |
WORKER_COUNT |
2 |
后台 worker 线程数 |
MAX_RETRIES |
3 |
任务最大重试次数 |
PG_HOST |
127.0.0.1 |
PostgreSQL 主机 |
PG_PORT |
54321 |
PostgreSQL 端口 |
PG_USER |
root |
数据库用户 |
PG_PASSWORD |
cubeSugar_postgresql |
数据库密码 |
PG_DATABASE |
fangtang_music |
数据库名 |
LX_RUNTIME_BASE |
http://127.0.0.1:8098 |
Node runtime 地址 |
SELF_BASE_URL |
http://127.0.0.1:8765 |
MCP 内部调用自己时用 |
JWT_SECRET |
cubesugar-music-default-secret-change-me |
生产环境必须改 |
📚 API 文档
鉴权
# 登录
curl -X POST http://127.0.0.1:8765/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}'
# → {"token": "eyJhbG...","user": {...}}
# 后续请求带 token
curl http://127.0.0.1:8765/api/tasks/list \
-H "Authorization: Bearer eyJhbG..."
# 签发 MCP 长 token (30 天)
curl -X POST http://127.0.0.1:8765/api/auth/mcp-token \
-H "Authorization: Bearer <token>"
# → {"token": "eyJhbG...","expires_in": 2592000}
搜歌
# 默认跨源
curl "http://127.0.0.1:8765/search?name=海阔天空&artist=Beyond" \
-H "Authorization: Bearer <token>"
# 指定源
curl "http://127.0.0.1:8765/search?name=test&source=tx"
提交下载任务
curl -X POST http://127.0.0.1:8765/api/tasks/submit \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"source": "wy",
"song_id": "1357375695",
"name": "海阔天空",
"artist": "Beyond",
"quality": "flac"
}'
批量歌单导入
curl -X POST http://127.0.0.1:8765/api/playlist/import \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://music.163.com/playlist?id=12345",
"quality": "flac"
}'
任务列表 (分页 + 状态筛选)
# 默认 status=all, page=1, page_size=20
curl "http://127.0.0.1:8765/api/tasks/list" -H "Authorization: Bearer <token>"
# 筛选下载成功 / 失败 / 待重试
curl "http://127.0.0.1:8765/api/tasks/list?status=success" -H "Authorization: Bearer <token>"
curl "http://127.0.0.1:8765/api/tasks/list?status=error" -H "Authorization: Bearer <token>"
curl "http://127.0.0.1:8765/api/tasks/list?status=retry" -H "Authorization: Bearer <token>"
# 分页
curl "http://127.0.0.1:8765/api/tasks/list?page=2&page_size=50" -H "Authorization: Bearer <token>"
本地音乐库索引
# 状态
curl "http://127.0.0.1:8765/api/library/stats" -H "Authorization: Bearer <token>"
# 查询
curl "http://127.0.0.1:8765/api/library/lookup?artist=Beyond&name=海阔天空" \
-H "Authorization: Bearer <token>"
# 触发重建 (后台 4-5 分钟)
curl -X POST "http://127.0.0.1:8765/api/library/rescan" -H "Authorization: Bearer <token>"
🔌 MCP 集成 (Claude / Hermes / Cursor)
# ~/.hermes/config.yaml 或 ~/.claude/mcp_servers.json
mcp_servers:
cubesugar-music:
url: http://your-host:8765/mcp/sse
transport: sse
headers:
Authorization: Bearer <从 /api/auth/mcp-token 拿到的 30 天 token>
X-Client: hermes-agent
MCP 工具列表 (10 个)
| 工具 | 说明 |
|---|---|
search_music |
搜歌 (跨源) |
download_music |
下载单首到队列 |
import_playlist |
批量导入歌单 |
list_tasks |
列下载任务 (带状态过滤) |
get_task_status |
单个任务状态 |
list_plugins |
列插件 |
import_plugin |
导入插件 (URL/文件) |
library_stats |
本地音乐库统计 |
library_lookup |
查本地库 (artist + name) |
library_rescan |
触发重建索引 |
🗂️ 数据库结构
| 表 | 说明 |
|---|---|
users |
用户 (默认 admin) |
plugins |
插件元数据 |
download_tasks |
下载任务 (status: pending/processing/success/error) |
local_library |
本地音乐索引 (artist, name, album, file_path) |
index_status |
索引状态 (最后扫描时间) |
🛠️ 开发
项目结构
cubesugar-music/
├── app/ # Python 主服务
│ ├── server.py # 主 HTTP 路由
│ ├── fetcher.py # 多源聚合上游
│ ├── library_index.py # 本地音乐库扫描器 + 索引查重
│ ├── id3_writer.py # FLAC/MP3 ID3 tag 写入
│ ├── worker/worker.py # 后台下歌 worker
│ ├── auth/ # JWT + PBKDF2 密码哈希
│ ├── db/ # PostgreSQL 连接池
│ ├── api/mcp.py # MCP server (SSE)
│ └── playlist.py # 歌单 URL 解析
├── node-runtime/ # Node 沙箱 (8098 端口)
├── sources/ # (空) 插件目录 - 用户自行填充
├── docker-compose.yml # 一键启动
├── Dockerfile
└── README.md
启动开发模式
# 1. 启动 postgres
docker run -d --name cubesugar-db \
-e POSTGRES_PASSWORD=cubeSugar_postgresql \
-e POSTGRES_DB=fangtang_music \
-p 54321:5432 \
postgres:15-alpine
# 2. 启动 runtime
cd node-runtime && node server.js &
# 3. 启动主服务
cd app
PORT=8765 DOWNLOAD_DIR=/vol2/1000/music \
PG_HOST=127.0.0.1 PG_PORT=54321 \
python3 server.py
🐛 常见问题
Q: 启动后 runtime 提示 500 / plugins 列表空?
A: 项目不内置插件。需要手动导入 LX Music 格式的 .js 插件文件。
A: 正常, 仓内不内置插件, sources/ 目录是空的, 需要自己导入插件 JS 文件。
Q: 搜歌结果显示的歌曲都搜不到?
A: 多源聚合已能覆盖大部分歌曲。如果某首歌搜不到, 检查:
- upstream 是否在线 (
/api/health状态) - 插件是否需要登录账号
- 公开 API 限流 (稍等再试)
Q: 下载的文件 Navidrome/Plex 显示 "Unknown Artist"?
A: 老文件没 ID3 tag, 手动补:
cd app/
python3 -c "from id3_writer import backfill_existing_files; print(backfill_existing_files('/vol2/1000/music'))"
会扫所有 FLAC/MP3, 从数据库元数据 + 文件路径回推写入 ID3 (4199 首约 30 分钟)
Q: 怎么给 Navidrome/Plex 用?
A: 两者都扫 /vol2/1000/music/ 目录:
- 库目录指向
/vol2/1000/music/ - 启用"扫描 ID3 tag"选项
- 几分钟后歌名/歌手/专辑全部就位
📜 License
MIT License - 见 LICENSE 文件
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。