AudioStream Orchestrator via MCP
A standardized interface utilizing the Model-Context-Protocol (MCP) to govern remote operations on the Spotify audio streaming platform, encompassing discovery, playback manipulation, configuration adjustments, and user state retrieval.
Author

KaanCL
Quick Info
Actions
Tags
🎧 Spotify Audio Orchestrator using MCP
This repository implements a service conforming to the Model-Context-Protocol (MCP) specification, designed to grant AI agents and compatible clients granular control over the Spotify ecosystem.
🌐 Protocol Context: MCP
The Model-Context-Protocol (MCP) furnishes a uniform contract for external tooling integration. By exposing Spotify functionalities as discrete MCP tools, this system ensures seamless interoperability with any client adhering to the MCP architecture, such as advanced conversational AI systems or dedicated orchestration bots.
🌟 Core Capabilities
- 🔎 Track/Content Discovery: Execute searches across the Spotify catalog.
- ▶️ Initiate Playback: Commence streaming on a designated device.
- ⏸️ Temporal Control: Halt or resume the current audio stream.
- ⏩ Navigation: Advance to the subsequent track or revert to the preceding one.
- 🎚️ Auditory Level Adjustment: Fine-tune the output volume across the active player.
- 🆔 Account Inquiry: Fetch details pertaining to the authenticated user.
- 📚 Library Access: Enumerate the user's curated music collections.
- 📡 Status Reporting: Query the metadata of the currently active audio selection.
⚙️ Prerequisites for Deployment
- Runtime Environment: Python version 3.11 or newer.
- Subscription Requirement: Active Spotify Premium service tier.
- Access Credentials: Valid Spotify Developer Application keys (Client ID/Secret).
🚀 Deployment Sequence
-
Source Acquisition: bash git clone https://github.com/KaanCL/Spotify-MCP-Server.git cd Spotify-MCP-Server
-
Environment Setup: bash uv venv
-
Dependency Resolution: bash uv sync
(Note: External libraries like spotipy are managed via uv sync defined in project configuration.)
🔑 Configuration Management
- Register a new application within the Spotify Developer Console.
- Secure your application's Client ID and Client Secret.
- Establish a
.envfile in the project root containing authorization data:
CLIENT_ID=your-spotify-client-id CLIENT_SECRET=your-spotify-client-secret REDIRECT_URI=http://localhost:8888/callback
▶️ Initialization and First Connection
Upon the initial execution of the MCP service:
- A browser window will launch, prompting the user for Spotify account authentication.
- Authorization consent must be granted for the application to interact with the user's Spotify data.
- Following successful authentication, a redirect to the specified callback URI will occur.
- The MCP server will finalize setup and commence listening for protocol commands, typically on port 8080.
🛠️ Command Invocation Table
The server registers the following callable methods within the MCP framework:
| Tool Identifier | Functionality Summary | Required Inputs (Schema) |
|---|---|---|
search |
Catalog content lookup | query: str |
start_playback |
Initiate media stream | track_name: str |
pause_playback |
Suspend current audio | None |
resume_playback |
Restart suspended audio | None |
next_track |
Skip forward in sequence | None |
previous_track |
Replay prior selection | None |
get_user_playlists |
List all user-created collections | None |
set_player_volume |
Modulate speaker output level | volume: int (Range 0-100) |
current_playback |
Report on active stream details | None |
get_current_user |
Fetch authenticated user profile | None |
🧩 Tool Reference Details
Every exposed tool corresponds to a Python method decorated with @mcp.tool(), structured for direct JSON serialization of results.
-
search(query: str) → dict: Queries Spotify based on the provided string. Returns a maximum of five matched items, detailing name, artist, album, unique URI, and web link. -
start_playback(track_name: str) → dict: Locates the specified track and begins playback on the currently active Spotify endpoint. -
pause_playback() → dict: Stops the presently active playback session. -
resume_playback() → dict: Resumes playback if it was previously halted. -
next_track() → dict: Advances to the ensuing track within the active queue or playlist context. -
previous_track() → dict: Rewinds playback to the prior track. -
get_user_playlists() → dict: Retrieves a manifest of user playlists, including identifying metadata (name, URL, ID) and track counts. -
set_player_volume(volume: int) → dict: Establishes the playback device volume, constrained between 0 and 100 inclusive. -
current_playback() → dict: Provides comprehensive status of the active media: state (playing/paused), track/artist/album identifiers, temporal position, and total duration. -
get_current_user() → dict: Fetches core profile attributes for the logged-in Spotify user (e.g., display name, email address, internal user ID).
🤖 Example Client Interaction (MCP Client)
Any MCP-compliant client can interact with this endpoint:
python from mcp.client import MCPClient
Establish connection
client = MCPClient("http://localhost:8080")
Perform a content lookup
search_results = client.call("search", {"query": "Stairway to Heaven"}) print(search_results)
Command playback initiation
client.call("start_playback", {"track_name": "Stairway to Heaven"})
Halt audio stream
client.call("pause_playback")
Query current stream metadata
present_status = client.call("current_playback") print(present_status)
🛑 Error Reporting Protocol
All service responses are serialized as JSON objects. Operational failures are signaled by the presence of an "error" field containing a human-readable explanation.
Failure Response Patterns:
{ "error": "Content not found: Search query yielded zero matching results." }
or
{ "error": "Device unavailability: Please activate Spotify on an accessible device before retrying." }
Guidance: Robust clients must always inspect for the
"error"key before attempting to parse or utilize the primary data payload.
Internal Error Management
- Error reporting adheres to a unified structure, facilitated by a dedicated
format_errorutility and enumerated constants (SpotifyError). - Common exception paths (e.g., device offline, invalid parameter values, authentication issues) are explicitly handled.
- All exceptions are normalized into a predictable JSON output format for simplified client-side exception choreography.
📐 System Architecture Visualization
mermaid graph TD A[MCP Client Application] -- HTTP Transport --> B[FastMCP Service Layer] B -- Internal Tool Invocation --> C[Spotify Interaction Module (spotipy wrapper)] C -- External API Call --> D[Spotify Web Services]
🧠 Operational Mechanism: MCP Framework
- Service Registration: The server introspects and registers defined tools, mapping them to URI endpoints.
- High-Performance Foundation: Leverages the FastMCP implementation for efficient request handling.
- Service Bridging: Utilizes the
spotipylibrary to interface with the underlying Spotify REST infrastructure. - Tool Definition: Every Spotify operation is encapsulated as an MCP tool, complete with precise type annotations and documentation strings.
The MCP layer abstracts the intricacies of the Spotify API, presenting capabilities to AI models through a clean, discoverable interface. This promotes decoupled architecture.
💎 Code Integrity and Maintainability Attributes
- Enumerations: Employed for configuration scopes and error enumeration to ensure type safety.
- Consolidated Error Handling: A singular formatting utility guarantees output uniformity.
- Abstraction (DRY): Repeated validation logic (e.g., checking for an active playback device) is externalized into utility functions.
- Static Typing: Comprehensive Python type hints are used throughout for enhanced static analysis and IDE integration.
- Thorough Documentation: All public components feature comprehensive docstrings.
- Extensibility: Adding new Spotify actions involves implementing a function in the interaction module and decorating it with
@mcp.tool()in the main entry point.
🧩 Extending Functionality
To integrate novel Spotify features:
1. Develop the corresponding logic function within the primary interaction module, ensuring robust error treatment and documentation.
2. Declare this new function as an MCP mechanism in main.py using the decorator.
3. Chronicle the new tool within this README.
Developer Guidance: All MCP tool returns must conform to dictionary structures for seamless JSON serialization. For diagnostic purposes, standard logging or print statements are encouraged within tool implementations. Detailed type hints are mandatory to preserve code clarity, maintainability, and tool discoverability within consuming environments. Ensure that the core Spotify interface module correctly manages authentication tokens and API requests. Proper configuration of credentials is vital for OAuth flows.
🛡️ Security Posture
- Authentication secrets are confined to the local
.envconfiguration file. - The
.envfile is explicitly excluded from source control via.gitignore. - By default, the service restricts inbound connections to the local machine loopback interface.
- Crucial Precaution: Never commit sensitive configuration data to any public or private repository!
❓ Troubleshooting Common Issues
- Device Status Error: Verify that the Spotify application is running and actively selected on one of your connected endpoints.
- Authorization Failures: Scrutinize the Client ID/Secret pair against the Spotify Developer Portal setup.
- API Throttling: Excessive, rapid requests can trigger Spotify's rate limiting mechanisms; moderate request frequency.
- Unforeseen Failures: Examine the
"error"field within the JSON response for specific diagnostic messages.
🧑💻 Development & Community Guidelines
- All function results are structured as Python dictionaries or lists to facilitate effortless JSON conversion.
- Consistency in error reporting (checking for the
"error"key) is paramount. - Propose new integrations by adding decorated functions in the primary execution script.
- Use appropriate logging modules for debugging instead of excessive terminal output.
- Contributions via pull requests are welcomed; however, initiating a discussion via an issue ticket beforehand is appreciated to align on proposed modifications.
📚 Essential Resources
Supplemental Context on Asynchronous Data Transfer (XMLHttpRequest):
XMLHttpRequest (XHR) is a foundational JavaScript API enabling browser applications to initiate asynchronous HTTP transactions with a remote server subsequent to the initial page load. This mechanism is central to Asynchronous JavaScript and XML (Ajax) programming patterns. Previously, server interaction mandated full-page reloads via form submissions or standard hyperlinks.
== Lineage ==
The kernel concept for XHR originated within the Microsoft Outlook development team circa 2000, finding its first implementation in Internet Explorer 5 (1999). The original invocation syntax deviated, utilizing COM object identifiers like ActiveXObject("Msxml2.XMLHTTP"). By the release of Internet Explorer 7 (2006), the standardized XMLHttpRequest identifier achieved universal browser adoption, including implementations across Mozilla's Gecko engine (2002), Safari 1.2 (2004), and Opera 8.0 (2005).
=== Standardization Efforts === The World Wide Web Consortium (W3C) formalized the object specification in a Working Draft on April 5, 2006. A subsequent Level 2 draft, introduced on February 25, 2008, augmented capabilities to include progress monitoring, cross-origin access control, and byte stream handling. By late 2011, the Level 2 features were integrated back into the primary specification. Development responsibility transitioned to WHATWG near the close of 2012, which now maintains the living document using Web IDL.
== Operational Steps == Executing a server request via XHR typically involves a sequence of five programming actions:
- Instantiation: Creating an instance of the
XMLHttpRequestobject constructor. - Configuration (
open): Invoking theopenmethod to define the HTTP verb, target resource URI, and whether the operation should be synchronous or asynchronous. - Asynchronous Listener Setup: For asynchronous calls, registering an event handler to capture state transitions.
- Transmission (
send): Initiating the request by calling thesendmethod, optionally supplying request body data. - Response Processing: Monitoring the object's state changes within the listener. Upon reaching state 4 (the 'done' state), the server response is accessible, typically residing in the
responseTextattribute.
Beyond these primary steps, XHR permits granular control: custom request headers can be appended, data transmission can be streamed, the response can be directly parsed from formats like JSON into native objects, or processing can occur incrementally as data arrives rather than waiting for complete payload reception. Furthermore, transmissions can be terminated prematurely or subjected to a strict timeout constraint.
