Skip to content

Agents and MCP

Agents use the same surfaces humans use. There is no hidden agent-only path. There are two ways to wire spotuify into an agent, and they compose:

  1. The agent skill teaches an agent to drive the spotuify CLI well (output flags, preview-first mutations, guardrails). Works with any agent that loads skills and can run shell commands.
  2. The MCP server exposes the daemon as structured tools for agents that speak MCP.

The skill is a single SKILL.md. Drop it into your agent’s skills directory.

Terminal window
mkdir -p ~/.claude/skills/spotuify
curl -fsSL https://raw.githubusercontent.com/planetaryescape/spotuify/main/skills/spotuify/SKILL.md \
-o ~/.claude/skills/spotuify/SKILL.md

Prefer a packaged bundle? Download spotuify.skill and unzip it into the same directory:

Terminal window
curl -fsSL https://spotuify.vercel.app/spotuify.skill -o /tmp/spotuify.skill
unzip -o /tmp/spotuify.skill -d ~/.claude/skills/spotuify

Once installed, the agent knows the command surface, always reads --format json, and previews mutations with --dry-run before applying them. It also knows the behaviors that trip up agents: the queue is a set (re-adding a queued track is skipped, and queue adds are not undoable), audio-output switches live without a daemon restart, and discovery runs through artist related / radio start.

Terminal window
spotuify mcp # JSON-RPC 2.0 over stdio (default transport)
spotuify mcp --http 127.0.0.1:8765 # loopback Streamable HTTP

The HTTP transport binds to loopback only and requires a token:

Terminal window
export SPOTUIFY_MCP_TOKEN="$(openssl rand -hex 32)"
spotuify mcp --http 127.0.0.1:8765

Most clients launch the stdio transport for you. Register spotuify mcp as the command.

Claude Code:

Terminal window
claude mcp add spotuify -- spotuify mcp

Claude Desktop (claude_desktop_config.json) or Cursor (~/.cursor/mcp.json):

{
"mcpServers": {
"spotuify": { "command": "spotuify", "args": ["mcp"] }
}
}

For an HTTP-based client, start spotuify mcp --http 127.0.0.1:8765 yourself and point the client at http://127.0.0.1:8765 with the SPOTUIFY_MCP_TOKEN as a bearer token.

Tools mirror the CLI (37 in total). Reads and transport are safe by default; persistent changes are preview-first and need confirmation in the tool args.

ToolKindNotes
searchreadlocal or remote search
now_playingreadcurrent playback
devices_list / queue_show / playlists_list / playlist_tracks / library_listreadcurrent state
devices_list / queue_show / playlists_listreadcurrent state
analytics_top / analytics_habits / analytics_rediscoveryanalyticslocal listening data
analytics_import_status / analytics_import_unresolvedanalyticsinspect historical import runs
analytics_import_lastfmdestructivedry-run unless apply: true
analytics_import_undodestructivedry-run unless yes: true or force: true
play / play_uri / pause / next / seek / volumetransportplayback control
queue_add / transfer_devicetransportqueue + device
playlist_plan / playlist_resolve_tracksreadplan a playlist, resolve to URIs
lyrics / related_artistsdiscoverysynced lyrics; Mercury-backed related artists
analytics_top / analytics_habits / analytics_search / analytics_rediscoveryanalyticslocal listening data
play / play_uri / pause / resume / next / previous / seek / volume / shuffle / repeattransportplayback control
queue_add / transfer_device / radio_starttransportqueue, device, Mercury radio
playlist_create / playlist_add / playlist_remove / playlist_unfollow / playlist_set_imagedestructivepreview unless confirmed
library_save / library_unsavedestructivelike/unlike
ops_log / undo_lastopsinspect the op log; reversal safety net
spotuify://playback
spotuify://devices
spotuify://playlists
spotuify://now_playing/lyrics
spotuify://doctor

Read a resource when the agent needs current state instead of issuing another command.

Over the stdio transport the server also pushes notifications/resources/updated for resources the client has resources/subscribed to (spotuify://playback, spotuify://devices, spotuify://playlists), so an agent can react to live changes without polling. The HTTP transport has no SSE, so push is stdio-only; HTTP clients re-read on their own cadence.

Terminal window
spotuify playlist plan "exile and returning home" --format json > plan.json
spotuify resolve-tracks --from plan.json --format jsonl > candidates.jsonl
spotuify playlist create "Exile and Return" --from candidates.jsonl --dry-run

Commit only after approval:

Terminal window
spotuify playlist create "Exile and Return" --from candidates.jsonl --yes --format json

Start with a preview. The MCP analytics_import_lastfm tool accepts user or username, optional api_key, optional from_ms / to_ms, and apply.

{
"user": "your-lastfm-user",
"from_ms": 1704067200000,
"apply": false
}

After the user approves the counts, retry with apply: true. Save the returned run_id, then use analytics_import_unresolved to inspect misses or analytics_import_undo to preview rollback.

Make me a playlist for a hard debugging session.
Use spotuify playlist plan, resolve-tracks, and playlist create --dry-run.
Show me the preview. Do not use --yes until I approve.
  • Use --format json or --format jsonl for agent reads.
  • Use --dry-run for broad playlist changes; show the preview before applying.
  • Use Last.fm import dry-run before apply: true; use import undo dry-run before yes: true.
  • Prefer URIs and IDs over display names.
  • Do not claim lyrics or themes unless you checked a lyrics provider or another source.
  • Do not run --yes without explicit user approval.