mirror of
https://github.com/openai/codex.git
synced 2026-11-13 21:30:47 +00:00
## Why MCP servers registered under the same name in different environments need distinct inventory, routing, and status reporting. ## What changed - Keep MCP inventory and runtime status keyed by registration scope so same-named servers remain separate. - Add optional `environmentId` selectors for status lookup, tool calls, resource reads, and OAuth login. Omitting the selector preserves existing name-only routing. - Carry environment identity through startup notifications, elicitation requests, and tool-call history, and display it in the TUI. - Support `/mcp login <name> --environment <id>` and update generated protocol schemas and SDK types. ## Testing Add integration coverage for two environments with identically named MCP servers, tools, and resource URIs. Verify separate inventory, explicit environment routing, legacy routing when the selector is omitted, and errors for unknown environments. Update protocol and TUI tests for environment identity. GitOrigin-RevId: 074a3db10549438cb6aff33eb7bed10791adae4d
78 lines
2.8 KiB
Rust
78 lines
2.8 KiB
Rust
//! Read selected-server metadata from one published thread runtime.
|
|
|
|
use std::sync::Arc;
|
|
|
|
use super::McpRuntime;
|
|
use super::McpRuntimeContext;
|
|
use crate::McpConfig;
|
|
use crate::McpServerStatusSnapshot;
|
|
use crate::McpSnapshotDetail;
|
|
use crate::ResolvedMcpServer;
|
|
use crate::mcp::collect_mcp_server_status_snapshot_from_manager;
|
|
use crate::mcp::compute_auth_statuses;
|
|
use crate::mcp::effective_mcp_servers;
|
|
|
|
impl McpRuntime {
|
|
/// Reuses the selected connection and catalog without starting unrelated servers.
|
|
/// Resolves the selector, configuration, and metadata in one captured runtime publication.
|
|
/// An expected registration excludes mismatched connections before discovery.
|
|
pub async fn server_status_snapshot(
|
|
&self,
|
|
server: &str,
|
|
environment_id: Option<&str>,
|
|
detail: McpSnapshotDetail,
|
|
expected_registration: Option<&ResolvedMcpServer>,
|
|
runtime_context: &McpRuntimeContext,
|
|
) -> anyhow::Result<(Arc<McpConfig>, McpServerStatusSnapshot)> {
|
|
let current = self.current.load_full();
|
|
let runtime_context = runtime_context.clone().with_selected_environments(
|
|
Arc::clone(¤t.environment_selections),
|
|
current.ready_environments.clone(),
|
|
);
|
|
let config = Arc::clone(
|
|
current
|
|
.config
|
|
.as_ref()
|
|
.ok_or_else(|| anyhow::anyhow!("MCP runtime is not configured"))?,
|
|
);
|
|
let server = config
|
|
.mcp_server_catalog
|
|
.resolve_server_key(server, environment_id);
|
|
let mut servers = effective_mcp_servers(&config, current.auth.as_ref());
|
|
servers.retain(|key, _| {
|
|
key == &server
|
|
&& expected_registration
|
|
.is_none_or(|expected| config.mcp_server_catalog.server(key) == Some(expected))
|
|
});
|
|
if config.xaa_enabled
|
|
&& servers
|
|
.values()
|
|
.any(|server| matches!(server.config().auth, codex_config::McpServerAuth::EmaAuth))
|
|
{
|
|
// Finish selected startup and any rejected-grant cleanup before reading auth.
|
|
current
|
|
.connections
|
|
.list_available_server_infos(|name| name == &server)
|
|
.await;
|
|
}
|
|
let auth_statuses = compute_auth_statuses(
|
|
servers.iter(),
|
|
config.mcp_oauth_credentials_store_mode,
|
|
config.auth_keyring_backend_kind,
|
|
current.auth.as_ref(),
|
|
current.auth_manager.as_ref(),
|
|
&config.ema_state,
|
|
&runtime_context,
|
|
)
|
|
.await;
|
|
let snapshot = collect_mcp_server_status_snapshot_from_manager(
|
|
¤t.connections,
|
|
auth_statuses,
|
|
servers.into_keys().collect(),
|
|
detail,
|
|
)
|
|
.await;
|
|
Ok((config, snapshot))
|
|
}
|
|
}
|