豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 9a47b65

Browse files
authored
feat: record client name in telemetry. (#1208)
The changes in the PR intercepts the name of the MCP client right after server initialization, coverts it into one of the existing enum values, and append it with the telemetry request. Note that the client name is unset if there is no client connected yet. This means the server_start event won't have a client name. Tested with gemini-cli. --------- Co-authored-by: Yulun Zeng <yulunz@chromium.org>
1 parent 25bbfd5 commit 9a47b65

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ export async function createMcpServer(
5757
return {};
5858
});
5959

60+
server.server.oninitialized = () => {
61+
const clientName = server.server.getClientVersion()?.name;
62+
if (clientName) {
63+
clearcutLogger?.setClientName(clientName);
64+
}
65+
};
66+
6067
let context: McpContext;
6168
async function getContext(): Promise<McpContext> {
6269
const chromeArgs: string[] = (serverArgs.chromeArg ?? []).map(String);

src/telemetry/ClearcutLogger.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ import {logger} from '../logger.js';
1010

1111
import type {LocalState, Persistence} from './persistence.js';
1212
import {FilePersistence} from './persistence.js';
13-
import {type FlagUsage, WatchdogMessageType, OsType} from './types.js';
13+
import {
14+
McpClient,
15+
type FlagUsage,
16+
WatchdogMessageType,
17+
OsType,
18+
} from './types.js';
1419
import {WatchdogClient} from './WatchdogClient.js';
1520

1621
const MS_PER_DAY = 24 * 60 * 60 * 1000;
@@ -31,6 +36,7 @@ function detectOsType(): OsType {
3136
export class ClearcutLogger {
3237
#persistence: Persistence;
3338
#watchdog: WatchdogClient;
39+
#mcpClient: McpClient;
3440

3541
constructor(options: {
3642
appVersion: string;
@@ -53,6 +59,18 @@ export class ClearcutLogger {
5359
clearcutForceFlushIntervalMs: options.clearcutForceFlushIntervalMs,
5460
clearcutIncludePidHeader: options.clearcutIncludePidHeader,
5561
});
62+
this.#mcpClient = McpClient.MCP_CLIENT_UNSPECIFIED;
63+
}
64+
65+
setClientName(clientName: string): void {
66+
const lowerName = clientName.toLowerCase();
67+
if (lowerName.includes('claude')) {
68+
this.#mcpClient = McpClient.MCP_CLIENT_CLAUDE_CODE;
69+
} else if (lowerName.includes('gemini')) {
70+
this.#mcpClient = McpClient.MCP_CLIENT_GEMINI_CLI;
71+
} else {
72+
this.#mcpClient = McpClient.MCP_CLIENT_OTHER;
73+
}
5674
}
5775

5876
async logToolInvocation(args: {
@@ -63,6 +81,7 @@ export class ClearcutLogger {
6381
this.#watchdog.send({
6482
type: WatchdogMessageType.LOG_EVENT,
6583
payload: {
84+
mcp_client: this.#mcpClient,
6685
tool_invocation: {
6786
tool_name: args.toolName,
6887
success: args.success,
@@ -76,6 +95,7 @@ export class ClearcutLogger {
7695
this.#watchdog.send({
7796
type: WatchdogMessageType.LOG_EVENT,
7897
payload: {
98+
mcp_client: this.#mcpClient,
7999
server_start: {
80100
flag_usage: flagUsage,
81101
},
@@ -99,6 +119,7 @@ export class ClearcutLogger {
99119
this.#watchdog.send({
100120
type: WatchdogMessageType.LOG_EVENT,
101121
payload: {
122+
mcp_client: this.#mcpClient,
102123
daily_active: {
103124
days_since_last_active: daysSince,
104125
},

src/telemetry/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export enum McpClient {
7575
MCP_CLIENT_UNSPECIFIED = 0,
7676
MCP_CLIENT_CLAUDE_CODE = 1,
7777
MCP_CLIENT_GEMINI_CLI = 2,
78+
MCP_CLIENT_OTHER = 3,
7879
}
7980

8081
// IPC types for messages between the main process and the

tests/telemetry/ClearcutLogger.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,24 @@ describe('ClearcutLogger', () => {
5454
});
5555
});
5656

57+
describe('setClientName', () => {
58+
it('appends mapped mcp_client to payload', async () => {
59+
const logger = new ClearcutLogger({
60+
persistence: mockPersistence,
61+
appVersion: '1.0.0',
62+
watchdogClient: mockWatchdogClient,
63+
});
64+
65+
logger.setClientName('gemini-cli-mcp-client');
66+
await logger.logServerStart({headless: true});
67+
68+
assert(mockWatchdogClient.send.calledOnce);
69+
const msg = mockWatchdogClient.send.firstCall.args[0];
70+
assert.strictEqual(msg.type, WatchdogMessageType.LOG_EVENT);
71+
assert.strictEqual(msg.payload.mcp_client, 2); // 2 is MCP_CLIENT_GEMINI_CLI
72+
});
73+
});
74+
5775
describe('logServerStart', () => {
5876
it('logs flag usage', async () => {
5977
const logger = new ClearcutLogger({

0 commit comments

Comments
 (0)