Tuneping.Mcp
0.1.1
dotnet tool install --global Tuneping.Mcp --version 0.1.1
dotnet new tool-manifest
dotnet tool install --local Tuneping.Mcp --version 0.1.1
#tool dotnet:?package=Tuneping.Mcp&version=0.1.1
nuke :add-package Tuneping.Mcp --version 0.1.1
Tuneping MCP server (tuneping-mcp)
A stdio Model Context Protocol server that gives AI agents the Tuneping API: what tens of thousands of internet radio stations announce as playing right now, a play history, a track and artist catalogue, and wishlists. It proxies https://api.tuneping.com/v1; every tool call is an ordinary API request under your key's quota.
Metadata detections, not fingerprinted airplay; about 73 % of directory stations expose a title, about half are songs.
Install
Needs the .NET 10 SDK to install (https://dotnet.microsoft.com/download): dotnet tool and dnx are SDK commands. The installed tool then runs on the .NET 10 runtime or later.
dotnet tool install -g Tuneping.Mcp # installs the tuneping-mcp command
dotnet tool update -g Tuneping.Mcp # later versions
tuneping-mcp --version
With the .NET 10 SDK, dnx Tuneping.Mcp runs it without installing (dnx ships with the SDK, not the runtime).
Configuration
| Variable | Default | Effect |
|---|---|---|
TUNEPING_API_KEY |
unset | Sent as Authorization: Bearer. Without it the eight Free tools work; get_station_history, get_track_plays, create_wishlist, list_wishlist_matches (Developer) and get_artist_airplay (Pro) answer a clear 401 unauthenticated error. Keys: https://tuneping.com/#pricing |
TUNEPING_BASE_URL |
https://api.tuneping.com/v1 |
Absolute https URL including /v1; plain http only for a loopback host (127.0.0.1, localhost), so the key never crosses a network unencrypted. |
TUNEPING_MCP_LOG |
Warning |
Log level on stderr (Warning, Information, Debug). Stdout carries JSON-RPC only. |
Client setup
Claude Desktop (claude_desktop_config.json):
{ "mcpServers": { "tuneping": { "command": "tuneping-mcp", "env": { "TUNEPING_API_KEY": "tp_live_…" } } } }
macOS GUI apps do not inherit the shell PATH: use the full path /Users/<you>/.dotnet/tools/tuneping-mcp; on Windows %USERPROFILE%\.dotnet\tools\tuneping-mcp.exe.
Claude Code:
claude mcp add tuneping --env TUNEPING_API_KEY=tp_live_… -- tuneping-mcp
or in a project's .mcp.json, or Cursor's mcp.json (~/.cursor/mcp.json or .cursor/mcp.json):
{ "mcpServers": { "tuneping": { "command": "tuneping-mcp", "env": { "TUNEPING_API_KEY": "tp_live_…" } } } }
Without a key
Leave out env (or --env) entirely: claude mcp add tuneping -- tuneping-mcp. The Free tools and both resources answer anonymously (per IP: 2 requests per second with bursts of 5, 1,000 per day, batches of 20 stations). The keyed tools then answer 401 unauthenticated without sending a request, naming the plan that unlocks them.
Tools
| Tool | Purpose | Plan |
|---|---|---|
search_now_playing(q, country?, limit?) |
Stations playing a title matching q right now | Free |
get_station(station_id) |
One station by Radio Browser UUID | Free |
search_stations(q, country?, tag?) |
Find stations by name, country, tag | Free |
get_station_now_playing(station_id) |
The title one station announces now | Free |
get_now_playing_batch(station_ids[]) |
Current titles for up to 100 stations (20 without a key) | Free |
get_station_history(station_id, from?, to?) |
One station's past titles | Developer (10 days), Pro (30 days) |
search_tracks(q) |
Catalogue tracks, trk_… ids |
Free |
search_artists(q) |
Catalogue artists, art_… ids |
Free |
get_track_plays(track_id, from?, to?, country?) |
Where and when a track was detected | Developer (10 days), Pro (30 days) |
get_artist_airplay(artist_id, group_by, from?, to?) |
Plays per station, country or day | Pro |
create_wishlist(kind, value, station_filter?) |
Record detections of an artist, track or query (poll delivery) | Developer |
list_wishlist_matches(wishlist_id) |
Matches of one wishlist | Developer |
get_coverage_stats() |
Coverage figures of the index | none |
get_station_history and get_track_plays return at most 200 rows per call, newest first; a non-null next_cursor means older rows exist, so narrow from/to. get_artist_airplay returns up to 1,000 groups.
Ids: station ids are Radio Browser UUIDs; tracks trk_…, artists art_…, wishlists wl_…. Dates are RFC 3339 UTC (2026-11-01 or 2026-11-01T00:00:00Z), from inclusive, to exclusive. create_wishlist is the only tool that writes.
Resources: tuneping://stats (coverage stats) and tuneping://station/{id} (one station).
Errors
API problems come back as tool errors (isError) with two lines: a summary with the API's status and code and a one-line hint, then the raw problem JSON:
403 forbidden_tier: Your tier keeps 10 days of history; `from` may not be older than 2026-10-24T09:00:00Z. Hint: Unlock with the Pro plan (30 days of history and artist airplay reports); https://tuneping.com/#pricing.
{"type":"https://tuneping.com/docs/errors/#forbidden_tier","title":"Upgrade required","status":403,…,"required_tier":"pro","upgrade_url":"https://tuneping.com/#pricing"}
Codes: 401 unauthenticated, 403 forbidden_tier (with required_tier) and forbidden_scope, 404 not_found, 422 validation_failed (with errors[]), 429 rate_limited / quota_exceeded, 503 unavailable. A Retry-After of at most 10 s on a 429 or 503 is honoured once; nothing else is retried. Parameters are checked before any request, with the API's own error codes.
Troubleshooting
tuneping-mcp --versionprints the version; it is also sent asUser-Agent: tuneping-mcp/<version>.TUNEPING_MCP_LOG=Debuglogs every API call (method, path and query, status, request id, any Retry-After wait) and the SDK's JSON-RPC handling to stderr (most clients show the server's stderr in their MCP log). Stdout never carries anything but JSON-RPC; the key is never logged.- A missing or ill-typed required argument (say
qabsent, orlimitas a string) gives the SDK's opaqueAn error occurred invoking '<tool>'.: the ModelContextProtocol SDK rejects it before the tool runs, so check the argument names and types againsttools/list. Every other problem comes back as the two-line error above. exit code 2at start, with the reason on stderr:TUNEPING_BASE_URLis not an absolute https URL (http only for a loopback host), orTUNEPING_API_KEYcontains a space or a non-ASCII character, for example the placeholdertp_live_…pasted unchanged.- The client log shows
You must install .NET to run this application(the client usually only says the server disconnected): .NET is installed outside the default location (dotnet-install.shinto~/.dotnet, Homebrew) and the GUI app does not get your shell'sDOTNET_ROOT. Add it to the server'senvblock next to the key, e.g."DOTNET_ROOT": "/Users/<you>/.dotnet"(dirname $(realpath $(which dotnet))prints it).
Attribution
Results of the Free tools and the resources carry an attribution member (Data by Tuneping, https://tuneping.com): show "Data by Tuneping" linking to https://tuneping.com when you display the data publicly.
Links
- API docs: https://tuneping.com/docs/
- Plans: https://tuneping.com/#pricing
- OpenAPI: https://tuneping.com/docs/openapi-v1.yaml
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.