| name | ncmctl-dev |
| description | NetEase Cloud Music CLI tool (ncmctl) development guide. Use this skill when working with the netease-cloud-music codebase, including ncmctl commands, API integration, crypto, NCM file decryption, daily tasks, music download, cloud upload, or any Go code in this repository. Trigger on mentions of ncmctl, 网易云音乐 CLI, NetEase Cloud Music API, weapi/eapi encryption, .ncm file format, cloud music daily tasks (sign/partner/scrobble), or when modifying, debugging, or extending any part of this project.
|
ncmctl Development Guide
ncmctl is a Go CLI tool for NetEase Cloud Music providing login, daily tasks, music download, cloud upload, and NCM file decryption.
Project Structure
cmd/ncmctl/main.go # CLI entry point
internal/ncmctl/ # CLI command implementations (cobra commands)
api/ # API client layer
├── api.go # Core Client: HTTP, encryption, cookie persistence
├── weapi/ # Web/Mini-program API (recommended, most complete)
├── eapi/ # PC/Mobile API
├── linux/ # Linux client API
└── types/ # Shared request/response types
pkg/
├── crypto/ # AES-CBC/ECB, RSA, weapi/eapi encryption
├── cookie/ # Cookie persistence and sync
├── cookiecloud/ # CookieCloud browser extension support
├── ncm/ # NCM file decryption + audio tag handling
├── database/ # Badger key-value store wrapper
├── log/ # Structured logging (lumberjack rotation)
└── utils/ # General utilities
config/ # Config structs + default config.yaml
Build & Test
make build
make install
go test -v ./...
go test -v -run TestName ./example/
make build-image
Requires Go >= 1.24. Tests needing login require cookie file or should be skipped.
CLI Commands
| Command | Login | Description |
|---|
login | No | Phone/Cookie/CookieCloud/QR code login |
logout | No | Clear stored credentials |
task | Yes | Run all daily tasks on cron schedule |
sign | Yes | YunBei + VIP daily check-in |
partner | Yes | Music partner auto-evaluation |
scrobble | Yes | Scrobble 300 songs daily |
download | Yes | Download songs/albums/playlists |
cloud | Yes | Upload music to cloud disk |
ncm | No | Decrypt .ncm → .mp3/.flac |
crypto | No | Encrypt/decrypt API parameters |
curl | No | Invoke API methods directly |
Adding a New CLI Command
- Create
internal/ncmctl/<command>.go implementing a struct with root, cmd, opts, l fields
- Implement
New<Command>(root *Root, l *log.Logger) constructor
- Define cobra command with
Use, Short, Example
- Add flags via
addFlags() method
- Implement
validate() and execute(ctx, args) methods
- For login-required commands: create API client, check
request.NeedLogin(ctx), defer request.TokenRefresh(ctx, &weapi.TokenRefreshReq{})
- Register in
internal/ncmctl/ncmctl.go: c.Add(New<Command>(c, c.l).Command())
Pattern for login-required commands:
cli, err := api.NewClient(c.root.Cfg.Network, c.l)
if err != nil { return fmt.Errorf("NewClient: %w", err) }
defer cli.Close(ctx)
request := weapi.New(cli)
if request.NeedLogin(ctx) { return fmt.Errorf("need login") }
defer func() {
refresh, err := request.TokenRefresh(ctx, &weapi.TokenRefreshReq{})
if err != nil || refresh.Code != 200 {
log.Warn("TokenRefresh resp:%+v err: %s", refresh, err)
}
}()
Adding a New API Endpoint
- Create file in
api/weapi/ or api/eapi/
- Define request/response structs (request fields use json tags)
- Implement method on API struct calling
a.client.Request(ctx, url, req, resp, opts...)
- Set correct
CryptoMode via option: api.WithCryptoMode(api.CryptoModeWEAPI)
- Default crypto mode is weapi; eapi uses
CryptoModeEAPI
API call flow:
cli := api.New(cfg)
weapiClient := weapi.New(cli)
resp, err := weapiClient.SomeMethod(ctx, &weapi.SomeMethodReq{...})
cli.Close(ctx)
Encryption Modes
| Mode | Algorithm | Use Case |
|---|
CryptoModeWEAPI | AES-CBC double encrypt + RSA | Web/Mini-program |
CryptoModeEAPI | AES-ECB | PC/Mobile |
CryptoModeLinux | AES-ECB | Linux client |
CryptoModeAPI | None | Basic API |
Core functions in pkg/crypto/crypto.go: WeApiEncrypt(), EApiEncrypt(), LinuxApiEncrypt(), EApiDecrypt().
Configuration
- Config file:
~/.ncmctl/config.yaml (optional, uses defaults if absent)
- Cookie storage:
~/.ncmctl/cookie.json (auto-persisted, 3s interval)
- Database:
~/.ncmctl/database/badger/ (scrobble dedup records)
- Logs:
~/.ncmctl/log/ncm.log
- Env var prefix:
NCmctl_ (e.g., NCmctl_Network_Debug=true)
- Magic variable:
${HOME} replaced at runtime
Download Quality Levels
| Level | Aliases | Format |
|---|
| standard | 128 | 128kbps |
| higher | 192 | 192kbps |
| exhigh | HQ, 320 | 320kbps |
| lossless | SQ | FLAC |
| hires | HR | Hi-Res |
Key Dependencies
| Package | Purpose |
|---|
spf13/cobra | CLI framework |
go-resty/resty/v2 | HTTP client |
dgraph-io/badger/v4 | Local KV database |
robfig/cron/v3 | Cron scheduling |
spf13/viper | Config management |
Important Notes
- Cookie persistence is interval-based (3s); unclean shutdown may lose recent cookies
- Scrobble dedup data in
~/.ncmctl/database/ should not be deleted
- Directory depth limit is 3 for cloud upload and NCM decryption
- Cloud upload max file size: 500MB
- Download parallelism max: 20; Cloud upload parallelism max: 10
- The
task command runs as a long-lived service; use Ctrl+C to stop
- Sign-in reward auto-claim (
--sign.automatic) has ban risk, disabled by default
- Scrobble (刷歌) currently has high risk of account ban due to strict risk control
For detailed command usage and API reference, read references/commands.md and references/api-guide.md.