Allow ChatGPT-hosted MCP servers to use session auth (#29733)

## Why

ChatGPT session authentication was inferred from the reserved Codex Apps
server name. That couples credential routing to Codex Apps-specific
behavior and prevents other MCP endpoints hosted by ChatGPT from
explicitly using the current session.

The opt-in also needs a clear security boundary: an arbitrary MCP
configuration must not be able to redirect ChatGPT credentials to
another origin.

## What changed

- Add `use_chatgpt_auth` to HTTP MCP server configuration, defaulting to
`false`.
- Honor the setting only when the parsed server URL has the same HTTP(S)
origin as the configured `chatgpt_base_url`; otherwise remove the
capability before startup.
- Resolve bearer tokens and static or environment-backed authorization
headers before selecting authentication, with configured authorization
taking precedence over ChatGPT session auth.
- Enable the setting for the built-in Codex Apps and hosted plugin
runtime endpoints while keeping Codex Apps caching and tool
normalization scoped to the reserved server.
- Persist the setting through MCP config rewrite paths and expose it in
the generated config schema.
- Load the current login state for `codex mcp list` so reported auth
status matches runtime behavior.

## Verification

Core integration coverage exercises the complete streamable HTTP MCP
startup path and verifies that:

- a same-origin opted-in server receives the current ChatGPT access
token;
- an explicitly configured authorization header takes precedence;
- a different-origin server completes MCP initialization and tool
listing without receiving any ChatGPT authorization header.
This commit is contained in:
Ahmed Ibrahim authored and GitHub committed 2026-06-24 19:21:28 -07:00
1 parent a0d5fd772e
commit 4c0706e24a
29 files changed
+313 -59

No files matched your search

@@ -32,6 +32,7 @@ fn stdio_server(
env_vars: Vec<McpServerEnvVar>,
) -> McpServerConfig {
McpServerConfig {
use_chatgpt_auth: false,
transport: McpServerTransportConfig::Stdio {
command: command.to_string(),
args: Vec::new(),
@@ -66,6 +67,7 @@ fn declared_placement_preserves_local_plugin_normalization() {
Vec::new(),
);
let expected_http = McpServerConfig {
use_chatgpt_auth: false,
transport: McpServerTransportConfig::StreamableHttp {
url: "https://example.com/mcp".to_string(),
bearer_token_env_var: None,