Fixes [#8889](https://github.com/openai/codex/issues/8889). ## Summary - Discover and use advertised MCP OAuth `scopes_supported` when no explicit or configured scopes are present. - Apply the same scope precedence across `mcp add`, `mcp login`, skill dependency auto-login, and app-server MCP OAuth login. - Keep discovered scopes ephemeral and non-persistent. - Retry once without scopes for CLI and skill auto-login flows if the OAuth provider rejects discovered scopes. ## Motivation Some MCP servers advertise the scopes they expect clients to request during OAuth, but Codex was ignoring that metadata and typically starting OAuth with no scopes unless the user manually passed `--scopes` or configured `server.scopes`. That made compliant MCP servers harder to use out of the box and is the behavior described in [#8889](https://github.com/openai/codex/issues/8889). This change also brings our behavior in line with the MCP authorization spec's scope selection guidance: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#scope-selection-strategy ## Behavior Scope selection now follows this order everywhere: 1. Explicit request scopes / CLI `--scopes` 2. Configured `server.scopes` 3. Discovered `scopes_supported` 4. Legacy empty-scope behavior Compatibility notes: - Existing working setups keep the same behavior because explicit and configured scopes still win. - Discovered scopes are never written back into config or token storage. - If discovery is missing, malformed, or empty, behavior falls back to the previous empty-scope path. - App-server login gets the same precedence rules, but does not add a transparent retry path in this change. ## Implementation - Extend streamable HTTP OAuth discovery to parse and normalize `scopes_supported`. - Add a shared MCP scope resolver in `core` so all login entrypoints use the same precedence rules. - Preserve provider callback errors from the OAuth flow so CLI/skill flows can safely distinguish provider rejections from other failures. - Reuse discovered scopes from the existing OAuth support check where possible instead of persisting new config.
codex-core
This crate implements the business logic for Codex. It is designed to be used by the various Codex UIs written in Rust.
Dependencies
Note that codex-core makes some assumptions about certain helper utilities being available in the environment. Currently, this support matrix is:
macOS
Expects /usr/bin/sandbox-exec to be present.
When using the workspace-write sandbox policy, the Seatbelt profile allows
writes under the configured writable roots while keeping .git (directory or
pointer file), the resolved gitdir: target, and .codex read-only.
Network access and filesystem read/write roots are controlled by
SandboxPolicy. Seatbelt consumes the resolved policy and enforces it.
Seatbelt also supports macOS permission-profile extensions layered on top of
SandboxPolicy:
- no extension profile provided:
keeps legacy default preferences read access (
user-preference-read). - extension profile provided with no
macos_preferencesgrant: does not add preferences access clauses. macos_preferences = "readonly": enables cfprefs read clauses anduser-preference-read.macos_preferences = "readwrite": includes readonly clauses plususer-preference-writeand cfprefs shm write clauses.macos_automation = true: enables broad Apple Events send permissions.macos_automation = ["com.apple.Notes", ...]: enables Apple Events send only to listed bundle IDs.macos_launch_services = true: enables LaunchServices lookups and open/launch operations.macos_accessibility = true: enablescom.apple.axservermach lookup.macos_calendar = true: enablescom.apple.CalendarAgentmach lookup.macos_contacts = "read_only": enables Address Book read access and Contacts read services.macos_contacts = "read_write": includes the readonly Contacts clauses plus Address Book writes and keychain/temp helpers required for writes.
Linux
Expects the binary containing codex-core to run the equivalent of codex sandbox linux (legacy alias: codex debug landlock) when arg0 is codex-linux-sandbox. See the codex-arg0 crate for details.
All Platforms
Expects the binary containing codex-core to simulate the virtual apply_patch CLI when arg1 is --codex-run-as-apply-patch. See the codex-arg0 crate for details.