## Why
A cached MCP tool can remain advertised after its server fails to start. Calling it previously returned a generic unavailable-tool error, hiding the startup failure from the model.
## What changed
Propagate preparation errors through MCP tool calls and recorded approval preparation, preserving the error chain and adding the server name to startup failures. Keep the unavailable-tool error for tools that are missing, filtered, or no longer visible to the model.
## Testing
Update the executor capability downgrade test to require the credential resolution startup error in the model's tool output and assert that the host token is absent.
GitOrigin-RevId: 434074eb748165b2fe19de3a40046835f26992df
## Why
Subagents reusing cached MCP tool definitions were forced to use the legacy protocol, preventing connection sharing from being negotiated on first use.
## What changed
Keep stdio protocol discovery enabled during deferred startup while allowing dormant subagents to advertise cached legacy tools. Track modern discovery separately from catalog updates so discovery clients reject older legacy catalogs while legacy clients can still reuse them. Keep modern tools out of the legacy catalog when joining pooled connections.
## Testing
Add coverage for deferred subagents negotiating sharing on first use and reusing the same server process, while a legacy sibling retains cached definitions without starting its server. Extend cache coverage to ensure older legacy fetches cannot undo modern discovery.
GitOrigin-RevId: 5f8f4deb22cfb81a08c05ff3fcd7ba5c9199551c
## What changed
Keep the advertised `_codex_apps.invocation_context` when an app's tool metadata refreshes on the same server connection, while using refreshed values for other metadata. If the invocation context changes on a different connection, skip the call as unavailable.
## Testing
Extend the code-mode compaction test to refresh app tools before resuming a cell and verify that calls retain the original invocation context while picking up the refreshed `resource_uri`.
GitOrigin-RevId: 1b6072faed74623994ea82035a6ed977451984a4
## What changed
- Select fresh authentication for each HTTP operation on eligible OpenAI MCP connections while preserving the connection's credential source and account network policy. Stop redirects when requests carry runtime assertions.
- Pass the owning thread's authentication and runtime context through app discovery, connector metadata, and trusted-access requests. Include the runtime authentication mode in MCP connection and tool-cache identities.
- Give resumed actors analytics clients bound to their own authentication context, and serialize stored-credential reloads with token refresh while preserving host-provided credentials.
## Testing
Add coverage for fresh request assertions, revoked account policies, redirect handling, resumed-actor isolation, and MCP uploads in dual-header and assertion-only modes.
GitOrigin-RevId: f06900a6db61cd6cf53c3aa8075afeec4d5706d9
## Why
MCP permission profiles need the directory context used to interpret them. Prepared calls must retain that context alongside their captured permissions across runtime refreshes.
## What changed
- Store each server's permission source as thread permissions or a captured environment `FileSystemSandboxContext`.
- Capture environment working directories, home and temporary directories, and materialized workspace roots. Retain the host working directory for thread permissions.
- Expose the captured source through `PreparedMcpCall::permission_source()`, while keeping hosted Apps on thread permissions even when a local environment is attached.
## Testing
Extend binding tests to verify that prepared calls retain environment sandbox paths across refreshes and expose the host working directory for thread permissions. Update elicitation coverage to include hosted Apps with an attached local environment.
GitOrigin-RevId: 87e94605daece324786eebc07b62a507d35e5ced
## Why
`CodexThread::call_mcp_tool` returns only the tool result, so computing attribution and creating a cached runtime binding for these calls is unnecessary.
## What changed
Add `McpRuntime::latest_call_tool_without_attribution` and use it for direct thread calls. Validate the call, wait for server startup, and dispatch through the latest connections without capturing an attribution binding.
## Testing
Extend the runtime binding cache test to verify that a successful call without attribution leaves the cached binding empty. Update the test server to return a successful tool result.
GitOrigin-RevId: 898e655d9a0174ddaf71c390757d6fc9a5a61780
## Why
Plugin and skill catalog reads currently wait for the Apps server's initial `tools/list` to finish, even after its MCP transport is initialized.
## What changed
Add the disabled-by-default `features.apps_early_resource_discovery` flag. When enabled, host-owned Apps requests for `mcp/plugin` and `mcp/skill` resources can use the initialized transport while the initial tool inventory is pending. Server readiness still waits for the inventory to complete, and retries use normal readiness.
Bound early client acquisition by the configured startup timeout, propagate startup failures and cancellation, and reject pages if the connection, authentication scope, or resource cache generation changes during discovery.
## Testing
Add coverage for gated discovery, concurrent plugin and skill reads, startup timeouts and failures, cancellation, cache invalidation, and account switches. Verify that early discovery reuses a single handshake and tool inventory, including with the newer MCP protocol and connection sharing enabled.
GitOrigin-RevId: 955b1f6d43b733bdf9763c1caf2ce6913c686c81
## Why
Hosted Apps returns no resource templates, so querying `resources/templates/list` is unnecessary.
## What changed
Return an empty template list for host-owned Apps in single-server binding requests and skip it during aggregate template discovery. Use server registration metadata so extension-provided servers named `codex_apps` continue to expose their templates.
## Testing
Add coverage for hosted Apps versus extension registrations and for full MCP server status with standalone and thread connections. Verify that status requests still call `resources/list` but omit `resources/templates/list`.
GitOrigin-RevId: 3182b619391aefbb2a47ca7b8d9611402846bfe3
## What changed
- Add `ConnectorRuntimeManager::without_shared_snapshot()` to keep connector catalogs local to each client and disable disk caching.
- Use the thread's own Apps discovery when snapshot sharing is disabled, preserving its catalog across turns.
- Expose `apps_tools_from_mcp_client()` to read a ready, unshared Apps client's tools without starting or waiting for discovery.
## Testing
Extend coverage for shared-cache eligibility and verify that an unshared thread waits for its own Apps discovery and uses its own tools on successive model requests, even when a peer finishes discovery first.
GitOrigin-RevId: d57ddacaede047e67c09d378c86c1aa3577ca56f
## What changed
Extend `mcp_connection_sharing` to pool compatible local stdio connections that negotiate MCP `2026-07-28`. Keep legacy servers and servers that request input during startup private.
Preserve each chat's tool catalog and route input requests to the calling chat. Release connections independently for each chat, shutting down the shared server after the final release, and retire pooled connections on forced refresh without interrupting other chats.
## Testing
Add pool, runtime, app-server, and core scenario tests covering protocol gating, startup cancellation, refresh, final-release shutdown, and separate tool visibility and simultaneous input responses across chats sharing one process.
GitOrigin-RevId: 896b107267a20ec1bffccdefca6c40fe2945a022
## Why
Stdio servers without `CODEX_MCP_PROTOCOL_VERSION` use the legacy handshake, even when they support MCP `2026-07-28`.
## What changed
- Add the disabled-by-default `mcp_connection_sharing` feature to enable discovery for eligible local stdio servers.
- Recover from failed or late discovery with a fresh handshake when needed, waiting for the previous helper to release resources before restarting.
- Retain a working legacy connection when an upgrade attempt fails for the same account, except on authentication errors.
- Keep tool catalogs separate by protocol and invalidate legacy catalogs when discovery negotiates the modern protocol.
## Testing
Add regression coverage for failed and late discovery, legacy fallback, protocol-specific catalog reuse, message limits, and Windows descendant cleanup.
GitOrigin-RevId: 36c675ef3b81d32fccf06ccbddda2312cfe602c9
## What changed
Add an optional `NetworkPolicyMetadataProvider` to the MCP runtime. Advertise `codex/network-policy-meta` only to trusted ChatGPT origins when a provider is available, and attach policy metadata only when the sending session also advertises support.
Strip caller-supplied policy metadata and derive restrictions from the call's captured permission profile and server environment. Resolve metadata against each session's capabilities, including after recovery, while retaining one policy snapshot per call. Fail the call before sending if policy resolution fails. Existing runtime callers leave the provider unset.
## Testing
Add tests for capability negotiation, trusted-origin restrictions, forged metadata removal, both tool dispatch paths, and policy snapshot reuse. Add HTTP session-recovery coverage for changing capabilities and policy-resolution failures while preserving caller metadata and read-only restrictions.
GitOrigin-RevId: 4b978f986abc0475fc67659be98fc01a2d6ce7cd
## What changed
- Prefer an eligible account grant over saved enterprise credentials, with a fallback to saved enterprise sign-in during initial connection if the account grant is rejected.
- Remember rejected account grants per enterprise MCP registration across threads and report authentication failures as requiring reauthentication. Keep administrator configuration errors distinct from sign-in failures.
- Compare account grants independently of access and ID token rotation, recheck the latest identity eligibility after exchange, and retry once when the refresh grant changes.
- Make MCP authentication status reflect usable account grants, saved enterprise credentials, and completed connection failures.
## Testing
Extend regression coverage for enterprise sign-in failures and recovery, MCP authentication status, account grant identity across token refreshes, and retries after transient credential failures.
GitOrigin-RevId: eeac65f668d5d2d55e9d8bf4547fbcbdd6a6c42d
## Why
Configuration reloads must cancel stale enterprise MCP startups while preserving access for running threads that still pass validation. Replacing a runtime during `thread/revert` must also leave the replacement able to use enterprise tools.
## What changed
- Separate pending startup cancellation from published thread lifetimes, with independent startup state for forks and replacement runtimes.
- Retain eligible enterprise MCP connections across refreshes and explicit reconnects while applying updated tool restrictions and approvals. Do not create replacement enterprise connections after initial startup.
- Revoke enterprise authorization when a thread is removed, drain requests when access is disabled, and revoke a connection's authority when token renewal requires authentication.
## Testing
Extend regression coverage to verify enterprise tool calls survive `thread/revert`, inherited fork configurations are cancelled after a reload, and enterprise calls fail after logout while ordinary MCP calls remain available.
GitOrigin-RevId: 2d634be3011854b57f73c741bd1ec6b5aed94ee5
## Why
Synchronous auth header construction could silently return no credentials when managed authentication became unavailable. Callers need an error to avoid sending requests with missing or partial authentication.
## What changed
- Make `AuthProvider::add_auth_headers`, `to_auth_headers`, and auth header telemetry fallible, and propagate failures through request and WebSocket setup.
- Return a transient error when managed authentication is unavailable, and preserve network policy denials through auth error conversion.
- Retry transient MCP authentication errors while treating build errors and policy denials as terminal.
- Cancel local MCP event streams before resolving authentication so cleanup still works when credentials become unavailable.
## Testing
Add regression coverage for rejected partial authentication, async header resolution, terminal auth errors without sending requests, managed account changes, MCP retry classification, and local stream cancellation after authentication becomes unavailable.
GitOrigin-RevId: 39d981e232cba1e302de502a2fa6239101114ed1
## What changed
- Connect directly configured MCP servers using account-scoped enterprise grants stored in the keyring, with token exchange and authenticated HTTP requests.
- Retain authorization for the thread across MCP refreshes and revoke it when the account owner changes, cloud configuration becomes invalid, or an enterprise login replaces the grant.
- Negotiate the enterprise-managed authorization extension with the `2026-07-28` protocol, bypass shared tool catalog caching for enterprise servers, and report credential status with enterprise sign-in guidance.
GitOrigin-RevId: c0f96d37194212758a211ae6a4107205df96df26
## 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
## 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
## Why
MCP servers at `https://gov.chatgpt.com` were treated as untrusted for ChatGPT authentication and switched to OAuth, preventing local Gov Apps from retaining the ChatGPT auth provider.
## What changed
Trust the `https://gov.chatgpt.com` origin alongside the existing ChatGPT origin when resolving MCP server authentication. Origin matching preserves scheme, host, and port restrictions.
## Testing
Add regression coverage for Gov Apps URL construction, trusted origin normalization, rejection of lookalike hosts and nonstandard schemes or ports, and retention of the local ChatGPT auth provider. Verify that explicit OAuth servers and servers in remote environments do not receive the host provider.
GitOrigin-RevId: 7ceaf7c524d963005d9f23204489bbde269f0dd5
## 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
## Why
A transient Apps MCP startup failure can remove cached tools that the model has already discovered, preventing a later Code Mode invocation from using them.
## What changed
Keep cached Apps tools in the model's tool catalog while startup recovery runs. Let invocation readiness start or join a shared retry before acquiring the tool execution lock, while tool discovery remains nonblocking. Keep recovery running if a waiting invocation is cancelled.
## Testing
Extend connection-manager tests to cover cached tool bindings and shared recovery. Add a Code Mode regression test that discovers a cached Calendar tool, invokes it after startup fails, and verifies that it succeeds after recovery while unrelated tools remain able to execute.
GitOrigin-RevId: e888501a1050884a50a473e71b893cf6672fe256
## 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
## Why
Prepared MCP calls cloned `ToolInfo` already stored in the binding's model-visible catalog, duplicating tool metadata.
## What changed
Store the binding catalog in an `Arc<[ToolInfo]>` and let prepared calls reference its entries by index. Keep separately owned metadata for tools hidden from the model and calls prepared outside the binding catalog.
## Testing
Extend the binding test to assert that advertised and prepared tool metadata share the same address, while preserving ready-client catalog selection and hidden-tool behavior when tool names collide.
GitOrigin-RevId: 24b92f7e1dbb421c9ebce875b9b1024f7d697c5e
## Why
Legacy MCP tool discovery discarded pagination cursors, leaving tools on later pages unavailable.
## What changed
Pass `tools/list` pagination cursors to the existing collector in both legacy and modern protocol modes. Legacy discovery now follows subsequent pages and applies the same pagination limits and cursor validation as modern discovery.
## Testing
Extend integration coverage to both protocol modes, checking that tools from later pages reach the model and can be called successfully, while catalogs with oversized cursors are rejected. Update the legacy discovery test to expect an error for a repeated cursor.
GitOrigin-RevId: a6daa8034d2a403c1f2a5846e385789d8a620af7
## Why
Inspecting one MCP server should not require full-inventory discovery or a separate connection when a thread already has one.
## What changed
- Add optional `serverName` to `mcpServerStatus/list` and update generated schemas and bindings.
- With `threadId`, apply any pending runtime refresh and reuse the thread's current connection and tool catalog, waiting only for the selected server during discovery.
- Without `threadId`, create a discovery connection for only the selected server. Unknown names return an empty page; omitting `serverName` preserves full-inventory discovery.
## Testing
Add a regression test covering both status detail modes, checking that tool metadata is preserved and that status reads do not repeat `initialize` or `tools/list` requests.
GitOrigin-RevId: 1b361b67a993ab45cae493e88c146f50cfaf753a
## Why
Cached executor MCP declarations must not gain access to host environment credentials when reconnecting to an executor that lacks environment credential resolution.
## What changed
- Retain credential policy through MCP registration, catalog materialization, and runtime setup. Derive selected HTTP plugin policy from the plugin's source environment.
- Reject host bearer-token fallback and transports requiring host environment headers or helpers for executor-owned declarations. Preserve host-configured credential resolution.
- Include credential policy in connection and tool catalog cache identities, and avoid reading host environment values for executor-only identities.
## Testing
Add regression coverage for legacy executors, cached declarations after a capability downgrade, policy preservation through catalog rebuilds, and connection and tool cache isolation.
GitOrigin-RevId: 2d5b85e4e98668c637c538cbe528914c936bd831
## Why
Fixed schema budgets can strip parameter descriptions from large MCP tools or render their Code Mode input types as `unknown`. Allow larger budgets to preserve that guidance.
## What changed
- Add `mcp_servers.<name>.tool_input_schema_max_bytes` to configure the UTF-8 byte threshold for best-effort input schema compaction, retaining the 5,000-byte default.
- Add `features.code_mode.tool_input_schema_max_bytes` for rendered input types. Use the largest of the 16,000-byte default, the Code Mode setting, and the ordinary MCP server's explicit setting.
- Apply rendering budgets to prompt declarations and the runtime tool catalog, and avoid reusing cached declarations after the Code Mode budget changes.
## Testing
Add coverage for UTF-8 compaction thresholds, budget precedence, configuration round trips, and preservation of parameter guidance in both the Code Mode prompt and `ALL_TOOLS`.
GitOrigin-RevId: 0ef2823a614d4794e636f518b09c0b03a5239b45
## Why
Required MCP servers can block startup while establishing a live connection even when a usable tool catalog is already cached.
## What changed
- Add per-server `startup_readiness = "catalog"` to expose cached tools while the connection starts, retaining `"connection"` as the default.
- Allow an eligible cached catalog to satisfy required-server startup validation and model binding capture. Explicit server or plugin requirements still wait for a live connection, and tool execution still requires the current connection.
- Check tool filters and model visibility when accepting cached catalogs, and preserve cached catalog revisions for binding reuse.
- Serialize the new setting, expose it in the configuration schema, and trace startup readiness at validation and model binding gates.
GitOrigin-RevId: a1cbdf1757ebb5824cffe2cc56408be49711c422
## 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
## Why
MCP requests requiring user input previously failed in subagents with guidance to ask the parent agent, blocking browser sign-in, form input, and interactive tool approval in the child thread.
## What changed
Remove the root-only MCP elicitation guard and `allow_user_interaction` plumbing so subagents can surface prompts and wait for responses under the existing approval policy and automatic review rules. Connector authentication can now return retry guidance after acceptance or preserve the original failure when declined.
Keep legacy tool approvals through `request_user_input` restricted to the root thread.
## Testing
Update unit and integration coverage for subagent prompt resolution, form responses, connector authentication acceptance and decline, automatic approval, strict review, and approval-policy updates on reused connections. Update the browser sign-in scenario snapshot to show the subagent continuing after an accepted response.
GitOrigin-RevId: c226fc6dfde724ed22b91dc04dd32bbc15245bee
## Why
MCP requests that need human input, including browser sign-in, must be handled by the root thread. Subagents need guidance to hand these blockers to their parent without prompting the user or automatically accepting requests that require input.
## What changed
- Reject interactive MCP elicitations and tool approval prompts in subagents with guidance to ask the parent and wait before retrying.
- Recognize browser authentication and `codex_requires_user_input` metadata even when the form schema is empty, while preserving automatic permission approvals and review decisions.
- Carry user-interaction eligibility through MCP runtime creation and connection reuse, and guard prompt registration.
- Preserve connector authentication diagnostics alongside handoff guidance, subject to normal tool-output limits.
## Testing
Add unit and integration coverage for blocked subagent prompts, root browser authentication, automatic approval and review, connection reuse, and authentication diagnostic preservation and truncation. Add a request-history snapshot for browser-auth handoff guidance.
GitOrigin-RevId: 83e146b6e5c1a2a22a34681ad45615f504b3c96c
## 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
## Why
Idle Apps clients and cached MCP bindings can retain replaced tool definitions. Shared catalog updates can also invalidate prepared calls even when the current definitions match the captured catalog, including after tools are restored while a call awaits approval.
## What changed
- Share immutable tool arrays across equivalent live discovery contexts and reuse storage for equal results. Let unused providers and cached bindings expire.
- Include requested capabilities and initialization results in the sharing scope, and detach servers that disable catalog caching from live sharing.
- Capture catalog snapshots for prepared calls. Accept equivalent shared catalogs regardless of tool-list order, while rejecting changed definitions and calls captured before an explicit refresh on that client.
## Testing
Add regression coverage for shared storage and scope isolation, release of replaced tools and unused bindings, equivalent catalog restoration, explicit refresh invalidation, and an Apps call completing after catalog restoration while awaiting approval.
GitOrigin-RevId: a0516186e4286d0ff13405fafbab6fcf3f1f3773
## What changed
Add `serverCapabilities` to `mcpServerStatus/list` responses in both `full` and `toolsAndAuthOnly` modes, including thread-scoped reads. Return the initialized server's capabilities object, including its `extensions` map, or `null` when unavailable.
Capture capabilities during initialization so they remain available when tool discovery fails. Clear them on each new connection attempt and keep them independent of shared tool caches. Update the protocol schemas, generated TypeScript and Python types, and documentation.
## Testing
Add coverage for extension capabilities surviving tool-discovery failures in both detail modes. Extend existing tests to check advertised extensions, absent capabilities after initialization failure, and serialization of unavailable capabilities as `null`.
GitOrigin-RevId: 8e9d67c10fac3a54e82bef8be5d99caaf82597d1
## What changed
- Apply `disabled_plugin_ids` to plugin skills, recommendations, hooks, and MCP servers without modifying shared plugin state.
- Activate selection changes when the next task starts, keeping pending settings from changing the active runtime.
- Hide app tools contributed only by disabled plugins from model tool catalogs and search. Preserve connectors shared with enabled plugins and existing direct Apps RPC behavior.
- Include plugin identity in MCP approval keys and use that identity when persisting plugin tool approvals.
## Testing
Add regression coverage for disabling and re-enabling plugin skills and tools, deferred activation of settings, shared connector ownership, selected plugin servers, executor hooks, and plugin-specific approval keys and persistence.
GitOrigin-RevId: 1153ff6aa7ab6953d50e838da05203904ecd2956
## Why
Extension-owned HTTP MCP servers previously inherited the default protocol mode. Extensions need to select a mode for their own server independently of other HTTP servers.
## What changed
- Add `McpServerContribution::SetWithProtocolMode` and re-export `McpProtocolMode` through the extension API.
- Carry the winning registration's protocol override through catalog resolution and materialization, and apply it to Streamable HTTP connections.
- Preserve existing defaults when no override is present. Selecting a protocol mode does not grant host-owned Apps cache access or environment authority.
## Testing
Add coverage for registration precedence and materialization, and extend cache isolation tests to cover explicit protocol selection. Add an integration test verifying that extension servers can select either the legacy or newer protocol while other HTTP servers retain the default mode.
GitOrigin-RevId: 606cecc03094a93258ffc433849f575020b81473
## Why
Status-only discovery could retain an `OAuth` status based on stored credentials even after the connection attempt failed authentication. This discovery path has no event channel to report the failure.
## What changed
Update the snapshot to report `NotLoggedIn` for servers previously marked `OAuth` whose connection attempts failed authentication. Preserve other authentication statuses and OAuth statuses for failures unrelated to authentication.
## Testing
Add a regression test covering OAuth authentication failure, successful OAuth startup, an unrelated provider error, and a bearer-token authentication failure.
GitOrigin-RevId: 9df68fb1f818e40acab0c71bb4fda118f03a7611
## Why
Hosted Codex Apps shared the `mcp_2026_07_28` protocol setting with other MCP servers, preventing independent protocol selection.
## What changed
- Add `features.codex_apps_mcp_2026_07_28`, disabled by default, for the host-owned HTTP `codex_apps` server. Enabling it attempts 2026-07-28 discovery with Legacy fallback.
- Keep other servers, including third-party registrations with Apps-like names or URLs and local stdio servers, governed by `mcp_2026_07_28`.
- Support the new flag through `experimentalFeature/enablement/set` and refresh protocol settings in existing sessions. Track protocol mode per server when deciding whether to reuse connections.
## Testing
Add coverage for independent feature and protocol selection, hosted event-stream protocol selection, standalone Legacy defaults and discovery fallback, and runtime enablement refreshing an existing app-server thread.
GitOrigin-RevId: 640e8e251f0c45e5f4829cc2b73c3082cf42f715
## Why
Dormant MCP servers with usable cached tool catalogs prevented binding reuse, causing each model step to capture a new binding even when the catalog was unchanged.
## What changed
Track dormant catalog revisions alongside ready client revisions so bindings can be reused until the catalog changes or the server starts. Explicit server and plugin requirements still trigger binding capture and startup. Check cached catalog availability without cloning tool definitions.
## Testing
Extend the lazy-startup integration test to verify that two model steps share one binding while the server stays dormant, and that starting the server invalidates that binding.
GitOrigin-RevId: ef0469a85000f84a928946c24350e3bda1522fb5
## Why
Refreshing installed Apps without a thread should update the tools available to existing threads on their next turn.
## What changed
- Publish live tool catalogs to clients with matching transport, auth, protocol, and listing settings within the same account and home directory. Ignore the thread attribution header when matching scopes.
- Adopt updated tools before catalog reads and new calls, preserving running calls and rejecting calls prepared against an outdated catalog revision.
- Keep the newest successful fetch per scope so older refreshes cannot overwrite newer tools, and exclude disk snapshots from live updates.
## Testing
Add regression coverage for refresh propagation to an existing thread without another tools listing, scope and account isolation, out-of-order refreshes, late client startup, and running versus stale prepared calls.
GitOrigin-RevId: 7a5ee34e23742ce374c6647dc8928b76ea622448
## What changed
Advertise the experimental `codex/auth-change` capability for stdio MCP connections with an auth manager. When the server opts in, send `notifications/codex/authChanged` after initialization and on subsequent auth changes, with credential and owner generation counters and no credentials.
Track owner changes separately from credential refreshes so consumers can detect login, logout, or user, workspace, and auth-mode changes even when notifications coalesce. Treat credential changes with incomplete owner identity as owner changes as well.
Tie the notification watcher to the managed client's lifetime, limit each send to five seconds, and close the connection if a subsequent notification fails.
## Testing
Add tests for credential refreshes versus owner changes, coalesced logout and account switches, capability opt-in, notification payloads, and watcher cleanup.
GitOrigin-RevId: 35a99f5252bd48ca60a71fbdd1f708a8158e812c
## Why
Device-authenticated verification needs an app response outside automated approval and review. Previously, MCP user-verification requests were always cancelled.
## What changed
- Add typed `openai/userVerification` elicitations carrying a title, description, and challenge through core and app-server.
- Route verification to one connection enabled by trusted host activation. Restrict responses to that owner, exclude requests from replay, and cancel on disconnect or authentication changes, including account switches away and back.
- Return proofs in `content`, discard response metadata, and cancel malformed acceptances. Suppress verification response logging and analytics, and send only a generic verification notice to realtime.
- Keep the mode experimental and exclude it from stable schema exports. Capability advertisement remains disabled, and the TUI cancels verification requests.
## Testing
Add coverage for owner isolation, disconnect and authentication races, proof response handling, automated-review bypass, inactive-host cancellation, stable schema filtering, and realtime payload exclusion. Update the MCP integration test to verify that an activated request holds the tool until the client responds.
GitOrigin-RevId: c8c7b6691a3f7756682bbcca9def1df0d1feb906
## Why
Refreshed Apps catalogs need to survive connection reuse. Catalog revisions scoped to the connection set can lose refreshed tools during reconciliation and invalidate prepared calls for unrelated servers.
## What changed
- Store tools, revisions, and refresh coordination on each MCP client, and key cached bindings by client identity and revision.
- Preserve existing binding snapshots while rejecting stale calls before preparation. Wait for active calls to finish before publishing a refreshed catalog.
- Add `CodexThread::refresh_codex_apps_tools` to reconcile the runtime and return the refreshed client's raw Apps inventory alongside tool names eligible under that runtime's generic MCP policy. Keep hidden and disabled tools in the inventory for callers to apply app-specific policy.
## Testing
Add regression coverage for refreshed catalogs surviving client reuse, unrelated calls remaining valid, binding cache invalidation, and refresh snapshots retaining the client's own inventory when another client wins the shared-cache race. Update stale-call and preparation tests to use client-owned catalogs.
GitOrigin-RevId: f2308c81f7474eb31f3380c091c977030123cda2
## Why
Selected plugin MCP servers may be skipped after the optional startup grace
period. When a user explicitly mentions a plugin or MCP server, the turn should
continue waiting so the requested tools are available to the model.
## What changed
- Track explicitly mentioned plugin IDs and MCP servers across later samples,
steered input, and same-turn restarts.
- Require matching selected-plugin MCP servers to finish startup before
capturing the tool catalog, while leaving unmentioned servers optional.
- Match `plugin://` identities independently of display names and ignore
targeting query parameters such as `app` and `browserFamily`.
## Testing
Added coverage for linked and structured plugin mentions, direct and batched
capability discovery, delayed environment attachment, steering, and same-turn
restarts.
GitOrigin-RevId: c509ef8df45df1a7edb0da6afdb2682dc53a4de8
## 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
## Why
Event subscriptions may need to outlive the MCP runtime associated with a task.
## What changed
- Add `McpEventStreamOpener`, which retains the hosted Apps MCP connection settings and opens each event stream with an independent client.
- Keep subscription cancellation tied to account changes and removal of the task's event server, including when cancellation ownership is forwarded across runtime replacement.
- Expose the opener and cancellation forwarding through `McpResourceClient`.
## Testing
Add an HTTP transport test that shuts down the runtime, refreshes credentials for the same account, and verifies that a new event stream connects with the current authorization and receives notifications.
GitOrigin-RevId: e102aa382e63121661ff0567f7523515e459922d
## 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
## What changed
- Add a positive `output_token_limit` setting to each entry under an MCP server's `tools` configuration.
- Apply the most restrictive limit when plugin and user policies overlap, while keeping approval policy independent.
- Carry the effective MCP output budget in conversation history so tool output, post-tool hook responses, and resumed sessions use the same truncation limit.
## Testing
- Cover configuration parsing, serialization, schema validation, and plugin policy merging.
- Cover MCP output below and above the configured limit, post-tool hook responses, and session resume.
GitOrigin-RevId: d0beb4fca9ba6055d9e1d31c137373b465d50d61
## Why
An MCP binding can wait for one server while another connection updates a
shared tool catalog. Preferring the catalog captured before that wait can omit
newly available tools from the first model request.
## What changed
- Recheck the current MCP tool catalog before using the captured fallback.
- Keep the captured catalog when it expires during the wait, while honoring a
server that disables catalog caching.
## Testing
- Cover a shared Apps cache populated by a peer while binding capture waits.
- Cover cache opt-out while capture waits for another server.
GitOrigin-RevId: e4389c7ba23e4d8397dbae0930c9e36ba0a172fb
## Why
Binding capture can wait for multiple MCP servers concurrently. During that wait, a tool catalog may be published by another connection or expire after it has already allowed a server to remain dormant. Re-reading only the current cache could omit those tools or trigger unnecessary startup.
## What changed
- Retain the cached catalog that permits lazy startup for the duration of binding capture.
- Recheck the cache after the optional startup grace so catalogs published while waiting are included.
- Add regression coverage for catalogs published during startup and catalogs that expire while another server is resolving.
GitOrigin-RevId: b5c66831db8f9ebecc79ff25c5b4b0182ad68a2f