Spotify MCP Server について
Cursor や Claude などの AI アシスタントから音楽検索、再生操作、プレイリスト管理を行う Spotify MCP サーバーです。曲、アルバム、アーティスト、キュー、デバイスの情報取得ツールも提供します。
主な機能
- 01曲、アルバム、アーティスト、プレイリストの検索
- 02再生中の曲とキューの参照
- 03再生、一時停止、再開、曲送り
- 04プレイリストの作成と編集
- 05保存した曲とアルバムの管理
活用シーン
- 01依頼に応じた音楽検索と再生
- 02テーマ別プレイリストの作成と曲の追加
- 03キューや最近再生した曲の確認
MCP 対応
MCP サーバーとして、Spotify の検索、再生操作、プレイリスト管理、音楽情報取得のツールを MCP クライアントに提供します。README では Claude Desktop、Cursor、VsCode (Cline) との連携が紹介されています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Spotify MCP Server
Cursor や Claude などの AI アシスタントが、Spotify の再生を操作したりプレイリストを管理したりできる、軽量な Model Context Protocol (MCP) サーバーです。
目次
使用例
- 「Elvis の最初の曲を再生して」
- 「Taylor Swift と Slipknot のフュージョンプレイリストを作成して」
- 「ワークアウトのプレイリストにあるテクノの曲をすべて、仕事用のプレイリストにコピーして」
- 「音量を少し下げて」
ツール
読み取り操作
-
searchSpotify
- 説明:Spotify でトラック、アルバム、アーティスト、プレイリストを検索します
- パラメーター:
query(string):検索語句type(string):検索する項目の種類(track、album、artist、playlist)limit(number、任意):返す結果の最大数(1~10、デフォルト:10)offset(number、任意):返す最初の結果のインデックス(デフォルト:0)
- 戻り値:一致した項目の ID、名前、その他の詳細を含むリスト
- 例:
searchSpotify("bohemian rhapsody", "track", 10)
-
getNowPlaying
- 説明:現在 Spotify で再生中のトラックについて、デバイスや音量の情報を含めて取得します
- パラメーター:なし
- 戻り値:トラック名、アーティスト、アルバム、再生位置、長さ、再生状態、デバイス情報、音量、シャッフル/リピート状態を含むオブジェクト
- 例:
getNowPlaying()
-
getMyPlaylists
- 説明:Spotify で現在のユーザーが所有するプレイリストの一覧を取得します
- パラメーター:
limit(number、任意):返すプレイリストの最大数(デフォルト:20)offset(number、任意):返す最初のプレイリストのインデックス(デフォルト:0)
- 戻り値:各プレイリストの ID、名前、トラック数、公開状態を含む配列
- 例:
getMyPlaylists(10, 0)
-
getPlaylistTracks
- 説明:指定した Spotify プレイリスト内のトラック一覧を取得します
- パラメーター:
playlistId(string):プレイリストの Spotify IDlimit(number、任意):返すトラックの最大数(デフォルト:100)offset(number、任意):返す最初のトラックのインデックス(デフォルト:0)
- 戻り値:各トラックの ID、名前、アーティスト、アルバム、長さ、追加日を含む配列
- 例:
getPlaylistTracks("37i9dQZEVXcJZyENOWUFo7")
-
getRecentlyPlayed
- 説明:Spotify で最近再生したトラックの一覧を取得します。
- パラメーター:
limit(number、任意):返すトラックの最大数を指定します。
- 戻り値:トラックが見つかった場合は、最近再生したトラックを整形した一覧を返します。見つからない場合は、「Spotify で最近再生したトラックはありません」というメッセージを返します。
- 例:
getRecentlyPlayed({ limit: 10 })
-
getUsersSavedTracks
- Description: ユーザーの「お気に入りの曲」ライブラリに保存されているトラックの一覧を取得します
- Parameters:
limit(number, optional): 返すトラックの最大数(1~50、デフォルト:50)offset(number, optional): ページネーション用のオフセット(0 始まりのインデックス、デフォルト:0)
- Returns: 保存されているトラックの名前、アーティスト、再生時間、トラック ID、「お気に入りの曲」に追加された日時を含む整形済みの一覧を返します。ページネーション情報(例:「1-20 of 150」)も表示します。
- Example:
getUsersSavedTracks({ limit: 20, offset: 0 })
-
getQueue
- Description: 現在再生中のトラックと、Spotify の再生キューにある次のアイテムを取得します
- Parameters:
limit(number, optional): 表示する次のアイテムの最大数(1~50、デフォルト:10)
- Returns: 現在再生中のトラックと、キューにある次のトラックの一覧
- Example:
getQueue({ limit: 20 })
-
getAvailableDevices
- Description: ユーザーが利用可能な Spotify Connect デバイスの情報を取得します
- Parameters: なし
- Returns: 名前、種類、アクティブ状態、音量、デバイス ID を含む利用可能なデバイスの一覧
- Example:
getAvailableDevices()
-
removeUsersSavedTracks
- Description: ユーザーの「お気に入りの曲」ライブラリから 1 つ以上のトラックを削除します(1 回のリクエストにつき最大 40 件)
- Parameters:
trackIds(array): 削除する Spotify トラック ID の配列(最大 40 件)
- Returns: 成功確認メッセージ
- Example:
removeUsersSavedTracks({ trackIds: ["4iV5W9uYEdYUVa79Axb7Rh", "1301WleyT98MSxVHPZCA6M"] })
-
getFollowedArtists
- Description: 現在のユーザーがフォローしているアーティストを取得します
- Parameters:
limit(number, optional): 返すアーティストの最大数(1~50、デフォルト:20)after(string, optional): 次のページを取得するための、前回の呼び出しで取得したカーソル(最後のアーティスト ID)
- Returns: フォローしているアーティストの名前と ID を含む整形済みの一覧(Spotify から提供される場合は人気度とジャンルも含む)と、続きがある場合は次のページ用のカーソルを返します
- Example:
getFollowedArtists({ limit: 50 })
再生/作成操作
-
playMusic
- Description: Spotify でトラック、アルバム、アーティスト、またはプレイリストの再生を開始します
- Parameters:
uri(string, optional): 再生するアイテムの Spotify URI(指定するとtypeとidを上書きします)type(string, optional): 再生するアイテムの種類(track、album、artist、playlist)id(string, optional): 再生するアイテムの Spotify IDdeviceId(string, optional): 再生に使用するデバイスの ID
- Returns: 成功ステータス
- Example:
playMusic({ uri: "spotify:track:6rqhFgbbKwnb9MLmUQDhG6" }) - Alternative:
playMusic({ type: "track", id: "6rqhFgbbKwnb9MLmUQDhG6" })
-
pausePlayback
- Description: Spotify で現在再生中のトラックを一時停止します
- Parameters:
deviceId(string, optional): 一時停止するデバイスの ID
- Returns: 成功ステータス
- Example:
pausePlayback()
-
resumePlayback
- Description: アクティブなデバイスで Spotify の再生を再開します
- Parameters:
deviceId(string, optional): 再生を再開するデバイスの ID
- Returns: 成功ステータス
- Example:
resumePlayback()
-
skipToNext
- Description: 現在の再生キューで次のトラックにスキップします
- Parameters:
deviceId(string, optional): デバイスの ID
- Returns: 成功ステータス
- Example:
skipToNext()
-
skipToPrevious
- Description: 現在の再生キューで前のトラックにスキップします
- Parameters:
deviceId(string, optional): デバイスの ID
- Returns: 成功ステータス
- Example:
skipToPrevious()
-
createPlaylist
- 説明: Spotify で新しいプレイリストを作成します
- パラメーター:
name(string): 新しいプレイリストの名前description(string, optional): プレイリストの説明public(boolean, optional): プレイリストを公開するかどうか(デフォルト: false)
- 戻り値: 新しいプレイリストの ID と URL を含むオブジェクト
- 例:
createPlaylist({ name: "Workout Mix", description: "Songs to get pumped up", public: false })
-
addTracksToPlaylist
- 説明: 既存の Spotify プレイリストにトラックを追加します
- パラメーター:
playlistId(string): プレイリストの IDtrackUris(array): 追加するトラック URI または ID の配列position(number, optional): トラックを挿入する位置
- 戻り値: 成功ステータスとスナップショット ID
- 例:
addTracksToPlaylist({ playlistId: "3cEYpjA9oz9GiPac4AsH4n", trackUris: ["spotify:track:4iV5W9uYEdYUVa79Axb7Rh"] })
-
addToQueue
- 説明: トラック、アルバム、アーティスト、またはプレイリストを現在の再生キューに追加します
- パラメーター:
uri(string, optional): キューに追加するアイテムの Spotify URI(type と id を上書きします)type(string, optional): キューに追加するアイテムの種類(track、album、artist、playlist)id(string, optional): キューに追加するアイテムの Spotify IDdeviceId(string, optional): キューに追加するデバイスの ID
- 戻り値: 成功ステータス
- 例:
addToQueue({ uri: "spotify:track:6rqhFgbbKwnb9MLmUQDhG6" }) - 別の方法:
addToQueue({ type: "track", id: "6rqhFgbbKwnb9MLmUQDhG6" })
-
setVolume
- 説明: 再生音量を指定した割合に設定します(Spotify Premium が必要です)
- パラメーター:
volumePercent(number): 設定する音量(0-100)deviceId(string, optional): 音量を設定するデバイスの ID
- 戻り値: 新しい音量レベルを含む成功ステータス
- 例:
setVolume({ volumePercent: 50 })
-
adjustVolume
- 説明: 再生音量を相対的な量だけ上げる、または下げます(Spotify Premium が必要です)
- パラメーター:
adjustment(number): 音量の調整量(-100 to 100)。正の値で音量が上がり、負の値で音量が下がります。deviceId(string, optional): 音量を調整するデバイスの ID
- 戻り値: 音量の変化を示す成功ステータス(例: "音量が 50% から 60% に上がりました")
- 例:
adjustVolume({ adjustment: 10 })(10% 上げます) - 例:
adjustVolume({ adjustment: -20 })(20% 下げます)
アルバム操作
-
getAlbums
- 説明: Spotify ID を指定して、1 枚以上のアルバムの詳細情報を取得します
- パラメーター:
albumIds(string|array): 単一のアルバム ID、またはアルバム ID の配列(最大 20 件)
- 戻り値: 名前、アーティスト、リリース日、タイプ、総トラック数、ID などのアルバム詳細情報です。アルバムが 1 枚の場合は詳細を、複数の場合は概要の一覧を返します。
- 例:
getAlbums("4aawyAB9vmqN3uQ7FjRGTy")またはgetAlbums(["4aawyAB9vmqN3uQ7FjRGTy", "1DFixLWuPkv3KT3TnV35m3"])
-
getAlbumTracks
- 説明: ページネーションに対応して、指定したアルバムのトラックを取得します
- パラメーター:
albumId(string): アルバムの Spotify IDlimit(number, optional): 返すトラックの最大数(1~50)offset(number, optional): ページネーションのオフセット(0 始まりのインデックス)
- 戻り値: トラック名、アーティスト、再生時間、ID を含む、アルバムのトラック一覧です。ページネーション情報も表示します。
- 例:
getAlbumTracks("4aawyAB9vmqN3uQ7FjRGTy", 10, 0)
-
saveOrRemoveAlbumForUser
- 説明: ユーザーの「Your Music」ライブラリにアルバムを保存、またはライブラリから削除します
- パラメーター:
albumIds(array): Spotify アルバム ID の配列(最大 20 件)action(string): 実行する操作:「save」または「remove」
- 戻り値: 確認メッセージを含む成功ステータス
- 例:
saveOrRemoveAlbumForUser(["4aawyAB9vmqN3uQ7FjRGTy"], "save")
-
checkUsersSavedAlbums
- 説明: アルバムがユーザーの「Your Music」ライブラリに保存されているか確認します
- パラメーター:
albumIds(array): 確認する Spotify アルバム ID の配列(最大 20 件)
- 戻り値: 各アルバムのステータス(保存済み、または未保存)
- 例:
checkUsersSavedAlbums(["4aawyAB9vmqN3uQ7FjRGTy", "1DFixLWuPkv3KT3TnV35m3"])
プレイリストの操作
-
getPlaylist
- 説明:トラック数、説明、オーナーなど、指定した Spotify プレイリストの詳細を取得します
- パラメーター:
playlistId(string):プレイリストの Spotify ID
- 戻り値:プレイリスト名、オーナー、トラック数、公開範囲、説明、ID、URL
- 例:
getPlaylist({ playlistId: "37i9dQZEVXcJZyENOWUFo7" })
-
updatePlaylist
- 説明:Spotify プレイリストの詳細(名前、説明、公開/非公開、コラボレーション設定)を更新します
- パラメーター:
playlistId(string):プレイリストの Spotify IDname(string, optional):プレイリストの新しい名前description(string, optional):プレイリストの新しい説明public(boolean, optional):プレイリストを公開するかどうかcollaborative(boolean, optional):プレイリストを共同編集可能にするかどうか(publicを false にする必要があります)
- 戻り値:更新されたフィールドの一覧を含む成功確認
- 例:
updatePlaylist({ playlistId: "3cEYpjA9oz9GiPac4AsH4n", name: "New Name", public: true })
-
removeTracksFromPlaylist
- 説明:Spotify プレイリストから1つ以上のトラックを削除します(1回のリクエストにつき最大100トラック)
- パラメーター:
playlistId(string):プレイリストの Spotify IDtrackIds(array):削除する Spotify トラック ID の配列(最大100件)snapshotId(string, optional):特定のバージョンを対象にするためのプレイリストのスナップショット ID
- 戻り値:削除したトラック数を含む成功確認
- 例:
removeTracksFromPlaylist({ playlistId: "3cEYpjA9oz9GiPac4AsH4n", trackIds: ["4iV5W9uYEdYUVa79Axb7Rh"] })
-
reorderPlaylistItems
- 説明:トラックの範囲を新しい位置に移動して、Spotify プレイリスト内の順序を変更します
- パラメーター:
playlistId(string):プレイリストの Spotify IDrangeStart(number):移動する最初のアイテムの位置(0始まりのインデックス)insertBefore(number):アイテムを挿入する位置(0始まりのインデックス)rangeLength(number, optional):移動する連続したアイテムの数(デフォルトは1)snapshotId(string, optional):特定のバージョンを対象にするためのプレイリストのスナップショット ID
- 戻り値:移動の詳細を含む成功確認
- 例:
reorderPlaylistItems({ playlistId: "3cEYpjA9oz9GiPac4AsH4n", rangeStart: 2, insertBefore: 0 })
セットアップ
前提条件
- 最新の Node.js Current リリース(現在は v26.8.1。以前のリリース系列はサポートされていません)
- Spotify Premium アカウント
- 登録済みの Spotify Developer アプリケーション
インストール
git clone https://github.com/marcelmarais/spotify-mcp-server.git
cd spotify-mcp-server
npm ci
npm run build
Spotify Developer アプリケーションの作成
- Spotify Developer Dashboard にアクセスします
- Spotify アカウントでログインします
- 「Create an App」ボタンをクリックします
- アプリ名と説明を入力します
- 利用規約に同意して「Create」をクリックします
- 新しいアプリのダッシュボードに Client ID が表示されます
- 「Show Client Secret」をクリックして Client Secret を表示します
- 「Edit Settings」をクリックし、リダイレクト URI(例:
http://127.0.0.1:8888/callback)を追加します - 変更を保存します
Spotify API の設定
プロジェクトのルートに spotify-config.json ファイルを作成します(用意されているサンプルをコピーして変更できます)。
# Copy the example config file
cp spotify-config.example.json spotify-config.json
次に、認証情報を入力するためにファイルを編集します。
{
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"redirectUri": "http://127.0.0.1:8888/callback"
}
認証プロセス
Spotify API は OAuth 2.0 を使用して認証します。アプリケーションを認証するには、次の手順に従ってください。
- 認証スクリプトを実行します。
npm run auth
-
スクリプトによって認証 URL が生成されます。この URL をウェブブラウザーで開きます。
-
Spotify へのログインと、アプリケーションの認証を求められます。
-
認証後、Spotify は URL にコードパラメーターを含めて、指定したリダイレクト URI にリダイレクトします。
-
認証スクリプトがこのコードをアクセス トークンとリフレッシュ トークンに自動的に交換します。
-
これらのトークンは
spotify-config.jsonファイルに保存されます。ファイルは次のようになります。
{
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"redirectUri": "http://localhost:8888/callback",
"accessToken": "BQAi9Pn...kKQ",
"refreshToken": "AQDQcj...7w",
"expiresAt": 1677889354671
}
注:expiresAt フィールドは、アクセストークンの有効期限を示す Unix タイムスタンプ(ミリ秒)です。
- トークンの自動更新:サーバーは、アクセストークンの有効期限が切れると(通常は 1 時間後)、自動的に更新します。更新には
refreshTokenが透過的に使用されるため、手動で再認証する必要はありません。更新に失敗した場合は、npm run authを再度実行して認証し直す必要があります。
Claude Desktop、Cursor、VsCode との連携[Cline モデル拡張機能経由]
Claude Desktop で MCP サーバーを使用するには、Claude の設定に追加します。
{
"mcpServers": {
"spotify": {
"command": "node",
"args": ["spotify-mcp-server/build/index.js"]
}
}
}
Cursor の場合は、Cursor Settings の MCP タブ(command + shift + J)を開きます。次のコマンドでサーバーを追加します。
node path/to/spotify-mcp-server/build/index.js
Cline で MCP を正しく設定するには、cline_mcp_settings.json のファイル設定が次のようになっていることを確認してください。
{
"mcpServers": {
"spotify": {
"command": "node",
"args": ["~/../spotify-mcp-server/build/index.js"],
"autoApprove": ["getListeningHistory", "getNowPlaying"]
}
}
}
自動承認配列にツールを追加すると、介入なしでツールを実行できます。
ストリーミング可能な HTTP
サーバーはデフォルトで stdio を使用します。複数の MCP クライアントが HTTP 経由で接続する、1 つの長時間稼働プロセスを実行するには、MCP_TRANSPORT=http を設定します。
MCP_TRANSPORT=http MCP_HTTP_PORT=3000 node path/to/spotify-mcp-server/build/index.js
クライアントは http://127.0.0.1:3000/mcp に接続します。MCP_HTTP_PORT のデフォルト値は 3000、MCP_HTTP_HOST のデフォルト値は 127.0.0.1 です。ループバックアドレスでは、Host または Origin ヘッダーに localhost、127.0.0.1、[::1]、MCP_HTTP_HOST、バインドされたアドレス以外の名前が指定されたリクエストは、DNS リバインディングを防ぐため拒否されます。このエンドポイントには認証がないため、別のアドレスにバインドする場合は、認証を提供する仕組みの背後にのみバインドしてください。
OAuth(MCPHub およびその他の OAuth 対応クライアント)
MCP_TRANSPORT=http に加えて MCP_AUTH=spotify を設定します。すると、サーバーは認可サーバーが Spotify 自身である、OAuth で保護された MCP エンドポイント(RFC 9728)として動作します。
MCP_TRANSPORT=http MCP_HTTP_PORT=3000 MCP_AUTH=spotify node path/to/spotify-mcp-server/build/index.js
Authorization: Bearerヘッダーを付けずにPOST /mcpを呼び出すと、/.well-known/oauth-protected-resourceを示すWWW-Authenticateチャレンジとともに401が返されます。- このメタデータドキュメントでは、認可サーバーとして
https://accounts.spotify.com(およびscopes_supportedに必要なスコープ一式)を通知します。そのため、OAuth に対応したクライアント(MCPHub など)は Spotify を検出し、ブラウザーで認可コードフローを実行して、発行されたアクセストークンを使って再接続します。 - Bearer トークンは Spotify のアクセストークンとしてリクエストごとに使用され、
spotify-config.jsonに書き込まれることはありません。npm run authも、保存されるリフレッシュトークンも、トークン更新タイマーもありません。クライアントによるトークンのローテーションは透過的に処理されます。 - 新しいトークンでの最初のリクエスト(つまり、ローテーション時)に、サーバーは Spotify に対してトークンを検証し(
GET /me)、結果をメモ化します。Spotify がトークンを拒否すると、サーバーはWWW-Authenticate: Bearer error="invalid_token"とともに401を返すため、クライアントは再認証が必要だと判断できます。トークンが永久に信頼されるわけではありません。検証済みトークンを使ったツール呼び出しに Spotify が後から401を返した場合(期限切れまたは取り消し)、サーバーはそのトークンを検証結果のメモから削除します。次のリクエストでは古い結果を再利用せず、あらためて/meに問い合わせます。Spotify のトークンは不透明なトークンであり、JWKS も公開イントロスペクションエンドポイントもありません。そのため、クライアントシークレットなしで可能な最も強力な検証は/meへの問い合わせです。これはトークンが Spotify で使用できることを証明しますが、このアプリ向けに発行されたトークンかどうかは検証できません(その検証にはクライアントシークレットが必要ですが、このモードでは意図的に保持しません)。 - このモードでは
spotify-config.jsonは不要です。stdio モードに変更はなく、引き続き設定ファイルを使用します。
環境変数:
| 変数 | デフォルト | 用途 |
|---|---|---|
MCP_AUTH | 未設定(stdio/設定ファイルモード) | spotify を設定すると、HTTP トランスポートで Bearer トークン認証が有効になります |
SPOTIFY_RESOURCE_URL | バインド先のホスト/ポートから導出 | 保護されたリソースのメタデータにおける resource の値です。サーバーに別のアドレス(リバースプロキシ、Docker のポートマッピングなど)からアクセスする場合は、MCP クライアントが使用する公開 URL を設定します。 |
SPOTIFY_AUTHORIZATION_SERVERS | https://accounts.spotify.com | メタデータ内の認可サーバー URL のカンマ区切りリストです。 |
Spotify アプリの初回設定(他のフローと同じダッシュボードを使用します):MCP クライアントがコールバックに使用するリダイレクト URI(例:ローカルの MCPHub ダッシュボードの場合は http://127.0.0.1:3000/oauth/callback)を追加し、クライアント ID をクライアントの OAuth 設定にコピーします。Spotify は新しいアプリで localhost のリダイレクト URI を受け付けないため、127.0.0.1 または HTTPS URL を使用してください。Spotify は動的クライアント登録をサポートしていないため、クライアント ID は手動で指定する必要があります。クライアントシークレットが必要なのは、client_secret_basic/client_secret_post を使ってコードを交換するクライアントのみです。
メタデータの scopes_supported で通知されるすべてのスコープ(15 個)を要求してください。クライアントがそれより少ないスコープを要求すると、不足するスコープを必要とするツールは 403 で失敗します。
MCPHub の設定例:
{
"mcpServers": {
"spotify": {
"type": "streamable-http",
"url": "http://127.0.0.1:3000/mcp",
"oauth": {
"clientId": "your-spotify-client-id",
"authorizationEndpoint": "https://accounts.spotify.com/authorize",
"tokenEndpoint": "https://accounts.spotify.com/api/token",
"redirectUri": "http://127.0.0.1:3000/oauth/callback",
"scopes": [
"user-read-private",
"user-read-email",
"user-read-playback-state",
"user-modify-playback-state",
"user-read-currently-playing",
"user-read-playback-position",
"playlist-read-private",
"playlist-read-collaborative",
"playlist-modify-private",
"playlist-modify-public",
"user-library-read",
"user-library-modify",
"user-read-recently-played",
"user-top-read",
"user-follow-read"
],
"resource": "http://127.0.0.1:3000"
}
}
}
}
Docker(MCPHub での使用を推奨)
このリポジトリには、Dockerfile(マルチステージ、node:26-alpine、非特権ユーザー)と、サーバーを内部 Docker ネットワーク上のOAuth で保護された Streamable HTTP モードで実行する docker-compose.yml が含まれています。ホストのポートは公開されないため、サーバーはホストの外部インターフェースに公開されません。同じ Docker ネットワーク上にある MCPHub コンテナだけが、http://spotify-mcp:3000/mcp でアクセスできます。Spotify の redirect_uri は MCPHub を指すため、公開アクセス可能にする必要があるのは MCPHub のダッシュボード/コールバック URL だけです。
このイメージにクライアントシークレット、リフレッシュトークン、spotify-config.json は必要ありません。
-
サーバーをビルドして起動します。
docker compose up -d --build -
Spotify Developer Dashboard で、アプリのリダイレクト URI としてMCPHub のコールバック URLを追加し(ローカルの MCPHub の場合は
http://127.0.0.1:3000/oauth/callbackなど。新しいアプリでは Spotify がlocalhostのリダイレクト URI を拒否します。デプロイ済みの場合は MCPHub のダッシュボードドメインを指定します)、クライアント IDをコピーします。 -
MCPHub をサーバーに接続します。
urlには Docker の DNS 名を指定し、resourceにも同じ値を設定します(サーバーが保護されたリソースのメタデータで通知するSPOTIFY_RESOURCE_URLと一致させる必要があります)。{ "mcpServers": { "spotify": { "type": "streamable-http", "url": "http://spotify-mcp:3000/mcp", "oauth": { "clientId": "your-spotify-client-id", "authorizationEndpoint": "https://accounts.spotify.com/authorize", "tokenEndpoint": "https://accounts.spotify.com/api/token", "redirectUri": "http://127.0.0.1:3000/oauth/callback", "scopes": [ "user-read-private", "user-read-email", "user-read-playback-state", "user-modify-playback-state", "user-read-currently-playing", "user-read-playback-position", "playlist-read-private", "playlist-read-collaborative", "playlist-modify-private", "playlist-modify-public", "user-library-read", "user-library-modify", "user-read-recently-played", "user-top-read", "user-follow-read" ], "resource": "http://spotify-mcp:3000" } } } }2 つの
spotify-mcpコンテナは、同じ Docker ネットワークを共有する必要があります。MCPHub が独自の compose スタックで実行されている場合は、MCPHub サービスにネットワークを追加し、両方の compose ファイルで共有ネットワークをexternal: trueとして宣言してください。MCPHub サービス(
mcphubの compose ファイル):services: mcphub: networks: - mcphub # its own network (from its existing file) - spotify-mcp # join the Spotify MCP network networks: spotify-mcp: external: true # the network is created by the other stackまたは、両方をご自身で管理している場合は、
docker network create spotify-mcpでネットワークを一度作成し、こちらのspotify-mcpネットワーク定義を含む両方の compose ファイルでexternal: trueにしてください。これにより、どちらのスタックもネットワークを作成しようとしなくなります。 -
MCPHub では、最初の呼び出しでブラウザー上に Spotify の認証フローが開始されます。MCPHub がトークンを保存し、自動的にローテーションします。
MCPHub が別のアドレス(別のホストやリバースプロキシなど)経由でサーバーにアクセスする場合は、.env の SPOTIFY_RESOURCE_URL にその URL を設定し、MCPHub の oauth.resource にも同じ値を設定してください。
コンテナイメージ
CI ワークフローでは、リント、型チェック、テストが成功した後に linux/amd64 と linux/arm64 のイメージをビルドします。プルリクエストではビルドのみを行います。デフォルトブランチへのプッシュと、そのブランチでの手動実行では、latest タグと sha-<full-commit-SHA> タグを付けて ghcr.io/<repository-owner>/<repository-name>(小文字)に公開します。変更不可のデプロイにはイメージダイジェストを固定してください。
公開には packages: write 権限を持つ自動の GITHUB_TOKEN を使用するため、個人アクセストークンは不要です。新しいフォークで要求された場合は、Actions を有効にしてください。初回公開後、匿名でのプルを許可するには、Package settings → Change visibility でパッケージを公開にしてください。新しい GHCR パッケージはデフォルトで非公開です(GitHub のドキュメント)。イメージにはアップストリームの MIT ライセンスが /app/LICENSE に含まれています。
開発
このサーバーは MCP TypeScript SDK v2 と Zod 4 を使用し、レガシー MCP クライアントとの互換性を保ちながら、プロトコルリビジョン 2026-07-28 を提供します。サポート対象は最新の Node.js Current リリースのみです(最低バージョンは v26.8.1)。CI では最新の Current リリースを使用します。固定された依存関係を npm ci でインストールしてください。
npm run lint
npm run typecheck
npm test
テストでは、モック HTTP レスポンスを使用して、MCP の初期化、ツールの検出、検証、Spotify の操作をテストします。Spotify の認証情報は不要で、Spotify アカウントに変更を加えることもありません。
ライセンス
MIT License のもとでライセンスされています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。