Skip to content

Commit 4d56757

Browse files
authored
chore: include tool args for perf advisor telemetry MCP-277 (#706)
1 parent 6521882 commit 4d56757

File tree

9 files changed

+294
-139
lines changed

9 files changed

+294
-139
lines changed

.github/workflows/code-health-long-running.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ permissions: {}
1111
jobs:
1212
run-long-running-tests:
1313
name: Run long running tests
14-
if: github.event_name == 'push' || (github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.head.repo.full_name == github.repository)
1514
runs-on: ubuntu-latest
1615
steps:
1716
- uses: GitHubSecurityLab/actions-permissions/monitor@v1

src/telemetry/types.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export type TelemetryEvent<T> = {
1616
duration_ms: number;
1717
result: TelemetryResult;
1818
category: string;
19-
};
19+
} & Record<string, string | number | string[]>;
2020
};
2121

2222
export type BaseEvent = TelemetryEvent<unknown>;
@@ -28,14 +28,12 @@ export type ToolEventProperties = {
2828
command: string;
2929
error_code?: string;
3030
error_type?: string;
31-
project_id?: string;
32-
org_id?: string;
3331
cluster_name?: string;
3432
is_atlas?: boolean;
35-
atlas_local_deployment_id?: string;
36-
};
33+
} & TelemetryToolMetadata;
3734

3835
export type ToolEvent = TelemetryEvent<ToolEventProperties>;
36+
3937
/**
4038
* Interface for server events
4139
*/
@@ -137,3 +135,23 @@ export type CommonProperties = {
137135
*/
138136
hosting_mode?: string;
139137
} & CommonStaticProperties;
138+
139+
/**
140+
* Telemetry metadata that can be provided by tools when emitting telemetry events.
141+
* For MongoDB tools, this is typically empty, while for Atlas tools, this should include
142+
* the project and organization IDs if available.
143+
*/
144+
export type TelemetryToolMetadata = AtlasLocalToolMetadata | AtlasToolMetadata | PerfAdvisorToolMetadata;
145+
146+
export type AtlasLocalToolMetadata = {
147+
atlas_local_deployment_id?: string;
148+
};
149+
150+
export type AtlasToolMetadata = {
151+
project_id?: string;
152+
org_id?: string;
153+
};
154+
155+
export type PerfAdvisorToolMetadata = AtlasToolMetadata & {
156+
operations: string[];
157+
};

src/tools/atlas/atlasTool.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
2-
import { ToolBase, type ToolArgs, type ToolCategory, type TelemetryToolMetadata } from "../tool.js";
2+
import type { AtlasToolMetadata } from "../../telemetry/types.js";
3+
import { ToolBase, type ToolArgs, type ToolCategory } from "../tool.js";
34
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
45
import { LogId } from "../../common/logger.js";
56
import { z } from "zod";
@@ -84,8 +85,8 @@ For more information on Atlas API access roles, visit: https://www.mongodb.com/d
8485
protected resolveTelemetryMetadata(
8586
result: CallToolResult,
8687
...args: Parameters<ToolCallback<typeof this.argsShape>>
87-
): TelemetryToolMetadata {
88-
const toolMetadata: TelemetryToolMetadata = {};
88+
): AtlasToolMetadata {
89+
const toolMetadata: AtlasToolMetadata = {};
8990
if (!args.length) {
9091
return toolMetadata;
9192
}
@@ -107,12 +108,12 @@ For more information on Atlas API access roles, visit: https://www.mongodb.com/d
107108

108109
// Extract projectId using type guard
109110
if ("projectId" in data && typeof data.projectId === "string" && data.projectId.trim() !== "") {
110-
toolMetadata.projectId = data.projectId;
111+
toolMetadata.project_id = data.projectId;
111112
}
112113

113114
// Extract orgId using type guard
114115
if ("orgId" in data && typeof data.orgId === "string" && data.orgId.trim() !== "") {
115-
toolMetadata.orgId = data.orgId;
116+
toolMetadata.org_id = data.orgId;
116117
}
117118
return toolMetadata;
118119
}

src/tools/atlas/read/getPerformanceAdvisor.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { z } from "zod";
22
import { AtlasToolBase } from "../atlasTool.js";
3-
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3+
import type { CallToolResult, ServerNotification, ServerRequest } from "@modelcontextprotocol/sdk/types.js";
44
import type { OperationType, ToolArgs } from "../../tool.js";
55
import { formatUntrustedData } from "../../tool.js";
66
import {
@@ -13,6 +13,8 @@ import {
1313
SLOW_QUERY_LOGS_COPY,
1414
} from "../../../common/atlas/performanceAdvisorUtils.js";
1515
import { AtlasArgs } from "../../args.js";
16+
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
17+
import type { PerfAdvisorToolMetadata } from "../../../telemetry/types.js";
1618

1719
const PerformanceAdvisorOperationType = z.enum([
1820
"suggestedIndexes",
@@ -130,4 +132,15 @@ export class GetPerformanceAdvisorTool extends AtlasToolBase {
130132
};
131133
}
132134
}
135+
136+
protected override resolveTelemetryMetadata(
137+
result: CallToolResult,
138+
args: ToolArgs<typeof this.argsShape>,
139+
extra: RequestHandlerExtra<ServerRequest, ServerNotification>
140+
): PerfAdvisorToolMetadata {
141+
return {
142+
...super.resolveTelemetryMetadata(result, args, extra),
143+
operations: args.operations,
144+
};
145+
}
133146
}

src/tools/atlasLocal/atlasLocalTool.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2-
import type { TelemetryToolMetadata, ToolArgs, ToolCategory } from "../tool.js";
2+
import type { ToolArgs, ToolCategory } from "../tool.js";
33
import { ToolBase } from "../tool.js";
44
import type { ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
55
import type { Client } from "@mongodb-js/atlas-local";
66
import { LogId } from "../../common/logger.js";
7+
import type { AtlasLocalToolMetadata } from "../../telemetry/types.js";
78

89
export const AtlasLocalToolMetadataDeploymentIdKey = "deploymentId";
910

@@ -118,14 +119,14 @@ please log a ticket here: https://github.com/mongodb-js/mongodb-mcp-server/issue
118119
return super.handleError(error, args);
119120
}
120121

121-
protected resolveTelemetryMetadata(result: CallToolResult): TelemetryToolMetadata {
122-
const toolMetadata: TelemetryToolMetadata = {};
122+
protected resolveTelemetryMetadata(result: CallToolResult): AtlasLocalToolMetadata {
123+
const toolMetadata: AtlasLocalToolMetadata = {};
123124

124125
// Atlas Local tools set the deployment ID in the result metadata for telemetry
125126
// If the deployment ID is set, we use it for telemetry
126127
const resultDeploymentId = result._meta?.[AtlasLocalToolMetadataDeploymentIdKey];
127128
if (resultDeploymentId !== undefined && typeof resultDeploymentId === "string") {
128-
toolMetadata.atlasLocaldeploymentId = resultDeploymentId;
129+
toolMetadata.atlas_local_deployment_id = resultDeploymentId;
129130
}
130131

131132
return toolMetadata;

src/tools/mongodb/mongodbTool.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { z } from "zod";
2-
import type { ToolArgs, ToolCategory, TelemetryToolMetadata } from "../tool.js";
2+
import type { ToolArgs, ToolCategory } from "../tool.js";
33
import { ToolBase } from "../tool.js";
44
import type { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
55
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
66
import { ErrorCodes, MongoDBError } from "../../common/errors.js";
77
import { LogId } from "../../common/logger.js";
88
import type { Server } from "../../server.js";
9+
import type { AtlasToolMetadata } from "../../telemetry/types.js";
910

1011
export const DbOperationArgs = {
1112
database: z.string().describe("Database name"),
@@ -115,12 +116,12 @@ export abstract class MongoDBToolBase extends ToolBase {
115116
result: CallToolResult,
116117
// eslint-disable-next-line @typescript-eslint/no-unused-vars
117118
args: ToolArgs<typeof this.argsShape>
118-
): TelemetryToolMetadata {
119-
const metadata: TelemetryToolMetadata = {};
119+
): AtlasToolMetadata {
120+
const metadata: AtlasToolMetadata = {};
120121

121122
// Add projectId to the metadata if running a MongoDB operation to an Atlas cluster
122123
if (this.session.connectedAtlasCluster?.projectId) {
123-
metadata.projectId = this.session.connectedAtlasCluster.projectId;
124+
metadata.project_id = this.session.connectedAtlasCluster.projectId;
124125
}
125126

126127
return metadata;

src/tools/tool.ts

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { CallToolResult, ToolAnnotations } from "@modelcontextprotocol/sdk/
55
import type { Session } from "../common/session.js";
66
import { LogId } from "../common/logger.js";
77
import type { Telemetry } from "../telemetry/telemetry.js";
8-
import { type ToolEvent } from "../telemetry/types.js";
8+
import type { TelemetryToolMetadata, ToolEvent } from "../telemetry/types.js";
99
import type { UserConfig } from "../common/config.js";
1010
import type { Server } from "../server.js";
1111
import type { Elicitation } from "../elicitation.js";
@@ -39,17 +39,6 @@ export type OperationType = "metadata" | "read" | "create" | "delete" | "update"
3939
*/
4040
export type ToolCategory = "mongodb" | "atlas" | "atlas-local";
4141

42-
/**
43-
* Telemetry metadata that can be provided by tools when emitting telemetry events.
44-
* For MongoDB tools, this is typically empty, while for Atlas tools, this should include
45-
* the project and organization IDs if available.
46-
*/
47-
export type TelemetryToolMetadata = {
48-
projectId?: string;
49-
orgId?: string;
50-
atlasLocaldeploymentId?: string;
51-
};
52-
5342
export type ToolConstructorParams = {
5443
session: Session;
5544
config: UserConfig;
@@ -304,21 +293,10 @@ export abstract class ToolBase {
304293
component: "tool",
305294
duration_ms: duration,
306295
result: result.isError ? "failure" : "success",
296+
...metadata,
307297
},
308298
};
309299

310-
if (metadata?.orgId) {
311-
event.properties.org_id = metadata.orgId;
312-
}
313-
314-
if (metadata?.projectId) {
315-
event.properties.project_id = metadata.projectId;
316-
}
317-
318-
if (metadata?.atlasLocaldeploymentId) {
319-
event.properties.atlas_local_deployment_id = metadata.atlasLocaldeploymentId;
320-
}
321-
322300
this.telemetry.emitEvents([event]);
323301
}
324302

0 commit comments

Comments
 (0)