Skip to content

Commit f5481fd

Browse files
committed
more tweaks
1 parent 9d2e127 commit f5481fd

File tree

7 files changed

+74
-31
lines changed

7 files changed

+74
-31
lines changed

src/common/logger.ts

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const LogId = {
6464
oidcFlow: mongoLogId(1_008_001),
6565
} as const;
6666

67-
interface LogPayload {
67+
export interface LogPayload {
6868
id: MongoLogId;
6969
context: string;
7070
message: string;
@@ -152,6 +152,26 @@ export abstract class LoggerBase<T extends EventMap<T> = DefaultEventMap> extend
152152
public emergency(payload: LogPayload): void {
153153
this.log("emergency", payload);
154154
}
155+
156+
protected mapToMongoDBLogLevel(level: LogLevel): "info" | "warn" | "error" | "debug" | "fatal" {
157+
switch (level) {
158+
case "info":
159+
return "info";
160+
case "warning":
161+
return "warn";
162+
case "error":
163+
return "error";
164+
case "notice":
165+
case "debug":
166+
return "debug";
167+
case "critical":
168+
case "alert":
169+
case "emergency":
170+
return "fatal";
171+
default:
172+
return "info";
173+
}
174+
}
155175
}
156176

157177
export class ConsoleLogger extends LoggerBase {
@@ -225,26 +245,6 @@ export class DiskLogger extends LoggerBase<{ initialized: [] }> {
225245

226246
this.logWriter[mongoDBLevel]("MONGODB-MCP", id, context, message, payload.attributes);
227247
}
228-
229-
private mapToMongoDBLogLevel(level: LogLevel): "info" | "warn" | "error" | "debug" | "fatal" {
230-
switch (level) {
231-
case "info":
232-
return "info";
233-
case "warning":
234-
return "warn";
235-
case "error":
236-
return "error";
237-
case "notice":
238-
case "debug":
239-
return "debug";
240-
case "critical":
241-
case "alert":
242-
case "emergency":
243-
return "fatal";
244-
default:
245-
return "info";
246-
}
247-
}
248248
}
249249

250250
export class McpLogger extends LoggerBase {
@@ -286,7 +286,11 @@ export class CompositeLogger extends LoggerBase {
286286
public log(level: LogLevel, payload: LogPayload): void {
287287
// Override the public method to avoid the base logger redacting the message payload
288288
for (const logger of this.loggers) {
289-
logger.log(level, { ...payload, attributes: { ...this.attributes, ...payload.attributes } });
289+
const attributes =
290+
Object.keys(this.attributes).length > 0 || payload.attributes
291+
? { ...this.attributes, ...payload.attributes }
292+
: undefined;
293+
logger.log(level, { ...payload, attributes });
290294
}
291295
}
292296

src/helpers/deviceId.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getDeviceId } from "@mongodb-js/device-id";
2-
import nodeMachineId from "node-machine-id";
2+
// Important: don't import the default module as that doesn't work for cjs module resolution.
3+
import { machineId } from "node-machine-id";
34
import type { LoggerBase } from "../common/logger.js";
45
import { LogId } from "../common/logger.js";
56

@@ -17,7 +18,7 @@ export class DeviceId {
1718
private constructor(logger: LoggerBase, timeout: number = DEVICE_ID_TIMEOUT) {
1819
this.logger = logger;
1920
this.timeout = timeout;
20-
this.getMachineId = (): Promise<string> => nodeMachineId.machineId(true);
21+
this.getMachineId = (): Promise<string> => machineId(true);
2122
this.abortController = new AbortController();
2223

2324
this.deviceIdPromise = DeviceId.UnknownDeviceId;

src/lib.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ export { Telemetry } from "./telemetry/telemetry.js";
33
export { Session, type SessionOptions } from "./common/session.js";
44
export { type UserConfig, defaultUserConfig } from "./common/config.js";
55
export { StreamableHttpRunner } from "./transports/streamableHttp.js";
6+
export { LoggerBase } from "./common/logger.js";
7+
export type { LogPayload, LoggerType, LogLevel } from "./common/logger.js";

src/transports/base.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ export abstract class TransportRunnerBase {
1616

1717
protected constructor(
1818
protected readonly userConfig: UserConfig,
19-
private readonly driverOptions: DriverOptions
19+
private readonly driverOptions: DriverOptions,
20+
additionalLoggers: LoggerBase[]
2021
) {
21-
const loggers: LoggerBase[] = [];
22+
const loggers: LoggerBase[] = [...additionalLoggers];
2223
if (this.userConfig.loggers.includes("stderr")) {
2324
loggers.push(new ConsoleLogger());
2425
}

src/transports/stdio.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { LoggerBase } from "../common/logger.js";
12
import { LogId } from "../common/logger.js";
23
import type { Server } from "../server.js";
34
import { TransportRunnerBase } from "./base.js";
@@ -54,8 +55,8 @@ export function createStdioTransport(): StdioServerTransport {
5455
export class StdioRunner extends TransportRunnerBase {
5556
private server: Server | undefined;
5657

57-
constructor(userConfig: UserConfig, driverOptions: DriverOptions) {
58-
super(userConfig, driverOptions);
58+
constructor(userConfig: UserConfig, driverOptions: DriverOptions, additionalLoggers: LoggerBase[] = []) {
59+
super(userConfig, driverOptions, additionalLoggers);
5960
}
6061

6162
async start(): Promise<void> {

src/transports/streamableHttp.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
44
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
55
import { TransportRunnerBase } from "./base.js";
66
import type { DriverOptions, UserConfig } from "../common/config.js";
7+
import type { LoggerBase } from "../common/logger.js";
78
import { LogId } from "../common/logger.js";
89
import { randomUUID } from "crypto";
910
import { SessionStore } from "../common/sessionStore.js";
@@ -30,8 +31,8 @@ export class StreamableHttpRunner extends TransportRunnerBase {
3031
throw new Error("Server is not started yet");
3132
}
3233

33-
constructor(userConfig: UserConfig, driverOptions: DriverOptions) {
34-
super(userConfig, driverOptions);
34+
constructor(userConfig: UserConfig, driverOptions: DriverOptions, additionalLoggers: LoggerBase[] = []) {
35+
super(userConfig, driverOptions, additionalLoggers);
3536
}
3637

3738
async start(): Promise<void> {

tests/integration/transports/streamableHttp.test.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { StreamableHttpRunner } from "../../../src/transports/streamableHttp.js";
22
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
33
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4-
import { describe, expect, it, beforeAll, afterAll } from "vitest";
4+
import { describe, expect, it, beforeAll, afterAll, beforeEach } from "vitest";
55
import { config, driverOptions } from "../../../src/common/config.js";
6+
import type { LoggerType, LogLevel, LogPayload } from "../../../src/common/logger.js";
7+
import { LoggerBase, LogId } from "../../../src/common/logger.js";
68

79
describe("StreamableHttpRunner", () => {
810
let runner: StreamableHttpRunner;
@@ -120,4 +122,35 @@ describe("StreamableHttpRunner", () => {
120122
}
121123
}
122124
});
125+
126+
describe("with custom logger", () => {
127+
beforeEach(() => {
128+
config.loggers = [];
129+
});
130+
131+
class CustomLogger extends LoggerBase {
132+
protected type?: LoggerType = "console";
133+
public messages: { level: LogLevel; payload: LogPayload }[] = [];
134+
protected logCore(level: LogLevel, payload: LogPayload): void {
135+
this.messages.push({ level, payload });
136+
}
137+
}
138+
139+
it("can provide custom logger", async () => {
140+
const logger = new CustomLogger();
141+
const runner = new StreamableHttpRunner(config, driverOptions, [logger]);
142+
await runner.start();
143+
144+
const messages = logger.messages;
145+
expect(messages.length).toBeGreaterThan(0);
146+
147+
const serverStartedMessage = messages.filter(
148+
(m) => m.payload.id === LogId.streamableHttpTransportStarted
149+
)[0];
150+
expect(serverStartedMessage).toBeDefined();
151+
expect(serverStartedMessage?.payload.message).toContain("Server started on");
152+
expect(serverStartedMessage?.payload.context).toBe("streamableHttpTransport");
153+
expect(serverStartedMessage?.level).toBe("info");
154+
});
155+
});
123156
});

0 commit comments

Comments
 (0)