fix(mcp): reliable OAuth across runtimes and honest pre-restart UI
MCP authorization was broken in several stacked ways. The browser return leg landed on the SPA behind the auth gate, so the system browser saw a login page instead of finishing; the pending-context store silently saved nothing because its route had no JSON body parser; and the callback-URL config write started deferring behind Apply & Restart, so authorization ran against a runtime without the URL and dead-ended on OpenCode's loopback listener. The return leg is now completed entirely server-side by an unauthenticated GET /mcp/oauth/callback that only forwards a code whose state matches a parked context. Desktop with the local server and VS Code switch to OpenCode's native flow over its fixed loopback port — no config writes or restarts at all, with a one-time cleanup of the previously written callback URL — and its completion signal drives the page instead of blind status polling. Remote, hosted-web, and mobile keep the server-callback flow, applying a queued callback-URL write immediately since authorization cannot wait for a manual restart. Also: a server queued behind Apply & Restart now shows an Awaiting restart badge and explanation instead of connect/reauthorize buttons that can only fail, and Reauthorize is offered only while the server is actually connected.
This commit is contained in:
@@ -1417,6 +1417,8 @@ export const settingsDict = {
|
||||
'settings.mcp.page.status.label.failed': 'Fehlgeschlagen',
|
||||
'settings.mcp.page.status.label.needsAuth': 'Autorisierung erforderlich',
|
||||
'settings.mcp.page.status.label.needsRegistration': 'Registrierung erforderlich',
|
||||
'settings.mcp.page.status.label.awaitingRestart': 'Wartet auf Neustart',
|
||||
'settings.mcp.page.status.description.awaitingRestart': 'Dieser Server ist gespeichert, aber noch nicht übernommen. Verwenden Sie „Apply & Restart“, damit OpenCode ihn lädt — danach sind Verbindung und Autorisierung verfügbar.',
|
||||
'settings.mcp.page.status.description.connected': 'Verbunden und bereit, Tools und Ressourcen zu entdecken.',
|
||||
'settings.mcp.page.status.description.failedDefault': 'OpenCode konnte diesen MCP-Server nicht erreichen.',
|
||||
'settings.mcp.page.status.description.needsAuth': 'Dieser entfernte MCP-Server erfordert Autorisierung, bevor eine Verbindung hergestellt werden kann.',
|
||||
|
||||
@@ -1482,6 +1482,8 @@ export const settingsDict = {
|
||||
'settings.mcp.page.status.label.failed': 'Failed',
|
||||
'settings.mcp.page.status.label.needsAuth': 'Needs auth',
|
||||
'settings.mcp.page.status.label.needsRegistration': 'Needs registration',
|
||||
'settings.mcp.page.status.label.awaitingRestart': 'Awaiting restart',
|
||||
'settings.mcp.page.status.description.awaitingRestart': 'This server is saved but not applied yet. Use Apply & Restart to load it into OpenCode — connect and authorization become available after that.',
|
||||
'settings.mcp.page.status.description.connected': 'Connected and ready for OpenCode to discover tools and resources.',
|
||||
'settings.mcp.page.status.description.failedDefault': 'OpenCode could not reach this MCP server.',
|
||||
'settings.mcp.page.status.description.needsAuth': 'This remote MCP server requires authorization before it can connect.',
|
||||
|
||||
@@ -1459,6 +1459,8 @@ export const settingsDict = {
|
||||
"settings.mcp.page.status.label.failed": "Fallido",
|
||||
"settings.mcp.page.status.label.needsAuth": "Necesita autenticación",
|
||||
"settings.mcp.page.status.label.needsRegistration": "Necesita registro",
|
||||
"settings.mcp.page.status.label.awaitingRestart": "Esperando reinicio",
|
||||
"settings.mcp.page.status.description.awaitingRestart": "Este servidor está guardado pero aún no aplicado. Usa «Apply & Restart» para cargarlo en OpenCode; después estarán disponibles la conexión y la autorización.",
|
||||
"settings.mcp.page.status.description.connected": "Conectado y listo para que OpenCode descubra herramientas y recursos.",
|
||||
"settings.mcp.page.status.description.failedDefault": "OpenCode no pudo alcanzar este servidor MCP.",
|
||||
"settings.mcp.page.status.description.needsAuth": "Este servidor MCP remoto requiere autorización antes de poder conectarse.",
|
||||
|
||||
@@ -1377,6 +1377,8 @@ export const settingsDict = {
|
||||
'settings.mcp.page.status.label.failed': 'Échoué',
|
||||
'settings.mcp.page.status.label.needsAuth': 'Nécessite une authentification',
|
||||
'settings.mcp.page.status.label.needsRegistration': 'Nécessite une inscription',
|
||||
'settings.mcp.page.status.label.awaitingRestart': 'En attente de redémarrage',
|
||||
'settings.mcp.page.status.description.awaitingRestart': 'Ce serveur est enregistré mais pas encore appliqué. Utilisez « Apply & Restart » pour le charger dans OpenCode — la connexion et l\'autorisation seront ensuite disponibles.',
|
||||
'settings.mcp.page.status.description.connected': 'Connecté et prêt pour OpenCode pour découvrir des outils et des ressources.',
|
||||
'settings.mcp.page.status.description.failedDefault': 'OpenCode n\'a pas pu atteindre ce serveur MCP.',
|
||||
'settings.mcp.page.status.description.needsAuth': 'Ce serveur MCP distant nécessite une autorisation avant de pouvoir se connecter.',
|
||||
|
||||
@@ -1492,6 +1492,8 @@ export const settingsDict = {
|
||||
'settings.mcp.page.status.label.failed': '失敗',
|
||||
'settings.mcp.page.status.label.needsAuth': '認証が必要',
|
||||
'settings.mcp.page.status.label.needsRegistration': '登録が必要',
|
||||
'settings.mcp.page.status.label.awaitingRestart': '再起動待ち',
|
||||
'settings.mcp.page.status.description.awaitingRestart': 'このサーバーは保存されていますが、まだ適用されていません。「Apply & Restart」で OpenCode に読み込むと、接続と認可が利用できるようになります。',
|
||||
'settings.mcp.page.status.description.connected': '接続済み。OpenCode がツールとリソースを検出できます。',
|
||||
'settings.mcp.page.status.description.failedDefault': 'OpenCode がこの MCP サーバーに到達できませんでした。',
|
||||
'settings.mcp.page.status.description.needsAuth': 'このリモート MCP サーバーは接続する前に認証が必要です。',
|
||||
|
||||
@@ -1459,6 +1459,8 @@ export const settingsDict = {
|
||||
'settings.mcp.page.status.label.failed': '실패',
|
||||
'settings.mcp.page.status.label.needsAuth': '인증 필요',
|
||||
'settings.mcp.page.status.label.needsRegistration': '등록 필요',
|
||||
'settings.mcp.page.status.label.awaitingRestart': '재시작 대기 중',
|
||||
'settings.mcp.page.status.description.awaitingRestart': '이 서버는 저장되었지만 아직 적용되지 않았습니다. Apply & Restart를 사용해 OpenCode에 불러오면 연결과 인증을 사용할 수 있습니다.',
|
||||
'settings.mcp.page.status.description.connected': '연결되었습니다. OpenCode가 도구와 리소스를 찾을 준비가 됐습니다.',
|
||||
'settings.mcp.page.status.description.failedDefault': 'OpenCode가 이 MCP 서버에 연결할 수 없습니다.',
|
||||
'settings.mcp.page.status.description.needsAuth': '이 원격 MCP 서버는 연결 전에 권한 부여가 필요합니다.',
|
||||
|
||||
@@ -503,6 +503,8 @@ export const settingsDict = {
|
||||
'settings.mcp.page.status.label.failed': 'Błąd',
|
||||
'settings.mcp.page.status.label.needsAuth': 'Wymaga autoryzacji',
|
||||
'settings.mcp.page.status.label.needsRegistration': 'Wymaga rejestracji',
|
||||
'settings.mcp.page.status.label.awaitingRestart': 'Oczekuje na restart',
|
||||
'settings.mcp.page.status.description.awaitingRestart': 'Ten serwer został zapisany, ale nie został jeszcze zastosowany. Użyj Apply & Restart, aby OpenCode go wczytał — potem będą dostępne połączenie i autoryzacja.',
|
||||
'settings.mcp.page.status.projectScopedTo': 'Ograniczony do projektu w {directory}',
|
||||
'settings.mcp.page.status.runtimeStatus': 'Status uruchomieniowy',
|
||||
'settings.mcp.page.status.userScoped': 'Konfiguracja użytkownika',
|
||||
|
||||
@@ -1459,6 +1459,8 @@ export const settingsDict = {
|
||||
"settings.mcp.page.status.label.failed": "Falhou",
|
||||
"settings.mcp.page.status.label.needsAuth": "Precisa de autenticação",
|
||||
"settings.mcp.page.status.label.needsRegistration": "Precisa de registro",
|
||||
"settings.mcp.page.status.label.awaitingRestart": "Aguardando reinício",
|
||||
"settings.mcp.page.status.description.awaitingRestart": "Este servidor foi salvo, mas ainda não aplicado. Use Apply & Restart para carregá-lo no OpenCode — depois disso, conexão e autorização ficam disponíveis.",
|
||||
"settings.mcp.page.status.description.connected": "Conectado e pronto para que OpenCode descubra ferramentas e recursos.",
|
||||
"settings.mcp.page.status.description.failedDefault": "OpenCode não conseguiu acessar este servidor MCP.",
|
||||
"settings.mcp.page.status.description.needsAuth": "Este servidor MCP remoto exige autorização antes de poder se conectar.",
|
||||
|
||||
@@ -1459,6 +1459,8 @@ export const settingsDict = {
|
||||
"settings.mcp.page.status.label.failed": "Не вдалося",
|
||||
"settings.mcp.page.status.label.needsAuth": "Потрібна авторизація",
|
||||
"settings.mcp.page.status.label.needsRegistration": "Потрібна реєстрація",
|
||||
"settings.mcp.page.status.label.awaitingRestart": "Очікує перезапуску",
|
||||
"settings.mcp.page.status.description.awaitingRestart": "Сервер збережено, але ще не застосовано. Натисніть Apply & Restart, щоб OpenCode його завантажив — після цього стануть доступні підключення та авторизація.",
|
||||
"settings.mcp.page.status.description.connected": "Підключено, OpenCode може відкривати інструменти й ресурси.",
|
||||
"settings.mcp.page.status.description.failedDefault": "OpenCode не вдалося отримати доступ до цього сервера MCP.",
|
||||
"settings.mcp.page.status.description.needsAuth": "Цей віддалений сервер MCP потребує авторизації, перш ніж він зможе підключитися.",
|
||||
|
||||
@@ -1459,6 +1459,8 @@ export const settingsDict = {
|
||||
'settings.mcp.page.status.label.failed': '失败',
|
||||
'settings.mcp.page.status.label.needsAuth': '需要授权',
|
||||
'settings.mcp.page.status.label.needsRegistration': '需要注册',
|
||||
'settings.mcp.page.status.label.awaitingRestart': '等待重启',
|
||||
'settings.mcp.page.status.description.awaitingRestart': '该服务器已保存但尚未生效。使用 Apply & Restart 让 OpenCode 加载它——之后即可进行连接和授权。',
|
||||
'settings.mcp.page.status.description.connected': '已连接,OpenCode 可发现工具和资源。',
|
||||
'settings.mcp.page.status.description.failedDefault': 'OpenCode 无法连接到此 MCP 服务器。',
|
||||
'settings.mcp.page.status.description.needsAuth': '此远程 MCP 服务器在连接前需要授权。',
|
||||
|
||||
@@ -1365,6 +1365,8 @@
|
||||
'settings.mcp.page.status.label.failed': '失敗',
|
||||
'settings.mcp.page.status.label.needsAuth': '需要授權',
|
||||
'settings.mcp.page.status.label.needsRegistration': '需要註冊',
|
||||
'settings.mcp.page.status.label.awaitingRestart': '等待重新啟動',
|
||||
'settings.mcp.page.status.description.awaitingRestart': '該伺服器已儲存但尚未生效。使用 Apply & Restart 讓 OpenCode 載入它——之後即可進行連線與授權。',
|
||||
'settings.mcp.page.status.description.connected': '已連線,OpenCode 可發現工具和資源。',
|
||||
'settings.mcp.page.status.description.failedDefault': 'OpenCode 無法連線到此 MCP 伺服器。',
|
||||
'settings.mcp.page.status.description.needsAuth': '此遠端 MCP 伺服器在連線前需要授權。',
|
||||
|
||||
Reference in New Issue
Block a user