ncm-mcp-server
README.md
# ncm-mcp-server
网易云音乐 MCP Server。接到 Claude 官端后,Claude 可以直接搜歌、加歌、切歌、接一起听邀请、发私信。
全程只需要手机 SSH,不需要电脑抳 F12 cookie。
## 架构
```
Claude.ai
↓ MCP (HTTPS)
nginx 你的域名/ncm/mcp
↓
ncm_mcp_server.py 127.0.0.1:3940
├─ 读操作 → NeteaseCloudMusicApi 容器 :3939
└─ 写操作 → 本地 eapi/weapi 加密 → 网易云官方接口
```
写操作不走容器,因为公开镜像的 eapi 加密参数已经过期,一起听和私信全部 400。
## 文件
| 文件 | 作用 |
|------|------|
| `ncm_crypto.py` | eapi / weapi 两套加密 |
| `ncm_client.py` | 请求层、cookie 和房间号读写 |
| `ncm_mcp_server.py` | MCP 主服务,16 个工具 |
| `login.py` | 登录拿完整 cookie(qr / sms / password) |
| `heartbeat.py` | 一起听心跳保活,给 cron 用 |
| `ncm-mcp.service` | systemd 单元 |
| `nginx.conf.example` | 反代配置 |
## 部署
### 1. 拉代码、装依赖
```bash
cd ~
git clone https://github.com/1049376904-crypto/ncm-mcp-server.git
cd ncm-mcp-server
sudo pip3 install -r requirements.txt
```
旧版 pip 不认 `--break-system-packages`,直接用上面这行就行。如果报 externally-managed-environment,加上该参数重试。
### 2. 起读接口容器
```bash
sudo docker run -d -p 3939:3000 --restart=always \
--name ncmapi binaryify/netease_cloud_music_api:latest
curl -s "http://localhost:3939/search?keywords=test" | head -c 120
```
出 JSON 就行。
### 3. 登录拿 cookie
建一个只有自己能读的目录,cookie 等同账号密码,别丢 `/tmp`:
```bash
mkdir -p ~/.ncm && chmod 700 ~/.ncm
export NCM_COOKIE_FILE=~/.ncm/music_cookie.txt
export NCM_ROOM_FILE=~/.ncm/listen_room_id.txt
```
然后选一种登录方式:
```bash
python3 login.py sms # 推荐:手机号 + 短信验证码
python3 login.py qr # 终端直接画二维码,网易云 APP 扫
python3 login.py password # 手机号 + 密码(网易云经常拦)
```
`qr` 模式在手机 SSH 里二维码可能挤得扫不出来,它会同时存一份 `/tmp/ncm_qr.png`。最稳的是 `sms`。
看到 `[ok] logged in as … (uid=…)` 就成了,**把这个 uid 记下来**,它是 AI 号的 uid。
### 4. 挂成服务
先改 `ncm-mcp.service` 里的 `User` 和路径对上你的实际用户,再:
```bash
sudo cp ncm-mcp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now ncm-mcp
sudo systemctl status ncm-mcp --no-pager
```
看日志:
```bash
sudo journalctl -u ncm-mcp -f
```
启动时会打印容器可达性、cookie 长度和监听地址,三行都正常再往下走。
### 5. nginx 反代
把 `nginx.conf.example` 的内容贴进你域名的 HTTPS server 块:
```bash
sudo nginx -t && sudo systemctl reload nginx
curl -i https://你的域名/ncm/mcp
```
返回 400/406 而不是 502,就说明反代通了(MCP 不吃裸 GET,报错是正常的)。502 代表后端没起来。
### 6. 心跳 cron
```bash
crontab -e
```
加一行(路径改成你自己的):
```
* * * * * NCM_COOKIE_FILE=/home/ubuntu/.ncm/music_cookie.txt NCM_ROOM_FILE=/home/ubuntu/.ncm/listen_room_id.txt /usr/bin/python3 /home/ubuntu/ncm-mcp-server/heartbeat.py >> /home/ubuntu/.ncm/heartbeat.log 2>&1
```
没有活跃房间时它直接退出,不会乱发请求,可以一直挂着。
### 7. 接到 Claude
Claude.ai → Settings → Connectors → Add custom connector:
- URL:`https://你的域名/ncm/mcp`
- 名称:网易云音乐
连上后应该能看到 16 个工具。
## 使用
### 一起听
1. 你在网易云 APP 里给 AI 号发一起听邀请
2. 告诉 Claude:“我发了一起听邀请”
3. Claude 调 `get_private_list` → `get_private_messages` 解析出 roomId 和 inviterId
4. Claude 调 `accept_listen_together` 加入,房间号自动存下,cron 接手保活
### 点歌
1. Claude 调 `search_music` 拿 songId
2. `add_song` 加进列表
3. **你清一次 APP 后台重进**(列表同步只能这么弄)
4. 之后 `play_command` 切歌,实时生效
### 工具清单
写操作:`accept_listen_together` `end_listen_together` `listen_together_heartbeat` `listen_together_status` `get_room_playlist` `play_command` `add_song` `send_private_message`
读操作:`search_music` `get_song_detail` `get_private_list` `get_private_messages` `get_user_playlist` `get_playlist_detail` `get_login_status` `get_user_detail`
兜底:`http_request`
## 安全
MCP 服务本身没有鲉权。它只听 127.0.0.1,靠 nginx 暴露。**任何知道 `https://你的域名/ncm/mcp` 的人都能操作你的网易云账号**。两个建议:
- 路径别用 `/ncm/`,换成一串随机字符,比如 `/ncm-a7f3k9d2/`
- 或者在 nginx 里加 header 校验,Claude 的 connector 支持自定义 header
cookie 等同账号密码,别提交进仓库,`.gitignore` 已经挡了。
## 排查
| 现象 | 原因 |
|------|------|
| 写操作全 400 | cookie 不完整,缺 `__csrf`;重新跑 `login.py` |
| 读操作报错 | 容器挂了,`sudo docker restart ncmapi` |
| 一起听房间自己断 | 心跳没跑,看 `heartbeat.log` |
| nginx 502 | 服务没起,`systemctl status ncm-mcp` |
| Claude 连不上 | 证书问题或 URL 漏了 `/mcp` |
| 加歌了但 APP 看不到 | 正常,清后台重进 |
## 致谢
基于 Iris & Rei 的接入教程实现。
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues