Commit Graph
16 Commits
Author SHA1 Message Date
Charlie Marsh 0bc73bbeb1 Add opt-in protocol discovery for local stdio MCP servers (#57210)
## 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
2026-10-26 19:37:06 +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
rreichel3-oai c7e80f873f Preserve executor MCP credential boundaries across reconnects (#48143)
## 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
2026-09-25 17:15:29 +00:00
Henry Levy b62fcd3c4b Allow cached catalogs to satisfy MCP startup readiness (#47935)
## 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
2026-09-24 20:38:50 +00:00
jif 20f109eadb Reuse MCP bindings while cached servers remain dormant (#44121)
## 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
2026-09-09 10:51:24 +00:00
jif 92f887ec35 Use refreshed MCP tool caches during binding capture (#41344)
## 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
2026-08-28 14:53:53 +00:00
trolle-oai 124e560b93 Make the optional MCP startup grace configurable (#41199)
## What changed

- Add `mcp_optional_startup_grace_ms` with a default of 1,000 ms to control how long tool catalog capture waits for optional MCP servers.
- Treat a value of `0` as disabling the shared grace, so optional servers use their configured `startup_timeout_sec` instead.
- Apply updated grace values during runtime and MCP configuration refreshes, and reset cached startup deadlines when the configured duration changes.

## Testing

- Cover custom, disabled, refreshed, and shared startup grace behavior in MCP connection and core integration tests.

GitOrigin-RevId: 936196215ed6e0a29c9ec72cfee17663978df8ef
2026-08-27 20:31:40 +00:00
jif 42b5f05cef Preserve MCP namespace descriptions in the tool catalog cache (#38623)
## What changed

Keep MCP namespace descriptions when publishing tool definitions to the
process-scoped catalog cache. Cached definitions now expose the server
instructions to the model before a lazily started MCP connection finishes
initializing.

## Testing

Update the cached MCP startup integration test to verify that cached namespace
descriptions retain the originating server instructions.

GitOrigin-RevId: d1b73381852fd43c6b54a7c22a599474c774dc20
2026-08-14 18:35:13 +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
jif 0ca439900e Cache tool catalogs for streamable HTTP MCP servers (#37970)
## Why

Subagents should be able to use known HTTP MCP tool definitions without opening a connection until a tool is actually called.

## What changed

- Add streamable HTTP configurations to the process-scoped MCP tool catalog cache when their authentication identity can be derived safely.
- Fingerprint transport settings, relevant environment variables, protocol mode, plugin status, and client capabilities so catalogs are reused only across equivalent connections.
- Keep OAuth and other dynamically resolved credential configurations out of the shared cache.

## Testing

- Add an integration test proving that a subagent receives cached HTTP tools without reinitializing the server, then starts its own connection when it calls one.

GitOrigin-RevId: bb2787e29e9b71993def31aafd1f0d8f1b728d26
2026-08-11 09:22:50 +00:00
jif 1151b23f01 Start cached MCP servers lazily for subagents (#37261)
## Why

Subagents can reuse cached MCP tool definitions without starting every optional
server before any of its tools are used.

## What changed

- Defer startup for subagent-owned, optional MCP servers when their cache has at
  least one visible, allowed tool, and trigger startup on the first operation
  that needs the live client.
- Keep root sessions, required servers, selected plugin servers, and explicit
  reconnects eager.
- Exclude empty catalogs from cache eligibility and keep dormant servers out of
  the initial startup summary.

## Testing

- Extend MCP tool-cache coverage for eager root startup, unused and filtered
  subagent servers, deferred startup status events, and startup that survives an
  interrupted first tool call.

GitOrigin-RevId: e7528ff08312583a6747cbc6550ea5b6eabda9a6
2026-08-06 11:18:24 +00:00
Martin Au-Yeung ee46c5ba0e Negotiate MCP extensions per app-server session (#36910)
## Why

App-server clients need to advertise structured MCP extension settings, including supported MCP App UI MIME types, rather than only opting into OpenAI form elicitation with a boolean.

## What changed

- Add an `extensions` map to initialize capabilities and preserve `mcpServerOpenaiFormElicitation` as a legacy alias for `openai/form`.
- Capture the declared extension profile when a thread is started, resumed, or forked, propagate it to subagents, and advertise it to downstream MCP servers during initialization.
- Keep the profile stable for the lifetime of the loaded session instead of changing it on later turns or direct tool calls.

## Testing

- Cover extension conversion, downstream MCP initialization, session isolation, legacy form support, and subagent inheritance.

GitOrigin-RevId: fbcedbb74ce788e574b0f884a4c45c4cedb9de54
2026-08-04 15:23:43 +00:00
jif 85c082cccc Share optional MCP startup grace across connection sets (#36011)
## Why

Each connection set could restart the one-second startup grace for the same
cacheable optional MCP server, repeatedly delaying catalog capture while that
server was still pending.

## What changed

- Store the optional startup deadline in the shared tool catalog cache entry.
- Reuse that deadline until a catalog is published, and allow a fresh grace
  period after the cached catalog expires.
- Preserve per-connection-set startup grace for servers that disable catalog
  caching.

## Testing

Added a paused-time test covering shared deadlines, immediate cached-tool reuse,
cache expiration, and disabled caching.

GitOrigin-RevId: 3494969ee7002c70ce9e4ffd370e46a22d38cc11
2026-07-29 18:53:15 +00:00
jif 3307ea8b63 Allow MCP servers to opt out of tool catalog caching (#33297)
## What changed

- Recognize the experimental `codex/tool-catalog-cache` server capability during MCP initialization.
- When the server advertises `cacheable: false`, clear its shared tool catalog snapshot and prevent subsequent fetches from repopulating the cache.

GitOrigin-RevId: bce98371a68881001d3ab1378fa1548575f2dadc
2026-07-15 09:20:44 +00:00
jif 42c5d3c80d Reuse MCP tool catalogs across sessions (#33184)
## Why

Starting a new session should not have to wait for an unchanged stdio MCP
server to initialize before its tools can be presented to the model.

## What changed

- Cache recent tool catalogs for matching stdio MCP server configurations and
  use them while a new live connection starts in the background.
- Bound the process-wide cache to 32 entries with a 30-minute TTL, and key
  entries by the server configuration, environment, working directory, and
  elicitation capabilities that affect the catalog.
- Keep connection-specific instructions and tool annotations out of cached
  catalogs. Resolve tool calls against the live connection so tools that are
  unavailable or hidden in the new session cannot be invoked from stale data.
- Publish only the newest completed catalog fetch and do not cache HTTP servers
  or stdio configurations that depend on remotely sourced environment values.

## Testing

- Add coverage for cache expiration, environment changes, catalog sanitization,
  and out-of-order refreshes.
- Add an end-to-end test that starts inference from cached definitions while a
  replacement MCP process initializes, then verifies calls and visibility
  against the live process.

GitOrigin-RevId: 2ed0f29ba53ace12532730f951b175c588aa3ae7
2026-07-14 22:25:39 +00:00