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:
- The agent skill teaches an agent to drive the
spotuifyCLI well (output flags, preview-first mutations, guardrails). Works with any agent that loads skills and can run shell commands. - The MCP server exposes the daemon as structured tools for agents that speak MCP.
Install the agent skill
Section titled “Install the agent skill”The skill is a single SKILL.md. Drop it into your agent’s skills directory.
mkdir -p ~/.claude/skills/spotuifycurl -fsSL https://raw.githubusercontent.com/planetaryescape/spotuify/main/skills/spotuify/SKILL.md \ -o ~/.claude/skills/spotuify/SKILL.mdPrefer a packaged bundle? Download spotuify.skill and unzip it into the same directory:
curl -fsSL https://spotuify.vercel.app/spotuify.skill -o /tmp/spotuify.skillunzip -o /tmp/spotuify.skill -d ~/.claude/skills/spotuifyOnce 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.
Run the MCP server
Section titled “Run the MCP server”spotuify mcp # JSON-RPC 2.0 over stdio (default transport)spotuify mcp --http 127.0.0.1:8765 # loopback Streamable HTTPThe HTTP transport binds to loopback only and requires a token:
export SPOTUIFY_MCP_TOKEN="$(openssl rand -hex 32)"spotuify mcp --http 127.0.0.1:8765Connect your agent
Section titled “Connect your agent”Most clients launch the stdio transport for you. Register spotuify mcp as the command.
Claude Code:
claude mcp add spotuify -- spotuify mcpClaude 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.
MCP tools
Section titled “MCP tools”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.
| Tool | Kind | Notes |
|---|---|---|
search | read | local or remote search |
now_playing | read | current playback |
devices_list / queue_show / playlists_list / playlist_tracks / library_list | read | current state |
devices_list / queue_show / playlists_list | read | current state |
analytics_top / analytics_habits / analytics_rediscovery | analytics | local listening data |
analytics_import_status / analytics_import_unresolved | analytics | inspect historical import runs |
analytics_import_lastfm | destructive | dry-run unless apply: true |
analytics_import_undo | destructive | dry-run unless yes: true or force: true |
play / play_uri / pause / next / seek / volume | transport | playback control |
queue_add / transfer_device | transport | queue + device |
playlist_plan / playlist_resolve_tracks | read | plan a playlist, resolve to URIs |
lyrics / related_artists | discovery | synced lyrics; Mercury-backed related artists |
analytics_top / analytics_habits / analytics_search / analytics_rediscovery | analytics | local listening data |
play / play_uri / pause / resume / next / previous / seek / volume / shuffle / repeat | transport | playback control |
queue_add / transfer_device / radio_start | transport | queue, device, Mercury radio |
playlist_create / playlist_add / playlist_remove / playlist_unfollow / playlist_set_image | destructive | preview unless confirmed |
library_save / library_unsave | destructive | like/unlike |
ops_log / undo_last | ops | inspect the op log; reversal safety net |
MCP resources
Section titled “MCP resources”spotuify://playbackspotuify://devicesspotuify://playlistsspotuify://now_playing/lyricsspotuify://doctorRead 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.
Safe playlist loop
Section titled “Safe playlist loop”spotuify playlist plan "exile and returning home" --format json > plan.jsonspotuify resolve-tracks --from plan.json --format jsonl > candidates.jsonlspotuify playlist create "Exile and Return" --from candidates.jsonl --dry-runCommit only after approval:
spotuify playlist create "Exile and Return" --from candidates.jsonl --yes --format jsonSafe Last.fm import loop
Section titled “Safe Last.fm import loop”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.
Prompt shape
Section titled “Prompt shape”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.Guardrails
Section titled “Guardrails”- Use
--format jsonor--format jsonlfor agent reads. - Use
--dry-runfor broad playlist changes; show the preview before applying. - Use Last.fm import dry-run before
apply: true; use import undo dry-run beforeyes: 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
--yeswithout explicit user approval.