[codex] Gate plugin MCP servers by auth route (#27459)

## Context

Some plugins expose both Apps and MCP servers. This PR moves auth-aware
surface projection into `core-plugins::PluginsManager`, so callers get a
consistent effective plugin view. Later PRs narrow the conflict rule and
update listing/install paths.

The high level goal of this PR is to set up the plumbing to
conditionally filter App/MCP in the plugin manager layer. We start by
removing MCP servers when using SIWC/Codex-backend auth, and removing
Apps when using API-key-style auth.

This PR is now stacked on #27652, which contains only the constructor
plumbing for seeding `PluginsManager` with the current auth mode.

## Stack

- PR1: #27652 seed plugin manager auth at construction.
- PR2: #27459 route plugin surfaces by auth mode.
- PR3: #27607 dedupe plugin MCP servers by App declaration name.
- PR4: #27602 preserve plugin Apps in connector listings.
- PR5: #27461 skip install-time plugin MCP OAuth for matching App
routes.

## Summary

- API-key/non-ChatGPT routes hide plugin Apps and keep plugin MCPs.
- ChatGPT/SIWC with Apps enabled keeps plugin Apps and suppresses MCPs
for dual-surface plugins.
- MCP-only plugins stay available for ChatGPT/SIWC sessions.
- Cached plugin load outcomes are re-projected when auth mode changes.

## Validation

```bash
cargo test -p codex-core-plugins plugin_auth_projection
cargo test -p codex-core list_tool_suggest_discoverable_plugins
git diff --check
```
This commit is contained in:
felixxia-oai
2026-06-12 19:42:11 -07:00
committed by GitHub
parent 5c8136f48a
commit 5d7db08b61
6 changed files with 348 additions and 55 deletions
@@ -6,6 +6,7 @@ use codex_core_plugins::remote::REMOTE_GLOBAL_MARKETPLACE_NAME;
use codex_core_plugins::remote::RemotePluginServiceConfig;
use codex_core_plugins::remote::fetch_and_cache_global_remote_plugin_catalog;
use codex_core_plugins::startup_sync::curated_plugins_repo_path;
use codex_protocol::protocol::Product;
use codex_tools::DiscoverablePluginInfo;
use pretty_assertions::assert_eq;
use tempfile::tempdir;
@@ -23,7 +24,11 @@ async fn list_discoverable_plugins_with_auth(
auth: Option<&codex_login::CodexAuth>,
loaded_plugin_app_connector_ids: &[String],
) -> anyhow::Result<Vec<DiscoverablePluginInfo>> {
let plugins_manager = PluginsManager::new(config.codex_home.to_path_buf());
let plugins_manager = PluginsManager::new_with_options(
config.codex_home.to_path_buf(),
Some(Product::Codex),
auth.map(codex_login::CodexAuth::api_auth_mode),
);
list_discoverable_plugins_with_manager_and_auth(
config,
&plugins_manager,