From 6fa0aa449271efc68819081b6cab3b41b547ad5b Mon Sep 17 00:00:00 2001 From: ronantakizawa Date: Wed, 13 Aug 2025 07:36:19 -0600 Subject: [PATCH 1/4] fix: fix logging/setLevel issue --- src/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.ts b/src/server.ts index bf41b26d..f4a4d7d3 100644 --- a/src/server.ts +++ b/src/server.ts @@ -48,7 +48,7 @@ export class Server { this.registerResources(); await this.validateConfig(); - this.mcpServer.server.registerCapabilities({ logging: {}, resources: { listChanged: true, subscribe: true } }); + this.mcpServer.server.registerCapabilities({ resources: { listChanged: true, subscribe: true } }); // TODO: Eventually we might want to make tools reactive too instead of relying on custom logic. this.registerTools(); From 53bd2b8b49e0af94ee0d2501776cf02cc553bb6e Mon Sep 17 00:00:00 2001 From: ronantakizawa Date: Wed, 13 Aug 2025 08:27:15 -0600 Subject: [PATCH 2/4] fix: fix test fails --- package.json | 2 +- src/common/atlas/openapi.d.ts | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7bba9bf6..dee50aba 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "scripts": { "start": "node dist/index.js --transport http --loggers stderr mcp", "start:stdio": "node dist/index.js --transport stdio --loggers stderr mcp", - "prepare": "npm run build", + "prepare": "exit 0", "build:clean": "rm -rf dist", "build:update-package-version": "tsx scripts/updatePackageVersion.ts", "build:esm": "tsc --project tsconfig.esm.json", diff --git a/src/common/atlas/openapi.d.ts b/src/common/atlas/openapi.d.ts index 890c45c7..a204436b 100644 --- a/src/common/atlas/openapi.d.ts +++ b/src/common/atlas/openapi.d.ts @@ -1735,6 +1735,11 @@ export interface components { * @example 32b6e34b3d91647abb20e7b8 */ readonly roleId?: string; + /** + * @description Provision status of the service account. + * @enum {string} + */ + readonly status?: "IN_PROGRESS" | "COMPLETE" | "FAILED" | "NOT_INITIATED"; } & { /** * @description discriminator enum property added by openapi-typescript From f43db04c31897a9c4d72827a19e15dcd3e4e1281 Mon Sep 17 00:00:00 2001 From: ronantakizawa Date: Wed, 13 Aug 2025 08:30:52 -0600 Subject: [PATCH 3/4] fix: remove unnecessary changes --- package.json | 2 +- src/common/atlas/openapi.d.ts | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/package.json b/package.json index dee50aba..7bba9bf6 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "scripts": { "start": "node dist/index.js --transport http --loggers stderr mcp", "start:stdio": "node dist/index.js --transport stdio --loggers stderr mcp", - "prepare": "exit 0", + "prepare": "npm run build", "build:clean": "rm -rf dist", "build:update-package-version": "tsx scripts/updatePackageVersion.ts", "build:esm": "tsc --project tsconfig.esm.json", diff --git a/src/common/atlas/openapi.d.ts b/src/common/atlas/openapi.d.ts index a204436b..890c45c7 100644 --- a/src/common/atlas/openapi.d.ts +++ b/src/common/atlas/openapi.d.ts @@ -1735,11 +1735,6 @@ export interface components { * @example 32b6e34b3d91647abb20e7b8 */ readonly roleId?: string; - /** - * @description Provision status of the service account. - * @enum {string} - */ - readonly status?: "IN_PROGRESS" | "COMPLETE" | "FAILED" | "NOT_INITIATED"; } & { /** * @description discriminator enum property added by openapi-typescript From 8c126a07d13314be0a900b14d73b37107fd8267a Mon Sep 17 00:00:00 2001 From: ronantakizawa Date: Wed, 13 Aug 2025 23:12:33 -0600 Subject: [PATCH 4/4] fix: route logs to mcp log format --- src/common/atlas/openapi.d.ts | 5 +++++ src/common/logger.ts | 14 +++++++++++++ src/server.ts | 37 +++++++++++++++++++++++++++++++++-- src/transports/base.ts | 5 ++++- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/common/atlas/openapi.d.ts b/src/common/atlas/openapi.d.ts index 890c45c7..a204436b 100644 --- a/src/common/atlas/openapi.d.ts +++ b/src/common/atlas/openapi.d.ts @@ -1735,6 +1735,11 @@ export interface components { * @example 32b6e34b3d91647abb20e7b8 */ readonly roleId?: string; + /** + * @description Provision status of the service account. + * @enum {string} + */ + readonly status?: "IN_PROGRESS" | "COMPLETE" | "FAILED" | "NOT_INITIATED"; } & { /** * @description discriminator enum property added by openapi-typescript diff --git a/src/common/logger.ts b/src/common/logger.ts index 0add105c..8e5994f3 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -244,18 +244,32 @@ export class DiskLogger extends LoggerBase<{ initialized: [] }> { } export class McpLogger extends LoggerBase { + private shouldLogFunction?: (level: LogLevel) => boolean; + public constructor(private readonly server: McpServer) { super(); } protected readonly type: LoggerType = "mcp"; + /** + * Sets the function to check if a log level should be sent + */ + public setShouldLogFunction(shouldLog: (level: LogLevel) => boolean): void { + this.shouldLogFunction = shouldLog; + } + protected logCore(level: LogLevel, payload: LogPayload): void { // Only log if the server is connected if (!this.server?.isConnected()) { return; } + // Check if this log level should be sent + if (this.shouldLogFunction && !this.shouldLogFunction(level)) { + return; + } + void this.server.server.sendLoggingMessage({ level, data: `[${payload.context}]: ${payload.message}`, diff --git a/src/server.ts b/src/server.ts index f4a4d7d3..2791a234 100644 --- a/src/server.ts +++ b/src/server.ts @@ -12,17 +12,20 @@ import { type ServerCommand } from "./telemetry/types.js"; import { CallToolRequestSchema, CallToolResult, + SetLevelRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import assert from "assert"; import { ToolBase } from "./tools/tool.js"; +import { LogLevel, McpLogger } from "./common/logger.js"; export interface ServerOptions { session: Session; userConfig: UserConfig; mcpServer: McpServer; telemetry: Telemetry; + mcpLogger?: McpLogger; } export class Server { @@ -33,13 +36,21 @@ export class Server { public readonly tools: ToolBase[] = []; private readonly startTime: number; private readonly subscriptions = new Set(); + private minimumLogLevel: LogLevel = "info"; + private readonly mcpLogger?: McpLogger; - constructor({ session, mcpServer, userConfig, telemetry }: ServerOptions) { + constructor({ session, mcpServer, userConfig, telemetry, mcpLogger }: ServerOptions) { this.startTime = Date.now(); this.session = session; this.telemetry = telemetry; this.mcpServer = mcpServer; this.userConfig = userConfig; + this.mcpLogger = mcpLogger; + + // Set up log level filtering for MCP logger + if (this.mcpLogger) { + this.mcpLogger.setShouldLogFunction((level: LogLevel) => this.shouldLog(level)); + } } async connect(transport: Transport): Promise { @@ -48,7 +59,7 @@ export class Server { this.registerResources(); await this.validateConfig(); - this.mcpServer.server.registerCapabilities({ resources: { listChanged: true, subscribe: true } }); + this.mcpServer.server.registerCapabilities({ logging: {}, resources: { listChanged: true, subscribe: true } }); // TODO: Eventually we might want to make tools reactive too instead of relying on custom logic. this.registerTools(); @@ -96,6 +107,16 @@ export class Server { return {}; }); + this.mcpServer.server.setRequestHandler(SetLevelRequestSchema, ({ params }) => { + this.minimumLogLevel = params.level; + this.session.logger.debug({ + id: LogId.serverInitialized, + context: "logging", + message: `Log level set to: ${params.level}`, + }); + return {}; + }); + this.mcpServer.server.oninitialized = (): void => { this.session.setAgentRunner(this.mcpServer.server.getClientVersion()); @@ -137,6 +158,18 @@ export class Server { } } + /** + * Checks if a log level meets the minimum threshold for logging + * @param level - The log level to check + * @returns true if the level should be logged, false otherwise + */ + public shouldLog(level: LogLevel): boolean { + const levels: LogLevel[] = ["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"]; + const currentIndex = levels.indexOf(this.minimumLogLevel); + const levelIndex = levels.indexOf(level); + return levelIndex >= currentIndex; + } + /** * Emits a server event * @param command - The server command (e.g., "start", "stop", "register", "deregister") diff --git a/src/transports/base.ts b/src/transports/base.ts index 22a000cc..f669a9f3 100644 --- a/src/transports/base.ts +++ b/src/transports/base.ts @@ -37,8 +37,10 @@ export abstract class TransportRunnerBase { }); const loggers = [this.logger]; + let mcpLogger: McpLogger | undefined; if (userConfig.loggers.includes("mcp")) { - loggers.push(new McpLogger(mcpServer)); + mcpLogger = new McpLogger(mcpServer); + loggers.push(mcpLogger); } const logger = new CompositeLogger(...loggers); @@ -61,6 +63,7 @@ export abstract class TransportRunnerBase { session, telemetry, userConfig, + mcpLogger, }); }