Commit Graph

198 Commits

Author SHA1 Message Date
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
Matthew Zeng
88912c04cd Enable coordinated MCP OAuth refresh (#42413)
## What changed

- Honor `McpOAuthRefreshMode::Coordinated` for streamable HTTP MCP connections by letting RMCP refresh and persist credentials through the pinned credential store.
- Reread credentials while holding the refresh lock, persist refreshed tokens before retrying requests, and serialize login and logout writes with in-flight refreshes.
- Keep OAuth preparation outside MCP operation and handshake deadlines, and allow refresh persistence to finish if the initiating caller is cancelled.

## Testing

- Cover coordinated startup refresh, concurrent refreshes, `401` retries, credential mutation races, provider timeouts, and caller cancellation.

GitOrigin-RevId: 100ae788048087be23e26bb43f868b1fcebb007a
2026-09-03 02:00:12 +00:00
Matthew Zeng
312709252d Add an RMCP OAuth credential store adapter (#42384)
## What changed

- Add a test-only `CredentialStore` adapter that maps RMCP refreshes onto Codex's pinned OAuth credential backend.
- Require refresh transaction guards for mutations, preserve the pinned backend, and update the runtime credential snapshot only after persistence succeeds.
- Preserve scopes and token expiry metadata while rejecting credentials that no longer match the connection's client or issuer.

## Testing

- Cover guarded save and clear operations, persistence failures, pinned-store read failures, replacement and removal handling, and expiry round trips.

GitOrigin-RevId: eb1b98024322c03af94f5ab2e88c7dc4ae54893a
2026-09-02 23:19:11 +00:00
viyatb-oai
f53c91be2c Add attributed exec process lifecycle telemetry (#42373)
## Why

Exec-server process and network-policy events need stable attribution to the
launching tool call and executor without recording process payloads.

## What changed

- Add optional `ExecMetadata` to `ExecParams` and propagate the thread and tool
  call IDs from unified exec.
- Emit bounded OpenTelemetry events for process start, spawn failure, sandbox
  denial, and exit. Correlate them with the launch trace and registry-issued
  executor identity while excluding arguments, paths, environment values,
  output, and error text.
- Preserve launch attribution across long-running processes and reconnects, and
  attach the same metadata to network-policy audit events.
- Keep the protocol backward compatible when metadata is omitted, and prevent
  invalid trace headers from inheriting an unrelated active span.

## Testing

Add coverage for metadata serialization and propagation, lifecycle event
fields, trace relationships, reconnect behavior, spawn failures, sandbox
denials, and network-policy attribution.

GitOrigin-RevId: 7aa480a7289c73cb95e2c124c35500bb6f0d5084
2026-09-02 21:58:58 +00:00
Charlie Marsh
02f47d3fb3 Use native spawning for bare macOS MCP commands (#42192)
## What changed

- Extend the macOS MCP launcher to use native spawning for bare command names as well as relative executable paths.
- Resolve bare commands against the child's configured `PATH`, including empty entries and the default path when `PATH` is unset, while preserving `argv[0]` and script spelling.
- Fall back to the existing command launcher for failed searches and executable text without a shebang so its errors and shell behavior remain unchanged.

## Testing

Add macOS coverage for child `PATH` resolution, default-path lookup, launch errors, and shebang-free executable fallback.

GitOrigin-RevId: 06e76bf8dbd515331b588da797eb57cb765a546d
2026-09-02 03:24:43 +00:00
Matthew Zeng
bd89ce67cc Prepare MCP connections for coordinated OAuth refresh (#42128)
## What changed

- Add the under-development `mcp_oauth_refresh_coordination` feature and pin its selected refresh mode to each MCP connection.
- Treat the refresh mode as part of OAuth connection identity so runtime and MCP configuration refreshes reconnect when the mode changes.
- Keep legacy refresh behavior in builds where coordination is unavailable and emit a warning when coordinated mode is selected.

## Testing

- Cover connection replacement when the feature is toggled through both runtime and MCP configuration refresh paths.

GitOrigin-RevId: 89596150f0338e6ede0e712badecea4450831766
2026-09-01 20:26:57 +00:00
Charlie Marsh
ea7e0714da Fix relative MCP server spawning on macOS (#42117)
## Why

Rust falls back to `fork` when a macOS command combines a relative executable
path with a working directory, due to a historical `posix_spawnp` issue. This
can make local MCP server startup less reliable.

## What changed

- Spawn relative macOS MCP executables directly with `posix_spawn`, preserving
  the configured path, `argv[0]`, working directory, environment, stdio, and
  process group.
- Keep the existing launcher for `PATH` lookup and executable text files without
  a shebang.
- Use one local child wrapper for legacy and 2026-07-28 protocol framing, with
  cancellation-safe waiting and cleanup that kills and reaps dropped children.

## Testing

Add macOS regression coverage for relative scripts, argument and descriptor
preservation, launch errors, cancelled waits, and cleanup after runtime shutdown.

GitOrigin-RevId: 1cbc6b90aed6f67e0a38f551964d80496ebc4471
2026-09-01 18:53:06 +00:00
Eric Traut
94cbbddafc Support package-style MCP server names (#41700)
## What changed

- Allow MCP server names to contain `:`, `@`, `/`, and `.`, enabling names such as `npm:@modelcontextprotocol/server-sequential.thinking`.
- Preserve these names across `mcp add`, `get`, `list`, and `remove`, runtime tool namespaces, and OAuth credential lookup.
- Quote non-bare server names in generated `config.toml` recovery hints and keep similarly escaped OAuth credential names isolated.

## Testing

- Add CLI and runtime round-trip coverage for npm-style names.
- Add snapshot coverage for quoted recovery hints and a regression test for OAuth credential-name collisions.

GitOrigin-RevId: 97e9353cdbc544db4eb2377ddbfa1d2d539b1e04
2026-08-30 16:45:34 +00:00
victor-openai
eec4a23cb1 Support openai/elicitation form requests (#41447)
## What changed

- Advertise `openai/elicitation` form support when the client declares an
  object-valued `form` capability, without deriving it from the legacy
  `openai/form` capability.
- Handle `openai/elicitation/create` requests in `form` mode and forward their
  metadata and opaque schema through app-server as `openaiForm`, preserving
  `x-openai-*` annotations.
- Keep legacy form handling independent and have the TUI automatically decline
  the new form requests it cannot render.

## Testing

- Add an app-server round-trip test for capability negotiation, request
  forwarding, and accepted responses.
- Extend MCP capability filtering coverage for `openai/elicitation.form`.

GitOrigin-RevId: 88f39257bffafe4ee98a9c910e38507843cd7eeb
2026-08-29 02:43:10 +00:00
xl-openai
d9511fb788 Refresh MCP HTTP helper headers after authorization failures (#41400)
## What changed

- Re-run the HTTP headers helper after a same-origin `POST` receives a `401` or `403`, and retry the request once when the effective headers changed.
- Share refreshes across concurrent rejected requests, retain the previous headers when refresh fails, and keep the retry within the original timeout.
- Allow helpers to supply `Authorization` while preserving explicit OAuth or bearer credentials, OAuth insufficient-scope challenges, and redirect safety checks.

## Testing

- Cover rotating helper headers for MCP tool calls and same-origin OAuth token refreshes.
- Cover concurrent rejections, failed and unchanged refreshes, retry limits, timeouts, and redirects.

GitOrigin-RevId: c662edefdb1cd2876d9d02545a72d5bd6739864f
2026-08-28 19:29:51 +00:00
rka-oai
035295b46e Improve sandboxing, MCP errors, and cached approvals (#41196)
Expand Windows deny-read globs robustly across protected directories while preserving filesystem enforcement. Preserve structured MCP tool and resource errors through app-server responses. Bind cached Guardian classifications to current local and root authorization state so stale scores cannot approve actions.

Add regression coverage for the sandbox resolver, structured protocol errors, and authorization changes.

GitOrigin-RevId: 4b80ed724d869afeca79204222d8465fa99d3a24
2026-08-27 20:05:08 +00:00
soyeon-oai
ae357e7250 Attach verified access context to eligible plugin MCP calls (#41005)
## What changed

- Fetch ChatGPT account access and attach `cyber_trusted_access` under
  `openai/entitlementContext` when an installed or selected plugin explicitly
  requests it from a local, read-only stdio tool with no arguments.
- Reject caller-supplied entitlement context on direct MCP calls, and fall back
  to an `unknown` status when access cannot be verified or the account changes
  during the lookup.
- Count entitlement lookup time against the MCP tool-call timeout.

## Testing

- Cover eligible calls plus unowned, remote, HTTP, mutable, argument-bearing,
  API-key, undeclared, direct, and account-switch cases in core and app-server
  integration tests.

GitOrigin-RevId: 303b61585ef4530276c373d914a2d0ccef1f4ac2
2026-08-27 00:02:26 +00:00
Nick Steele
9b4a0f8a0a Add enterprise IdP identity resolution for MCP OAuth (#40739)
## What changed

- Resolve stored enterprise IdP sessions against discovered authorization
  metadata, requiring the configured issuer, public-client authentication, and
  supported ID-JAG token exchange capabilities.
- Bind OIDC identity claims and MCP resource indicators to their configured
  issuer, client, and server, and require reauthentication when pinned keyring
  credentials are removed or replaced.
- Hold the credential lock while rereading refresh tokens, and isolate
  enterprise credentials by reserved namespace and Codex home.

## Testing

- Cover metadata and claim validation, resource binding, credential replacement
  and keyring failures, refresh locking, expired ID tokens, and credential
  namespace isolation.

GitOrigin-RevId: edce3c6159f7d6831edf72e9608b3fc3f5823c83
2026-08-25 23:51:57 +00:00
Nick Steele
f6805328c4 Add enterprise ID-JAG exchange for MCP OAuth (#40722)
## What changed

- Add a non-interactive two-step exchange that obtains an ID-JAG from an
  enterprise identity provider and trades it for a resource-bound MCP bearer
  token.
- Validate trusted endpoint URLs, request inputs, ID-JAG claims, resource and
  scope bindings, and token responses before credentials are forwarded or a
  bearer token is returned.
- Expose structured authentication failures while redacting credentials and
  provider-controlled error details from diagnostics.

## Testing

- Cover successful exchanges, signed scope narrowing, invalid claims and token
  responses, request validation, and error redaction.

GitOrigin-RevId: d716e0e1c2dc6b230cecbc0e9cc09afeee81d599
2026-08-25 22:12:41 +00:00
stevenlee-oai
9be8d6e1c3 Harden MCP OAuth callback handling (#40691)
## Why

MCP servers can share an OAuth callback URL. Without a validated issuer or a
server-specific callback path, an authorization response could be associated
with the wrong server.

## What changed

- Use stable callbacks when authorization metadata advertises issuer-bound
  responses, and validate the returned issuer before exchanging the code.
- Retain server-specific callback IDs for providers without issuer support,
  including fallback to the global or default callback for legacy registered
  clients.
- Persist registered callback URLs for MCP servers and plugins, and insert the
  active listener port into portless loopback redirects.

## Testing

Add coverage for issuer validation, callback-mode discovery, registered and
legacy clients, plugin OAuth, CLI persistence, and loopback listener ports.

GitOrigin-RevId: 2878c92e237fc17fd3def0bd2e1cce3e104a3db8
2026-08-25 20:26:23 +00:00
cgst-oai
2df6705423 Cache executor metadata from initialization (#40343)
## What changed

- Include `environmentInfo` in the exec-server `initialize` response and seed the Rust client's metadata cache from it.
- Fall back to one lazy `environment/info` request when connecting to older servers that omit initialization metadata, then share the cached result across client clones and session recovery.
- Keep app-server `environment/info` requests uncached so they continue to probe the executor.

## Testing

- Cover initialization metadata, the legacy-server fallback, shared caching, accepted WebSocket environments, and repeated uncached app-server probes.

GitOrigin-RevId: 380132d9db183998d73e8c6b0954e4d70c7e8406
2026-08-24 06:43:07 +00:00
Eric Traut
343074d420 Report runtime MCP connection status (#40068)
## Why

MCP inventory can be cached or collected separately from a thread's live
connections, so tool availability alone does not describe the current runtime
state.

## What changed

- Add a nullable `runtimeStatus` to `mcpServerStatus/list` for thread-scoped
  requests, covering not-started, starting, connected, authentication-required,
  failed, cancelled, and disabled connections.
- Observe published connection state without starting or reconnecting servers,
  and return an unknown status when no thread is supplied or the active
  configuration no longer matches the published registration.
- Show connection state and tool counts in the compact `/mcp` view while
  retaining the detailed inventory in `/mcp verbose` and compatibility with
  servers that omit `runtimeStatus`.

## Testing

- Cover runtime status transitions, deferred and disabled servers, closed
  transports, configuration changes, protocol compatibility, and TUI rendering.

GitOrigin-RevId: e3bb6efe652f0fa8b3c97d5c53e4729b3a87cd91
2026-08-22 05:54:43 +00:00
jif
7f9832d0d0 Enforce issuer binding for MCP OAuth endpoints (#39935)
## Why

Interactive MCP OAuth must not trust authorization metadata that could route an
authorization code or PKCE verifier to an unrelated token endpoint.

## What changed

- Require an advertised issuer to match the origin that served authorization
  metadata.
- Validate authorization and token endpoint origins before starting both
  pre-registered and dynamically registered client flows.
- Allow delegated endpoint origins when the server advertises issuer-bound
  authorization responses, while retaining narrow compatibility exceptions for
  existing providers.

## Testing

Add coverage for rejected untrusted metadata, accepted issuer-bound delegation,
legacy provider exceptions, and both client registration paths.

GitOrigin-RevId: 43c9f94c9f6ba2d23d7e373576cf9fa26861cfc3
2026-08-21 13:28:28 +00:00
jif
93c54bca38 Resolve HTTP MCP bearer tokens in executor environments (#39926)
## Why

Executor-owned HTTP MCP servers need to read their bearer credentials from the
selected executor environment instead of the host process.

## What changed

- Preserve `bearer_token_env_var` for executor-owned HTTP MCP configurations and
  resolve it when the executor sends each request.
- Extend delegated HTTP headers with executor-local environment references while
  rejecting missing, empty, or protected credential variables.
- Keep transport-provided bearer authentication compatible with MCP redirect and
  OAuth handling without sending a placeholder authorization value.

## Testing

- Cover authenticated executor-owned MCP requests end to end.
- Cover delegated header resolution and rejection of protected variables.
- Cover parsing executor-owned bearer configuration and transport-provided bearer
  behavior.

GitOrigin-RevId: 442bf7382198ffb69eba797eb36d4c74faabda88
2026-08-21 12:50:15 +00:00
stevenlee-oai
a3bce23f3b Update rmcp to 3.1.3 (#39798)
## What changed

- Upgrade `rmcp` and `rmcp-macros` from 3.1.2 to 3.1.3.
- Preserve authentication-required and retryable transport classifications when modern MCP discovery falls back to legacy initialization.
- Prevent unrelated discovery errors from triggering legacy fallback while retaining their diagnostics.

## Testing

- Cover authentication challenges and transient initialization failures during legacy fallback.
- Verify that a failed OAuth issuer check does not consume the pending authorization state.

GitOrigin-RevId: 957c0873fec1148883dd163fbaeb77d7593d8c53
2026-08-20 20:53:17 +00:00
victor-openai
097825f75a Add app-server MCP event streaming (#39761)
## What changed

- Add experimental `mcpServer/event/stream/start` and `mcpServer/event/stream/stop` requests for hosted apps, plus `mcpServer/event/stream/notification` forwarding.
- Scope subscriptions to the owning app-server connection and subscribed thread, enforce unique IDs and a per-connection limit, and clean them up when the thread is unsubscribed or the connection closes.
- Wait for the MCP active notification before completing startup, retry streams that close immediately, and terminate them when authentication or hosted runtime ownership changes.

## Testing

- Add an app-server integration test covering activation, event forwarding, duplicate subscription rejection, and explicit cancellation.

GitOrigin-RevId: 8a6fc1615adfc5af7e67def3b824fa5909ab3e7b
2026-08-20 17:49:35 +00:00
jif
d0cc662b8c Cache shell snapshots in the exec server (#39756)
## What changed

- Add the `shellSnapshotV2` executor capability and an optional shell snapshot request to `ExecParams`.
- Capture and restore Unix shell state and profile exports from an in-memory, attachment-scoped cache for `bash`, `zsh`, and `sh`.
- Apply environment policies, runtime `PATH` entries, sandbox context, and live managed-proxy settings when preparing restored commands.
- Bound snapshot size, capture time, scope length, and cache capacity, and fall back to the original command when capture fails.

## Testing

- Cover local, remote, TTY, sandboxed, and supported-shell execution, plus environment filtering, proxy handling, in-memory reuse, and capture failure fallback.

GitOrigin-RevId: 624f747972c249c88c6f10f42cf0af97b75b5541
2026-08-20 17:39:06 +00:00
Jeremy Rose
250b5ea2bf Bind MCP OAuth refresh tokens to their issuer (#39615)
## Why

An authorization server discovered for an MCP server can change. A stored refresh token must not be sent to a different issuer than the one that originally granted it.

## What changed

- Persist the discovered authorization server issuer with new OAuth credentials and preserve it across refreshes.
- Validate that issuer against a single pinned metadata snapshot before refreshing or adopting stored refresh credentials.
- Require reauthentication when refresh credentials have no issuer or the issuer changed. An unexpired access token can still be used without exposing its refresh token.

## Testing

Add coverage for issuer persistence, missing and changed issuers, metadata changes during startup, and refresh-token preservation.

GitOrigin-RevId: 07e48ba892f627428a28bbed5cca4ad703e2a5fd
2026-08-20 06:25:17 +00:00
jif
929e2b9c1d Harden MCP OAuth fallback credential writes (#39611)
## Why

The fallback file contains OAuth credentials, so it must be private from the
moment it is created and writes must not follow links to another path.

## What changed

- Create the fallback file with mode `0600` on Unix before writing credentials.
- Reject symlinks and other non-regular files on Unix and Windows, including
  Windows reparse points.
- Truncate and update an existing regular file through the validated file
  handle, restoring private Unix permissions when needed.

## Testing

Added coverage for creation under a permissive umask, updates through an
existing hard link, permission restoration, and symlink rejection.

GitOrigin-RevId: d3e4be52e8f4cebb66c59d496a7f77a952a2d0d9
2026-08-20 06:17:48 +00:00
thomas
f1087ff151 Expand OAuth metadata redirect test coverage (#39320)
## What changed

- Cover same-origin redirects for protected-resource and authorization-server metadata.
- Verify that cross-origin redirects are rejected before contacting their targets and that redirect cycles fail within a bounded timeout.
- Exercise issuer validation and resource-header isolation for both direct and redirected metadata across legacy and Agent Plugin discovery modes.
- Reuse the test environment's local HTTP client throughout the discovery tests.

GitOrigin-RevId: bd12ac232c3b020a1c098a413361f8e205699699
2026-08-19 00:05:23 +00:00
thomas
7500ab4c8d Update rmcp to 3.1.2 (#39101)
## What changed

- Upgrade `rmcp` from 3.0.0 to 3.1.2.
- Use `rmcp`'s native JSON-RPC decoding and remove the local compatibility layer for multi-round-trip tool results.
- Preserve response metadata on `input_required` SSE results.
- Support OAuth protected-resource metadata discovery and include the discovered resource audience when refreshing tokens.

## Testing

- Add coverage for metadata preservation on modern SSE `input_required` responses.
- Add an OAuth startup scenario that discovers protected-resource metadata and verifies the refresh-token resource audience.

GitOrigin-RevId: 689f009b4a33552b640304111b74585b4009eeb8
2026-08-17 23:04:09 +00:00
Eric Traut
ff770113ca Restrict MCP HTTP redirects to the configured origin (#39046)
## Why

MCP requests can contain sensitive headers and tool-call bodies. Following a
cross-origin redirect could disclose them to another server.

## What changed

- Follow redirects only when every hop remains on the configured server's
  origin, and require HTTPS for redirects on non-loopback hostnames.
- Preserve standard redirect method and body handling while sharing the
  original timeout and enforcing a 10-hop limit.
- Avoid replaying plaintext proxy credentials across redirects, while leaving
  OAuth requests that stop at redirects unchanged.

## Testing

Add coverage for same-origin and cross-origin redirects, redirect methods,
headers and bodies, proxy credentials, timeouts, hop limits, and legacy MCP
tool calls.

GitOrigin-RevId: 3e267911a1665ad8c2fc63825099a758770f4d68
2026-08-17 18:46:12 +00:00
Eric Traut
02360b48d1 Isolate MCP resource headers during OAuth requests (#39019)
## Why

Headers configured for an MCP resource can contain credentials and must not be
forwarded to a different origin during OAuth discovery, registration, or token
exchange.

## What changed

- Apply configured resource headers only to OAuth requests on the MCP resource
  origin, while allowing OAuth-generated headers to take precedence.
- Follow credentialed OAuth redirects only when each destination remains on the
  resource origin. Preserve redirect method semantics, the overall timeout, the
  response size limit, and a maximum of 10 redirects.
- Use the Codex MCP user agent for requests to authorization-server origins.

## Testing

Add coverage for cross-origin header isolation, same-origin dynamic client
registration redirects, OAuth header precedence, token refresh, timeout
accounting, and response size limits.

GitOrigin-RevId: 609d06e2b065e4aa9ca5382b4ae60455f9e26db9
2026-08-17 16:29:47 +00:00
Ankush Gupta
4d9f3021c8 Include node_repl images in Guardian review evidence (#38454)
## What changed

- Preserve valid image content from completed `node_repl` Code Mode responses alongside text evidence for Guardian reviews.
- Enable multimodal evidence for models that require automatic `node_repl` review, or when both `guardian_enhanced_node_repl_transcripts` and `guardian_node_repl_transcript_images` are enabled.
- Bound retained and rendered evidence, deduplicate images already present in review history, and fall back to text-only evidence when the reviewer lacks image support or prompt capacity.
- Keep review evidence out of the parent turn input.

## Testing

- Cover feature gating, mixed text and image ordering, truncation and eviction, unsupported reviewers, prompt pressure, image detail normalization, and reused review sessions.

GitOrigin-RevId: a3e482402f7b3484401b231dadc662e6e3504fdf
2026-08-13 23:29:52 +00:00
Ankush Gupta
053dda6b89 Include Node REPL results in Guardian reviews (#38397)
## What changed

- Capture accepted, successful `node_repl` results from Code Mode and include them as bounded, untrusted evidence in Guardian review prompts.
- Enable the enhanced transcript through `guardian_enhanced_node_repl_transcripts` or when the selected model requires automatic Node REPL review.
- Keep this evidence out of the parent model history, exclude encrypted and failed results, and avoid resending admitted evidence when a Guardian session is reused.
- Clear retained evidence and invalidate review sessions when a thread is rolled back.

## Testing

- Add unit coverage for evidence ordering, escaping, truncation, and empty responses.
- Add an integration test covering feature-disabled, feature-enabled, and model-required behavior, including filtering and review-session reuse.

GitOrigin-RevId: edc3dca5d5b88d472a492f35531ec46889a89d72
2026-08-13 15:50:48 +00:00
xl-openai
379cb68444 Add dynamic HTTP header helpers for MCP servers (#38245)
## What changed

- Add `http_headers_helper` configuration for local streamable HTTP MCP servers. The configured shell command runs once per connection and returns a JSON object of headers that is cached across requests.
- Apply helper headers to MCP startup and OAuth flows while restricting them to the server origin, stopping redirects, rejecting reserved or duplicate headers, and enforcing output and execution limits.
- Reject helpers for remote or managed-disabled servers, use the local environment working directory, and redact helper commands from `codex mcp list` and `codex mcp get` output.

## Testing

- Cover configuration validation, helper lifecycle and output parsing, origin isolation, OAuth discovery and token refresh, managed requirements, environment selection, and CLI redaction.

GitOrigin-RevId: 84e0e26ce75520b0869d37c72b1678e033bd6818
2026-08-12 20:36:32 +00:00
stevenlee-oai
4c89139da9 Add CIMD support to MCP OAuth registration (#38089)
## What changed

- Make automatic MCP OAuth registration prefer Client ID Metadata Documents
  (CIMD) when the authorization server advertises support for public clients and
  Codex is using its native loopback callback. Fall back to advertised Dynamic
  Client Registration (DCR) otherwise.
- Add explicit `cimd` and `dcr` registration overrides to the CLI and app-server
  OAuth login API. Validate CIMD metadata and callback URLs before starting the
  authorization flow.
- Use a callback-specific Codex client metadata URL for CIMD and retain the
  exact redirect URI through authorization and token exchange.

## Testing

- Cover automatic and forced CIMD selection, DCR fallback, invalid metadata and
  redirects, token refresh, authenticated MCP requests, and conformance
  regression checks.

GitOrigin-RevId: 4238372ca53b0f38e781e141ab5da97e0a6ddf45
2026-08-12 00:01:01 +00:00
stevenlee-oai
6dc3ac8721 Add per-login MCP OAuth client registration selection (#38052)
## What changed

- Add `--oauth-client-registration` with `auto` and `dcr` choices to `codex mcp add` and `codex mcp login`.
- Add the equivalent optional `clientRegistration` field to `mcpServer/oauth/login` and the generated protocol schemas.
- Keep automatic dynamic client registration as the default, prefer a configured OAuth client ID when present, and apply the selection only to the current login without persisting it in MCP configuration.

## Testing

- Cover dynamic registration and configured-client OAuth flows through the app server.
- Verify the CLI does not persist the per-login registration choice.

GitOrigin-RevId: 653a4a1054ff43c2c5d52ae863b6a96d21692a53
2026-08-11 18:35:03 +00:00
Eric Traut
b2543af02b Propagate custom CA settings to local MCP servers (#38040)
## Why

Local stdio MCP servers may start in a different working directory from Codex,
so inherited relative CA bundle paths can otherwise resolve to the wrong file.

## What changed

- Forward the supported custom CA environment variables to local stdio MCP
  servers, convert inherited non-empty paths to absolute paths, and let explicit
  MCP environment overrides take precedence.
- Match CA variable names and `PATH` case-insensitively where required, avoiding
  duplicate environment entries and preserving executable discovery on Windows.

## Testing

- Add an end-to-end stdio MCP test covering relative inherited CA paths, empty
  values, explicit overrides, alternate key casing, and a different server
  working directory.
- Exercise executable resolution with Windows-style `Path` casing.

GitOrigin-RevId: ea1bc0ae63bc0dc780acb8363b2ed102120f282e
2026-08-11 17:24:04 +00:00
jif
dd22460869 Add MCP OAuth credential contention regression tests (#37866)
## What changed

- Cover non-blocking credential probes when the file or secrets store is locked, including retaining only a matching prior credential snapshot and recovering after the lock is released.
- Extend the streamable HTTP OAuth round trip to verify that user turns continue during store contention, newly discovered servers recover after contention, and logged-out servers do not reuse authenticated connections.
- Cover reconciliation of authentication failures and effective `Authorization` headers.

GitOrigin-RevId: 8e377644001bd0be04dc9f79841080094d09d199
2026-08-10 18:40:02 +00:00
jif
afcc95b431 Speed up MCP OAuth credential reads (#37860)
## Why

Refreshing MCP connection identities should not stall the async executor while another process holds the OAuth credential-store lock.

## What changed

- Probe file and secrets credential stores without waiting during runtime refreshes, retaining the last known credentials when the store is contended.
- Reuse unchanged authentication failures while credentials are temporarily unavailable instead of restarting the connection.
- Run blocking credential loads on a blocking worker during MCP client construction.
- Allow OAuth fallback when a configured authorization header is missing, empty, or invalid.

GitOrigin-RevId: 38dad5606da9a1ceb30fe945000ec9151a5058fa
2026-08-10 17:58:15 +00:00
iceweasel-oai
8b1b065719 Speed up MCP OAuth credential reads (#37842)
## Why

Concurrent MCP startup and status checks should not serialize when they only read the shared credential store. Repeated reads of the encrypted MCP OAuth store also needlessly decrypted unchanged contents.

## What changed

- Use shared locks for `File` and `Secrets` credential reads while keeping saves and deletes exclusive.
- Cache decrypted MCP OAuth secrets by store path, ciphertext, and passphrase, and invalidate the cache after writes.

## Testing

- Cover concurrent readers, reader/writer exclusion, shared credential loads, and cache invalidation after updates and deletes.

GitOrigin-RevId: f13512e6404d4919879ba5ba77a3e34e52b35640
2026-08-10 15:43:10 +00:00
cooper-oai
c4513cb982 Prevent launch context from reaching child processes (#37607)
## Why

Model-reachable child processes should not inherit Codex launch context.

## What changed

- Treat `OPENAI_FEDERATION_RULE_ID` and `OPENAI_IDENTITY_TOKEN_FILE` as non-inheritable environment variables, with case-insensitive matching.
- Remove them after shell environment policy overrides and before spawning commands across execution, MCP, hooks, Git helpers, and remote helper processes.

## Testing

- Cover inherited and explicitly configured variants, including mixed-case names.
- Verify the variables are absent from real child environments and app-server command and process execution.

GitOrigin-RevId: 2535527893985fef0995617f4c5b2462bea7c136
2026-08-08 16:58:26 +00:00
Evan Fannin
41014b11bd Add MCP event discovery and subscriptions (#37494)
## What changed

- Expose hosted Plugin Runtime event definitions through `McpResourceClient::list_events`.
- Add cancellable `events/stream` subscriptions that route lifecycle notifications to the matching request and cancel when the stream is dropped.
- Bound event notification and queue sizes, time out stalled response headers, and close streamable HTTP responses locally on cancellation.

## Testing

- Add streamable HTTP integration coverage for isolated concurrent subscriptions, local cancellation, and stalled response-header timeouts.

GitOrigin-RevId: 98c6fffa8f004eb2638c1b0705f659222cbbdfdb
2026-08-07 19:36:52 +00:00
Cam moten
9daa491f7c Harden local MCP server process tree cleanup (#37366)
## Why

A local stdio MCP server can exit while its descendants remain alive. Cleaning up
only the server process can therefore leak processes after client shutdown.

## What changed

- Contain locally launched MCP servers in non-breakaway Windows job objects and
  terminate the job during shutdown so descendants exit with the server.
- Preserve compatibility when job creation or assignment is unavailable by
  retrying without containment and terminating an owned process handle instead.
- Use the process-group member fallback when terminating piped processes on
  macOS.

## Testing

- Cover descendant cleanup and breakaway prevention for both local MCP protocol
  modes on Windows.
- Cover the Windows nested-job assignment fallback and verify the suspended
  process resumes before handle-based termination.

GitOrigin-RevId: 33d3cc122de8f7ce0ae69a649b12ea0ff64b7c6f
2026-08-07 03:34:49 +00:00