mirror of
https://github.com/openai/codex.git
synced 2026-05-01 01:47:18 +00:00
- Split MCP runtime/server code out of `codex-core` into the new `codex-mcp` crate. New/moved public structs/types include `McpConfig`, `McpConnectionManager`, `ToolInfo`, `ToolPluginProvenance`, `CodexAppsToolsCacheKey`, and the `McpManager` API (`codex_mcp::mcp::McpManager` plus the `codex_core::mcp::McpManager` wrapper/shim). New/moved functions include `with_codex_apps_mcp`, `configured_mcp_servers`, `effective_mcp_servers`, `collect_mcp_snapshot`, `collect_mcp_snapshot_from_manager`, `qualified_mcp_tool_name_prefix`, and the MCP auth/skill-dependency helpers. Why: this creates a focused MCP crate boundary and shrinks `codex-core` without forcing every consumer to migrate in the same PR. - Move MCP server config schema and persistence into `codex-config`. New/moved structs/enums include `AppToolApproval`, `McpServerToolConfig`, `McpServerConfig`, `RawMcpServerConfig`, `McpServerTransportConfig`, `McpServerDisabledReason`, and `codex_config::ConfigEditsBuilder`. New/moved functions include `load_global_mcp_servers` and `ConfigEditsBuilder::replace_mcp_servers`/`apply`. Why: MCP TOML parsing/editing is config ownership, and this keeps config validation/round-tripping (including per-tool approval overrides and inline bearer-token rejection) in the config crate instead of `codex-core`. - Rewire `codex-core`, app-server, and plugin call sites onto the new crates. Updated `Config::to_mcp_config(&self, plugins_manager)`, `codex-rs/core/src/mcp.rs`, `codex-rs/core/src/connectors.rs`, `codex-rs/core/src/codex.rs`, `CodexMessageProcessor::list_mcp_server_status_task`, and `utils/plugins/src/mcp_connector.rs` to build/pass the new MCP config/runtime types. Why: plugin-provided MCP servers still merge with user-configured servers, and runtime auth (`CodexAuth`) is threaded into `with_codex_apps_mcp` / `collect_mcp_snapshot` explicitly so `McpConfig` stays config-only.
51 lines
1.7 KiB
Rust
51 lines
1.7 KiB
Rust
use codex_login::default_client::is_first_party_chat_originator;
|
|
use codex_login::default_client::originator;
|
|
|
|
const DISALLOWED_CONNECTOR_IDS: &[&str] = &[
|
|
"asdk_app_6938a94a61d881918ef32cb999ff937c",
|
|
"connector_2b0a9009c9c64bf9933a3dae3f2b1254",
|
|
"connector_3f8d1a79f27c4c7ba1a897ab13bf37dc",
|
|
"connector_68de829bf7648191acd70a907364c67c",
|
|
"connector_68e004f14af881919eb50893d3d9f523",
|
|
"connector_69272cb413a081919685ec3c88d1744e",
|
|
];
|
|
const FIRST_PARTY_CHAT_DISALLOWED_CONNECTOR_IDS: &[&str] =
|
|
&["connector_0f9c9d4592e54d0a9a12b3f44a1e2010"];
|
|
const DISALLOWED_CONNECTOR_PREFIX: &str = "connector_openai_";
|
|
|
|
pub fn is_connector_id_allowed(connector_id: &str) -> bool {
|
|
is_connector_id_allowed_for_originator(connector_id, originator().value.as_str())
|
|
}
|
|
|
|
fn is_connector_id_allowed_for_originator(connector_id: &str, originator_value: &str) -> bool {
|
|
let disallowed_connector_ids = if is_first_party_chat_originator(originator_value) {
|
|
FIRST_PARTY_CHAT_DISALLOWED_CONNECTOR_IDS
|
|
} else {
|
|
DISALLOWED_CONNECTOR_IDS
|
|
};
|
|
|
|
!connector_id.starts_with(DISALLOWED_CONNECTOR_PREFIX)
|
|
&& !disallowed_connector_ids.contains(&connector_id)
|
|
}
|
|
|
|
pub fn sanitize_name(name: &str) -> String {
|
|
sanitize_slug(name).replace("-", "_")
|
|
}
|
|
|
|
fn sanitize_slug(name: &str) -> String {
|
|
let mut normalized = String::with_capacity(name.len());
|
|
for character in name.chars() {
|
|
if character.is_ascii_alphanumeric() {
|
|
normalized.push(character.to_ascii_lowercase());
|
|
} else {
|
|
normalized.push('-');
|
|
}
|
|
}
|
|
let normalized = normalized.trim_matches('-');
|
|
if normalized.is_empty() {
|
|
"app".to_string()
|
|
} else {
|
|
normalized.to_string()
|
|
}
|
|
}
|