CLI for Tidal music streaming service, designed for LLM agent automation
The server provides 40 tools with complete schemas and consistent descriptions. All tools are explicitly registered with Zod schemas in site/app/mcp-lib/tools.ts. Most tool names follow verb_noun conventions (search_*, get_*, create_*, list_*, etc.). Descriptions are present and meaningful (average ~80-100 chars), though they could be more prescriptive about use cases and dependencies. Parameter schemas are well-typed with enums for constrained inputs (type fields). A significant strength is consistent tool annotation use (readOnlyHint, destructiveHint for risk classification). However, output schemas are not documented, responses are text-wrapped JSON without explicit field documentation. Error handling is minimal, no recovery guidance or retryability classification. Several related tools could be better composed (e.g., add_track/add_album → single batch variant). Some parameters lack dependency documentation (e.g., playlistUuid must exist before add_track is called).
Find albums by barcode/UPC
Get album details including artists and cover art
Get albums by an artist
Get artist details including biography
Get radio playlists based on an artist
Get top tracks for an artist
Add a playlist to your favorites
Output schemas not documented. Tools return text-wrapped JSON via text() helper, but the structure of returned fields is not declared. LLMs cannot plan downstream calls or extract specific fields reliably.
No error recovery guidance. Tools throw generic errors ('Unauthorized: invalid token', 'Unauthorized: no Tidal session') without actionable next steps. LLMs cannot distinguish retryable from fatal errors.
Missing pagination support. list_*, search_* tools return unbounded results. No limit parameter, no offset/cursor, no total count. Large result sets will blow context windows.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 78 | <=2025-11-25 | v2 |
List your favorited playlists
Remove a playlist from your favorites
Add an item to your library
Remove an item from your library
Get items inside a specific mix
Get playback information for a track
Get playback URL for a track
Add all tracks from an album to a playlist
Add a track to a playlist
Create a new playlist
Delete a playlist
List your playlists
Move a track to a different position in a playlist
Remove a track from a playlist
Rename an existing playlist
Update the description of a playlist
Get recently added tracks from your library
Get personalized recommendations
Save an item for later
List items saved for later
Remove an item from saved
Search Tidal for artists, albums, tracks, videos, or playlists
Clear all search history entries
Delete a single search history entry
List your search history
Get search suggestions and direct hits for a query
Create a share link for a track or album
Find artists similar to a given artist
Find tracks similar to a given track
Find tracks by ISRC code
Get track details including artists, album, BPM, key
Get radio playlists based on a track
Get your user profile
No batch/bulk operations. Tools like add_track and add_album are separate, forcing agents into loops. A single batch_add_to_playlist taking an array would reduce round-trips and token waste.
Undocumented parameter dependencies. playlistUuid must exist before add_track; type enum in library_add/remove determines which ID types are valid. No docs explain these prerequisites.
No idempotency guarantees. Agents retry on network failures, repeated calls to playlist_create or add_track could create duplicates. No conditional keys or idempotency tokens.
Token injection via authInfo.token. The extractToken() pattern passes bearer tokens directly from extra context. No validation that the token is properly formatted or scoped.
Descriptions lack WHEN/WHY context. 'Get top tracks for an artist' doesn't explain when to call this vs similar_tracks or track_radio. LLMs must guess intent from the name alone.