Skip to content

feat(mcp): add OAuth authentication#1870

Merged
zerob13 merged 5 commits into
devfrom
codex/docs-mcp-oauth
Jul 3, 2026
Merged

feat(mcp): add OAuth authentication#1870
zerob13 merged 5 commits into
devfrom
codex/docs-mcp-oauth

Conversation

@zerob13

@zerob13 zerob13 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add OAuth flow for remote MCP servers, including loopback callback handling, credential storage, renderer auth status, and callback URL fallback.
  • Switch OpenAI Codex OAuth to external browser login with the shared loopback callback flow.
  • Fix MCP settings toggle/auth feedback regressions and Sheet close buttons inside drag regions.

Tests

  • CI=true corepack pnpm vitest --config vitest.config.ts test/main/presenter/mcpPresenter/mcpOAuthManager.test.ts test/renderer/components/McpServers.test.ts test/renderer/stores/mcpStore.test.ts
  • CI=true corepack pnpm vitest --config vitest.config.renderer.ts test/renderer/components/SheetContentDrag.test.ts
  • CI=true corepack pnpm run format
  • CI=true corepack pnpm run i18n
  • CI=true corepack pnpm run lint
  • CI=true corepack pnpm run typecheck

Note: lint/typecheck print the existing local engine warning because this machine is on Node v24.14.0 while package.json wants >=24.14.1 <25.

Summary by CodeRabbit

  • New Features
    • Added OAuth sign-in for MCP servers and OpenAI Codex using external login plus paste callback URL completion.
    • Added MCP server authentication states/actions (Authenticate, complete from callback URL, Logout) with live updates across the app.
    • Improved MCP server list ordering to show enabled servers before disabled.
    • Added localized UI text for callback/authentication flows.
  • Bug Fixes
    • Prevented stale/incorrect auth errors during callback handling and completion retries.
    • Ensured MCP tool discovery stays up to date with MCP client list changes (fixing missing tools in sessions).
  • Chores
    • Applied Electron no-drag styling to shared sheet close buttons.

Add OAuth support for streamable HTTP/SSE MCP servers with loopback callback handling, external browser login, callback URL fallback, and renderer auth status refreshes. Also switch Codex OAuth to external browser callback flow and fix related MCP panel close controls.
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2593f9b-dc74-476f-90a5-4cc345dd9057

📥 Commits

Reviewing files that changed from the base of the PR and between e398368 and 8cdadd2.

📒 Files selected for processing (37)
  • docs/issues/pr-1870-review-fixes/plan.md
  • docs/issues/pr-1870-review-fixes/spec.md
  • docs/issues/pr-1870-review-fixes/tasks.md
  • src/main/presenter/mcpPresenter/mcpOAuthManager.ts
  • src/main/presenter/mcpPresenter/mcpOAuthProvider.ts
  • src/main/presenter/mcpPresenter/oauthCredentialStore.ts
  • src/renderer/settings/components/OpenAICodexOAuth.vue
  • src/renderer/src/components/mcp-config/components/McpServerCard.vue
  • src/renderer/src/components/mcp-config/components/McpServers.vue
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/shadcn/components/ui/sheet/SheetContent.vue
  • src/shared/contracts/events/mcp.events.ts
  • src/shared/contracts/routes/mcp.routes.ts
  • src/shared/contracts/routes/oauth.routes.ts
  • test/main/presenter/mcpPresenter/mcpOAuthManager.test.ts
  • test/main/presenter/mcpPresenter/oauthCredentialStore.test.ts
  • test/renderer/components/McpServerCard.test.ts
  • test/renderer/components/McpServers.test.ts
  • test/renderer/components/OpenAICodexOAuth.test.ts
  • test/renderer/components/SheetContentDrag.test.ts
✅ Files skipped from review due to trivial changes (17)
  • docs/issues/pr-1870-review-fixes/tasks.md
  • docs/issues/pr-1870-review-fixes/plan.md
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
🚧 Files skipped from review as they are similar to previous changes (13)
  • src/shared/contracts/routes/oauth.routes.ts
  • src/shadcn/components/ui/sheet/SheetContent.vue
  • src/shared/contracts/routes/mcp.routes.ts
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/settings/components/OpenAICodexOAuth.vue
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/components/mcp-config/components/McpServers.vue
  • src/main/presenter/mcpPresenter/oauthCredentialStore.ts
  • src/main/presenter/mcpPresenter/mcpOAuthManager.ts
  • src/main/presenter/mcpPresenter/mcpOAuthProvider.ts
  • test/renderer/components/McpServers.test.ts
  • src/renderer/src/components/mcp-config/components/McpServerCard.vue

📝 Walkthrough

Walkthrough

This PR adds MCP and OpenAI Codex OAuth loopback auth flows, renderer auth state and UI wiring, a shared sheet close-button no-drag fix, and documentation updates for MCP behavior changes.

Changes

MCP and Codex OAuth Loopback Authentication

Layer / File(s) Summary
Planning and specification documents
docs/features/mcp-oauth-authentication/*, docs/issues/*
Adds feature, issue, and task documents for OAuth loopback auth, callback refresh, save-toast i18n, session tools, enabled-server sorting, and permission removal.
Loopback auth core and MCP presenter wiring
src/main/presenter/oauthLoopbackCallback.ts, src/main/presenter/mcpPresenter/*, test/main/presenter/mcpPresenter/*
Adds the loopback callback session helper, MCP OAuth storage/provider/manager logic, presenter integration, and server/client wiring for auth-aware startup and restart.
Routes, events, and presenter types
src/shared/contracts/*, src/shared/types/presenters/core.presenter.d.ts
Adds MCP server-auth routes, the Codex callback-completion route, the auth-changed event, and presenter type declarations.
OpenAI Codex external-browser login
src/main/presenter/openaiCodexAuth/index.ts, src/main/presenter/oauthPresenter.ts, src/renderer/api/OAuthClient.ts, src/renderer/settings/components/OpenAICodexOAuth.vue, test/main/presenter/openaiCodexAuth.test.ts, test/renderer/components/OpenAICodexOAuth.test.ts
Replaces embedded-browser Codex login with external-browser loopback auth, adds callback-URL completion, and updates renderer flow and tests.
Renderer auth state and UI
src/renderer/api/McpClient.ts, src/renderer/src/stores/mcp.ts, src/renderer/src/components/mcp-config/components/*, src/renderer/src/pages/plugins/McpPluginsPage.vue, test/renderer/components/*, test/renderer/stores/mcpStore.test.ts, test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts
Adds MCP auth state tracking, server auth actions, callback dialogs, Codex paste-callback UI, and renderer tests.
Localized authentication strings
src/renderer/src/i18n/*/settings.json
Adds OpenAI Codex and MCP authentication-related UI strings across locale settings files.

Sheet Close Button Drag Region Fix

Layer / File(s) Summary
Sheet close no-drag style and regression test
src/shadcn/components/ui/sheet/SheetContent.vue, test/renderer/components/SheetContentDrag.test.ts
Adds inline -webkit-app-region: no-drag styling to the shared sheet close button and verifies it in a regression test.

MCP Behavior Documentation

Layer / File(s) Summary
Permission system removal docs
docs/architecture/remove-mcp-permission-system/*
Documents removal of MCP-specific permission handling and the related implementation tasks, migration notes, and risks.
Session tool discovery docs
docs/issues/mcp-tools-missing-from-session/*
Documents the MCP tools-missing-from-session investigation, behavior, and task checklist.
Enabled-server sort docs
docs/issues/mcp-enabled-server-sort/*
Documents the MCP enabled-server sort plan, spec, and task checklist.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant McpServerCard
  participant McpServers
  participant mcpStore
  participant McpClient

  McpServerCard->>McpServers: authenticate
  McpServers->>mcpStore: startServerAuth(serverName)
  mcpStore->>McpClient: startServerAuth(serverName)
  McpClient-->>mcpStore: McpServerAuthStatus
  McpServers->>mcpStore: completeServerAuthFromCallbackUrl(serverName, url)
  mcpStore->>McpClient: completeServerAuthFromCallbackUrl(...)
  McpClient-->>mcpStore: authenticated status
Loading
sequenceDiagram
  participant OpenAICodexOAuth
  participant OpenAICodexAuth
  participant Browser

  OpenAICodexOAuth->>OpenAICodexAuth: startBrowserLogin()
  OpenAICodexAuth->>Browser: shell.openExternal(authUrl)
  Browser-->>OpenAICodexOAuth: callback URL
  OpenAICodexOAuth->>OpenAICodexAuth: completeBrowserLoginFromCallbackUrl(url)
  OpenAICodexAuth-->>OpenAICodexOAuth: OpenAICodexAuthStatus
Loading

Possibly related PRs

  • ThinkInAIXYZ/deepchat#1597: Both PRs modify the MCP presenter/server manager error-handling path, including src/main/presenter/mcpPresenter/serverManager.ts.
  • ThinkInAIXYZ/deepchat#1375: Both PRs modify src/main/presenter/oauthPresenter.ts and its OAuth presenter API surface.
  • ThinkInAIXYZ/deepchat#1792: Both PRs change OpenAI Codex authentication internals and the login flow around browser/URL completion.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: adding OAuth authentication, especially for MCP.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/docs-mcp-oauth

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 20

🧹 Nitpick comments (5)
test/renderer/components/SheetContentDrag.test.ts (1)

4-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the rendered close button, not the source file.

This source-text check is brittle: it can pass even if the effective DOM no longer carries the no-drag style after wrapper/template changes. A mount-based assertion would verify the Electron behavior directly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/renderer/components/SheetContentDrag.test.ts` around lines 4 - 11, The
current SheetContent drag-region test is asserting against the source text from
SheetContent.vue instead of the rendered close button, which makes it brittle.
Update the SheetContent drag test in SheetContent drag region to mount the
component and inspect the actual DialogClose element in the rendered DOM, then
assert that the close button carries the no-drag class/style (such as
window-no-drag-region and -webkit-app-region: no-drag) directly on the rendered
output.
src/shared/contracts/events/mcp.events.ts (1)

4-4: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Reuse the strict McpServerAuthStatusSchema instead of a no-op z.custom().

z.object(...)-based McpServerAuthStatusSchema already exists in src/shared/contracts/routes/mcp.routes.ts with real field/enum validation. This file redefines a same-named schema using z.custom<McpServerAuthStatus>(), which performs no runtime validation (any value type-checks). That means this event payload's status field bypasses shape validation that the route contracts enforce for the identical type, and the duplicate name across two files is confusing.

♻️ Proposed fix to reuse the strict schema
-import type {
-  McpServerAuthStatus,
+import { McpServerAuthStatusSchema } from './routes/mcp.routes'
+import type {
   ...
 } from '`@shared/presenter`'
-const McpServerAuthStatusSchema = z.custom<McpServerAuthStatus>()

(adjust the relative import path to match this file's actual location under src/shared/contracts/events/)

Also applies to: 13-13, 49-57

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/contracts/events/mcp.events.ts` at line 4, The event contract is
redefining McpServerAuthStatusSchema with z.custom<McpServerAuthStatus>(), which
skips runtime validation and duplicates the same schema name already defined in
the MCP route contracts. Update the schema definition in
McpServerAuthStatusSchema to reuse the strict z.object-based schema from the
routes module instead of the no-op custom validator, and adjust the related
McpServerAuthStatus imports/usages in this events contract so the status field
is validated consistently everywhere.
src/shared/contracts/routes/oauth.routes.ts (1)

56-63: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider validating callbackUrl as a URL.

callbackUrl: z.string() accepts any string, including non-URL garbage from a manual paste. Zod v4 provides a top-level z.url() format validator that would reject malformed input at the contract boundary rather than relying on downstream parsing to fail gracefully.

♻️ Suggested tightening
 export const oauthOpenAICodexCompleteBrowserLoginFromUrlRoute = defineRouteContract({
   name: 'oauth.openaiCodex.completeBrowserLoginFromUrl',
   input: z.object({
-    callbackUrl: z.string()
+    callbackUrl: z.url()
   }),
   output: OpenAICodexStatusResultSchema
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/contracts/routes/oauth.routes.ts` around lines 56 - 63, The
oauth.openaiCodex.completeBrowserLoginFromUrl contract currently accepts any
string for callbackUrl, so tighten the input validation at the route boundary.
Update oauthOpenAICodexCompleteBrowserLoginFromUrlRoute in oauth.routes.ts to
use Zod’s URL validator for callbackUrl instead of a plain string, keeping the
rest of the contract unchanged.
test/main/presenter/mcpPresenter/mcpOAuthManager.test.ts (1)

1-49: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

LGTM! Correctly exercises the credential-precedence path in completeAuthFromCallbackUrl/getStatus.

Given the issues flagged in mcpOAuthManager.ts (missing stale-flow guard in finishAuthenticatedFlow, and the isOAuthError field-check gap), consider adding regression tests for those once fixed — e.g., simulating a second startAuth call completing before a stale first flow resolves.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/main/presenter/mcpPresenter/mcpOAuthManager.test.ts` around lines 1 -
49, Add regression coverage for the stale OAuth flow cases in McpOAuthManager:
the current test only verifies credential precedence in
completeAuthFromCallbackUrl/getStatus, but the review points to missing
protection in finishAuthenticatedFlow and a gap in isOAuthError field detection.
Add tests that simulate overlapping startAuth flows where an older flow resolves
after a newer one, and verify the stale completion is ignored while the active
flow still succeeds; also add a test that exercises isOAuthError with partial
error objects to confirm the field check works as intended.
src/renderer/src/i18n/ja-JP/settings.json (1)

1134-1138: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

New OpenAI Codex/MCP auth strings left untranslated (English) in the Japanese locale file.

Keys like openaiCodexPasteCallback, authRequired, authCallbackDescription, etc. are inserted verbatim in English rather than translated to Japanese, unlike the rest of the file's localized content.

Also applies to: 1457-1465

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/i18n/ja-JP/settings.json` around lines 1134 - 1138, The
Japanese locale file still contains several new OpenAI Codex/MCP auth strings in
English, so translate those newly added keys to match the rest of the locale.
Update the entries around the OpenAI Codex callback/auth section, including keys
like openaiCodexPasteCallback, openaiCodexCallbackTitle,
openaiCodexCallbackDescription, openaiCodexCallbackPlaceholder,
openaiCodexCompleteAuthentication, and the related
authRequired/authCallbackDescription strings mentioned in the later block. Keep
the translations consistent with existing Japanese terminology used elsewhere in
the settings.json localization.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/presenter/mcpPresenter/mcpOAuthManager.ts`:
- Around line 64-77: The isOAuthError helper is only checking the .code field
even though it declares status and httpStatus, so 401-style HTTP client errors
can be missed. Update isOAuthError in mcpOAuthManager to inspect the actual HTTP
status from status, httpStatus, and any response.status shape before falling
back to message patterns, using the existing UnauthorizedError and
OAUTH_AUTH_ERROR_PATTERNS logic. This should ensure handleConnectionError gets a
correct OAuth classification for fetch/axios-style errors.
- Around line 292-322: finishAuthenticatedFlow should ignore stale/superseded
OAuth flows the same way failAuthFlow does. Add an identity check against
pendingFlows.get(flow.serverName) at the start of finishAuthenticatedFlow so
only the currently active PendingMcpOAuthFlow can delete the entry, close the
callback session, set authenticated status, and trigger onAuthenticated. Keep
the existing failAuthFlow guard pattern and make sure both finishAuthFlow and
the AUTHORIZED path end up using the guarded finishAuthenticatedFlow behavior.
- Around line 262-276: The not-found path in completeAuthFromCallbackUrl sets an
error status, but the pending flow remains active so getStatus() returns
authenticating instead of the newly set error state. Update the mcpOAuthManager
flow handling so the not-found branch either cancels/removes the pending flow
before returning or returns the just-set error status directly, and ensure the
getStatus(serverName, config) path in this method does not override the callback
failure state.

In `@src/main/presenter/mcpPresenter/mcpOAuthProvider.ts`:
- Around line 68-74: The redirectToAuthorization method in MCPOAuthProvider
opens the remote authorizationUrl directly, so add a scheme check before calling
shell.openExternal. Validate that authorizationUrl.protocol is only http: or
https: and reject anything else with an error before opening the browser; keep
the existing interactive guard intact and apply the check in
redirectToAuthorization where the URL is passed to shell.openExternal.

In `@src/main/presenter/mcpPresenter/oauthCredentialStore.ts`:
- Around line 55-102: `clearEntryScope` in `McpOAuthCredentialStore` is deleting
fields only on a local copy, but `saveEntry` merges that copy back with the
existing persisted entry and restores the old values. Update the scoped-clear
flow so the targeted property is actually removed from storage, either by
teaching `saveEntry` to respect explicit deletions or by having
`clearEntryScope` rewrite the entry directly before calling `saveAll`. Make sure
the behavior for `clientInformation`, `tokens`, `codeVerifier`, and
`discoveryState` matches the intended scope removal, while `clearEntry` and
`saveEntry` still work for normal updates.

In `@src/renderer/settings/components/OpenAICodexOAuth.vue`:
- Around line 104-140: The Enter key handler on the callback Input can
re-trigger `completeBrowserLoginFromUrl` while the OAuth exchange is already
running, even though the submit Button is guarded by `busyAction ===
'callback'`. Update `OpenAICodexOAuth.vue` so the `@keydown.enter.prevent` path
uses the same in-flight guard as the Button, and make
`completeBrowserLoginFromUrl` itself no-op when `busyAction` indicates a
callback submission is already underway. Use the existing `busyAction`,
`callbackUrl`, and `completeBrowserLoginFromUrl` symbols to keep both submission
paths consistent and prevent duplicate `completeOpenAICodexBrowserLoginFromUrl`
calls.

In `@src/renderer/src/components/mcp-config/components/McpServerCard.vue`:
- Around line 110-121: The `getStatusInfo` mapping in `McpServerCard.vue` reuses
the wrong label for the `auth-error` case, so update that branch to use the
dedicated `settings.mcp.authFailed` i18n key instead of
`settings.mcp.authRequired`. Keep the existing `auth-required` case unchanged,
and make sure the `auth-error` status still returns its red styling while
showing the distinct failure text.

In `@src/renderer/src/components/mcp-config/components/McpServers.vue`:
- Around line 250-273: `submitAuthCallbackUrl` in `McpServers.vue` can be
re-entered while a request is already in flight, causing duplicate
`completeServerAuthFromCallbackUrl` calls for the same callback URL. Add an
early return guard at the start of `submitAuthCallbackUrl` using
`isSubmittingAuthCallback` so repeated Enter presses are ignored until the
current submission finishes. Keep the existing loading flag behavior intact in
the `try/finally` flow and preserve the current success/failure handling.

In `@src/renderer/src/i18n/da-DK/settings.json`:
- Around line 1067-1071: The new authentication copy in the Danish locale is
still in English, so translate the added OpenAI Codex callback/auth strings
before shipping. Update the entries around openaiCodexPasteCallback,
openaiCodexCallbackTitle, openaiCodexCallbackDescription,
openaiCodexCallbackPlaceholder, and openaiCodexCompleteAuthentication in the
da-DK settings JSON, and also translate the other added auth block referenced by
the review so the entire OAuth/MCP flow remains consistently Danish.

In `@src/renderer/src/i18n/de-DE/settings.json`:
- Around line 1391-1395: The new authentication strings in the locale entries
are still in English, so translate the added copy in the German settings and
related auth section before shipping. Update the newly added keys such as
openaiCodexPasteCallback, openaiCodexCallbackTitle,
openaiCodexCallbackDescription, openaiCodexCallbackPlaceholder, and
openaiCodexCompleteAuthentication, and also the matching block referenced by the
comment, keeping the wording consistent with the existing German translations in
this file.

In `@src/renderer/src/i18n/es-ES/settings.json`:
- Around line 1391-1395: The new auth-related strings in settings.json are still
in English, so update the Spanish locale copy for the affected keys before
shipping. Translate the added OpenAI Codex callback and
completion/authentication entries (for example openaiCodexPasteCallback,
openaiCodexCallbackTitle, openaiCodexCallbackDescription,
openaiCodexCallbackPlaceholder, openaiCodexCompleteAuthentication, and the other
added auth block around the later matching keys) to natural es-ES text, keeping
terminology consistent with the rest of the file.

In `@src/renderer/src/i18n/fa-IR/settings.json`:
- Around line 1134-1138: The new openaiCodex* and mcp.* entries in the fa-IR
locale are still in English, so translate these added auth/setup strings into
Persian to keep the DeepChat dialogs fully localized. Update the relevant keys
in settings.json, including the
openaiCodexCallback*/openaiCodexCompleteAuthentication group and the mcp.*
strings mentioned in the review, while preserving the existing key names and
JSON structure.

In `@src/renderer/src/i18n/fr-FR/settings.json`:
- Around line 1134-1138: The new authentication and MCP copy is still in English
in the fr-FR locale, so localize the added openaiCodex* and mcp.* entries in
settings.json before merging. Update the French translations for the new strings
near openaiCodexCallbackTitle/openaiCodexCompleteAuthentication and the related
mcp section so the auth/setup dialogs remain fully consistent in French.

In `@src/renderer/src/i18n/he-IL/settings.json`:
- Around line 1134-1138: The new authentication strings are still in English in
the he-IL locale, causing mixed-language UI. Localize the added openaiCodex*
entries and the related mcp.* strings in settings.json to Hebrew, keeping the
existing key names intact and matching the style used by other translations in
this file.

In `@src/renderer/src/i18n/id-ID/settings.json`:
- Around line 1391-1395: The new authentication strings are still in English in
the id-ID locale, so localize the added openaiCodex* and mcp.* entries in the
settings JSON before merging. Update the affected copy in the translation file
so the OAuth/authentication UI shows Indonesian text consistently, and use the
existing surrounding keys in settings.json as the reference point for all new
labels, descriptions, and placeholders.

In `@src/renderer/src/i18n/it-IT/settings.json`:
- Around line 1391-1395: The new auth-related entries in the it-IT locale are
still in English, so localize the added openaiCodex* and mcp.* strings in
settings.json to Italian. Update the translated copy for the
callback/authentication dialogs in the same locale block, keeping the existing
key names like openaiCodexPasteCallback, openaiCodexCallbackTitle, and the mcp.*
entries consistent with the rest of the file.

In `@src/renderer/src/i18n/tr-TR/settings.json`:
- Around line 1391-1395: The new authentication strings in the Turkish locale
are still in English, so translate the added OAuth/MCP copy before shipping.
Update the new entries in settings.json for the openaiCodex* keys, and also the
additional block referenced in the same locale file, so all auth-related text is
fully localized and consistent for Turkish users.

In `@src/renderer/src/i18n/vi-VN/settings.json`:
- Around line 1391-1395: The new authentication strings are still in English in
the vi-VN locale, so translate the added copy before shipping. Update the values
for the openaiCodex* keys in settings.json and the other newly added auth block
referenced by the same locale so Vietnamese users see a fully localized
OAuth/MCP flow. Keep the existing key names unchanged and replace only the
displayed text with Vietnamese translations.

In `@src/renderer/src/i18n/zh-HK/settings.json`:
- Around line 1133-1138: The newly added zh-HK strings are using Simplified
Chinese instead of Traditional Chinese, so retranslate all affected entries in
settings.json to match the rest of the locale. Update the new keys around the
OpenAI Codex/auth flow, including openaiCodexPasteCallback,
openaiCodexCallbackTitle, openaiCodexCallbackDescription,
openaiCodexCallbackPlaceholder, openaiCodexCompleteAuthentication, authRequired,
authenticate, authFailed, authCallbackTitle, authCallbackDescription,
authCallbackPlaceholder, completeAuthentication, saveSuccess, and saveFailed,
keeping terminology consistent with existing Traditional Chinese text such as
openaiCodexLoginTip.

In `@src/renderer/src/i18n/zh-TW/settings.json`:
- Around line 1133-1138: The newly added locale strings in zh-TW/settings.json
are using Simplified Chinese instead of Traditional Chinese, so update the
affected translation keys to zh-TW wording for consistency with the rest of the
file. Fix the values for the new auth/callback-related entries such as
openaiCodexPasteCallback, openaiCodexCallbackTitle,
openaiCodexCallbackDescription, openaiCodexCallbackPlaceholder,
openaiCodexCompleteAuthentication, authRequired, authenticate, authFailed,
authCallbackTitle, authCallbackDescription, authCallbackPlaceholder,
completeAuthentication, saveSuccess, and saveFailed, and verify the same set in
the later matching block referenced by the diff.

---

Nitpick comments:
In `@src/renderer/src/i18n/ja-JP/settings.json`:
- Around line 1134-1138: The Japanese locale file still contains several new
OpenAI Codex/MCP auth strings in English, so translate those newly added keys to
match the rest of the locale. Update the entries around the OpenAI Codex
callback/auth section, including keys like openaiCodexPasteCallback,
openaiCodexCallbackTitle, openaiCodexCallbackDescription,
openaiCodexCallbackPlaceholder, openaiCodexCompleteAuthentication, and the
related authRequired/authCallbackDescription strings mentioned in the later
block. Keep the translations consistent with existing Japanese terminology used
elsewhere in the settings.json localization.

In `@src/shared/contracts/events/mcp.events.ts`:
- Line 4: The event contract is redefining McpServerAuthStatusSchema with
z.custom<McpServerAuthStatus>(), which skips runtime validation and duplicates
the same schema name already defined in the MCP route contracts. Update the
schema definition in McpServerAuthStatusSchema to reuse the strict
z.object-based schema from the routes module instead of the no-op custom
validator, and adjust the related McpServerAuthStatus imports/usages in this
events contract so the status field is validated consistently everywhere.

In `@src/shared/contracts/routes/oauth.routes.ts`:
- Around line 56-63: The oauth.openaiCodex.completeBrowserLoginFromUrl contract
currently accepts any string for callbackUrl, so tighten the input validation at
the route boundary. Update oauthOpenAICodexCompleteBrowserLoginFromUrlRoute in
oauth.routes.ts to use Zod’s URL validator for callbackUrl instead of a plain
string, keeping the rest of the contract unchanged.

In `@test/main/presenter/mcpPresenter/mcpOAuthManager.test.ts`:
- Around line 1-49: Add regression coverage for the stale OAuth flow cases in
McpOAuthManager: the current test only verifies credential precedence in
completeAuthFromCallbackUrl/getStatus, but the review points to missing
protection in finishAuthenticatedFlow and a gap in isOAuthError field detection.
Add tests that simulate overlapping startAuth flows where an older flow resolves
after a newer one, and verify the stale completion is ignored while the active
flow still succeeds; also add a test that exercises isOAuthError with partial
error objects to confirm the field check works as intended.

In `@test/renderer/components/SheetContentDrag.test.ts`:
- Around line 4-11: The current SheetContent drag-region test is asserting
against the source text from SheetContent.vue instead of the rendered close
button, which makes it brittle. Update the SheetContent drag test in
SheetContent drag region to mount the component and inspect the actual
DialogClose element in the rendered DOM, then assert that the close button
carries the no-drag class/style (such as window-no-drag-region and
-webkit-app-region: no-drag) directly on the rendered output.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 128639e9-7231-479a-898d-a7cc44c48582

📥 Commits

Reviewing files that changed from the base of the PR and between bd85fe8 and 7d82031.

📒 Files selected for processing (62)
  • docs/features/mcp-oauth-authentication/plan.md
  • docs/features/mcp-oauth-authentication/spec.md
  • docs/features/mcp-oauth-authentication/tasks.md
  • docs/issues/mcp-oauth-callback-refresh/plan.md
  • docs/issues/mcp-oauth-callback-refresh/spec.md
  • docs/issues/mcp-oauth-callback-refresh/tasks.md
  • docs/issues/mcp-save-toast-i18n/plan.md
  • docs/issues/mcp-save-toast-i18n/spec.md
  • docs/issues/mcp-save-toast-i18n/tasks.md
  • docs/issues/sheet-close-no-drag/plan.md
  • docs/issues/sheet-close-no-drag/spec.md
  • docs/issues/sheet-close-no-drag/tasks.md
  • src/main/presenter/mcpPresenter/index.ts
  • src/main/presenter/mcpPresenter/mcpClient.ts
  • src/main/presenter/mcpPresenter/mcpOAuthManager.ts
  • src/main/presenter/mcpPresenter/mcpOAuthProvider.ts
  • src/main/presenter/mcpPresenter/oauthConstants.ts
  • src/main/presenter/mcpPresenter/oauthCredentialStore.ts
  • src/main/presenter/mcpPresenter/serverManager.ts
  • src/main/presenter/oauthLoopbackCallback.ts
  • src/main/presenter/oauthPresenter.ts
  • src/main/presenter/openaiCodexAuth/index.ts
  • src/main/routes/index.ts
  • src/renderer/api/McpClient.ts
  • src/renderer/api/OAuthClient.ts
  • src/renderer/settings/components/OpenAICodexOAuth.vue
  • src/renderer/src/components/mcp-config/components/McpServerCard.vue
  • src/renderer/src/components/mcp-config/components/McpServers.vue
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/pages/plugins/McpPluginsPage.vue
  • src/renderer/src/stores/mcp.ts
  • src/shadcn/components/ui/sheet/SheetContent.vue
  • src/shared/contracts/events.ts
  • src/shared/contracts/events/mcp.events.ts
  • src/shared/contracts/routes.ts
  • src/shared/contracts/routes/mcp.routes.ts
  • src/shared/contracts/routes/oauth.routes.ts
  • src/shared/types/presenters/core.presenter.d.ts
  • test/main/presenter/mcpPresenter/mcpOAuthManager.test.ts
  • test/main/presenter/openaiCodexAuth.test.ts
  • test/renderer/components/McpServers.test.ts
  • test/renderer/components/SheetContentDrag.test.ts
  • test/renderer/stores/mcpStore.test.ts

Comment thread src/main/presenter/mcpPresenter/mcpOAuthManager.ts
Comment thread src/main/presenter/mcpPresenter/mcpOAuthManager.ts
Comment thread src/main/presenter/mcpPresenter/mcpOAuthManager.ts
Comment thread src/main/presenter/mcpPresenter/mcpOAuthProvider.ts
Comment thread src/main/presenter/mcpPresenter/oauthCredentialStore.ts
Comment thread src/renderer/src/i18n/it-IT/settings.json Outdated
Comment thread src/renderer/src/i18n/tr-TR/settings.json Outdated
Comment thread src/renderer/src/i18n/vi-VN/settings.json Outdated
Comment thread src/renderer/src/i18n/zh-HK/settings.json Outdated
Comment thread src/renderer/src/i18n/zh-TW/settings.json Outdated
@zerob13 zerob13 merged commit 6a0c7e4 into dev Jul 3, 2026
3 checks passed
@zhangmo8 zhangmo8 deleted the codex/docs-mcp-oauth branch July 7, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant