spotify-mcp-server

jadilson12/spotify-mcp-server

3.3

If you are the rightful owner of spotify-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

Spotipy MCP Server integrates Spotify music control with Model Context Protocol (MCP) for enhanced music management.

Tools
5
Resources
0
Prompts
0

Spotipy MCP Server

CI/CD Pipeline Python 3.12 Python 3.13 License: MIT Tests

MCP (Model Context Protocol) Server with Spotipy integration for music control via Spotify.

๐Ÿš€ Features

  • โœ… Playback control (play, pause, next, previous)
  • โœ… Volume adjustment
  • โœ… Music search
  • โœ… Get current track
  • โœ… Playlist management
  • โœ… Complete REST API
  • โœ… Automatic documentation (Swagger)
  • โœ… Complete MCP integration with tools and resources

๐Ÿ“‹ Prerequisites

  • Python 3.12+
  • Spotify Developer account
  • Registered application in Spotify Developer Dashboard

๐Ÿ› ๏ธ Installation

  1. Clone the repository:
git clone https://github.com/jadilson12/spotify-mcp-server
cd spotify-mcp-server
  1. Install dependencies:
make install
  1. Configure environment variables:
cp env.example .env

Edit the .env file with your Spotify credentials:

SPOTIFY_CLIENT_ID=your_client_id_here
SPOTIFY_CLIENT_SECRET=your_client_secret_here
SPOTIFY_REDIRECT_URI=http://localhost:8888/callback

๐ŸŽต Spotify Configuration

๐Ÿ“‹ Step-by-Step Tutorial: Getting Spotify Credentials

Step 1: Access Spotify Developer Dashboard
  1. Go to Spotify Developer Dashboard
  2. Log in with your Spotify account (or create one if you don't have it)
Step 2: Create a New Application
  1. Click "Create App" button
  2. Fill in the application details:
    • App name: Spotify MCP Server (or any name you prefer)
    • App description: MCP Server for Spotify music control
    • Website: http://localhost:8000 (optional)
    • Redirect URI: http://localhost:8888/callback
    • API/SDKs: Select "Web API"
  3. Click "Save"
Step 3: Get Your Credentials
  1. After creating the app, you'll be redirected to your app dashboard
  2. Copy the Client ID (visible on the main page)
  3. Click "Show Client Secret" and copy the Client Secret
  4. โš ๏ธ Keep these credentials secure! Never share them publicly.
Step 4: Configure Redirect URIs
  1. In your app dashboard, go to "Edit Settings"
  2. Under "Redirect URIs", add: http://localhost:8888/callback
  3. Click "Add" and then "Save"
Step 5: Configure Required Scopes
  1. In your app dashboard, go to "Edit Settings"
  2. Under "User Management", you'll see the scopes section
  3. Important: The following scopes will be requested during authentication:
    • user-read-playback-state - Read playback state
    • user-modify-playback-state - Control playback
    • user-read-currently-playing - Current track
    • playlist-read-private - Private playlists
    • user-library-read - User library
    • user-top-read - Top artists and tracks
    • user-read-recently-played - Recently played tracks
    • user-follow-read - Followed artists
    • user-read-email - User email
    • user-read-private - Private information
Step 6: Update Your .env File
  1. Copy the env.example file to .env
  2. Replace the placeholder values with your actual credentials:
SPOTIFY_CLIENT_ID=your_actual_client_id_here
SPOTIFY_CLIENT_SECRET=your_actual_client_secret_here
SPOTIFY_REDIRECT_URI=http://localhost:8888/callback
Step 7: Test Your Configuration
  1. Start the server: make dev
  2. The first time you use the API, you'll be redirected to Spotify for authentication
  3. Accept the permissions requested by Spotify
  4. You should now be able to control your Spotify music!

๐Ÿ” Security Tips

  • Never commit your .env file to version control
  • Keep your credentials private and secure
  • Use different apps for development and production
  • Regularly rotate your client secret if needed

๐Ÿš€ Usage

Start the server:

make dev

The server will be available at:

๐Ÿ› ๏ธ Development Guide

๐Ÿ”„ Essential Commands

# Complete server restart
pkill -f "python.*mcp-server" && sleep 2 && make dev

# Kill MCP ports (REQUIRED before run-inspector)
lsof -ti:6274 | xargs kill -9 && lsof -ti:6277 | xargs kill -9

# Check ports in use
lsof -i:6274 && lsof -i:6277

โš ๏ธ IMPORTANT: Always Kill Ports!

BEFORE running make run-inspector, ALWAYS execute:

# Kill MCP ports (REQUIRED)
lsof -ti:6274 | xargs kill -9 && lsof -ti:6277 | xargs kill -9

Why is this necessary?

  • MCP Inspector uses ports 6274 (UI) and 6277 (Proxy)
  • If ports are occupied, Inspector cannot start
  • Previous processes may have left ports in use

๐ŸŽฏ Development Workflow

  1. After Modifying Code:
pkill -f "python.*mcp-server" && sleep 2 && make dev
  1. To Test with MCP Inspector:
lsof -ti:6274 | xargs kill -9 && lsof -ti:6277 | xargs kill -9
make run-inspector

Available commands:

make dev              # Start development server
make install          # Install dependencies
make clean            # Clean temporary files
make test             # Run tests
make lint             # Check code quality
make format           # Format code
make run-inspector    # Run MCP Inspector
make help             # Show help

๐ŸŽต MCP Features

Available Tools:

  • play_music - Play music
  • search_tracks - Search tracks
  • get_current_track - Current track
  • get_playlists - List playlists
  • get_recommendations - Recommendations
  • get_user_profile - User profile
  • get_devices - Available devices
  • get_queue - Playback queue
  • get_genres - Music genres
  • get_audio_features - Audio characteristics

Available Resources:

  • spotify://playback/current - Current playback
  • spotify://playlists - User playlists
  • spotify://devices - Devices
  • spotify://genres - Genres
  • spotify://profile - User profile
  • spotify://playback/queue - Playback queue

Resource Templates:

  • spotify://playlist/{playlist_id} - Specific playlist
  • spotify://track/{track_id} - Specific track
  • spotify://artist/{artist_id} - Specific artist
  • spotify://album/{album_id} - Specific album
  • spotify://search/{query} - Search results

๐Ÿ“š API Endpoints

Authentication

  • POST /auth - Authenticate with Spotify
  • POST /auth/reauth - Re-authenticate with configured credentials

Playback

  • GET /current-track - Get current track
  • POST /play - Play music
  • POST /pause - Pause music
  • POST /next - Next track
  • POST /previous - Previous track
  • POST /volume/{volume} - Adjust volume (0-100)
  • POST /seek/{position_ms} - Seek to specific position
  • POST /shuffle - Toggle shuffle mode
  • POST /repeat - Toggle repeat mode

Playlists and Albums

  • GET /playlists - Get user playlists
  • GET /playlist/{playlist_id} - Get playlist tracks
  • GET /albums - Get user saved albums
  • GET /tracks - Get user saved tracks

Artists and Top Tracks

  • GET /artists - Get user favorite artists
  • GET /tracks/top - Get most played tracks

Playback Queue

  • GET /queue - Get current playback queue
  • POST /queue/add - Add track to queue

Devices

  • GET /devices - Get available devices
  • POST /devices/{device_id}/transfer - Transfer playback

Search and Recommendations

  • GET /search/{query} - Search tracks
  • GET /recommendations - Get personalized recommendations
  • GET /genres - Get available music genres

User and Analysis

  • GET /user/profile - Get user profile
  • GET /audio-features/{track_id} - Get audio features

System

  • GET / - Server status
  • GET /health - Health check

๐Ÿ”ง Usage Examples

Play a specific track:

curl -X POST "http://localhost:8000/play" \
  -H "Content-Type: application/json" \
  -d '{"track_uri": "spotify:track:4iV5W9uYEdYUVa79Axb7Rh"}'

Search tracks:

curl "http://localhost:8000/search/bohemian%20rhapsody?limit=5"

Adjust volume:

curl -X POST "http://localhost:8000/volume/50"

Get current track:

curl "http://localhost:8000/current-track"

Get user playlists:

curl "http://localhost:8000/playlists"

Get tracks from a specific playlist:

curl "http://localhost:8000/playlist/37i9dQZF1DXcBWIGoYBM5M"

Get saved tracks:

curl "http://localhost:8000/tracks"

Get favorite artists:

curl "http://localhost:8000/artists"

Get recommendations based on artists:

curl "http://localhost:8000/recommendations?seed_artists=4gzpq5DPGxSnKTe4SA8HAU&limit=10"

Toggle shuffle:

curl -X POST "http://localhost:8000/shuffle"

Add track to queue:

curl -X POST "http://localhost:8000/queue/add?track_uri=spotify:track:4iV5W9uYEdYUVa79Axb7Rh"

Get available devices:

curl "http://localhost:8000/devices"

Seek to specific position (30 seconds):

curl -X POST "http://localhost:8000/seek/30000"

Re-authenticate with Spotify:

curl -X POST "http://localhost:8000/auth/reauth"

๐Ÿš€ CI/CD Pipeline

๐Ÿ“Š Pipeline Status

Our CI/CD pipeline ensures code quality and security:

  • โœ… Tests: 60 tests passing on Python 3.12 & 3.13
  • โœ… Linting: Code quality checks with flake8
  • โœ… Formatting: Black and isort formatting validation
  • โœ… Security: Secrets detection and .env file validation
  • โœ… Build: Package building and artifact generation

๐Ÿ”„ Pipeline Jobs

JobDescriptionStatus
TestRun all tests on Python 3.12 & 3.13
LintCode quality and formatting checks
SecuritySecrets detection and security validation
BuildPackage building and distribution

๐Ÿ›ก๏ธ Security Checks

The pipeline includes comprehensive security validation:

  • ๐Ÿ” TruffleHog: Advanced secret scanner for detecting credentials
  • ๐Ÿ•ต๏ธ detect-secrets: Multi-pattern secret detection with baseline
  • ๐Ÿ” Pattern Matching: Custom regex patterns for sensitive data
  • ๐Ÿ“ File Validation: Checks for committed sensitive files (.env, .key, .pem)
  • โš™๏ธ Gitignore Validation: Ensures sensitive file patterns are ignored
  • ๐ŸŒ URL Scanning: Detects hardcoded cloud service URLs
  • ๐Ÿ“Š Security Reports: Generates detailed security scan artifacts

Protected Patterns:

  • API keys and tokens
  • Passwords and secrets
  • Base64/Hex encoded strings
  • AWS, Google, Azure credentials
  • Private keys and certificates
  • Spotify client credentials

๐Ÿ“‹ Local Pipeline Testing

Test the pipeline locally before pushing:

# Run all pipeline checks locally
make test-pytest    # Tests
make lint          # Linting
make format        # Formatting
make security      # Security checks

๐Ÿ” Security Commands

# Run security checks
make security       # Basic security validation

# Full security scan (requires tools)
pip install detect-secrets truffleHog3
detect-secrets scan --all-files
trufflehog3 --format json .

๐Ÿงช Tests

โœ… 60 tests PASSING | โฑ๏ธ ~0.38s | ๐Ÿ”ง 100% Functional

๐Ÿš€ Run Tests

# Run all tests (recommended)
make test-pytest

# Or use pytest directly
python -m pytest tests/ -v --tb=short --color=yes

๐Ÿ“‹ Test Coverage

๐Ÿ”ง MCP Tools Tests (36 tests)
  • โœ… Playback control (play_music, pause_music, next_track, previous_track)
  • โœ… Volume management (set_volume)
  • โœ… Search and discovery (search_tracks, search_artists, search_albums, search_playlists)
  • โœ… Playlists and albums (get_playlists, get_playlist_tracks, get_album_tracks)
  • โœ… Profile and preferences (get_user_profile, get_top_tracks, get_top_artists)
  • โœ… Personal library (get_saved_tracks, get_saved_albums, get_followed_artists)
  • โœ… Devices and queue (get_devices, get_queue, add_to_queue)
  • โœ… Recommendations (get_recommendations, get_genres, get_audio_features)
  • โœ… Navigation (skip_to_next, skip_to_previous, seek_to_position)
  • โœ… History (get_recently_played)
  • โœ… Related artists (get_related_artists, get_artist_top_tracks, get_artist_albums)
๐Ÿ’ฌ MCP Prompts Tests (6 tests)
  • โœ… spotify_assistant - Intelligent music assistant
  • โœ… spotify_usage_guide - Feature usage guide
  • โœ… spotify_troubleshooting - Problem solving
๐Ÿ“š MCP Resources Tests (12 tests)
  • โœ… spotify://playback/current - Current playback state
  • โœ… spotify://playlists/user - User playlists
  • โœ… spotify://devices/available - Available devices
  • โœ… spotify://genres/available - Music genres
  • โœ… spotify://user/profile - User profile
  • โœ… spotify://playback/queue - Playback queue
  • โœ… spotify://user/top-tracks - Top tracks
  • โœ… spotify://user/top-artists - Top artists
  • โœ… spotify://user/recently-played - Recently played
  • โœ… spotify://user/saved-tracks - Saved tracks
  • โœ… spotify://user/saved-albums - Saved albums
  • โœ… spotify://user/followed-artists - Followed artists
๐Ÿ”ง Functionality Tests (3 tests)
  • โœ… Correct tool structure
  • โœ… Valid descriptions in all tools
  • โœ… Error handling implemented
๐Ÿ“Š Validation Tests (2 tests)
  • โœ… Volume request validation
  • โœ… Search request validation
๐Ÿ”— Integration Test (1 test)
  • โœ… Server completeness (tools, prompts, resources)

๐ŸŽฏ Available Test Commands

# Run all tests
make test-pytest           # Using pytest (recommended)

# Specific tests (future)
make test-tools            # Tools tests only
make test-prompts          # Prompts tests only
make test-resources        # Resources tests only
make test-integration      # Integration tests only
make test-coverage         # Check coverage

# Test with detailed output
python -m pytest tests/ -v -s --tb=long

๐Ÿ“ˆ Latest Test Results

===================================== test session starts =====================================
collected 60 items

TestMCPServerBasics โœ… (4/4)
TestMCPTools โœ… (36/36)
TestMCPPrompts โœ… (6/6)
TestMCPResources โœ… (12/12)
TestToolFunctionality โœ… (2/2)
TestErrorHandling โœ… (1/1)
TestDataValidation โœ… (2/2)
TestIntegration โœ… (1/1)

===================================== 60 passed in 0.38s ======================================

๐Ÿ” Test Structure

tests/
โ”œโ”€โ”€ test_main.py          # All MCP server tests
โ”œโ”€โ”€ __init__.py           # Module initialization
โ””โ”€โ”€ README.md            # Test documentation

๐Ÿงช How to Add New Tests

  1. For new tool:
@pytest.mark.asyncio
async def test_new_tool_exists(self):
    """Test if new tool exists"""
    tools = await app.get_tools()
    assert 'new_tool' in tools
  1. For new resource:
@pytest.mark.asyncio
async def test_new_resource_exists(self):
    """Test if new resource exists"""
    resources = await app.get_resources()
    assert 'spotify://new/resource' in resources

โš ๏ธ Important for Tests

  • ALWAYS run tests after modifying code
  • Use make test-pytest for fast and reliable execution
  • Tests don't require real Spotify authentication
  • Tests focus on structure and feature availability

๐Ÿ” Linting and Formatting

make lint    # Check code quality
make format  # Format code automatically

๐Ÿ“ Project Structure

mcp-server/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ mcp-server.py    # Main MCP server
โ”‚   โ”œโ”€โ”€ service.py       # Spotify logic
โ”‚   โ”œโ”€โ”€ server.py        # FastAPI server
โ”‚   โ””โ”€โ”€ config.py        # Configuration
โ”œโ”€โ”€ tests/               # Tests
โ”œโ”€โ”€ makefile             # Development commands
โ”œโ”€โ”€ pyproject.toml       # Project configuration

โ”œโ”€โ”€ env.example          # Environment variables example
โ””โ”€โ”€ README.md           # This file

โš ๏ธ Common Issues

Error: "PORT IS IN USE"

# Quick solution
lsof -ti:6274 | xargs kill -9
lsof -ti:6277 | xargs kill -9

Error: "ModuleNotFoundError"

# Reinstall dependencies
make install

Server not responding

# Complete restart
pkill -f "python.*mcp-server" && sleep 2 && make dev

Error 403 - Insufficient Permission

If you receive error 403 with message "Insufficient client scope":

  1. Verify all required scopes are configured
  2. Re-authenticate with Spotify using /auth endpoint
  3. Make sure you accepted all requested permissions

Endpoints Requiring Specific Permissions

  • /artists and /tracks/top - Require user-top-read
  • /recommendations - Require at least one valid seed
  • /user/profile - Require user-read-email and user-read-private

Known Issues

  • Recommendations (404): The recommendations API may return 404 in some cases. This can be due to:
    • Temporary Spotify API issues
    • Invalid or not found seeds
    • Authentication problems
  • Solution: Use /auth/reauth endpoint to re-authenticate if necessary

๐Ÿ”ง Important Tips

  1. ALWAYS restart server after modifying mcp-server.py
  2. ALWAYS kill ports before running Inspector (6274 and 6277)
  3. ALWAYS verify ports are free before running make run-inspector
  4. Check logs to identify problems
  5. Use make dev for local development
  6. Keep .env properly configured

๐Ÿค Contributing

We welcome contributions! Please follow these steps:

๐Ÿš€ Development Workflow

  1. Fork the project
  2. Create a feature branch:
    git checkout -b feature/AmazingFeature
    
  3. Make your changes and test locally:
    make test-pytest    # Run tests
    make lint          # Check code quality
    make format        # Format code
    
  4. Commit your changes:
    git commit -m 'Add some AmazingFeature'
    
  5. Push to your branch:
    git push origin feature/AmazingFeature
    
  6. Open a Pull Request

โœ… CI/CD Requirements

All contributions must pass our CI/CD pipeline:

  • Tests: All 60 tests must pass
  • Linting: Code must pass flake8 checks
  • Formatting: Code must be properly formatted with Black
  • Security: No secrets or sensitive files committed
  • Build: Package must build successfully

๐Ÿ›ก๏ธ Security Guidelines

  • Never commit .env files or credentials
  • Use placeholders in examples (e.g., your_client_id_here)
  • Follow the security checklist in SECURITY.md
  • Test locally before pushing

๐Ÿ“‹ Code Quality Standards

  • Python 3.12+ compatibility
  • Type hints for all functions
  • Docstrings for all public functions
  • Error handling for all external API calls
  • Tests for new functionality

๐Ÿ“„ License

This project is under MIT license. See the LICENSE file for more details.

๐Ÿ†˜ Support

If you encounter any problems or have questions:

  1. Check if Spotify credentials are correct
  2. Make sure Spotify is running on some device
  3. Check server logs for more details
  4. Open an issue in the repository

๐Ÿ”— Useful Links


๐ŸŽต Music is life! Let's make an amazing MCP server! ๐Ÿš€