237 Commits
Author SHA1 Message Date
jif 4e7b9e285b Recheck EMA request authority at HTTP boundaries (#55288)
## Why

Authorization can change during token renewal before a revocation watcher runs. Requests must check that their authority is still current before dispatch.

## What changed

- Let `EmaRequestAuthority` accept a cancellation token and a synchronous authority check, revoking itself when the check fails.
- Recheck authority after authentication and after receiving HTTP responses for both regular and streaming requests.
- Add `CloudConfigBundleBinding::invalidated()` to wait until a captured policy binding is no longer current.

## Testing

Update tests to cover ownership changing during token renewal without explicit revocation, preventing HTTP dispatch, and parent-token cancellation ending an existing response stream.

GitOrigin-RevId: a142d6bcd0cd7a3d2e9d438a45dc640d93235656
2026-10-19 14:08:49 +00:00
victor-openai 0e67502123 Preserve MCP tool-list metadata in server status (#54686)
## Why

MCP tool discovery discarded response-level `_meta`, leaving server-status clients unable to inspect metadata associated with the tool catalog.

## What changed

- Preserve opaque `_meta` from the first `tools/list` page through catalog refreshes and caches.
- Expose it as `toolListMeta` in `McpServerStatus`, with `null` when unavailable, and update generated schemas and bindings.
- Scope cached Apps catalog metadata to discovery settings, including client capabilities and extensions, while retaining tools from older caches without metadata.
- Restrict server capabilities in status snapshots to the selected servers.

## Testing

Add regression coverage for listing legacy cached Apps tools during failed startup, and update protocol serialization expectations for nullable `toolListMeta`.

GitOrigin-RevId: 62335e2fd8c482067a7a78a7612b58c3eaa9fb55
2026-10-16 19:26:46 +00:00
jif 0df4aa6778 Honor MCP tool-list changes within a turn (#54656)
## Why

MCP servers can expose new tools during discovery. Refreshing the catalog after a tool-list notification lets Codex discover and call those tools in the same turn.

## What changed

- Add the disabled-by-default `mcp_tool_list_changed` feature for ordinary MCP servers.
- Track notifications in transport order and refresh catalogs before subsequent discovery or tool binding. Coalesce concurrent refreshes and retry listings invalidated by notifications, including during pagination.
- Retain the previous catalog on refresh failure, apply a retry cooldown, and invalidate affected startup caches. Allow notification refreshes to proceed while admitted calls finish.

## Testing

Add coverage for same-turn discovery and invocation in direct and Code Mode, notifications during startup and pagination, disabled behavior, cache invalidation, and concurrent refreshes with timeout recovery.

GitOrigin-RevId: 9afee8deba00dd9851b5f32625f61f96965aa00c
2026-10-16 16:40:17 +00:00
Alex Zamoshchin b26b0a7a77 Prefer resource-specific scopes during MCP OAuth discovery (#54653)
## Why

Authorization server metadata can advertise scopes unrelated to the MCP resource. Using that list for discovery can request broader scopes than the resource requires.

## What changed

Update `rmcp` and use its initial scope selection during OAuth discovery: prefer scopes from the initial `WWW-Authenticate` challenge, fall back to protected resource metadata, and include `offline_access` when supported. Stop using the authorization server's general scope list as the discovered resource scopes.

## Testing

Add coverage for challenge scope precedence, resource metadata fallback, scope normalization, and exclusion of unrelated authorization server scopes. Add a no-browser login regression test for a preregistered client whose authorization server advertises neither scopes nor dynamic registration.

GitOrigin-RevId: 68d83cf61fb0b73dac9e861e476f484990fd93b6
2026-10-16 16:23:55 +00:00
Anthony Tafoya 12fd621f62 Preserve specific MCP failure codes in metrics and spans (#54094)
## Why

MCP request failures and tool errors reported only through `codex/telemetry` metadata previously received an `unknown` error code, obscuring the failure category.

## What changed

- Classify typed request failures into bounded codes such as `request_timeout`, `transport_closed`, and `protocol_error`, and carry them into MCP call metrics and spans before errors become strings.
- Preserve typed timeouts when a prepared tool call exhausts its deadline during trusted access lookup.
- Accept allowlisted `error_code` values from `codex/telemetry` as a fallback after structured content and connector authentication metadata. Keep model output unchanged and ignore unrecognized metadata codes.

## Testing

Add coverage for typed errors wrapped in context, prepared-call timeout classification, metadata precedence and rejection, unchanged model output, and exported span error attributes.

GitOrigin-RevId: d7a440a6c9119b8a07a7f1fad697eb25af506f00
2026-10-14 20:53:59 +00:00
Matthew Zeng 4ae6016a93 Retire rejected MCP OAuth refresh tokens (#54079)
## Why

Coordinated MCP OAuth refresh must stop retrying a definitively rejected refresh token, including after the runtime is rebuilt.

## What changed

Remove the rejected refresh token while preserving the access token and credential record. Compare stored credentials under the appropriate locks before writing so a replacement login is preserved, and update file entries using their existing keys.

Keep rejection handling alive through caller cancellation and prevent reuse within the runtime even if persistence fails. For ordinary direct-keyring credentials shared across `CODEX_HOME` directories, retire the token only in the current runtime because locking does not span those directories. Report persistence failures without exposing backend diagnostics.

## Testing

Add coverage for reauthentication after runtime rebuild, legacy file keys, cancellation with a concurrent credential replacement, keyring scope, and persistence failures with diagnostic redaction.

GitOrigin-RevId: a6e602ca2e2893ed711d853becc45142d9575fab
2026-10-14 20:00:52 +00:00
iceweasel-oai 0fd85b0752 Fix Windows environment handling for remote MCP servers (#54069)
## Why

Remote MCP environment filtering could drop `SystemDrive` and `LocalAppData`. Explicit overrides also need Windows-aware merging to replace inherited variables with differently cased names.

## What changed

- Preserve `SYSTEMDRIVE` and `LOCALAPPDATA` when remote environment variables activate the allowlist.
- Apply explicit environment overrides through the executor environment policy, while retaining the final overlay for variables excluded by the allowlist.

## Testing

Extend environment-policy tests to cover the additional Windows variables, overrides with differently cased names, and the final overlay used by older executors.

GitOrigin-RevId: 36df69117f248536e47cf7e1d855b99a138fe698
2026-10-14 18:56:46 +00:00
Michael Bolin 7d0b91d5d6 Separate MCP sandbox policy from launcher metadata (#53709)
## Why

MCP servers must forward sandbox policy unchanged to `codex sandbox --sandbox-state-json`, while interpreting launcher information to find the Codex CLI. Keep those contracts separate so consumers can preserve unknown policy fields.

## What changed

- Accept the experimental `codex/sandbox-state` capability alongside the deprecated `codex/sandbox-state-meta` capability, and send identical policy values under both `_meta` keys.
- Move `codexExecutable` out of the policy into `codex/sandbox-launcher`, supplied only when a verified CLI path is available for a local stdio server.
- Replace stale sandbox metadata while retaining unrelated entries, and remove stale launcher metadata when no launcher is available.
- Document the metadata contract and how servers should forward policy and retain authority for long-lived subprocesses.

## Testing

Update unit and integration coverage for policy serialization, identical state aliases, launcher availability across execution environments, and stale metadata replacement.

GitOrigin-RevId: e544c06e6e023953b1fc8069b7b1affa065262d1
2026-10-13 16:23:44 +00:00
alishobeiri-oai de8fab6d7a Upgrade rmcp to 3.5.1 and harden lifecycle tests (#52972)
## What changed

- Update the pinned `rmcp` dependency and Cargo/Bazel lockfiles, and migrate MCP handlers and fixtures to `ClientConfig` and `ServerConfig`.
- Stop requiring responses for cancelled elicitation requests in cancellation tests while retaining checks for cleanup and continued connection usability.
- Handle client disconnects during WebSocket writes in the TUI test server, use an asynchronous HTTP mock for loopback proxy testing, and improve remote executor test diagnostics and the Windows subprocess fixture.
- Use `invalid_prompt` for the memory worker failure fixture.

## Testing

Add a regression test covering transport EOF during both form elicitation and user verification. Keep the client alive while checking that pending response channels close, the timeout pause clears, and the service exits with `QuitReason::Closed`.

GitOrigin-RevId: c0166b83fab3b59d84a5207c6630cb6adcf3b230
2026-10-10 19:43:24 +00:00
berkdeniz-oai b38942ce7c Preserve diagnostic reasons for MCP user verification failures (#51808)
## Why

User-verification cancellations previously discarded failure reasons, leaving MCP servers unable to distinguish user cancellation from unavailable approval, interruption, or invalid proof.

## What changed

- Carry a bounded `openai/userVerificationReason` value in response `_meta` for verification failures, declines, and cancellations across the TUI, app server, and MCP client.
- Preserve recognized reasons and classify invalid responses, missing or invalid proofs, response errors, closed response channels, interruptions, and unavailable approval.
- Discard unknown reasons and unrelated metadata. Keep proof material out of decline and cancellation responses, and keep display messages and raw error diagnostics out of response metadata.

## Testing

Add and update tests for typed failure propagation, metadata filtering, invalid proofs, response-channel failures, interrupted requests, and unavailable approval, including TUI RPC and native MCP response coverage.

GitOrigin-RevId: 6b7f855ce8eb13e759b5b86d0dc2b1afdfcff7b3
2026-10-07 19:28:14 +00:00
zbarsky-openai 9dd798805f Prevent recursive Tokio tracing in telemetry and SQLite logs (#51775)
## Why

Tokio runtime tracing can cause SQLite log writes to enqueue more writes and exporter activity to generate further OTLP exports.

## What changed

- Exclude `tokio` and `runtime` spans from OTLP export alongside `h2` spans.
- Limit `tokio::` and `runtime::` targets to `INFO` in the default log filter, and reject their `TRACE` events directly in the SQLite sink even without an outer filter.
- Box and pin the session-loop future before spawning it.
- Reorder tracing and Tokio test attributes, restrict the skills concurrency test's subscriber to the catalog-refresh span, and use the default log filter in the SQLite formatter comparison test.

GitOrigin-RevId: f545013a2469088d7f9890c1f46bb93eb5446d2d
2026-10-07 17:28:32 +00:00
jif 1199b39762 Wait for helper completion in HTTP header cancellation tests (#51689)
Replace fixed 500 ms sleeps in `helper_attempt_is_shared_after_cancellation` with polling of the helper completion marker every 10 ms, bounded by a five-second timeout.

This lets the test observe completion independently of the cancelled headers or refresh request without assuming the helper finishes within 500 ms. Preserve the assertions that subsequent calls reuse the same helper attempt.

GitOrigin-RevId: 2612679aff756306ea3e05ef7bb9b4db02633fd5
2026-10-07 13:17:08 +00:00
Anton Panasenko ef8cfe5e96 Retry registry authentication outages and jitter executor reconnects (#50465)
## Why

Remote executors need to recover from confirmed authentication-service outages and spread reconnect attempts after a shared outage. Registration retries must remain limited to confirmed failures before a write, since replaying an ambiguous request can replace a newer registration.

## What changed

- Retry registry responses with HTTP 502 and `authentication_service_unavailable`, alongside the existing HTTP 503 `registration_conflict` retries.
- Accept structured registry errors in `detail`, keeping the canonical `error` authoritative when both are present.
- Randomize reconnect delays between half and all of the current exponential backoff, retaining the 30-second cap.

## Testing

Add coverage for reconnect jitter bounds, authentication-outage retry cancellation, error-envelope precedence, and preservation of Noise identity and initialized sessions across retries. Make the HTTP-header helper cleanup test wait for the helper PID before cancellation and verify process termination when the provider is dropped.

GitOrigin-RevId: 35fdb57732d17b0bbfeca8a4dc557a0988e29a31
2026-10-02 23:54:32 +00:00
Matthew Zeng a20fe6335f Replace the Figma OAuth exception with Mercado Pago (#50189)
## What changed

Allow the issuer `https://mcp.mercadopago.com/mcp` to use authorization endpoints on `https://auth.mercadopago.com` and token endpoints on `https://mcp.mercadopago.com` without issuer-bound callbacks. Remove the previous Figma exception.

## Testing

Update the provider-exception test to accept the Mercado Pago combination and reject lookalike issuer hosts, unrelated token hosts, and HTTP issuer and token URLs.

GitOrigin-RevId: 3838c7e4c32d6a2022f0011d6020e383035fe67f
2026-10-02 05:25:51 +00:00
aidan 7d3e696c4c Preserve Windows environment variables for remote MCP servers (#50129)
## Why

When Codex runs on Unix and launches a stdio MCP server on a Windows executor, explicit remote environment variables activate an allowlist based on Unix defaults. This can filter out Windows runtime and temporary-directory variables.

## What changed

Include `SYSTEMROOT`, `TEMP`, and `TMP` in the remote environment allowlist whenever explicit remote variables are requested.

## Testing

Extend the environment-filtering test to verify that `SystemRoot`, `TEMP`, and `TMP` survive alongside requested variables while unrequested secrets remain excluded.

GitOrigin-RevId: 059c9e23833be66aaf5b65ba5f95013f94f0f792
2026-10-02 00:45:51 +00:00
Tamir Duberstein b06b7d2f77 Upgrade Windows bindings to windows-sys 0.61.2 (#50058)
## What changed

- Centralize `windows-sys` at version `0.61.2` in the workspace and migrate dependent crates to it.
- Adapt Windows API calls to the updated handle, boolean, and type definitions. Replace custom handle owners with `OwnedHandle` and use `BorrowedHandle` where ownership stays with the caller.
- Add explicit wrappers for non-owning Windows handles passed between threads.

## Testing

Enable the MCP refresh cleanup test on Windows. Retain process handles to verify that a superseded MCP server stays alive during an in-flight call, exits after cancellation, and leaves the replacement running until shutdown.

GitOrigin-RevId: 86f53d9b300d13edff7154f4a7c32e34dacd2919
2026-10-01 18:05:05 +00:00
jif 595534314f Use descriptor-safe helpers for executable test fixtures (#50018)
## Why

Concurrent Linux test spawns can inherit writable descriptors for executable fixtures, preventing those fixtures from being executed even after the writing test closes its descriptor.

## What changed

Replace direct executable fixture writes and copies across the Rust tests with `codex_utils_cargo_bin::write_executable` and `copy_executable`. These existing helpers complete writes and copies in separate processes on Linux.

Remove the empty temporary inode before creating fake bubblewrap executables, and stage tampered bubblewrap bytes in a separate data file before copying them into the executable fixture. Add the required test dependencies.

GitOrigin-RevId: c875c83088731a4933ef1574e8d79d8cecc12f54
2026-10-01 15:57:03 +00:00
Nick Steele ecc78e4cf5 Add renewable EMA HTTP authentication and credential versioning (#49987)
## What changed

- Add `EmaAuthenticatedHttpClient` to cache and renew resource bearers, serialize concurrent renewals, and include authentication time in the request deadline. Confine bearers to the configured MCP endpoint and reject redirects.
- Return authentication-required errors for `401` responses without replaying MCP operations. Preserve a newer cached bearer when a delayed response rejects an older one.
- Add revocable request authority that cancels pending requests and ends response streams.
- Pin enterprise credentials to a persistent version advanced on save or deletion. Use short credential locks and invalidate rejected grants only when their record and version are still current, preserving newer logins.
- Hide keyring account identifiers from enterprise credential errors and traces while preserving authentication failure classification.

## Testing

Add tests for token expiry and renewal, endpoint confinement, redirects, request deadlines, revocation during renewal and streaming, delayed `401` responses, credential replacement and logout races, and credential error privacy.

GitOrigin-RevId: ee3e5cf7ecbba3d09e1ab29ed4fbb2a35eacc60d
2026-10-01 13:57:48 +00:00
jif a933dd77db Share byte buffers across exec-server output chunks (#49972)
## Why

Retaining process output, publishing events, and serving reads cloned the underlying byte buffers. Sharing those buffers avoids copying output bytes when chunks are cloned.

## What changed

Store `ByteChunk` bytes in `Arc<Vec<u8>>` and retain `ProcessOutputChunk` values directly. Add borrowed byte access for the MCP process transport while preserving base64 serialization and owned byte extraction through `into_inner()`.

## Testing

Add a unit test covering base64 serialization, deserialization, and independent owned bytes extracted from shared chunks.

GitOrigin-RevId: 6bba114af48424aa844487aa75163cfc604e0575
2026-10-01 12:41:39 +00:00
Nick Steele 15fd656ddb Discover and validate MCP authorization servers before ID-JAG exchange (#49478)
## What changed

Add `exchange_ema_auth_token` to discover and validate the MCP resource's authorization server before resolving enterprise identity credentials and performing the ID-JAG token exchange. Keep the lower-level exchange primitive private.

- Probe `server/discover` with the enterprise-managed authorization extension, support recognized legacy discovery rejections, and follow protected-resource metadata challenges or well-known fallbacks.
- Match configured resource and issuer constraints, require advertised public-client JWT bearer support, and validate token endpoint metadata without requiring an authorization endpoint.
- Bound discovery with a shared timeout, redirect and authorization-server limits, reject cross-origin metadata redirects, and restrict private authorization-server destinations while allowing local loopback discovery.

## Testing

Add tests covering resource and issuer mismatches before identity access, metadata capability validation, query preservation, modern challenges, JSON and SSE legacy fallback behavior, cross-origin redirect rejection, and private or malformed issuer destinations.

GitOrigin-RevId: 9a55233a20ff42c293f9bd8175e01141ac2d8576
2026-09-30 04:30:01 +00:00
Nick Steele c9b3924a62 Use the rmcp SDK for enterprise-managed token exchanges (#49473)
## What changed

Upgrade `rmcp` to a pinned Git revision of version `3.3.0` and enable `auth-enterprise-managed`. Delegate the two-stage ID-JAG exchange and token validation to the SDK, replacing the local implementation while retaining Codex HTTP routing and credential lifecycle policy.

Map SDK errors by exchange stage so `invalid_grant` distinguishes enterprise identity failures from resource authorization failures, and preserve handling of `insufficient_user_authentication`.

## Testing

Update exchange tests to verify rejection of unsupported `authorization_details` and malformed signed scopes. Exercise errors from both token endpoints to check credential policy, prevent credential reflection in diagnostics, and ensure rejected grants are not retried.

GitOrigin-RevId: a56034aa3fd70002754ea552fd2da70bdcd85b31
2026-09-30 03:33:43 +00:00
Celia Chen 05ea5f757e Add attributed MCP OAuth credential storage telemetry (#49392)
## What changed

- Instrument MCP OAuth loads, saves, deletes, fallback cleanup, and refresh persistence with credential-free storage metrics, distinguishing configured policy from operations on a pinned store.
- Retain the originating client across background tasks, blocking storage operations, and session recovery, including recovery after startup found no credentials.
- Preserve typed keyring and lock error categories for metrics and remove raw error details from storage warnings.

## Testing

Add tests for policy and pinned-store outcomes, best-effort cleanup failures, wrapped lock errors, and successful or failed refresh persistence without duplicate observations. Add recovery tests that verify client attribution after anonymous startup and across threads with different originators.

GitOrigin-RevId: 5ea4528bcdcf500c8ffdf1d9c7008ea52112c726
2026-09-29 23:01:46 +00:00
Nick Steele 4994306e9f Enable enterprise MCP sign-in and account-scoped grant cleanup (#49276)
## Why

The app server previously rejected OAuth login for enterprise-managed MCP servers. These servers need an explicit sign-in flow that ties saved authorization to the active Codex user and workspace and prevents canceled or superseded attempts from saving credentials.

## What changed

- Enable enterprise sign-in through `mcpServer/oauth/login` for configured servers with a connected thread, trusted IdP registration, and `features.use_xaa` enabled. Scope shared enterprise credentials by user, workspace, issuer, and client ID.
- Add `loginId` to MCP OAuth login responses and completion notifications, preserving compatibility with older servers that omit it.
- Support enterprise login replacement and `account/login/cancel`, wait for callback listener shutdown before replacement, and recheck account and configuration before saving grants. Fence stale attempts across processes and account changes.
- Remove shared enterprise authorization during account logout and `codex mcp logout`, including when the feature is disabled. Continue account logout if enterprise cleanup fails, and invalidate MCP runtimes on account changes.

Start a fresh session after successful enterprise sign-in to use the saved grant.

## Testing

Add regression coverage for login replacement and cancellation, callback port reuse, account changes during setup, cross-process logout invalidation, persisted workspace policy selection, cleanup failures, and responses from older servers without `loginId`.

GitOrigin-RevId: 7ed4caaab4659ed1e67064262cf5cee48e3a26ac
2026-09-29 14:46:33 +00:00
Eric Traut fbc169827e Suppress Windows console windows for background subprocesses (#49164)
## Why

Background helpers launched from a detached Windows process can allocate console windows. Job Object launches and containment fallbacks need to preserve console suppression as well.

## What changed

- Add `codex_utils_process::background_command` to set `CREATE_NO_WINDOW` on Windows, and use it across background subprocess launches, including Git, plugins, authentication, diagnostics, and sandbox helpers.
- Centralize console suppression in Job Object launches. Keep `CREATE_NO_WINDOW` when retrying without containment, and clear `CREATE_SUSPENDED` so the fallback child can run.
- Preserve console inheritance for interactive shell launches and interactive AWS authentication refreshes.

## Testing

Add Windows regression tests covering console-free launches from detached parents through standard and Tokio commands, stdout/stderr capture, successful containment, Job Object creation and assignment failures, and sandbox setup refresh helpers.

GitOrigin-RevId: b2c238fa7d4f9fbd868e5adf7d4be9958ff01e6c
2026-09-29 04:38:37 +00:00
jif 18344a972d Centralize executable fixture creation to avoid Linux ETXTBSY races (#48727)
## Why

Concurrent tests can inherit writable descriptors for executable fixtures, causing `ETXTBSY` when those fixtures launch on Linux.

## What changed

Expose shared `write_executable` and `copy_executable` helpers from `codex_utils_cargo_bin` and adopt them in CLI, exec-server, and MCP tests. On Linux, writes and copies complete in separate processes so sibling test spawns cannot inherit the writable descriptors. Script fixtures receive mode `0o755`, and copied executables retain their source permissions.

Remove the executable-busy retry loop from the program resolver test now that its script uses the shared helper.

GitOrigin-RevId: 61624158190bb1e75c27d9eb9c87a2defc147fb7
2026-09-27 15:25:13 +00:00
jif 274d41a398 Prevent Linux ETXTBSY races in MCP stdio tests (#48724)
## Why

Concurrent test spawns can inherit a writable descriptor for the MCP server
wrapper, causing `ETXTBSY` when launching it on Linux.

## What changed

Write the wrapper through a separate `/bin/sh` process on Linux so its writable
descriptor stays out of the test process. Check the writer's exit status and
include stderr on failure. Retain direct file writes on other Unix platforms.

GitOrigin-RevId: f99952ec000ba7317243e87fd664dc0e31bb7b24
2026-09-27 14:55:33 +00:00
malsamiri-oai 4b9e0cc77f Suppress console windows for local Windows MCP servers (#48238)
## What changed

Expose Windows process creation flags on the shared command wrapper and use
`CREATE_NO_WINDOW` when launching local stdio MCP servers, including fallback
launches without Job Object containment. Preserve `CREATE_SUSPENDED` when
assigning the server to a Job Object before execution.

## Testing

Add a Windows regression test covering direct launches and launches through
`cmd.exe`. Verify that the server has no console, initializes successfully,
returns tools, and exits after shutdown.

GitOrigin-RevId: 84475e82999d91a431e09327d4f5639b59c01427
2026-09-25 22:56:00 +00:00
willwang-openai 83b56bc5ad Support client secrets for pre-registered MCP OAuth clients (#47891)
## Why

MCP OAuth configuration supported a pre-registered client ID but could not supply a client secret for token exchange or refresh.

## What changed

- Add `oauth.client_secret` and `codex mcp add --oauth-client-secret`, requiring a nonempty secret and client ID. Persist the secret in server configuration and accept `clientSecret` in plugin configuration.
- Pass configured credentials through CLI, app-server, and plugin login flows and token refresh. Require a new login when a configured confidential client's ID differs from stored credentials.
- Redact secrets in debug output and keep them out of authorization URLs and persisted OAuth token records.
- Invalidate cached OAuth connections when the configured client ID or secret changes.

## Testing

Add coverage for configuration validation and round trips, CLI argument redaction and subsequent login, app-server login, connection invalidation, and refresh with `client_secret_basic` and `client_secret_post` in both refresh modes. Verify secret exclusion from token records and reject mismatched client IDs before contacting the provider.

GitOrigin-RevId: 85bb0e410e9e68e6cd68eb6359badfc7eac78147
2026-09-24 17:26:18 +00:00
Yuzhu Shen b086ad5493 Make Linux descriptor cleanup fork-safe (#47654)
## Why

Linux descriptor cleanup used allocating directory enumeration after `fork`. The child needs allocation-free cleanup while preserving Rust's spawn-error channel until `exec` succeeds.

## What changed

- Mark unrelated descriptors close-on-exec with `close_range(CLOSE_RANGE_CLOEXEC)`, leaving stdio and explicitly preserved descriptors' flags untouched.
- Fall back to stack-backed `getdents64` enumeration of the child's descriptor table when `close_range` fails.
- Document best-effort cleanup: failures allow launch to proceed and may leave unrelated descriptors inherited.

## Testing

Add Linux tests for descriptor inheritance, unsorted and duplicate allowlists, unchanged parent descriptors, fallback cleanup above a lowered descriptor limit, preserved exec-error reporting, and successful launch when both cleanup paths fail. Retain MCP coverage for descriptor exclusion in servers and descendants.

GitOrigin-RevId: 13abb95f82557324c7b40feb36bd6f806d60674e
2026-09-23 20:20:06 +00:00
Charlie Marsh b8d365b18e Extend child commands with session and descriptor controls (#47604)
## What changed

- Add `ProcessMode::NewSession`, null stdin, and opt-in Linux parent-death termination to the shared child command API.
- Replace `DescriptorPolicy::StdioOnly` with `Explicit` and add `preserve_fds` to allow selected inheritable Unix descriptors alongside stdio. Preserve descriptor numbers without duplicating or closing the parent's descriptors, keeping POSIX record locks intact.
- Support session creation and preserved descriptors in the native macOS backend, with a compatible fallback for high descriptor numbers rejected by native file actions.

## Testing

Add regression coverage for process groups and sessions, descriptor preservation across native and executable-text launches, the last descriptor slot below the file limit, and retention of parent record locks.

GitOrigin-RevId: 29ecd859d3b673da6ae6412cc06a32fa10d11346
2026-09-23 17:59:47 +00:00
viyatb-oai 2c2a42e65d Restrict MCP OAuth authorization endpoints to HTTP(S) (#47326)
## What changed

Reject authorization endpoints with schemes other than `http` or `https` before client registration or authorization URL return. Document this constraint for `mcpServer/oauth/login`.

## Testing

Make existing asynchronous tests wait for cleanup: wait for `ThreadIdle` before injecting user input in the guardian cached-score test, and poll for queue consumption before asserting that dispatched items are gone.

GitOrigin-RevId: e5f6b4c5556234c3cc2aa56910486e892c011116
2026-09-22 17:31:02 +00:00
Ben Romano 94174e44cb Preserve MCP request trace context across transport workers (#47212)
## Why

MCP requests pass through background transport queues, so HTTP requests need the caller's trace context carried explicitly to preserve trace ancestry.

## What changed

- Capture W3C trace context in request metadata for tool and resource operations, custom requests, and event streams.
- Restore that context in an `mcp.http.request` span around HTTP POSTs, linking outgoing HTTP traces to the originating request.
- Preserve application metadata while replacing trace fields with the current caller's context and removing stale `tracestate`. Read the SDK's merged metadata so extension fields retain precedence over parameter metadata.

## Testing

Add a unit test for metadata merge precedence and an integration test covering concurrent paginated requests, tool calls, custom requests, and tool-call continuations across legacy and `2026-07-28` protocol modes. Verify HTTP trace ancestry, metadata preservation, and removal of stale `tracestate`.

GitOrigin-RevId: 0b22cd75f31f9fcb855b27fa8d34ecdffd6e3549
2026-09-22 06:47:07 +00:00
Yuzhu Shen afe4249cfe Restrict Unix local MCP servers to stdio descriptors (#47094)
## Why

Local MCP servers communicate over stdio, so unrelated parent file descriptors should not propagate into the server or its descendants.

## What changed

Apply `DescriptorPolicy::StdioOnly` when launching local stdio MCP servers on Unix, preserving their explicit transport stdio.

## Testing

Add Unix integration tests that check inheritable pipe, socket, and file descriptors are absent from servers and descendants across absolute, relative, and shell-fallback launches. Verify MCP communication, arguments, environment, working directory, parent descriptor ownership, and exec failure reporting remain intact.

GitOrigin-RevId: 37409a5673dbaafa851fd1f78e3a2443eda5f7c6
2026-09-21 19:37:46 +00:00
teddywyly-oai a6fdb11eda Preserve metadata in native user verification requests (#46952)
## Why

Native `openai/userVerification` requests need to carry optional `_meta` to clients for extension-specific presentation.

## What changed

- Accept optional metadata objects with the same validation as MCP elicitation.
- Restore metadata from the MCP request context, excluding `progressToken`, and forward it through `mcpServer/elicitation/request`.
- Update protocol types, schemas, and documentation while retaining support for requests without metadata. Challenge bytes and acceptance proofs remain unchanged.

## Testing

Add coverage for metadata validation, transport context restoration, and protocol round trips. Extend MCP integration tests to check that verification metadata reaches the client.

GitOrigin-RevId: 5d04004244cf33effac675c19e543157c48d1504
2026-09-21 07:01:52 +00:00
Charlie Marsh 3801fc8dea Make local child process launch settings explicit (#46660)
## Why

The native macOS backend cannot inspect every setting or callback on a Tokio command. A shared, constrained launch API makes the supported settings explicit for both backends.

## What changed

- Replace `spawn_child` with `codex_utils_pty::Command`, enforcing an explicitly supplied environment, piped stdio, and kill-on-drop behavior.
- Add `ProcessMode::Inherit` and `ProcessMode::NewGroup`, honoring the selected mode in native macOS and Tokio spawning.
- Share the `Child` wrapper across platforms and migrate local MCP server launching to the new API, retaining its new process group and Windows suspended-spawn support.

## Testing

Adapt the existing macOS spawn compatibility and child lifecycle tests to the new API. Add a regression test that checks inherited and new process groups with both backends.

GitOrigin-RevId: 3e7a401659e3a8a94a13c4ff58d67bdcd2eea33d
2026-09-19 15:14:22 +00:00
Charlie Marsh d086e2752d Move local child-process spawning into codex-utils-pty (#46659)
## What changed

Expose the shared `Child` type and `spawn_child` function from `codex-utils-pty`, and update the MCP stdio transport to use them. Move the existing macOS spawning implementation and its tests into the utility crate, preserving platform-specific spawning, piped stdio, and kill-on-drop behavior.

GitOrigin-RevId: 26c2fb2f22cdba907aa9d18cab7dc8c4ac1c909e
2026-09-19 15:13:59 +00:00
jif d6fb836f31 Use macOS member fallback in shared process-group termination helpers (#46521)
## Why

On macOS, process-group signals can be denied even when individual members can be signalled. Core execution cleanup used helpers that did not retry those signals against group members.

## What changed

- Make `terminate_process_group` and `kill_process_group` use the existing member fallback on macOS, and simplify MCP and pipe callers to use the shared helpers.
- Use the saved process-group ID when escalating cancellation after the termination grace period, so this path also uses the fallback.
- Update the unsafe process-group ID test to exercise `terminate_process_group`.

GitOrigin-RevId: 1bab28d3d53cd401b51ffe71d41fbece12aed66d
2026-09-18 23:59:18 +00:00
alexsong-oai a129392ebb Add OAuth credential management for model provider gateways (#46318)
## What changed

- Export `GatewayAuthConfig` and `GatewayAuthManager` with PKCE browser sign-in, loopback callbacks, cached token resolution, and refresh after expiry or rejection.
- Store gateway credentials in a dedicated encrypted namespace with an independent keyring key. Serialize token exchanges and persistence across processes, preserve refresh rotations after caller cancellation, and retain pending credentials when saving fails.
- Validate OAuth endpoints and token responses, disable token-request redirects and logging, and redact sensitive error details.

## Testing

Add tests covering browser authorization, callback state validation and cleanup, concurrent refreshes, cancellation, failed-save recovery, storage isolation, endpoint validation, and credential redaction.

GitOrigin-RevId: e0c17f1eab7acca378a14b2d00b80940d8542e47
2026-09-17 23:35:32 +00:00
Rennie b97abdbe30 Add read-only policy support to MCP tool requests (#46042)
## Why

Read-only MCP discovery and invocation need a consistent policy across requests, connection reuse, and tool catalogs. Reusing an unrestricted connection or cached catalog can bypass filtered discovery.

## What changed

- Thread `requires_read_only_mcp_tools` through MCP configuration and client setup, leaving it disabled by default.
- When enabled, set `openai/readOnly` to `true` in `tools/list` and `tools/call` request metadata, overriding a caller-supplied `false` while preserving other metadata, pagination, and arguments.
- Include the policy in connection identity and bypass shared Apps and persistent tool catalog caches for read-only connections.

## Testing

Add coverage for metadata propagation in legacy and modern protocol modes, preservation through session recovery, and isolation from unrestricted connections and shared Apps catalogs.

GitOrigin-RevId: f4a3a4021a54e302bffd53f08092b080c056246b
2026-09-16 22:25:54 +00:00
malsamiri-oai 8e2afc0912 Recover OAuth metadata discovery from 503 responses via OIDC (#44636)
## Why

A `503` from an issuer's OAuth metadata endpoint can block discovery even when its OIDC metadata is available, preventing expired OAuth tokens from being refreshed during MCP startup.

## What changed

Try the same issuer's OIDC discovery endpoints when an OAuth authorization-server metadata GET returns `503`. Support issuers with path components and keep all attempts within the original request's timeout.

Reuse existing header, origin, and response-size checks, leave issuer validation to RMCP, and do not follow fallback redirects. Preserve discovery errors when fallback fails instead of enabling legacy endpoint fallback, and propagate terminal HTTP failures.

## Testing

Add tests for OIDC candidate order, malformed metadata, issuer mismatches, header isolation, redirects, terminal failures, unaffected requests, and the shared timeout. Add startup coverage for refreshing expired persisted tokens after OIDC fallback in both legacy and coordinated refresh modes.

GitOrigin-RevId: 6d94fd09e9ba26cb83e029171449e91410a0f6cb
2026-09-10 20:50:10 +00:00
willwang-openai f8ab57359d Add manual callback input to MCP OAuth login (#44629)
## Why

Allow MCP authentication to complete when the browser cannot reach the callback page by accepting the full redirect URL copied from its address bar.

## What changed

- Add `codex mcp login <name> --no-browser` to print the authorization URL and accept a pasted callback without launching a browser. HTTP callbacks remain supported while waiting for input.
- Validate pasted redirect URLs and OAuth responses before exchanging tokens, hide terminal input, bound input size, and avoid echoing callback values in diagnostics.
- Preserve manual input across discovered-scope retries and support cancellation during callback input and token exchange.

## Testing

Add unit and CLI integration tests for callback validation, bounded input, credential storage, HTTP callback completion with stdin open, scope retries, and cancellation during token exchange.

GitOrigin-RevId: 16ea9c3221f72d93e6e3e5acdc6b9465293a0a65
2026-09-10 19:51:52 +00:00
Nick Steele 86661eb626 Simplify enterprise OAuth login helpers and expand callback tests (#44616)
## What changed

- Consolidate callback address and port parsing in `enterprise_callback_settings`.
- Reuse `StoredOAuthTokens::has_refresh_token` for credential validation.
- Keep `EnterpriseOAuthHttpClient` private and inline removal of the `resource` parameter from authorization code token requests.
- Share the `complete_login` test helper across login and logout tests.

## Testing

Expand callback settings coverage to check default and configured ports, ports from callback URLs, and rejection of conflicting ports alongside loopback address validation.

GitOrigin-RevId: 42c9be5663ce13b7349cefac2c6a20c4fa974aef
2026-09-10 18:43:15 +00:00
riley-oai c6a59ef923 Support native verification in MCP tool continuations (#44346)
## Why

RMCP's standard input request union excludes custom methods, so tool continuations need explicit handling for OpenAI form elicitation and native user verification.

## What changed

- Route MCP `2026-07-28` tool inputs through the existing client service, preserving capability checks and verification response validation.
- Support `openai/elicitation/create` form and `openai/userVerification` inputs alongside standard MCP inputs, and return responses with the server's opaque `requestState`.
- Bound continuation rounds, back off for state-only responses, and reject unsupported or malformed inputs.
- Give concurrent verification prompts distinct cancellation ownership and release pending prompts and timeout pauses when the connection closes.
- Prevent session recovery from restarting a tool after submitting a verification proof while preserving authentication challenges.

## Testing

Add HTTP continuation tests covering mixed input types, proof validation, request metadata preservation, invalid requests, round limits, authentication challenges, session expiry after proof submission, and independent prompt cancellation. Add duplex transport tests for pending-input cleanup on cancellation and transport closure.

GitOrigin-RevId: b7db6d47fa0969b6a938220dfe3610e5ba5188b2
2026-09-10 00:14:43 +00:00
jif 3436cad5ab Fix MCP elicitation cancellation and reset state on reconnect (#44238)
## Why

Form and URL elicitations could keep waiting for a response and leave tool timeouts paused after cancellation. Remembered cancellations could also affect reused request IDs on a new connection.

## What changed

- Honor request cancellation and server cancellation notifications for all elicitations, without requiring user-verification support. Return `cancel` and release pending response routes and timeout pauses.
- Create a fresh elicitation service for each connection attempt, including initialization retries and session recovery, so cancellation state stays scoped to its connection.

## Testing

Add regression tests for form and URL elicitation cancellation, cleanup on service shutdown, and acceptance of previously cancelled request IDs after connection recovery.

GitOrigin-RevId: 388a8d72e55e89ad3d44d4739d8434485588aa1a
2026-09-09 17:42:20 +00:00
Andrei Eternal 5ac0b8768d Surface MCP reconnect signals when expired OAuth tokens cannot refresh (#43947)
## Why

Refresh failures could leave expired MCP OAuth credentials reporting ordinary errors instead of signaling that authentication is required, preventing tool calls from offering a reconnect signal.

## What changed

- Classify provider failures and timeouts as `AuthorizationRequired` when the access token has expired. Keep proactive refresh failures as ordinary errors while the token remains valid.
- Reread stored credentials after a failed refresh and adopt a valid login completed during the request, enforcing the existing issuer binding for refresh tokens. Preserve stored credentials for later retries.
- Convert authentication-required tool-call errors into a reconnect message with `mcp/www_authenticate` metadata, without exposing provider or transport details.

## Testing

Add coverage for startup and runtime OAuth recovery, proactive refresh failures, concurrent login adoption, issuer mismatches, credential preservation, and successful retries. Verify failed local refreshes do not send tool calls and server-rejected calls are not replayed.

GitOrigin-RevId: 9cf64b0452685d2085df5dc0bcecee16ffe42e47
2026-09-09 00:03:41 +00:00
Mitsuhiro Kotake 44ab72674e Close MCP stderr readers on client teardown (#43870)
## Why

A descendant outside an MCP server's process group can keep stderr open after the server exits, leaving the reader task and its file descriptor alive.

## What changed

Signal the local stderr reader during explicit shutdown and when the process handle is dropped. Allow up to 250 ms to drain queued diagnostics before closing the reader, even if stderr never reaches EOF.

## Testing

Add a Unix regression test covering explicit shutdown and client drop with a descendant that keeps stderr open. Verify that file descriptor counts return to baseline while the descendant remains alive and that queued diagnostics are logged.

GitOrigin-RevId: 1b544e8dba2b5616db6739d075e7232564c92884
2026-09-08 17:42:14 +00:00
Nick Steele b090e901f8 Add staged enterprise OIDC login and coordinated logout (#43844)
## Why

Enterprise sign-in needs to keep browser completion separate from credential storage so callers can recheck the active account and configuration before saving a grant. Logout must also prevent an earlier sign-in from restoring credentials, including from another process sharing `CODEX_HOME`.

## What changed

- Add enterprise login APIs in `rmcp-client` that return an authorization URL and stage validated credentials for an explicit `commit_if` call. Store grants only in the keyring after rechecking caller authority under the credential lock.
- Require a registered client ID, published metadata matching the configured issuer, HTTP loopback callbacks, a refresh token, and a valid OIDC identity assertion. Request `openid` and `offline_access` with `prompt=consent`, and omit MCP resource indicators from authorization and code exchange.
- Persist a login generation under the credential lock so logout invalidates pending and staged sign-ins across processes, even when no grant is stored.
- Keep credentials and account identifiers out of enterprise error chains and logs, and avoid logging callback payloads when the receiver has closed.

## Testing

Add coverage for discovery validation, loopback callbacks, PKCE, staged keyring storage, cancellation, stale attempts, cross-process logout, and error/log privacy. Preserve ordinary MCP OAuth login without a refresh token, and adjust the terminal polling test deadline to include the minimum empty-poll wait.

GitOrigin-RevId: 2a27b9a26505a2f6fdecce8877f6e2c21e148f72
2026-09-08 16:07:38 +00:00
riley-oai 3cd6004dc4 Add capability-gated MCP user-verification handling (#43289)
## What changed

- Handle `openai/userVerification` requests through `openai/elicitation/create` when the client advertises `userVerification` support.
- Validate request fields, size limits, and base64url encoding. Require a correctly shaped, bounded proof for acceptance; cancel invalid acceptance responses and discard proof material on decline or cancellation.
- Handle request and service cancellation, including cancellation received before request dispatch. Bound early-cancellation storage and cancel new verifications when capacity is exceeded.
- Keep verification inactive in Codex: cancel requests without prompting until the typed app-server and UI path is available.

## Testing

Add tests for request and proof validation, malformed modes, cancellation races and capacity limits, timeout-pause cleanup, and independent concurrent requests. Add integration coverage showing that verification does not prompt or prevent tool and turn completion before activation.

GitOrigin-RevId: 6313c1be40fae0b33cc3ce0f8fe025b4124ed2ef
2026-09-06 21:41:16 +00:00
jif 88f87d907a Avoid port races in streamable HTTP tests (#42767)
## Why

The test helper previously released its reserved port before starting the
streamable HTTP server. Another concurrent test could claim that port and
satisfy the readiness probe for the wrong process.

## What changed

Start the child server on an OS-assigned port and wait for it to publish its
actual bound address. Use that address to build the base URL returned to the
streamable HTTP integration tests.

GitOrigin-RevId: 606ae446f947d39424e4ec996ac647881777ff44
2026-09-04 13:35:41 +00:00
Alex Kotliarskyi 0650d6d1ca Preserve MCP authentication challenges on tool calls (#42552)
## Why

When silent OAuth refresh cannot recover a rejected MCP tool call, the caller
needs the server's authentication challenge to initiate interactive login. The
rejected call must not be replayed automatically after refresh has failed.

## What changed

- Convert `401 Unauthorized` responses with `WWW-Authenticate` headers into an
  MCP tool error containing `mcp/www_authenticate` metadata.
- Preserve multiple authentication challenges by combining all
  `WWW-Authenticate` header values.
- Keep successful silent refresh behavior while avoiding replay when refresh
  fails.

## Testing

Added coverage for successful and failed refresh, multiple authentication
headers, propagation through agent tool-call events, and no-replay behavior.

GitOrigin-RevId: c560cff6286d7ab09b1f5c6cf3618d4650cde47d
2026-09-03 15:12:02 +00:00