From f8557e378f065d374a0728dcae559bf367fd148e Mon Sep 17 00:00:00 2001 From: ciregenz Date: Sun, 26 Apr 2026 18:12:45 -0700 Subject: [PATCH] [eric] 1.0.26: ship Discord shim default + auto-migrate legacy + clean Google reconnect --- backend/apps/tools_lib/tools_lib.py | 26 +++++++++++++++++++++++++- frontend/src/app/pages/Tools/Tools.tsx | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/backend/apps/tools_lib/tools_lib.py b/backend/apps/tools_lib/tools_lib.py index 5a9f7d35..594e0721 100644 --- a/backend/apps/tools_lib/tools_lib.py +++ b/backend/apps/tools_lib/tools_lib.py @@ -87,7 +87,23 @@ def _load(tool_id: str) -> ToolDefinition: if not os.path.exists(path): raise HTTPException(status_code=404, detail="Tool not found") with open(path) as f: - return ToolDefinition(**json.load(f)) + tool = ToolDefinition(**json.load(f)) + # Migrate Discord tool configs from the old npx-based spawn (which + # broke whenever the npx cache was partially populated) to the local + # Python shim. Idempotent — if it's already on the shim, no-op. + if ( + tool.name.lower() == "discord" + and tool.mcp_config + and tool.mcp_config.get("command") == "npx" + and any("mcp-discord" in str(a) for a in (tool.mcp_config.get("args") or [])) + ): + tool.mcp_config = { + "type": "stdio", + "command": "python", + "args": ["-m", "backend.apps.discord_mcp_shim"], + } + _save(tool) + return tool @tools_lib.router.get("/builtin") @@ -1300,6 +1316,14 @@ async def refresh_google_token(tool: ToolDefinition) -> Optional[str]: }) if resp.status_code != 200: logger.warning("Google token refresh failed: HTTP %d %s", resp.status_code, resp.text[:200]) + # 400/401 → refresh_token is invalid for this client (expected + # for users upgrading across a client_id change, or after the + # user revoked access at myaccount.google.com). Mark the tool + # as expired so the UI surfaces a Reconnect prompt instead of + # silently failing every Google MCP call. + if resp.status_code in (400, 401): + tool.auth_status = "expired" + _save(tool) return None data = resp.json() new_token = data.get("access_token", "") diff --git a/frontend/src/app/pages/Tools/Tools.tsx b/frontend/src/app/pages/Tools/Tools.tsx index 16ef1a65..d62ee0e1 100644 --- a/frontend/src/app/pages/Tools/Tools.tsx +++ b/frontend/src/app/pages/Tools/Tools.tsx @@ -244,7 +244,7 @@ const INTEGRATIONS: Integration[] = [ id: 'discord', name: 'Discord', description: 'Read messages, send messages, manage channels, and interact with Discord servers via the OpenSwarm bot.', - mcp_config: { type: 'stdio', command: 'npx', args: ['-y', 'mcp-discord'] }, + mcp_config: { type: 'stdio', command: 'python', args: ['-m', 'backend.apps.discord_mcp_shim'] }, color: '#5865F2', website: 'https://github.com/barryyip0625/mcp-discord', icon: (