Skip to content

fix: support Streamable HTTP MCP servers for Codex CLI (closes #1260)#1262

Open
masaishi wants to merge 7 commits into
microsoft:mainfrom
masaishi:fix/codex-streamable-http-mcp
Open

fix: support Streamable HTTP MCP servers for Codex CLI (closes #1260)#1262
masaishi wants to merge 7 commits into
microsoft:mainfrom
masaishi:fix/codex-streamable-http-mcp

Conversation

@masaishi
Copy link
Copy Markdown

@masaishi masaishi commented May 11, 2026

Description

Codex CLI supports Streamable HTTP MCP servers, but apm install was skipping Codex for every remote MCP entry, and README.md documented this as intended behavior.

This PR aligns the Codex adapter with the official Codex MCP spec:

  • Emit Streamable HTTP remote MCPs to ~/.codex/config.toml as mcp_servers.<name> entries with url = "..." (and http_headers when provided).
  • Keep SSE skipped, but update the notice to point users to transport: streamable-http (SSE is deprecated by the MCP spec and absent from the Codex config schema).
  • Extend the conflict detector to recognize flat-key mcp_servers.<name> entries that use url (previously only command / args were matched).
  • Remove the misleading “Codex CLI does not support remote MCP servers” line from README.md.

Fixes #1260

Type of change

  • Bug fix
  • Documentation
  • Maintenance / refactor

Testing

  • Tested locally

  • All existing tests pass

  • Added tests for new functionality (if applicable)

    • Streamable HTTP server config generation and SSE-skip behavior in test_mcp_client_factory.py
    • Codex flat-key remote URL detection in test_conflict_detection.py
    • Streamable-HTTP self-defined transport handling in _build_self_defined_info (test_mcp_integrator.py)

Copilot AI review requested due to automatic review settings May 11, 2026 01:45
@masaishi
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Codex CLI adapter so apm install can emit Streamable HTTP (remote) MCP server entries into Codex config.toml, while continuing to skip SSE remotes with an updated warning message. It also expands conflict detection to recognize Codex TOML “flat-key” server entries that are configured via url, and removes a README statement claiming Codex cannot use remote MCP servers.

Changes:

  • Codex adapter: generate mcp_servers.<name> TOML entries for remote streamable-http MCP servers (including http_headers), and skip SSE remotes via formatter signaling.
  • Conflict detector: treat mcp_servers.<name> flat-key configs containing url as existing servers (not just command/args).
  • Tests + README: add unit coverage for streamable-http + conflict detection, and remove misleading README wording about Codex remote MCP support.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/apm_cli/adapters/client/codex.py Adds remote Streamable HTTP config emission for Codex and SSE-skip path via _format_server_config() returning None.
src/apm_cli/core/conflict_detector.py Extends Codex flat-key server detection to include url-based configs.
tests/unit/test_mcp_client_factory.py Updates SSE skip test to assert _rich_warning content; adds streamable-http formatting + install tests.
tests/unit/test_conflict_detection.py Adds coverage for detecting Codex flat-key remote url entries.
tests/unit/integration/test_mcp_integrator.py Adds coverage ensuring self-defined streamable-http builds a remotes entry.
README.md Removes the statement that Codex CLI does not support remote MCP servers.

Comment on lines +223 to +227
remote = self._select_remote_with_url(remotes) or remotes[0]
server_name = server_info.get("name", "")
if (remote.get("transport_type") or "").strip() == "sse":
_rich_warning(
f"Skipping MCP server '{server_name}' for Codex CLI: SSE transport "
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APM always builds a single-element remotes list (mcp_integrator.py:216: info["remotes"] = [remote]), so the proposed “first SSE, later streamable-http” scenario cannot occur.

Additionally, the _select_remote_with_url(remotes) or remotes[0] pattern is already identical across the other adapters:

  • copilot.py:541
  • gemini.py:131
  • vscode.py:362

The recommendation to “mirror the other adapters’ validation” is therefore self-defeating, because the referenced implementations use the exact same logic.

Comment on lines +234 to +237
remote_config = {
"url": (remote.get("url") or "").strip(),
"id": server_info.get("id", ""),
}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codex.py:617-627’s _select_remote_with_url contractually never returns a remote with an empty URL.

Writing id as an empty string is intentional and consistent with copilot.py:565. This follows the conflict_detector schema convention (introduced in commit 6a44d74).

Omitting the key would break conflict detection behavior.

Comment on lines 172 to +177
# Generate server configuration with environment variable resolution
server_config = self._format_server_config(server_info, env_overrides, runtime_vars)

# Skip if formatter signaled "unsupported" (e.g. SSE remote on Codex)
if server_config is None:
return False
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix it
1a75308

Comment on lines +297 to +301
"headers": [
{"name": "Authorization", "value": "Bearer ghp_xxx"},
{"name": "X-Figma-Region", "value": "us-east-1"},
],
}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub’s PAT format requires:

ghp_ + 36 alphanumeric characters

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Codex CLI skips Streamable HTTP MCP servers; README claims this is unsupported

2 participants