xiaozhi-music-mcp
小智音乐 MCP 服务
这是一个运行在个人电脑或云主机上的小智外部 MCP 服务。程序通过小智控制台提供的 WebSocket 接入点主动连接小智云端,为 EchoEar(喵伴)的设备端在线音乐工具搜索歌曲并生成局域网播放地址。
音乐源默认按 Navidrome → 网易云完整歌曲 → Fangpi → Jamendo → 可选非官方适配器 的顺序降级。真正的播放仍由 EchoEar 固件内置的 self.online_music.play_music 执行。
搜索默认启用 MCP 侧智能候选排序:标准化 ASR 文本,根据标题、拼音、歌手和版本要求评分,再只解析高分候选的播放权限。30 秒试听会保留并标记,高相关试听优先于无关完整歌曲。可在 config/music_query_aliases.json 中维护高频 ASR 纠错,详细设计见 docs/SMART_MUSIC_SEARCH_DESIGN.md。
工作方式
music_mcp_server.py(按优先级搜索歌曲)
↕ stdio
mcp_pipe.py ↔ 小智云端 ↔ EchoEar 的 self.online_music.play_music(播放)
↳ :8765/media/<临时令牌>/audio(动态音频代理)
↳ :8765/media/<临时令牌>/manifest.json(歌曲信息、封面与歌词)mcp_pipe.py主动连接MCP_ENDPOINT,因此本地运行时不需要公网 IP 或端口映射。music_mcp_server.py是标准 FastMCP stdio 服务。mcp_pipe.py会在局域网启动动态音频代理,隐藏上游鉴权信息并解决部分 ESP32 无法直连 HTTPS/CDN 的问题;默认端口为8765。新版代理会为每首歌生成短期媒体清单。封面按需裁剪为 360 × 360 暗化背景和 192 × 192 唱片;可用歌词以 LRC 转发。旧
/stream/<令牌>地址仍兼容。Provider 配置和非官方适配器协议见 PROVIDERS.md。
电脑必须保持开机、联网,桥接程序必须持续运行。
1. 获取新的 MCP 接入点
登录 xiaozhi.me。
进入对应设备或智能体的“配置角色”页面。
点击“MCP 接入点”,复制
wss://api.xiaozhi.me/mcp/?token=...地址。如果曾经使用过本仓库旧配置中的 Token,请在控制台撤销它并生成新 Token。
不要把真实接入点提交到 Git。
2. 安装
要求 Python 3.10 或更高版本。
部署向导(推荐)
在仓库目录运行一个命令:
bash scripts/deploy_wizard.sh向导会依次完成:
检查 Python 版本并创建
.venv;安装依赖;
保留已有
.env/.env.local,缺少时创建配置并安全读取MCP_ENDPOINT;固定 EchoEar 所需的音频代理端口
8765;运行 Provider、音频代理、标准 MCP 和 WebSocket 桥接测试;
在 macOS 上可选择立即安装后台服务以及是否登录自启动。
如已单独完成测试,可使用:
bash scripts/deploy_wizard.sh --skip-tests向导不会安装或迁移 Navidrome、网易云 API 等独立服务,它们仍需按 PROVIDERS.md 配置。
手动安装
cd xiaozhi-music-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt3. 配置
推荐使用 .env:
cp .env.example .env编辑 .env,把占位地址换成刚生成的接入点:
MCP_ENDPOINT=wss://api.xiaozhi.me/mcp/?token=你的新Token
LOG_LEVEL=INFO
MUSIC_PROXY_PORT=8765
MUSIC_PROVIDER_ORDER=navidrome,netease,fangpi,jamendo,unofficial
NAVIDROME_URL=http://127.0.0.1:4533
NAVIDROME_USERNAME=你的用户名
NAVIDROME_PASSWORD=你的密码
JAMENDO_CLIENT_ID=你的ClientID
FANGPI_PROVIDER_ENABLED=true
FANGPI_API_TIMEOUT_SECONDS=10当前 EchoEar 测试固件固定允许端口 8765,请勿修改该值。
Fangpi 默认启用,因此未配置其他音乐源时仍会尝试搜索;如果 Cloudflare 拒绝独立客户端,可按 PROVIDERS.md 手动配置浏览器 Cookie。网易云和通用非官方适配器默认关闭。乐鑫官方测试音频作为诊断入口始终保留,不依赖音乐源配置。
.env 已加入 .gitignore。
也可以只在当前终端设置:
export MCP_ENDPOINT='wss://api.xiaozhi.me/mcp/?token=你的新Token'4. 启动
后台服务(推荐)
首次安装运行:
bash scripts/music_service.sh install安装程序会询问:
是否启用登录自动启动?[y/N]默认选择 N:服务立即在 macOS LaunchAgent 中运行,关闭终端或退出 Codex 后仍会继续工作,但下次登录不会自动启动。选择 Y 则同时开启登录自启动。
启动命令会读取当前 Provider 配置,先自动拉起需要本地进程的托管 Provider,再启动 MCP。停止、重启、状态、自启动切换和日志查看也会统一管理这些进程。网易云本机端点默认托管;Navidrome 或通用适配器只有显式配置 *_SERVICE_MANAGED=true 时才由本项目拉起。Fangpi 与 Jamendo 是远程 HTTP 来源,不会创建本地进程。
Provider 采用故障隔离:单个托管 Provider 拉起失败只会输出警告,不会阻止 MCP 启动;搜索时也会自动继续尝试后续来源。启动命令只有在项目安装、环境文件或 Provider 配置语法本身无效时才会失败。
日常管理命令:
bash scripts/music_service.sh start
bash scripts/music_service.sh update
bash scripts/music_service.sh stop
bash scripts/music_service.sh restart
bash scripts/music_service.sh status
bash scripts/music_service.sh enable-autostart
bash scripts/music_service.sh disable-autostart
bash scripts/music_service.sh logsupdate 会在干净的 main 分支上快进到 GitHub origin/main,自动创建或复用 .venv、升级安装 requirements.txt 中的依赖,并运行完整回归测试。服务原本在运行时会在全部验证成功后自动重启;服务原本已停止时保持停止,随后可直接运行 start。为保护本地改动,工作区不干净、当前不在 main 或无法快进时会停止更新。
disable-autostart 不会中断正在运行的服务,只会阻止它在下次登录时自动启动。stop 不会改变自启动设置。
前台运行
source .venv/bin/activate
python mcp_pipe.py成功时会看到:
连接小智 MCP 接入点:wss://api.xiaozhi.me/mcp/?token=***
小智 MCP 接入点连接成功
已启动本地 MCP 服务:.../music_mcp_server.py
动态音乐局域网代理已启动:http://局域网IP:8765/media/<临时令牌>/audio然后回到小智控制台刷新 MCP 接入点,应能看到在线状态和 1 个工具:resolve_music_url。小智不需要了解各个 Provider,来源选择由服务端完成。
角色人物介绍应加入:
收到音乐相关需求时,禁止使用 search_music、官方 play_music 和 self.music.play_song。
先调用外部 MCP 工具 resolve_music_url 搜索歌曲并获得音频 URL。
解析成功后,必须立即调用设备端 MCP 工具 self.online_music.play_music,
并原样使用 resolve_music_url 返回的 device_arguments。新版 EchoEar 固件会同时接收可选的 device_arguments.metadata_url,用于显示歌名、歌手、暗化封面、旋转唱片和三行同步歌词。旧固件和旧 URL 播放流程保持兼容。
必要时重启小智设备,再尝试:
“播放乐鑫官方测试音频”
“播放海阔天空 Beyond”(需要相应音乐源中存在该歌曲)
前台运行时,停止服务请按 Ctrl+C。
飞书使用行为统计(可选)
启用后,搜索、Provider 结果和设备首次请求音频等事件会先写入本地 SQLite,再由后台 Worker 异步同步到飞书多维表格。飞书断网或登录失效不会影响音乐播放,授权恢复后会自动补传。
1. 安装并登录飞书 CLI
先安装官方 lark-cli,并确认命令可用:
lark-cli --version项目使用 CLI 的 Device Flow 登录,不需要创建本地回调服务器,也不需要在项目中配置 App ID、App Secret、Access Token 或 Refresh Token。首次使用时,管理命令会在需要时执行 CLI 配置初始化,并申请 Base 业务域权限。登录用户仍需对目标多维表格具有可管理权限。
2. 配置并登录
在 .env.local 中配置:
ANALYTICS_ENABLED=true
ANALYTICS_TRANSCRIPT_MODE=masked
FEISHU_ANALYTICS_ENABLED=true
FEISHU_AUTH_REQUIRED_ON_START=false
LARK_CLI_BIN=
FEISHU_BASE_TOKEN=多维表格URL中base/后面的Token完成首次登录和初始化:
bash scripts/music_service.sh auth login
bash scripts/music_service.sh analytics init
bash scripts/music_service.sh analytics testauth login 会调用 lark-cli auth login --domain base,按 CLI 提示完成 Device Flow 授权。Token 的存储和刷新由 CLI 管理,项目不会读取 Token。
如果没有配置 FEISHU_BASE_TOKEN,交互式执行 analytics init 会询问是否自动创建并初始化“小智使用分析”多维表格;确认后会复用并重命名飞书自动生成的首张数据表,不留下无用表。非交互部署可显式执行:
bash scripts/music_service.sh analytics init --create-base也可以通过 --base-name "家庭小智分析" 自定义名称。初始化完成后,Base Token、表 ID 和仪表盘 ID 会写入权限为 0600 的 .env。
3. 日常管理
bash scripts/music_service.sh auth status
bash scripts/music_service.sh analytics status
bash scripts/music_service.sh analytics sync
bash scripts/music_service.sh analytics retry交互式执行 start 时,如果尚未登录,会自动进入登录流程。LaunchAgent 等后台启动不会等待浏览器;它会记录 AUTH_REQUIRED,保留本地事件并继续提供音乐服务。只有显式设置 FEISHU_AUTH_REQUIRED_ON_START=true 时,授权失败才会阻止启动。
当前版本能完整统计 MCP 可观察到的音乐搜索和开始播放行为。普通对话、唤醒、自然播放结束、换歌和音频欠载需要 EchoEar 固件增加遥测上报后才能准确记录。
迁移到另一台电脑
不需要修改 EchoEar 固件。新电脑通过 MCP_ENDPOINT 主动连接小智云端,但动态音频地址使用新电脑的局域网 IP,因此新电脑和 EchoEar 必须处于同一局域网。
1. 切换前检查
新电脑安装 Python 3.10 或更高版本,并保持开机、联网且不会自动睡眠;
防火墙允许 Python 接收局域网 TCP
8765;路由器没有开启客户端隔离;
如果启用了 VPN,确认日志显示的是 EchoEar 可以访问的局域网 IPv4 地址;
使用同一个
MCP_ENDPOINT时,先停止旧电脑服务,避免两个桥接程序同时占用同一个接入点。
推荐在小智控制台生成新的 MCP 接入点 Token,切换成功后撤销旧 Token。不要通过 Git、聊天记录或公开网盘迁移 Token 和 Cookie。
2. 获取代码并迁移本地配置
git clone git@github.com:maxjchuang/xiaozhi-music-mcp.git
cd xiaozhi-music-mcp通过加密传输、隔空投送或其他可信方式,把旧电脑项目目录中的 .env 和 .env.local 复制到新电脑相同位置,然后限制权限:
chmod 600 .env .env.local
bash scripts/deploy_wizard.sh如果不迁移旧配置,部署向导会创建 .env 并要求输入新的 MCP_ENDPOINT,其他 Provider 按 .env.example 和 PROVIDERS.md 配置。
3. 迁移网易云音乐服务
启用网易云 Provider 时,新电脑还必须独立运行 NeteaseCloudMusicApiEnhanced:
mkdir -p ~/.local/share/xiaozhi
cd ~/.local/share/xiaozhi
git clone --filter=blob:none \
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git \
netease-api-enhanced
cd netease-api-enhanced
npm install其本地 .env 至少保持以下约束:
HOST=127.0.0.1
PORT=3000
ENABLE_GENERAL_UNBLOCK=false网易云登录态保存在这个独立服务的 .env 中,而不是本仓库。可以安全迁移原来的 NETEASE_COOKIE=MUSIC_U=...,也可以在新电脑重新扫码登录。启动后先验证搜索接口:
已完成 Provider 配置后,可以通过统一服务命令管理网易云账号:
# 查看当前登录状态
bash scripts/music_service.sh netease status
# 扫码登录;成功后自动保存 Cookie 并重载 Provider
bash scripts/music_service.sh netease login
# 退出并清除本机 Cookie
bash scripts/music_service.sh netease logout
# 退出当前账号后立即扫码登录新账号
bash scripts/music_service.sh netease reloginlogin 和 relogin 会自动打开二维码图片,且不会在终端或日志中输出完整 Cookie。
也可以手动启动 API 并验证搜索接口:
cd ~/.local/share/xiaozhi/netease-api-enhanced
npm start保持该终端运行,并在另一个终端执行:
curl --fail --get \
--data-urlencode 'keywords=海阔天空 Beyond' \
--data 'type=1' \
--data 'limit=1' \
http://127.0.0.1:3000/cloudsearch验证成功后,macOS 上可交给本项目的统一服务管理器持续运行;Linux 仍需使用 systemd 或其他进程管理器。
本仓库对应配置为:
NETEASE_PROVIDER_ENABLED=true
NETEASE_API_URL=http://127.0.0.1:3000
NETEASE_SERVICE_MANAGED=true
NETEASE_SERVICE_DIR=~/.local/share/xiaozhi/netease-api-enhanced
NETEASE_SERVICE_COMMAND=["npm","start"]
FANGPI_PROVIDER_ENABLED=falseNavidrome、Jamendo 和其他适配器只需迁移自己实际启用的配置。若 Navidrome 位于 NAS 或另一台电脑,NAVIDROME_URL 必须改成新电脑可以访问的地址,不能继续使用错误的 127.0.0.1。本机 Navidrome 如需统一托管,可按 PROVIDERS.md 配置其服务目录和启动命令。
4. 接管服务
先在旧电脑停止服务:
bash scripts/music_service.sh stop然后在新电脑启动。macOS 推荐:
bash scripts/music_service.sh install
bash scripts/music_service.sh update
bash scripts/music_service.sh status
bash scripts/music_service.sh logsLinux 可以先以前台方式验证:
source .venv/bin/activate
python mcp_pipe.pyWindows 目前不支持 Bash 部署向导和 music_service.sh,可以在 PowerShell 中使用 .venv\Scripts\python.exe mcp_pipe.py 前台验证,再配置任务计划。当前 music_service.sh 只支持 macOS;其他系统验证成功后需自行配置 systemd 或任务计划。Docker 部署还需要确保返回给 EchoEar 的不是容器内部 IP,因此普通端口映射不适合作为首次迁移验证方式。
5. 分层验证
先验证本地代码,不连接小智也能执行:
source .venv/bin/activate
python -m unittest -v test_music_providers.py test_audio_proxy.py
python test_mcp.py
python test_mcp_pipe.py启动服务后,状态和日志应包含:
运行状态:运行中
音频代理:正在监听 TCP 8765
小智 MCP 接入点连接成功
已启动本地 MCP 服务
动态音乐局域网代理已启动:http://新电脑局域网IP:8765/media/<临时令牌>/audio可以从同一局域网的另一台电脑测试端口:
nc -vz 新电脑局域网IP 8765最后进行两级设备验证:
对 EchoEar 说“播放乐鑫官方测试音频”,验证小智 MCP、局域网代理和设备 URL 播放链路;
再说“播放海阔天空 Beyond”,验证实际 Provider、账号权限、完整歌曲过滤和代理播放。
成功时服务日志会出现来自设备的请求,例如:
[audio-proxy] "GET /stream/... HTTP/1.1" 200支持 HTTP Range 的播放请求也可能返回 206。如果控制台显示 MCP 在线但设备不能播放,优先检查日志中的代理 IP、TCP 8765 防火墙以及两台设备是否确实处于同一局域网。
本地测试
不连接小智也可以验证标准 MCP 握手和工具调用:
source .venv/bin/activate
python -m unittest -v test_music_providers.py test_audio_proxy.py
python test_mcp.py
python test_mcp_pipe.py直接运行 python music_mcp_server.py 时程序会等待 stdio MCP 请求,这属于正常现象;日常接入小智应运行 mcp_pipe.py。
可用工具
工具 | 功能 |
| 按 Provider 优先级搜索歌曲,生成短期局域网地址并返回 EchoEar 设备工具所需参数 |
当前限制
Navidrome 只管理用户自己的音乐文件;网易云 Provider 仅接受平台原生完整歌曲并过滤 30 秒试听;Fangpi 是默认启用但可能变化的非官方网页源;Jamendo 以独立音乐为主。
非官方适配器默认关闭,稳定性、账号权限和内容合规性由适配器使用者负责。
EchoEar 与运行 MCP 的电脑必须在同一局域网,且本机防火墙需允许 Python 接收 TCP 8765 端口的局域网连接。
EchoEar 的 URL 播放仍可能经过 Nologo 在线音乐后台,并受设备端
config_music_player_enabled、账号或名额限制。当前自动选择每个 Provider 返回的第一条结果;重名歌曲建议在语音请求中同时说明歌手。
安全说明
MCP_ENDPOINT中的 Token 相当于凭据,不要上传、截图或写进日志。Navidrome 密码、网易云 Cookie、Jamendo Client ID 和非官方适配器令牌只放在本地环境文件,不要提交到 Git。
桥接程序输出地址时会隐藏查询参数中的 Token。
如果 Token 曾提交到公开仓库,仅删除当前文件不够;还应撤销 Token,并按需要清理 Git 历史。