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

mongodb-js / mongodb-mcp-server / 18552067365

16 Oct 2025 06:13AM UTC coverage: 82.527% (+0.3%) from 82.215%
18552067365

push

github

web-flow
chore: extend accuracy tests to support custom user and cluster config (#655)

1189 of 1575 branches covered (75.49%)

Branch coverage included in aggregate %.

5806 of 6901 relevant lines covered (84.13%)

70.79 hits per line

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

82.31
/src/common/session.ts
1
import { ObjectId } from "bson";
2✔
2
import type { ApiClientCredentials } from "./atlas/apiClient.js";
3
import { ApiClient } from "./atlas/apiClient.js";
2✔
4
import type { Implementation } from "@modelcontextprotocol/sdk/types.js";
5
import type { CompositeLogger } from "./logger.js";
6
import { LogId } from "./logger.js";
2✔
7
import EventEmitter from "events";
2✔
8
import type {
9
    AtlasClusterConnectionInfo,
10
    ConnectionManager,
11
    ConnectionSettings,
12
    ConnectionStateConnected,
13
    ConnectionStateErrored,
14
} from "./connectionManager.js";
15
import type { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
16
import { ErrorCodes, MongoDBError } from "./errors.js";
2✔
17
import type { ExportsManager } from "./exportsManager.js";
18
import type { Keychain } from "./keychain.js";
19

20
export interface SessionOptions {
21
    apiBaseUrl: string;
22
    apiClientId?: string;
23
    apiClientSecret?: string;
24
    logger: CompositeLogger;
25
    exportsManager: ExportsManager;
26
    connectionManager: ConnectionManager;
27
    keychain: Keychain;
28
}
29

30
export type SessionEvents = {
31
    connect: [];
32
    close: [];
33
    disconnect: [];
34
    "connection-error": [ConnectionStateErrored];
35
};
36

37
export class Session extends EventEmitter<SessionEvents> {
2✔
38
    readonly sessionId: string = new ObjectId().toString();
2✔
39
    readonly exportsManager: ExportsManager;
40
    readonly connectionManager: ConnectionManager;
41
    readonly apiClient: ApiClient;
42
    readonly keychain: Keychain;
43

44
    mcpClient?: {
45
        name?: string;
46
        version?: string;
47
        title?: string;
48
    };
49

50
    public logger: CompositeLogger;
51

52
    constructor({
2✔
53
        apiBaseUrl,
97✔
54
        apiClientId,
97✔
55
        apiClientSecret,
97✔
56
        logger,
97✔
57
        connectionManager,
97✔
58
        exportsManager,
97✔
59
        keychain,
97✔
60
    }: SessionOptions) {
97✔
61
        super();
97✔
62

63
        this.keychain = keychain;
97✔
64
        this.logger = logger;
97✔
65
        const credentials: ApiClientCredentials | undefined =
97✔
66
            apiClientId && apiClientSecret
97✔
67
                ? {
14✔
68
                      clientId: apiClientId,
14✔
69
                      clientSecret: apiClientSecret,
14✔
70
                  }
14!
71
                : undefined;
83✔
72

73
        this.apiClient = new ApiClient({ baseUrl: apiBaseUrl, credentials }, logger);
97✔
74
        this.exportsManager = exportsManager;
97✔
75
        this.connectionManager = connectionManager;
97✔
76
        this.connectionManager.events.on("connection-success", () => this.emit("connect"));
97✔
77
        this.connectionManager.events.on("connection-time-out", (error) => this.emit("connection-error", error));
97✔
78
        this.connectionManager.events.on("connection-close", () => this.emit("disconnect"));
97✔
79
        this.connectionManager.events.on("connection-error", (error) => this.emit("connection-error", error));
97✔
80
    }
97✔
81

82
    setMcpClient(mcpClient: Implementation | undefined): void {
2✔
83
        if (!mcpClient) {
87!
84
            this.connectionManager.setClientName("unknown");
×
85
            this.logger.debug({
×
86
                id: LogId.serverMcpClientSet,
×
87
                context: "session",
×
88
                message: "MCP client info not found",
×
89
            });
×
90
        }
×
91

92
        this.mcpClient = {
87✔
93
            name: mcpClient?.name || "unknown",
87!
94
            version: mcpClient?.version || "unknown",
87!
95
            title: mcpClient?.title || "unknown",
87✔
96
        };
87✔
97

98
        // Set the client name on the connection manager for appName generation
99
        this.connectionManager.setClientName(this.mcpClient.name || "unknown");
87!
100
    }
87✔
101

102
    async disconnect(): Promise<void> {
2✔
103
        const atlasCluster = this.connectedAtlasCluster;
597✔
104

105
        await this.connectionManager.close();
597✔
106

107
        if (atlasCluster?.username && atlasCluster?.projectId) {
597!
108
            void this.apiClient
1✔
109
                .deleteDatabaseUser({
1✔
110
                    params: {
1✔
111
                        path: {
1✔
112
                            groupId: atlasCluster.projectId,
1✔
113
                            username: atlasCluster.username,
1✔
114
                            databaseName: "admin",
1✔
115
                        },
1✔
116
                    },
1✔
117
                })
1✔
118
                .catch((err: unknown) => {
1✔
119
                    const error = err instanceof Error ? err : new Error(String(err));
×
120
                    this.logger.error({
×
121
                        id: LogId.atlasDeleteDatabaseUserFailure,
×
122
                        context: "session",
×
123
                        message: `Error deleting previous database user: ${error.message}`,
×
124
                    });
×
125
                });
1✔
126
        }
1✔
127
    }
597✔
128

129
    async close(): Promise<void> {
2✔
130
        await this.disconnect();
86✔
131
        await this.apiClient.close();
86✔
132
        await this.exportsManager.close();
86✔
133
        this.emit("close");
86✔
134
    }
86✔
135

136
    async connectToMongoDB(settings: ConnectionSettings): Promise<void> {
2✔
137
        await this.connectionManager.connect({ ...settings });
285✔
138
    }
285✔
139

140
    get isConnectedToMongoDB(): boolean {
2✔
141
        return this.connectionManager.currentConnectionState.tag === "connected";
1,598✔
142
    }
1,598✔
143

144
    isSearchSupported(): Promise<boolean> {
2✔
145
        const state = this.connectionManager.currentConnectionState;
7✔
146
        if (state.tag === "connected") {
7✔
147
            return state.isSearchSupported();
6✔
148
        }
6✔
149

150
        return Promise.resolve(false);
1✔
151
    }
7✔
152

153
    get serviceProvider(): NodeDriverServiceProvider {
2✔
154
        if (this.isConnectedToMongoDB) {
222✔
155
            const state = this.connectionManager.currentConnectionState as ConnectionStateConnected;
222✔
156
            return state.serviceProvider;
222✔
157
        }
222!
158

159
        throw new MongoDBError(ErrorCodes.NotConnectedToMongoDB, "Not connected to MongoDB");
×
160
    }
222✔
161

162
    get connectedAtlasCluster(): AtlasClusterConnectionInfo | undefined {
2✔
163
        return this.connectionManager.currentConnectionState.connectedAtlasCluster;
715✔
164
    }
715✔
165
}
2✔
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

© 2026 Coveralls, Inc