Include plugin id in plugin MCP tool metadata (#23353)

Adding the id of the plugin that contains the MCP (if any) so we can
apply filters at plugin level.

## Summary
- carry the plugin owner into MCP runtime provenance
- attach `plugin_id` to outbound plugin-backed MCP tool-call `_meta`
- avoid misattributing user-configured MCP servers that shadow plugin
server names

## Testing
- `just fmt`
- `just fix -p codex-mcp`
- `just fix -p codex-core`
- `cargo test -p codex-mcp`
- `cargo test -p codex-core
plugin_mcp_tool_call_request_meta_includes_plugin_id`
- `cargo test -p codex-core
to_mcp_config_omits_plugin_id_when_user_server_shadows_plugin_mcp`
- `cargo test -p codex-core
rebuild_preserving_session_layers_refreshes_plugin_derived_mcp_config`
- `git diff --check`

## Notes
- Attempted `cargo test -p codex-core`; it aborted in
`agent::control::tests::resume_agent_from_rollout_skips_descendants_when_parent_resume_fails`
with a stack overflow before the full suite completed.
This commit is contained in:
Matthew Zeng authored and GitHub committed 2026-05-18 15:33:33 -07:00
1 parent f2368b7de6
commit a66e0e9c4b
7 files changed
+155 -13

No files matched your search

+14 -3
View File
@@ -138,6 +138,8 @@ pub struct McpConfig {
///
/// Runtime-only additions are merged later by [`effective_mcp_servers`].
pub configured_mcp_servers: HashMap<String, McpServerConfig>,
/// Winning plugin owner for plugin-provided MCP servers, keyed by server name.
pub plugin_ids_by_mcp_server_name: HashMap<String, String>,
/// Plugin metadata used to attribute MCP tools/connectors to plugin display names.
pub plugin_capability_summaries: Vec<PluginCapabilitySummary>,
}
@@ -146,6 +148,7 @@ pub struct McpConfig {
pub struct ToolPluginProvenance {
plugin_display_names_by_connector_id: HashMap<String, Vec<String>>,
plugin_display_names_by_mcp_server_name: HashMap<String, Vec<String>>,
plugin_ids_by_mcp_server_name: HashMap<String, String>,
}
impl ToolPluginProvenance {
@@ -163,9 +166,15 @@ impl ToolPluginProvenance {
.unwrap_or(&[])
}
fn from_capability_summaries(capability_summaries: &[PluginCapabilitySummary]) -> Self {
pub fn plugin_id_for_mcp_server_name(&self, server_name: &str) -> Option<&str> {
self.plugin_ids_by_mcp_server_name
.get(server_name)
.map(String::as_str)
}
fn from_config(config: &McpConfig) -> Self {
let mut tool_plugin_provenance = Self::default();
for plugin in capability_summaries {
for plugin in &config.plugin_capability_summaries {
for connector_id in &plugin.app_connector_ids {
tool_plugin_provenance
.plugin_display_names_by_connector_id
@@ -195,6 +204,8 @@ impl ToolPluginProvenance {
plugin_names.sort_unstable();
plugin_names.dedup();
}
tool_plugin_provenance.plugin_ids_by_mcp_server_name =
config.plugin_ids_by_mcp_server_name.clone();
tool_plugin_provenance
}
@@ -244,7 +255,7 @@ pub fn effective_mcp_servers_from_configured(
}
pub fn tool_plugin_provenance(config: &McpConfig) -> ToolPluginProvenance {
ToolPluginProvenance::from_capability_summaries(&config.plugin_capability_summaries)
ToolPluginProvenance::from_config(config)
}
pub async fn read_mcp_resource(
+16 -2
View File
@@ -30,6 +30,7 @@ fn test_mcp_config(codex_home: PathBuf) -> McpConfig {
apps_enabled: false,
client_elicitation_capability: ElicitationCapability::default(),
configured_mcp_servers: HashMap::new(),
plugin_ids_by_mcp_server_name: HashMap::new(),
plugin_capability_summaries: Vec::new(),
}
}
@@ -124,7 +125,10 @@ fn mcp_prompt_auto_approval_rejects_auto_mode_in_default_permission_mode() {
#[test]
fn tool_plugin_provenance_collects_app_and_mcp_sources() {
let provenance = ToolPluginProvenance::from_capability_summaries(&[
let mut config = test_mcp_config(PathBuf::new());
config.plugin_ids_by_mcp_server_name =
HashMap::from([("alpha".to_string(), "alpha@test".to_string())]);
config.plugin_capability_summaries = vec![
PluginCapabilitySummary {
display_name: "alpha-plugin".to_string(),
app_connector_ids: vec![AppConnectorId("connector_example".to_string())],
@@ -140,7 +144,8 @@ fn tool_plugin_provenance_collects_app_and_mcp_sources() {
mcp_server_names: vec!["beta".to_string()],
..PluginCapabilitySummary::default()
},
]);
];
let provenance = tool_plugin_provenance(&config);
assert_eq!(
provenance,
@@ -159,8 +164,17 @@ fn tool_plugin_provenance_collects_app_and_mcp_sources() {
("alpha".to_string(), vec!["alpha-plugin".to_string()]),
("beta".to_string(), vec!["beta-plugin".to_string()]),
]),
plugin_ids_by_mcp_server_name: HashMap::from([(
"alpha".to_string(),
"alpha@test".to_string(),
)]),
}
);
assert_eq!(
provenance.plugin_id_for_mcp_server_name("alpha"),
Some("alpha@test")
);
assert_eq!(provenance.plugin_id_for_mcp_server_name("beta"), None);
}
#[test]