From 3b26971c6ca17c0c3f738f665b02a6c600a0de8a Mon Sep 17 00:00:00 2001 From: TheAchiever6823 <61914223+ShawnMadadha@users.noreply.github.com> Date: Mon, 18 May 2026 14:58:21 -0700 Subject: [PATCH] [shawn] fix: log Spotify scopes at MCP startup + clear credentials on disconnect --- backend/apps/spotify_mcp/server.py | 14 ++++++++++++++ backend/apps/tools_lib/tools_lib.py | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/backend/apps/spotify_mcp/server.py b/backend/apps/spotify_mcp/server.py index 7a7da822..7f16bccf 100644 --- a/backend/apps/spotify_mcp/server.py +++ b/backend/apps/spotify_mcp/server.py @@ -101,6 +101,20 @@ def _get_client() -> spotipy.Spotify: except SpotifyOauthError as exc: raise RuntimeError(f"Spotify refresh_token rejected: {exc}. Reconnect Spotify in OpenSwarm.") + # Log what scopes the token ACTUALLY carries. If a playlist or library + # action errors later with "Insufficient scope", check this line first + # — it shows exactly what was granted at sign-in time. + granted = (token_info.get("scope") or "").split() + expected = set(_scopes().split()) + missing = expected - set(granted) + if missing: + logger.warning( + f"Spotify token is missing scopes: {sorted(missing)}. " + f"Some tools will fail with 'Insufficient scope'. Reconnect in OpenSwarm Tools page." + ) + else: + logger.info(f"Spotify token has all {len(granted)} expected scopes") + _client = spotipy.Spotify(auth=token_info["access_token"]) return _client diff --git a/backend/apps/tools_lib/tools_lib.py b/backend/apps/tools_lib/tools_lib.py index 30b7c042..7113aa32 100644 --- a/backend/apps/tools_lib/tools_lib.py +++ b/backend/apps/tools_lib/tools_lib.py @@ -1122,6 +1122,11 @@ async def oauth_disconnect(tool_id: str): logger.warning(f"Failed to revoke Google token for tool {tool.id}: {e}") tool.oauth_tokens = {} + # Also clear env-var-style credentials (used by Spotify's SPOTIFY_REFRESH_TOKEN + # and any other future tool that stores secrets in credentials instead of + # oauth_tokens). Without this, disconnect "succeeds" but the old token + # still gets injected into the MCP server's env on next spawn. + tool.credentials = {} tool.auth_status = "configured" tool.connected_account_email = None _save(tool)