Skip to content

Commit 6aec4d0

Browse files
committed
feat: add tool call params logging
1 parent ade1a41 commit 6aec4d0

4 files changed

Lines changed: 40 additions & 0 deletions

File tree

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ export async function createMcpServer(
254254
} finally {
255255
void clearcutLogger?.logToolInvocation({
256256
toolName: tool.name,
257+
params,
258+
schema,
257259
success,
258260
latencyMs: bucketizeLatency(Date.now() - startTime),
259261
});

src/telemetry/ClearcutLogger.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ export class ClearcutLogger {
207207

208208
async logToolInvocation(args: {
209209
toolName: string;
210+
params: ShapeOutput<zod.ZodRawShape>;
211+
schema: zod.ZodRawShape;
210212
success: boolean;
211213
latencyMs: number;
212214
}): Promise<void> {
@@ -216,6 +218,7 @@ export class ClearcutLogger {
216218
mcp_client: this.#mcpClient,
217219
tool_invocation: {
218220
tool_name: args.toolName,
221+
tool_params: sanitizeParams(args.params, args.schema),
219222
success: args.success,
220223
latency_ms: args.latencyMs,
221224
},

src/telemetry/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface ToolInvocation {
2222
tool_name: string;
2323
success: boolean;
2424
latency_ms: number;
25+
tool_params?: object;
2526
}
2627

2728
export interface ServerStart {

tests/telemetry/ClearcutLogger.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ describe('ClearcutLogger', () => {
4646
});
4747
await logger.logToolInvocation({
4848
toolName: 'test_tool',
49+
params: {},
50+
schema: {},
4951
success: true,
5052
latencyMs: 123,
5153
});
@@ -57,6 +59,38 @@ describe('ClearcutLogger', () => {
5759
assert.strictEqual(msg.payload.tool_invocation?.success, true);
5860
assert.strictEqual(msg.payload.tool_invocation?.latency_ms, 123);
5961
});
62+
it('sends sanitized params', async () => {
63+
const logger = new ClearcutLogger({
64+
persistence: mockPersistence,
65+
appVersion: '1.0.0',
66+
watchdogClient: mockWatchdogClient,
67+
});
68+
69+
const schema = {
70+
uid: zod.string(),
71+
myString: zod.string(),
72+
};
73+
74+
const params = {
75+
uid: 'sensitive',
76+
myString: 'hello',
77+
};
78+
79+
await logger.logToolInvocation({
80+
toolName: 'test_tool',
81+
params,
82+
schema,
83+
success: true,
84+
latencyMs: 123,
85+
});
86+
87+
assert(mockWatchdogClient.send.calledOnce);
88+
const msg = mockWatchdogClient.send.firstCall.args[0];
89+
assert.strictEqual(msg.type, WatchdogMessageType.LOG_EVENT);
90+
assert.deepStrictEqual(msg.payload.tool_invocation?.tool_params, {
91+
my_string_length: 5,
92+
});
93+
});
6094
});
6195

6296
describe('setClientName', () => {

0 commit comments

Comments
 (0)