• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb-js / mongodb-mcp-server / 16294787182

15 Jul 2025 01:35PM UTC coverage: 77.486% (+0.1%) from 77.385%
16294787182

Pull #372

github

web-flow
Merge cdb37b931 into 48bce63a0
Pull Request #372: chore: Improve access list and connect experienece [MCP-5]

503 of 693 branches covered (72.58%)

Branch coverage included in aggregate %.

44 of 46 new or added lines in 6 files covered. (95.65%)

15 existing lines in 2 files now uncovered.

2863 of 3651 relevant lines covered (78.42%)

28.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.44
/src/common/logger.ts
1
import fs from "fs/promises";
2✔
2
import { mongoLogId, MongoLogId, MongoLogManager, MongoLogWriter } from "mongodb-log-writer";
2✔
3
import redact from "mongodb-redact";
2✔
4
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
import { LoggingMessageNotification } from "@modelcontextprotocol/sdk/types.js";
6

7
export type LogLevel = LoggingMessageNotification["params"]["level"];
8

9
export const LogId = {
2✔
10
    serverStartFailure: mongoLogId(1_000_001),
2✔
11
    serverInitialized: mongoLogId(1_000_002),
2✔
12
    serverCloseRequested: mongoLogId(1_000_003),
2✔
13
    serverClosed: mongoLogId(1_000_004),
2✔
14
    serverCloseFailure: mongoLogId(1_000_005),
2✔
15

16
    atlasCheckCredentials: mongoLogId(1_001_001),
2✔
17
    atlasDeleteDatabaseUserFailure: mongoLogId(1_001_002),
2✔
18
    atlasConnectFailure: mongoLogId(1_001_003),
2✔
19
    atlasInspectFailure: mongoLogId(1_001_004),
2✔
20
    atlasConnectAttempt: mongoLogId(1_001_005),
2✔
21
    atlasConnectSucceeded: mongoLogId(1_001_006),
2✔
22
    atlasApiRevokeFailure: mongoLogId(1_001_007),
2✔
23
    atlasIpAccessListAdded: mongoLogId(1_001_008),
2✔
24

25
    telemetryDisabled: mongoLogId(1_002_001),
2✔
26
    telemetryEmitFailure: mongoLogId(1_002_002),
2✔
27
    telemetryEmitStart: mongoLogId(1_002_003),
2✔
28
    telemetryEmitSuccess: mongoLogId(1_002_004),
2✔
29
    telemetryMetadataError: mongoLogId(1_002_005),
2✔
30
    telemetryDeviceIdFailure: mongoLogId(1_002_006),
2✔
31
    telemetryDeviceIdTimeout: mongoLogId(1_002_007),
2✔
32

33
    toolExecute: mongoLogId(1_003_001),
2✔
34
    toolExecuteFailure: mongoLogId(1_003_002),
2✔
35
    toolDisabled: mongoLogId(1_003_003),
2✔
36

37
    mongodbConnectFailure: mongoLogId(1_004_001),
2✔
38
    mongodbDisconnectFailure: mongoLogId(1_004_002),
2✔
39

40
    toolUpdateFailure: mongoLogId(1_005_001),
2✔
41
} as const;
2✔
42

43
abstract class LoggerBase {
2✔
44
    abstract log(level: LogLevel, id: MongoLogId, context: string, message: string): void;
45

46
    info(id: MongoLogId, context: string, message: string): void {
2✔
47
        this.log("info", id, context, message);
138✔
48
    }
138✔
49

50
    error(id: MongoLogId, context: string, message: string): void {
2✔
51
        this.log("error", id, context, message);
37✔
52
    }
37✔
53
    debug(id: MongoLogId, context: string, message: string): void {
2✔
54
        this.log("debug", id, context, message);
303✔
55
    }
303✔
56

57
    notice(id: MongoLogId, context: string, message: string): void {
2✔
UNCOV
58
        this.log("notice", id, context, message);
×
59
    }
×
60

61
    warning(id: MongoLogId, context: string, message: string): void {
2✔
UNCOV
62
        this.log("warning", id, context, message);
×
63
    }
×
64

65
    critical(id: MongoLogId, context: string, message: string): void {
2✔
UNCOV
66
        this.log("critical", id, context, message);
×
67
    }
×
68

69
    alert(id: MongoLogId, context: string, message: string): void {
2✔
UNCOV
70
        this.log("alert", id, context, message);
×
71
    }
×
72

73
    emergency(id: MongoLogId, context: string, message: string): void {
2✔
UNCOV
74
        this.log("emergency", id, context, message);
×
75
    }
×
76
}
2✔
77

78
class ConsoleLogger extends LoggerBase {
2✔
79
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
2✔
80
        message = redact(message);
11✔
81
        console.error(`[${level.toUpperCase()}] ${id.__value} - ${context}: ${message}`);
11✔
82
    }
11✔
83
}
2✔
84

85
class DiskLogger extends LoggerBase {
2✔
86
    private constructor(private logWriter: MongoLogWriter) {
2✔
87
        super();
34✔
88
    }
34✔
89

90
    static async fromPath(logPath: string): Promise<DiskLogger> {
2✔
91
        await fs.mkdir(logPath, { recursive: true });
34✔
92

93
        const manager = new MongoLogManager({
34✔
94
            directory: logPath,
34✔
95
            retentionDays: 30,
34✔
96
            onwarn: console.warn,
34✔
97
            onerror: console.error,
34✔
98
            gzip: false,
34✔
99
            retentionGB: 1,
34✔
100
        });
34✔
101

102
        await manager.cleanupOldLogFiles();
34✔
103

104
        const logWriter = await manager.createLogWriter();
34✔
105

106
        return new DiskLogger(logWriter);
34✔
107
    }
34✔
108

109
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
2✔
110
        message = redact(message);
467✔
111
        const mongoDBLevel = this.mapToMongoDBLogLevel(level);
467✔
112

113
        this.logWriter[mongoDBLevel]("MONGODB-MCP", id, context, message);
467✔
114
    }
467✔
115

116
    private mapToMongoDBLogLevel(level: LogLevel): "info" | "warn" | "error" | "debug" | "fatal" {
2✔
117
        switch (level) {
467✔
118
            case "info":
467✔
119
                return "info";
136✔
120
            case "warning":
467!
UNCOV
121
                return "warn";
×
122
            case "error":
467✔
123
                return "error";
37✔
124
            case "notice":
467!
125
            case "debug":
467✔
126
                return "debug";
294✔
127
            case "critical":
467!
128
            case "alert":
467!
129
            case "emergency":
467!
UNCOV
130
                return "fatal";
×
131
            default:
467!
UNCOV
132
                return "info";
×
133
        }
467✔
134
    }
467✔
135
}
2✔
136

137
class McpLogger extends LoggerBase {
2✔
138
    constructor(private server: McpServer) {
2✔
139
        super();
34✔
140
    }
34✔
141

142
    log(level: LogLevel, _: MongoLogId, context: string, message: string): void {
2✔
143
        // Only log if the server is connected
144
        if (!this.server?.isConnected()) {
467✔
145
            return;
49✔
146
        }
49✔
147

148
        void this.server.server.sendLoggingMessage({
418✔
149
            level,
418✔
150
            data: `[${context}]: ${message}`,
418✔
151
        });
418✔
152
    }
467✔
153
}
2✔
154

155
class CompositeLogger extends LoggerBase {
2✔
156
    private loggers: LoggerBase[];
157

158
    constructor(...loggers: LoggerBase[]) {
2✔
159
        super();
39✔
160

161
        if (loggers.length === 0) {
39✔
162
            // default to ConsoleLogger
163
            this.loggers = [new ConsoleLogger()];
39✔
164
            return;
39✔
165
        }
39!
166

UNCOV
167
        this.loggers = [...loggers];
×
168
    }
39✔
169

170
    setLoggers(...loggers: LoggerBase[]): void {
2✔
171
        if (loggers.length === 0) {
34!
UNCOV
172
            throw new Error("At least one logger must be provided");
×
173
        }
×
174
        this.loggers = [...loggers];
34✔
175
    }
34✔
176

177
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
2✔
178
        for (const logger of this.loggers) {
478✔
179
            logger.log(level, id, context, message);
945✔
180
        }
945✔
181
    }
478✔
182
}
2✔
183

184
const logger = new CompositeLogger();
2✔
185
export default logger;
2✔
186

187
export async function setStdioPreset(server: McpServer, logPath: string): Promise<void> {
34✔
188
    const diskLogger = await DiskLogger.fromPath(logPath);
34✔
189
    const mcpLogger = new McpLogger(server);
34✔
190

191
    logger.setLoggers(mcpLogger, diskLogger);
34✔
192
}
34✔
193

194
export function setContainerPreset(server: McpServer): void {
2✔
UNCOV
195
    const mcpLogger = new McpLogger(server);
×
196
    const consoleLogger = new ConsoleLogger();
×
197

UNCOV
198
    logger.setLoggers(mcpLogger, consoleLogger);
×
199
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc