Skip to content

fix: fix logging/setLevel issue #455

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
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
5 changes: 5 additions & 0 deletions src/common/atlas/openapi.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions src/common/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`,
Expand Down
35 changes: 34 additions & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -33,13 +36,21 @@ export class Server {
public readonly tools: ToolBase[] = [];
private readonly startTime: number;
private readonly subscriptions = new Set<string>();
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<void> {
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -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")
Expand Down
5 changes: 4 additions & 1 deletion src/transports/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -61,6 +63,7 @@ export abstract class TransportRunnerBase {
session,
telemetry,
userConfig,
mcpLogger,
});
}

Expand Down
Loading