Agents & Automation
spogo is built to be driven by something other than a human at a terminal — shell scripts, cron jobs, CI pipelines, AI coding agents. The same properties that make it pleasant interactively (stable JSON, plain mode, predictable exit codes, stderr-only logs) also make it safe to script.
#The contract
A script-friendly CLI must guarantee:
- Stable output. spogo's
--jsonand--plainmodes don't change keys/columns between releases without a major bump. - Stable exit codes.
0success,1generic,2usage,3auth,4network. Branch on these. - stdout is data. stderr carries everything else. Pipes always work.
- No interactive surprises. When stdin is not a TTY, spogo refuses to prompt. Pass
--no-inputto be explicit. - No tight rate limits. Cookie auth via Connect avoids the public Web API throttle.
See Output for the full contract.
#Wiring spogo into a shell script
#!/usr/bin/env bash
set -euo pipefail
# Make sure auth still works
if ! spogo auth status >/dev/null 2>&1; then
echo "spogo: cookies missing or stale; re-run 'spogo auth import'" >&2
exit 3
fi
# Capture the currently playing track ID
track_id=$(spogo status --json | jq -r '.item.id // empty')
if [[ -z "$track_id" ]]; then
echo "Nothing playing" >&2
exit 0
fi
# Save it
spogo library tracks add "$track_id"
Pin to a specific spogo version in CI to avoid silent JSON drift across releases.
#Common patterns
#Save the currently playing track
id=$(spogo status --json | jq -r '.item.id')
spogo library tracks add "$id"
#Build a playlist from a search
spogo playlist create "Weekly Lo-Fi"
spogo search track "lo-fi 2026" --limit 30 --plain |
awk '{print $1}' |
xargs spogo playlist add "Weekly Lo-Fi"
#Snapshot library to JSON
spogo library tracks list --limit 1000 --json > snapshots/tracks.$(date +%F).json
#Move playback to a specific room when leaving home
spogo device set "Phone"
#"Sleep timer" — pause after N minutes
sleep "${1:-1800}" && spogo pause
#Cron / launchd / systemd
spogo writes nothing to stdout that isn't useful and nothing to stderr unless something happened — perfect for cron tail logs.
# Snapshot liked tracks daily at 04:00
0 4 * * * /usr/local/bin/spogo library tracks list --limit 1000 --json > "$HOME/snapshots/tracks-$(date +\%F).json" 2>&1
For headless servers / CI runners, copy a working cookie jar (from a machine where you ran auth import) into the runner's spogo config directory rather than trying to import from a browser that doesn't exist.
#CI
GitHub Actions example:
- name: Install spogo
run: brew install steipete/tap/spogo
- name: Restore cookies
run: |
mkdir -p "$HOME/.config/spogo/default"
echo "$SPOGO_COOKIES" > "$HOME/.config/spogo/default/cookies.json"
env:
SPOGO_COOKIES: ${{ secrets.SPOGO_COOKIES }}
- name: Snapshot library
run: spogo library tracks list --json --limit 1000 > tracks.json
Treat the cookie jar like a credential — it's tied to your Spotify session.
#Coding agents
spogo is a good fit for AI coding agents (Claude Code, Codex, Cursor) because:
- Self-documenting.
spogo --helpandspogo <subcommand> --helpdescribe the entire surface. The Spec is short and stable. - Deterministic. Stable JSON keys mean the agent's parsing doesn't drift across releases.
- Safe-ish. The destructive surface is small (
library tracks remove,playlist remove,auth clear). Wrap those behind explicit confirmation in your agent prompt.
Recommended agent rules:
- Always pass
--jsonor--plainfor output the agent will parse. - Always pass
--no-inputso spogo cannot block on a prompt. - Branch on exit code, not stderr text.
- Pin spogo version in the agent's environment.
A starter system prompt fragment for an agent:
You can use the
spogoCLI to control Spotify. Always pass--jsonand--no-input. Readspogo --helpandspogo <cmd> --helpbefore invoking unfamiliar commands. Treat exit code3as "needs auth" — surface that to the user, don't try to recover automatically.
#Safety
spogo has no built-in command allowlist or read-only mode. If you're handing it to an unattended process or untrusted agent and want to restrict it:
- Run inside a separate spogo profile (
SPOGO_PROFILE=automation) with cookies for an account that has limited permissions. - Wrap spogo in a thin shell script that whitelists subcommands.
- Use the
applescriptengine on macOS — no cookies, no remote mutations possible (only local app control).
#Debugging an automation
Always re-run with -v (or -d for full HTTP traces) when something misbehaves — diagnostic output goes to stderr and won't pollute pipelines:
spogo -d status 2>spogo.log | jq .
See Troubleshooting.