From bbfa08fe3b904f5134f200d5b9ae7f6c28598521 Mon Sep 17 00:00:00 2001 From: Chris Dong Date: Mon, 13 Jul 2026 20:08:36 +0000 Subject: [PATCH] Include connector IDs in MCP tool call analytics (#32867) ## What changed - Add the optional `connector_id` to `codex_mcp_tool_call_event` parameters. - Populate it from the MCP tool call's `app_context` when available. ## Testing - Extend the completed tool item analytics test to verify the connector ID is serialized. GitOrigin-RevId: ea62202318dd492fa0ffd4ff1d48a66d1cc37e96 --- codex-rs/analytics/src/analytics_client_tests.rs | 14 +++++++++++++- codex-rs/analytics/src/events.rs | 1 + codex-rs/analytics/src/reducer.rs | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/codex-rs/analytics/src/analytics_client_tests.rs b/codex-rs/analytics/src/analytics_client_tests.rs index 7b878e952c..e873b006f0 100644 --- a/codex-rs/analytics/src/analytics_client_tests.rs +++ b/codex-rs/analytics/src/analytics_client_tests.rs @@ -111,6 +111,7 @@ use codex_app_server_protocol::ItemCompletedNotification; use codex_app_server_protocol::ItemGuardianApprovalReviewCompletedNotification; use codex_app_server_protocol::ItemStartedNotification; use codex_app_server_protocol::JSONRPCErrorError; +use codex_app_server_protocol::McpToolCallAppContext; use codex_app_server_protocol::McpToolCallStatus; use codex_app_server_protocol::NonSteerableTurnKind; use codex_app_server_protocol::PatchApplyStatus; @@ -4353,7 +4354,14 @@ async fn turn_event_counts_completed_tool_items() { tool: "search".to_string(), status, arguments: json!({}), - app_context: None, + app_context: Some(McpToolCallAppContext { + connector_id: "connector-test".to_string(), + link_id: None, + resource_uri: None, + app_name: None, + template_id: None, + action_name: None, + }), mcp_app_resource_uri: None, plugin_id: Some("sample@test".to_string()), result: None, @@ -4445,6 +4453,10 @@ async fn turn_event_counts_completed_tool_items() { .expect("MCP tool call event should be emitted"); let payload = serde_json::to_value(mcp_tool_call_event).expect("serialize MCP tool call event"); assert_eq!(payload["event_params"]["plugin_id"], json!("sample@test")); + assert_eq!( + payload["event_params"]["connector_id"], + json!("connector-test") + ); reducer .ingest( diff --git a/codex-rs/analytics/src/events.rs b/codex-rs/analytics/src/events.rs index 999ae3e1f0..8235299630 100644 --- a/codex-rs/analytics/src/events.rs +++ b/codex-rs/analytics/src/events.rs @@ -674,6 +674,7 @@ pub(crate) struct CodexMcpToolCallEventParams { pub(crate) mcp_tool_name: String, pub(crate) mcp_error_present: bool, pub(crate) plugin_id: Option, + pub(crate) connector_id: Option, } #[derive(Serialize)] diff --git a/codex-rs/analytics/src/reducer.rs b/codex-rs/analytics/src/reducer.rs index 13696d670f..41b608a75f 100644 --- a/codex-rs/analytics/src/reducer.rs +++ b/codex-rs/analytics/src/reducer.rs @@ -1884,6 +1884,7 @@ fn tool_item_event(input: ToolItemEventInput<'_>) -> Option { error, duration_ms, plugin_id, + app_context, .. } => { let (terminal_status, failure_kind) = mcp_tool_call_outcome(status)?; @@ -1915,6 +1916,9 @@ fn tool_item_event(input: ToolItemEventInput<'_>) -> Option { mcp_tool_name: tool.clone(), mcp_error_present: error.is_some(), plugin_id: plugin_id.clone(), + connector_id: app_context + .as_ref() + .map(|app_context| app_context.connector_id.clone()), }, }, ))