Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/mcp-provider-api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export {
type Services,
type TelemetryService,
type TelemetryEvent,
type PdpEvent,
type OrgService,
type ConfigService,
type StartupFlags
Expand Down
8 changes: 8 additions & 0 deletions packages/mcp-provider-api/src/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ export interface Services {

export interface TelemetryService {
sendEvent(eventName: string, event: TelemetryEvent): void;
sendPdpEvent(event: PdpEvent): void;
}

export type TelemetryEvent = {
[key: string]: string | number | boolean | null | undefined;
};

export type PdpEvent = {
eventName: `${string}.${string}`;
productFeatureId: `aJC${string}`;
componentId?: string;
eventVolume?: number;
};


export interface OrgService {
getAllowedOrgUsernames(): Promise<Set<string>>;
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-provider-code-analyzer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@salesforce/code-analyzer-pmd-engine": "^0.37.0",
"@salesforce/code-analyzer-regex-engine": "^0.33.0",
"@salesforce/code-analyzer-retirejs-engine": "^0.32.0",
"@salesforce/mcp-provider-api": "^0.4.1",
"@salesforce/mcp-provider-api": "file:../mcp-provider-api",
"fast-xml-parser": "^5.5.3",
"zod": "^3.25.76"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/mcp-provider-code-analyzer/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export const TelemetryEventName = "code-analyzer"
export const TelemetrySource = "MCP"

// Product Feature ID for PFT (Product Feedback Telemetry) events
export const CODE_ANALYZER_PRODUCT_FEATURE_ID = "aJCEE0000000mDK4AY"

export const McpTelemetryEvents = {
ENGINE_SELECTION: 'engine_selection',
ENGINE_EXECUTION: 'engine_execution',
Expand Down
6 changes: 3 additions & 3 deletions packages/mcp-provider-code-analyzer/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ export class CodeAnalyzerMcpProvider extends McpProvider {
configFactory,
enginePluginsFactory,
telemetryService: services.getTelemetryService()
})),
}), services.getTelemetryService()),
new CodeAnalyzerDescribeRuleMcpTool(new DescribeRuleActionImpl({
configFactory,
enginePluginsFactory,
telemetryService: services.getTelemetryService()
})),
}), services.getTelemetryService()),
new CodeAnalyzerListRulesMcpTool(new ListRulesActionImpl({
configFactory,
enginePluginsFactory,
telemetryService: services.getTelemetryService()
})),
}), services.getTelemetryService()),
new CodeAnalyzerQueryResultsMcpTool(new QueryResultsActionImpl(), services.getTelemetryService()),
new GenerateXpathPromptMcpTool(new GetAstNodesActionImpl(), services.getTelemetryService()),
new CreateCustomRuleMcpTool(new CreateXpathCustomRuleActionImpl(), services.getTelemetryService())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ export class CreateCustomRuleMcpTool extends McpTool<InputArgsShape, OutputArgsS
rulesetPath: output.rulesetPath,
configPath: output.configPath
});
// Send PFT event for product analytics
this.telemetryService.sendPdpEvent({
eventName: 'codeAnalyzer.createCustomRule',
productFeatureId: Constants.CODE_ANALYZER_PRODUCT_FEATURE_ID,
componentId: CreateCustomRuleMcpTool.NAME
});
}
return {
content: [{ type: "text", text: message }],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { z } from "zod";
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import { McpTool, McpToolConfig, ReleaseState, Services, Toolset } from "@salesforce/mcp-provider-api";
import { McpTool, McpToolConfig, ReleaseState, Services, Toolset, TelemetryService } from "@salesforce/mcp-provider-api";
import { DescribeRuleAction, DescribeRuleActionImpl, DescribeRuleInput, DescribeRuleOutput} from "../actions/describe-rule.js";
import { CodeAnalyzerConfigFactoryImpl } from "../factories/CodeAnalyzerConfigFactory.js";
import { EnginePluginsFactoryImpl } from "../factories/EnginePluginsFactory.js";
import { getErrorMessage } from "../utils.js";
import {CodeAnalyzerRunMcpTool} from "./run_code_analyzer.js";
import * as Constants from "../constants.js";

const DESCRIPTION: string = `A tool for getting the description of a Code Analyzer rule.
This tool can return a JSON that describes the properties of a Code Analyzer rule, which may include information about
Expand Down Expand Up @@ -38,15 +39,18 @@ type OutputArgsShape = typeof outputSchema.shape;
export class CodeAnalyzerDescribeRuleMcpTool extends McpTool<InputArgsShape, OutputArgsShape> {
public static readonly NAME: string = 'describe_code_analyzer_rule';
private readonly action: DescribeRuleAction;
private readonly telemetryService?: TelemetryService;

public constructor(
action: DescribeRuleAction = new DescribeRuleActionImpl({
configFactory: new CodeAnalyzerConfigFactoryImpl(),
enginePluginsFactory: new EnginePluginsFactoryImpl()
})
}),
telemetryService?: TelemetryService
) {
super();
this.action = action;
this.telemetryService = telemetryService;
}

public getReleaseState(): ReleaseState {
Expand Down Expand Up @@ -77,6 +81,14 @@ export class CodeAnalyzerDescribeRuleMcpTool extends McpTool<InputArgsShape, Out
let output: DescribeRuleOutput;
try {
output = await this.action.exec(input);
// Send PFT event for product analytics
if (output.status === "success") {
this.telemetryService?.sendPdpEvent({
eventName: 'codeAnalyzer.describeRule',
productFeatureId: Constants.CODE_ANALYZER_PRODUCT_FEATURE_ID,
componentId: CodeAnalyzerDescribeRuleMcpTool.NAME
});
}
} catch (e) {
output = { status: getErrorMessage(e) };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ export class GenerateXpathPromptMcpTool extends McpTool<InputArgsShape, OutputAr
engine: input.engine,
language: input.language
});
// Send PFT event for product analytics
this.telemetryService.sendPdpEvent({
eventName: 'codeAnalyzer.generateXpathPrompt',
productFeatureId: Constants.CODE_ANALYZER_PRODUCT_FEATURE_ID,
componentId: 'get_ast_nodes_to_generate_xpath'
});
}
return buildToolResult(output);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {z} from "zod";
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import {McpTool, ReleaseState, McpToolConfig, Toolset} from "@salesforce/mcp-provider-api";
import {McpTool, ReleaseState, McpToolConfig, Toolset, TelemetryService} from "@salesforce/mcp-provider-api";
import {ListRulesAction, ListRulesInput, ListRulesOutput, ListRulesActionImpl} from "../actions/list-rules.js";
import {CodeAnalyzerConfigFactoryImpl} from "../factories/CodeAnalyzerConfigFactory.js";
import {EnginePluginsFactoryImpl} from "../factories/EnginePluginsFactory.js";
import {getErrorMessage} from "../utils.js";
import { isFullListSelector, makePolicyError } from "../policies.js";
import * as Constants from "../constants.js";
import {
ENGINE_NAMES,
SEVERITY_NUMBERS,
Expand Down Expand Up @@ -83,6 +84,7 @@ type OutputArgsShape = typeof outputSchema.shape;
export class CodeAnalyzerListRulesMcpTool extends McpTool<InputArgsShape, OutputArgsShape> {
public static readonly NAME: string = 'list_code_analyzer_rules';
private readonly action: ListRulesAction;
private readonly telemetryService?: TelemetryService;

/**
* Validates a selector string ensuring that each token (split on ',' and ':')
Expand Down Expand Up @@ -133,10 +135,12 @@ export class CodeAnalyzerListRulesMcpTool extends McpTool<InputArgsShape, Output
action: ListRulesAction = new ListRulesActionImpl({
configFactory: new CodeAnalyzerConfigFactoryImpl(),
enginePluginsFactory: new EnginePluginsFactoryImpl()
})
}),
telemetryService?: TelemetryService
) {
super();
this.action = action;
this.telemetryService = telemetryService;
}

public getReleaseState(): ReleaseState {
Expand Down Expand Up @@ -193,6 +197,14 @@ export class CodeAnalyzerListRulesMcpTool extends McpTool<InputArgsShape, Output
}
try {
output = await this.action.exec(input);
// Send PFT event for product analytics
if (output.status === "success") {
this.telemetryService?.sendPdpEvent({
eventName: 'codeAnalyzer.listRules',
productFeatureId: Constants.CODE_ANALYZER_PRODUCT_FEATURE_ID,
componentId: CodeAnalyzerListRulesMcpTool.NAME
});
}
} catch (e) {
output = { status: getErrorMessage(e) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ export class CodeAnalyzerQueryResultsMcpTool extends McpTool<InputArgsShape, Out
totalViolations: output.totalViolations ?? 0,
totalMatches: output.totalMatches ?? 0
});
// Send PFT event for product analytics
this.telemetryService?.sendPdpEvent({
eventName: 'codeAnalyzer.query',
productFeatureId: Constants.CODE_ANALYZER_PRODUCT_FEATURE_ID,
componentId: CodeAnalyzerQueryResultsMcpTool.NAME
});
const contentItems: { type: "text"; text: string }[] = [];
if (truncated) {
contentItems.push({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import fs from "node:fs";
import { z } from "zod";
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import { McpTool, McpToolConfig, ReleaseState, Services, Toolset } from "@salesforce/mcp-provider-api";
import { McpTool, McpToolConfig, ReleaseState, Services, Toolset, TelemetryService } from "@salesforce/mcp-provider-api";
import { getMessage } from "../messages.js";
import { getErrorMessage } from "../utils.js";
import { RunAnalyzerAction, RunAnalyzerActionImpl, RunInput, RunOutput } from "../actions/run-analyzer.js";
import { CodeAnalyzerListRulesMcpTool } from "./list_code_analyzer_rules.js";
import { CodeAnalyzerConfigFactoryImpl } from "../factories/CodeAnalyzerConfigFactory.js";
import { EnginePluginsFactoryImpl } from "../factories/EnginePluginsFactory.js";
import * as Constants from "../constants.js";

const MAX_ALLOWABLE_TARGET_COUNT = 10;

Expand Down Expand Up @@ -56,15 +57,18 @@ type OutputArgsShape = typeof outputSchema.shape;
export class CodeAnalyzerRunMcpTool extends McpTool<InputArgsShape, OutputArgsShape> {
public static readonly NAME: string = 'run_code_analyzer';
private readonly action: RunAnalyzerAction;
private readonly telemetryService?: TelemetryService;

public constructor(
action: RunAnalyzerAction = new RunAnalyzerActionImpl({
configFactory: new CodeAnalyzerConfigFactoryImpl(),
enginePluginsFactory: new EnginePluginsFactoryImpl()
})
}),
telemetryService?: TelemetryService
) {
super();
this.action = action;
this.telemetryService = telemetryService;
}

public getReleaseState(): ReleaseState {
Expand Down Expand Up @@ -106,6 +110,14 @@ export class CodeAnalyzerRunMcpTool extends McpTool<InputArgsShape, OutputArgsSh
}

const output: RunOutput = await this.action.exec(input);
// Send PFT event for product analytics
if (output.status === "success" || output.resultsFile) {
this.telemetryService?.sendPdpEvent({
eventName: 'codeAnalyzer.run',
productFeatureId: Constants.CODE_ANALYZER_PRODUCT_FEATURE_ID,
componentId: CodeAnalyzerRunMcpTool.NAME
});
}
return {
content: [{ type: "text", text: JSON.stringify(output) }],
structuredContent: output
Expand Down
5 changes: 5 additions & 0 deletions packages/mcp/src/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Services as IServices,
TelemetryService,
TelemetryEvent,
PdpEvent,
OrgService,
SanitizedOrgAuthorization,
ConfigService,
Expand Down Expand Up @@ -70,4 +71,8 @@ class NoopTelemetryService implements TelemetryService {
public sendEvent(_eventName: string, _event: TelemetryEvent): void {
// no-op
}

public sendPdpEvent(_event: PdpEvent): void {
// no-op
}
}
Loading
Loading