Skip to content

Commit 981573f

Browse files
committed
Merge Commit 'bbcc906': add(mcp): Add MCP Server name to ToolCallEvent OTel logging (google-gemini#7829)
2 parents 822ae40 + bbcc906 commit 981573f

File tree

4 files changed

+94
-5
lines changed

4 files changed

+94
-5
lines changed

packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,10 @@ export class ClearcutLogger {
483483
gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_CONTENT_LENGTH,
484484
value: JSON.stringify(event.content_length),
485485
},
486+
{
487+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_MCP_SERVER_NAME,
488+
value: JSON.stringify(event.mcp_server_name),
489+
},
486490
];
487491

488492
if (event.metadata) {

packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ export enum EventMetadataKey {
5050
// Logs whether the session was configured to respect gitignore files.
5151
GEMINI_CLI_START_SESSION_RESPECT_GITIGNORE = 12,
5252

53+
// Logs the output format of the session.
54+
GEMINI_CLI_START_SESSION_OUTPUT_FORMAT = 94,
55+
5356
// ==========================================================================
5457
// User Prompt Event Keys
5558
// ===========================================================================
@@ -64,6 +67,9 @@ export enum EventMetadataKey {
6467
// Logs the function name.
6568
GEMINI_CLI_TOOL_CALL_NAME = 14,
6669

70+
// Logs the MCP server name.
71+
GEMINI_CLI_TOOL_CALL_MCP_SERVER_NAME = 95,
72+
6773
// Logs the user's decision about how to handle the tool call.
6874
GEMINI_CLI_TOOL_CALL_DECISION = 15,
6975

packages/core/src/telemetry/loggers.test.ts

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ import * as metrics from './metrics.js';
7676
import { FileOperation } from './metrics.js';
7777
import * as sdk from './sdk.js';
7878
import { vi, describe, beforeEach, it, expect, afterEach } from 'vitest';
79-
import type { GenerateContentResponseUsageMetadata } from '@google/genai';
79+
import type {
80+
CallableTool,
81+
GenerateContentResponseUsageMetadata,
82+
} from '@google/genai';
83+
import { DiscoveredMCPTool } from '../tools/mcp-tool.js';
8084
import * as uiTelemetry from './uiTelemetry.js';
8185
import { makeFakeConfig } from '../test-utils/config.js';
8286
import { ClearcutLogger } from './clearcut-logger/clearcut-logger.js';
@@ -930,6 +934,75 @@ describe('loggers', () => {
930934
'event.timestamp': '2025-01-01T00:00:00.000Z',
931935
});
932936
});
937+
938+
it('should log a tool call with mcp_server_name for MCP tools', () => {
939+
const mockMcpTool = new DiscoveredMCPTool(
940+
{} as CallableTool,
941+
'mock_mcp_server',
942+
'mock_mcp_tool',
943+
'tool description',
944+
{
945+
type: 'object',
946+
properties: {
947+
arg1: { type: 'string' },
948+
arg2: { type: 'number' },
949+
},
950+
required: ['arg1', 'arg2'],
951+
},
952+
);
953+
954+
const call: CompletedToolCall = {
955+
status: 'success',
956+
request: {
957+
name: 'mock_mcp_tool',
958+
args: { arg1: 'value1', arg2: 2 },
959+
callId: 'test-call-id',
960+
isClientInitiated: true,
961+
prompt_id: 'prompt-id',
962+
},
963+
response: {
964+
callId: 'test-call-id',
965+
responseParts: [{ text: 'test-response' }],
966+
resultDisplay: undefined,
967+
error: undefined,
968+
errorType: undefined,
969+
},
970+
tool: mockMcpTool,
971+
invocation: {} as AnyToolInvocation,
972+
durationMs: 100,
973+
};
974+
const event = new ToolCallEvent(call);
975+
976+
logToolCall(mockConfig, event);
977+
978+
expect(mockLogger.emit).toHaveBeenCalledWith({
979+
body: 'Tool call: mock_mcp_tool. Success: true. Duration: 100ms.',
980+
attributes: {
981+
'session.id': 'test-session-id',
982+
'user.email': 'test-user@example.com',
983+
'event.name': EVENT_TOOL_CALL,
984+
'event.timestamp': '2025-01-01T00:00:00.000Z',
985+
function_name: 'mock_mcp_tool',
986+
function_args: JSON.stringify(
987+
{
988+
arg1: 'value1',
989+
arg2: 2,
990+
},
991+
null,
992+
2,
993+
),
994+
duration_ms: 100,
995+
success: true,
996+
prompt_id: 'prompt-id',
997+
tool_type: 'mcp',
998+
mcp_server_name: 'mock_mcp_server',
999+
decision: undefined,
1000+
error: undefined,
1001+
error_type: undefined,
1002+
metadata: undefined,
1003+
},
1004+
});
1005+
});
9331006
});
9341007

9351008
describe('logMalformedJsonResponse', () => {

packages/core/src/telemetry/types.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ export class ToolCallEvent implements BaseTelemetryEvent {
137137
prompt_id: string;
138138
tool_type: 'native' | 'mcp';
139139
content_length?: number;
140+
mcp_server_name?: string;
140141
// eslint-disable-next-line @typescript-eslint/no-explicit-any
141142
metadata?: { [key: string]: any };
142143

@@ -153,11 +154,16 @@ export class ToolCallEvent implements BaseTelemetryEvent {
153154
this.error = call.response.error?.message;
154155
this.error_type = call.response.errorType;
155156
this.prompt_id = call.request.prompt_id;
156-
this.tool_type =
157-
typeof call.tool !== 'undefined' && call.tool instanceof DiscoveredMCPTool
158-
? 'mcp'
159-
: 'native';
160157
this.content_length = call.response.contentLength;
158+
if (
159+
typeof call.tool !== 'undefined' &&
160+
call.tool instanceof DiscoveredMCPTool
161+
) {
162+
this.tool_type = 'mcp';
163+
this.mcp_server_name = call.tool.serverName;
164+
} else {
165+
this.tool_type = 'native';
166+
}
161167

162168
if (
163169
call.status === 'success' &&

0 commit comments

Comments
 (0)