From 4b18a53ec20d852e5b8e5d34438922411d7c94a0 Mon Sep 17 00:00:00 2001 From: Bharathvaj Ganesan Date: Fri, 14 Mar 2025 09:28:29 +0530 Subject: [PATCH 1/3] fix: user agent logging and cleanup --- modelcontextprotocol/README.md | 17 ----- .../src/chargebee-ai-client/index.ts | 33 +-------- .../src/chargebee-ai-client/types.ts | 9 --- modelcontextprotocol/src/config.ts | 8 -- modelcontextprotocol/src/global.d.ts | 1 - modelcontextprotocol/src/index.ts | 26 ------- modelcontextprotocol/src/mcp.ts | 62 ++++------------ .../src/tools/documentation-search.ts | 4 +- modelcontextprotocol/src/utils/index.ts | 1 - modelcontextprotocol/src/utils/platform.ts | 22 +++++- modelcontextprotocol/src/utils/telemetry.ts | 74 ------------------- modelcontextprotocol/tsconfig.json | 48 +++++------- 12 files changed, 56 insertions(+), 249 deletions(-) delete mode 100644 modelcontextprotocol/src/config.ts delete mode 100644 modelcontextprotocol/src/utils/telemetry.ts diff --git a/modelcontextprotocol/README.md b/modelcontextprotocol/README.md index 822f293..4547db7 100644 --- a/modelcontextprotocol/README.md +++ b/modelcontextprotocol/README.md @@ -94,23 +94,6 @@ Access the MCP settings by clicking "Edit MCP Settings" in Roo Code settings or To contribute to this project, please see the [contribution guide](CONTRIBUTING.md). -## Telemetry - -The Chargebee MCP server collects anonymous usage data to help improve the product. This data includes: - -- Server startup and shutdown events -- Tool usage statistics -- Error information -- Session duration - -### Disabling Telemetry - -You can disable telemetry by setting the `CHARGEBEE_TELEMETRY_DISABLED` environment variable to `1`: - -```bash -export CHARGEBEE_TELEMETRY_DISABLED=1 -``` - ## License [MIT](https://github.com/chargebee/agentkit/blob/develop/LICENSE) diff --git a/modelcontextprotocol/src/chargebee-ai-client/index.ts b/modelcontextprotocol/src/chargebee-ai-client/index.ts index f19f76c..5e6b00b 100644 --- a/modelcontextprotocol/src/chargebee-ai-client/index.ts +++ b/modelcontextprotocol/src/chargebee-ai-client/index.ts @@ -4,13 +4,10 @@ import { DocumentationSearchResponse, Method, RequestOptions, - TelemetryData, } from './types.js'; -import { logger } from '@/utils/log.js'; /** * Client for interacting with the Chargebee AI API - * Provides methods for documentation search and telemetry reporting */ export class ChargebeeAIClient { private readonly clientConfig: ClientConfig; @@ -74,44 +71,18 @@ export class ChargebeeAIClient { * @returns Promise resolving to an array of search results in markdown format */ public documentationSearch: Method = - async (params: DocumentationSearchParams, options = {}) => { + async (params: DocumentationSearchParams) => { const response = await this.request({ endpoint: '/v1/documentation/search', method: 'POST', body: JSON.stringify({ ...params, }), - ...options, }); return response.results; }; - - /** - * Send telemetry data to the telemetry endpoint - * @param data - The telemetry data to send - * @param options - Optional request configuration - * @returns A promise that resolves when the telemetry is sent - */ - public sendTelemetry: Method = async ( - data: TelemetryData, - options = {}, - ) => { - try { - await this.request({ - endpoint: '/v1/telemetry', - method: 'POST', - body: JSON.stringify(data), - ...options, - }); - } catch (error) { - // Silently fail telemetry errors to not disrupt the main application flow - logger.debug( - `Telemetry error: ${error instanceof Error ? error.message : String(error)}`, - ); - } - }; } export const chargebeeAIClient = new ChargebeeAIClient({ baseUrl: AGENTKIT_BASE_URL, -}); \ No newline at end of file +}); diff --git a/modelcontextprotocol/src/chargebee-ai-client/types.ts b/modelcontextprotocol/src/chargebee-ai-client/types.ts index b435534..c5d0aaf 100644 --- a/modelcontextprotocol/src/chargebee-ai-client/types.ts +++ b/modelcontextprotocol/src/chargebee-ai-client/types.ts @@ -17,15 +17,6 @@ export interface DocumentationSearchParams { user_request?: string; } -export interface TelemetryData { - event: string; - timestamp: string; - version: string; - platform: string; - sessionDuration: number; - [key: string]: any; -} - export interface RequestOptions extends RequestInit { endpoint: string; } diff --git a/modelcontextprotocol/src/config.ts b/modelcontextprotocol/src/config.ts deleted file mode 100644 index b910554..0000000 --- a/modelcontextprotocol/src/config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import packageJson from '../package.json' assert { type: 'json' }; - -export const config = { - version: packageJson.version, - telemetry: { - disabled: process.env.CHARGEBEE_TELEMETRY_DISABLED === '1', - }, -}; diff --git a/modelcontextprotocol/src/global.d.ts b/modelcontextprotocol/src/global.d.ts index 238501b..27cf959 100644 --- a/modelcontextprotocol/src/global.d.ts +++ b/modelcontextprotocol/src/global.d.ts @@ -3,7 +3,6 @@ declare global { namespace NodeJS { interface ProcessEnv { - CHARGEBEE_TELEMETRY_DISABLED?: string; AGENTKIT_BASE_URL?: string; } } diff --git a/modelcontextprotocol/src/index.ts b/modelcontextprotocol/src/index.ts index 99bea34..2c524fe 100644 --- a/modelcontextprotocol/src/index.ts +++ b/modelcontextprotocol/src/index.ts @@ -5,7 +5,6 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' import { Command } from 'commander'; import { VERSION } from './constants.js'; import { ChargebeeMCPServer } from './mcp.js'; -import { telemetryService } from './utils/telemetry.js'; /** * Main entry point for the Chargebee MCP server @@ -23,24 +22,13 @@ async function main() { const mcpServer = new ChargebeeMCPServer(); const transport = new StdioServerTransport(); - // Track server startup - await telemetryService.trackEvent('server_start', { - version: VERSION, - }); - await mcpServer.connect(transport); - // Track server connected - await telemetryService.trackEvent('server_connected'); - // Handle process signals const cleanup = async () => { if (mcpServer) { logger.info('Shutting down Chargebee MCP server...'); - // Track server shutdown - await telemetryService.trackEvent('server_shutdown'); - await mcpServer.close(); process.exit(0); } @@ -52,11 +40,6 @@ async function main() { // Keep the process running await new Promise(() => {}); } catch (error) { - // Track server error - await telemetryService.trackEvent('server_error', { - error: error instanceof Error ? error.message : String(error), - }); - logger.error('Error starting Chargebee MCP server:', error); process.exit(1); } @@ -70,15 +53,6 @@ async function main() { * @param error - The error that occurred during initialization */ function handleError(error: any) { - // Track initialization error - telemetryService - .trackEvent('initialization_error', { - error: error instanceof Error ? error.message : String(error), - }) - .catch(() => { - // Ignore telemetry errors during shutdown - }); - logger.error('\n🚨 Error initializing Aero AI MCP server:\n'); logger.warn(` ${error.message}\n`); process.exit(1); diff --git a/modelcontextprotocol/src/mcp.ts b/modelcontextprotocol/src/mcp.ts index d6b9cf5..ad65972 100644 --- a/modelcontextprotocol/src/mcp.ts +++ b/modelcontextprotocol/src/mcp.ts @@ -1,8 +1,9 @@ +import crypto from 'node:crypto'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { MCP_SERVER_NAME, VERSION } from './constants.js'; import { tools } from './tools/index.js'; -import { logger } from './utils/log.js'; -import { telemetryService } from './utils/telemetry.js'; +import { getUserAgent } from './utils/platform.js'; +import { chargebeeAIClient } from './chargebee-ai-client/index.js'; /** * A server implementation for the Model Context Protocol (MCP) specific to Chargebee. @@ -16,15 +17,20 @@ export class ChargebeeMCPServer extends McpServer { version: VERSION, }); - const mcpClientDetails = this.server.getClientVersion(); - this.registerTools(); - // Track server initialization - telemetryService.trackEvent('server_initialized', { - clientName: mcpClientDetails?.name, - clientVersion: mcpClientDetails?.version, - }); + this.server.oninitialized = () => { + const mcpClient = this.server.getClientVersion(); + const userAgent = getUserAgent({ + mcpClientName: mcpClient?.name, + mcpClientVersion: mcpClient?.version, + }); + + chargebeeAIClient.attachHeaders({ + 'User-Agent': userAgent, + 'x-mcp-session-id': crypto.randomUUID(), + }); + }; } /** @@ -40,26 +46,8 @@ export class ChargebeeMCPServer extends McpServer { tool.description, tool.parameters.shape, async (arg: any) => { - const startTime = Date.now(); - let success = false; - try { - logger.info('Received tool call:', tool.name); - - await this.trackEvent('tool_call_start', { - tool: tool.name, - method: tool.method, - }); - const result = await tool.execute(arg, this); - success = true; - - // Track tool call success - await this.trackEvent('tool_call_success', { - tool: tool.name, - method: tool.method, - duration: Date.now() - startTime, - }); return { content: [ @@ -70,16 +58,6 @@ export class ChargebeeMCPServer extends McpServer { ], }; } catch (error) { - logger.error(`Error executing tool: ${tool.name}`, error); - - // Track tool call error - await this.trackEvent('tool_call_error', { - tool: tool.name, - method: tool.method, - error: error instanceof Error ? error.message : String(error), - duration: Date.now() - startTime, - }); - return { content: [ { @@ -94,14 +72,4 @@ export class ChargebeeMCPServer extends McpServer { ); }); } - - private async trackEvent(eventName: string, data: any) { - const mcpClientDetails = this.server.getClientVersion(); - - await telemetryService.trackEvent(eventName, { - ...data, - clientName: mcpClientDetails?.name, - clientVersion: mcpClientDetails?.version, - }); - } } diff --git a/modelcontextprotocol/src/tools/documentation-search.ts b/modelcontextprotocol/src/tools/documentation-search.ts index eb0811b..3a96672 100644 --- a/modelcontextprotocol/src/tools/documentation-search.ts +++ b/modelcontextprotocol/src/tools/documentation-search.ts @@ -1,5 +1,4 @@ import { chargebeeAIClient } from '@/chargebee-ai-client/index.js'; -import { ChargebeeMCPServer } from '@/mcp.js'; import { z } from 'zod'; /** @@ -25,7 +24,7 @@ It takes the following arguments: const documentationSearchParameters = z.object({ query: z.string().describe(queryParamDescription), - user_request: z.string().describe(userRequestParamDescription), + user_request: z.string().describe(userRequestParamDescription).optional(), data_sources: z .array(z.enum(['help_documentation', 'api_documentation', 'release_notes'])) .describe(dataSourceParamDescription) @@ -121,7 +120,6 @@ const documentationSearchParameters = z.object({ */ const documentationSearch = async ( parameters: z.infer, - mcpServer: ChargebeeMCPServer, ) => { try { const results = await chargebeeAIClient.documentationSearch({ diff --git a/modelcontextprotocol/src/utils/index.ts b/modelcontextprotocol/src/utils/index.ts index 229acf5..22126bd 100644 --- a/modelcontextprotocol/src/utils/index.ts +++ b/modelcontextprotocol/src/utils/index.ts @@ -1,3 +1,2 @@ export * from './log.js'; export * from './platform.js'; -export * from './telemetry.js'; diff --git a/modelcontextprotocol/src/utils/platform.ts b/modelcontextprotocol/src/utils/platform.ts index f5c3398..23db936 100644 --- a/modelcontextprotocol/src/utils/platform.ts +++ b/modelcontextprotocol/src/utils/platform.ts @@ -1,5 +1,21 @@ +import { VERSION } from '@/constants.js'; import os from 'os'; -export function getPlatformInfo() { - return `${os.platform()}`; -} \ No newline at end of file +interface UserAgentParams { + mcpClientName?: string; + mcpClientVersion?: string; +} + +/** + * Generates a User-Agent string + * @param {Object} params - Configuration parameters + * @param {string} params.mcpClientName - Name of the MCP client + * @param {string} params.mcpClientVersion - Version of the MCP client + * @returns {string} Formatted User-Agent string + */ +export function getUserAgent({ + mcpClientName = 'unknown', + mcpClientVersion = 'unknown', +}: UserAgentParams) { + return `ChargebeeMCP/${VERSION} (${os.platform()}; Node/${process.version}; ${mcpClientName}/${mcpClientVersion})`; +} diff --git a/modelcontextprotocol/src/utils/telemetry.ts b/modelcontextprotocol/src/utils/telemetry.ts deleted file mode 100644 index 18f1ab7..0000000 --- a/modelcontextprotocol/src/utils/telemetry.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { chargebeeAIClient } from '@/chargebee-ai-client/index.js'; -import { TelemetryData } from '@/chargebee-ai-client/types.js'; -import { config } from '@/config.js'; -import { logger } from './log.js'; -import { getPlatformInfo } from './platform.js'; - -/** - * Telemetry service for tracking usage and events - */ -class TelemetryService { - private isEnabled: boolean; - private sessionStartTime: number; - - constructor() { - this.sessionStartTime = Date.now(); - this.isEnabled = !config.telemetry.disabled; - - if (this.isEnabled) { - // Get the telemetry endpoint from config or use a default - logger.debug(`Telemetry initialized`); - } else { - logger.info('Telemetry is disabled'); - } - } - - /** - * Track an event with the telemetry service - * @param eventName - The name of the event to track - * @param properties - Additional properties to include with the event - */ - public async trackEvent( - eventName: string, - properties: Record = {}, - ): Promise { - if (!this.isEnabled) { - return; - } - - try { - const eventData: TelemetryData = { - event: eventName, - timestamp: new Date().toISOString(), - version: config.version, - platform: getPlatformInfo(), - sessionDuration: Date.now() - this.sessionStartTime, - ...properties, - }; - - await this.sendTelemetry(eventData); - } catch (error) { - // Silently fail telemetry errors to not disrupt the main application flow - logger.debug( - `Telemetry error: ${error instanceof Error ? error.message : String(error)}`, - ); - } - } - - /** - * Send telemetry data to the endpoint - * @param data - The data to send - */ - private async sendTelemetry(data: TelemetryData): Promise { - try { - await chargebeeAIClient.sendTelemetry(data); - } catch (error) { - // Log but don't throw to prevent disrupting the main application flow - logger.debug( - `Failed to send telemetry: ${error instanceof Error ? error.message : String(error)}`, - ); - } - } -} - -export const telemetryService = new TelemetryService(); diff --git a/modelcontextprotocol/tsconfig.json b/modelcontextprotocol/tsconfig.json index 2fd9f3c..029c45a 100644 --- a/modelcontextprotocol/tsconfig.json +++ b/modelcontextprotocol/tsconfig.json @@ -1,30 +1,20 @@ { - "compilerOptions": { - "target": "ES2020", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "esModuleInterop": true, - "strict": true, - "outDir": "dist", - "skipLibCheck": true, - "declaration": false, - "resolveJsonModule": true, - "baseUrl": ".", - "types": [ - "node" - ], - "paths": { - "@/*": [ - "src/*" - ] - } - }, - "include": [ - "src/**/*", - "tsup.config.ts" - ], - "exclude": [ - "node_modules", - "dist" - ] -} \ No newline at end of file + "compilerOptions": { + "target": "ES2020", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "esModuleInterop": true, + "strict": true, + "outDir": "dist", + "skipLibCheck": true, + "declaration": false, + "resolveJsonModule": true, + "baseUrl": ".", + "types": ["node"], + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src/**/*", "tsup.config.ts"], + "exclude": ["node_modules", "dist"] +} From 52a00e4865c71b93d068f49b7904d2b78b0fdaff Mon Sep 17 00:00:00 2001 From: Bharathvaj Ganesan Date: Fri, 14 Mar 2025 09:39:49 +0530 Subject: [PATCH 2/3] fix: add node prefix for clarity --- modelcontextprotocol/src/utils/platform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modelcontextprotocol/src/utils/platform.ts b/modelcontextprotocol/src/utils/platform.ts index 23db936..90f36d5 100644 --- a/modelcontextprotocol/src/utils/platform.ts +++ b/modelcontextprotocol/src/utils/platform.ts @@ -1,5 +1,5 @@ import { VERSION } from '@/constants.js'; -import os from 'os'; +import os from 'node:os'; interface UserAgentParams { mcpClientName?: string; From bc8faf202dec19168542a0087842c0a522c79447 Mon Sep 17 00:00:00 2001 From: Ashik Nesin <48757775+cb-ashik@users.noreply.github.com> Date: Fri, 14 Mar 2025 12:41:51 +0530 Subject: [PATCH 3/3] Update README.md --- modelcontextprotocol/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modelcontextprotocol/README.md b/modelcontextprotocol/README.md index 4547db7..6650133 100644 --- a/modelcontextprotocol/README.md +++ b/modelcontextprotocol/README.md @@ -96,4 +96,4 @@ To contribute to this project, please see the [contribution guide](CONTRIBUTING. ## License -[MIT](https://github.com/chargebee/agentkit/blob/develop/LICENSE) +[MIT](https://github.com/chargebee/agentkit/blob/main/LICENSE)