cubesugar-music
🎵 方糖音乐 (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 过期等),多源聚合已能覆盖大部分歌曲
导入前请检查插件代码安全性
⚙️ 配置
环境变量
变量 | 默认值 | 说明 |
|
| HTTP 服务端口 |
|
| 下载目录(host 路径, 必须可写) |
|
| 插件目录(需用户填充) |
|
| 后台 worker 线程数 |
|
| 任务最大重试次数 |
|
| PostgreSQL 主机 |
|
| PostgreSQL 端口 |
|
| 数据库用户 |
|
| 数据库密码 |
|
| 数据库名 |
|
| Node runtime 地址 |
|
| MCP 内部调用自己时用 |
|
| 生产环境必须改 |
📚 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-agentMCP 工具列表 (10 个)
工具 | 说明 |
| 搜歌 (跨源) |
| 下载单首到队列 |
| 批量导入歌单 |
| 列下载任务 (带状态过滤) |
| 单个任务状态 |
| 列插件 |
| 导入插件 (URL/文件) |
| 本地音乐库统计 |
| 查本地库 (artist + name) |
| 触发重建索引 |
🗂️ 数据库结构
表 | 说明 |
| 用户 (默认 admin) |
| 插件元数据 |
| 下载任务 (status: pending/processing/success/error) |
| 本地音乐索引 (artist, name, album, file_path) |
| 索引状态 (最后扫描时间) |
🛠️ 开发
项目结构
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 文件
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/fangtang0206/cubesugar-music'
If you have feedback or need assistance with the MCP directory API, please join our Discord server