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

mongodb-js / mongodb-mcp-server / 20658627791

02 Jan 2026 01:14PM UTC coverage: 79.712% (-0.04%) from 79.748%
20658627791

Pull #819

github

web-flow
Merge 98a9a8565 into 37fe8dac4
Pull Request #819: feat: add transport metadata to all tools - MCP-348

1487 of 1942 branches covered (76.57%)

Branch coverage included in aggregate %.

28 of 29 new or added lines in 4 files covered. (96.55%)

11 existing lines in 2 files now uncovered.

6827 of 8488 relevant lines covered (80.43%)

87.12 hits per line

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

85.16
/src/common/session.ts
1
import { ObjectId } from "bson";
3✔
2
import type { ApiClientCredentials } from "./atlas/apiClient.js";
3
import { ApiClient } from "./atlas/apiClient.js";
3✔
4
import type { Implementation } from "@modelcontextprotocol/sdk/types.js";
5
import type { CompositeLogger } from "./logger.js";
6
import { LogId } from "./logger.js";
3✔
7
import EventEmitter from "events";
3✔
8
import type {
9
    AtlasClusterConnectionInfo,
10
    ConnectionManager,
11
    ConnectionSettings,
12
    ConnectionStateConnected,
13
    ConnectionStateErrored,
14
    ConnectionStringAuthType,
15
} from "./connectionManager.js";
16
import type { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
17
import { ErrorCodes, MongoDBError } from "./errors.js";
3✔
18
import type { ExportsManager } from "./exportsManager.js";
19
import type { Client } from "@mongodb-js/atlas-local";
20
import type { Keychain } from "./keychain.js";
21
import type { VectorSearchEmbeddingsManager } from "./search/vectorSearchEmbeddingsManager.js";
22
import { generateConnectionInfoFromCliArgs } from "@mongosh/arg-parser";
3✔
23
import { type UserConfig } from "../common/config/userConfig.js";
24

25
export interface SessionOptions {
26
    userConfig: UserConfig;
27
    logger: CompositeLogger;
28
    exportsManager: ExportsManager;
29
    connectionManager: ConnectionManager;
30
    keychain: Keychain;
31
    atlasLocalClient?: Client;
32
    vectorSearchEmbeddingsManager: VectorSearchEmbeddingsManager;
33
}
34

35
export type SessionEvents = {
36
    connect: [];
37
    close: [];
38
    disconnect: [];
39
    "connection-error": [ConnectionStateErrored];
40
};
41

42
export class Session extends EventEmitter<SessionEvents> {
3✔
43
    private readonly userConfig: UserConfig;
44
    readonly sessionId: string = new ObjectId().toString();
3✔
45
    readonly exportsManager: ExportsManager;
46
    readonly connectionManager: ConnectionManager;
47
    readonly apiClient: ApiClient;
48
    readonly atlasLocalClient?: Client;
49
    readonly keychain: Keychain;
50
    readonly vectorSearchEmbeddingsManager: VectorSearchEmbeddingsManager;
51

52
    mcpClient?: {
53
        name?: string;
54
        version?: string;
55
        title?: string;
56
    };
57

58
    public logger: CompositeLogger;
59

60
    constructor({
3✔
61
        userConfig,
138✔
62
        logger,
138✔
63
        connectionManager,
138✔
64
        exportsManager,
138✔
65
        keychain,
138✔
66
        atlasLocalClient,
138✔
67
        vectorSearchEmbeddingsManager,
138✔
68
    }: SessionOptions) {
138✔
69
        super();
138✔
70

71
        this.userConfig = userConfig;
138✔
72
        this.keychain = keychain;
138✔
73
        this.logger = logger;
138✔
74
        const credentials: ApiClientCredentials | undefined =
138✔
75
            userConfig.apiClientId && userConfig.apiClientSecret
138✔
76
                ? {
13✔
77
                      clientId: userConfig.apiClientId,
13✔
78
                      clientSecret: userConfig.apiClientSecret,
13✔
79
                  }
13!
80
                : undefined;
125✔
81

82
        this.apiClient = new ApiClient({ baseUrl: userConfig.apiBaseUrl, credentials }, logger);
138✔
83
        this.atlasLocalClient = atlasLocalClient;
138✔
84
        this.exportsManager = exportsManager;
138✔
85
        this.connectionManager = connectionManager;
138✔
86
        this.vectorSearchEmbeddingsManager = vectorSearchEmbeddingsManager;
138✔
87
        this.connectionManager.events.on("connection-success", () => this.emit("connect"));
138✔
88
        this.connectionManager.events.on("connection-time-out", (error) => this.emit("connection-error", error));
138✔
89
        this.connectionManager.events.on("connection-close", () => this.emit("disconnect"));
138✔
90
        this.connectionManager.events.on("connection-error", (error) => this.emit("connection-error", error));
138✔
91
    }
138✔
92

93
    setMcpClient(mcpClient: Implementation | undefined): void {
3✔
94
        if (!mcpClient) {
119!
95
            this.connectionManager.setClientName("unknown");
×
96
            this.logger.debug({
×
97
                id: LogId.serverMcpClientSet,
×
98
                context: "session",
×
99
                message: "MCP client info not found",
×
100
            });
×
101
        }
×
102

103
        this.mcpClient = {
119✔
104
            name: mcpClient?.name || "unknown",
119!
105
            version: mcpClient?.version || "unknown",
119!
106
            title: mcpClient?.title || "unknown",
119✔
107
        };
119✔
108

109
        // Set the client name on the connection manager for appName generation
110
        this.connectionManager.setClientName(this.mcpClient.name || "unknown");
119!
111
    }
119✔
112

113
    async disconnect(): Promise<void> {
3✔
114
        const atlasCluster = this.connectedAtlasCluster;
743✔
115

116
        await this.connectionManager.close();
743✔
117

118
        if (atlasCluster?.username && atlasCluster?.projectId) {
743!
119
            void this.apiClient
3✔
120
                .deleteDatabaseUser({
3✔
121
                    params: {
3✔
122
                        path: {
3✔
123
                            groupId: atlasCluster.projectId,
3✔
124
                            username: atlasCluster.username,
3✔
125
                            databaseName: "admin",
3✔
126
                        },
3✔
127
                    },
3✔
128
                })
3✔
129
                .catch((err: unknown) => {
3✔
UNCOV
130
                    const error = err instanceof Error ? err : new Error(String(err));
×
UNCOV
131
                    this.logger.error({
×
UNCOV
132
                        id: LogId.atlasDeleteDatabaseUserFailure,
×
UNCOV
133
                        context: "session",
×
UNCOV
134
                        message: `Error deleting previous database user: ${error.message}`,
×
UNCOV
135
                    });
×
136
                });
3✔
137
        }
3✔
138
    }
743✔
139

140
    async close(): Promise<void> {
3✔
141
        await this.disconnect();
116✔
142
        await this.apiClient.close();
116✔
143
        await this.exportsManager.close();
116✔
144
        this.emit("close");
115✔
145
    }
116✔
146

147
    async connectToConfiguredConnection(): Promise<void> {
3✔
148
        const connectionInfo = generateConnectionInfoFromCliArgs({
35✔
149
            ...this.userConfig,
35✔
150
            connectionSpecifier: this.userConfig.connectionString,
35✔
151
        });
35✔
152
        await this.connectToMongoDB(connectionInfo);
35✔
153
    }
35✔
154

155
    async connectToMongoDB(settings: ConnectionSettings): Promise<void> {
3✔
156
        await this.connectionManager.connect({ ...settings });
343✔
157
    }
343✔
158

159
    get isConnectedToMongoDB(): boolean {
3✔
160
        return this.connectionManager.currentConnectionState.tag === "connected";
1,045✔
161
    }
1,045✔
162

163
    async isSearchSupported(): Promise<boolean> {
3✔
164
        const state = this.connectionManager.currentConnectionState;
66✔
165
        if (state.tag === "connected") {
66✔
166
            return await state.isSearchSupported();
65✔
167
        }
65✔
168

169
        return false;
1✔
170
    }
66✔
171

172
    async assertSearchSupported(): Promise<void> {
3✔
173
        const isSearchSupported = await this.isSearchSupported();
23✔
174
        if (!isSearchSupported) {
23✔
175
            throw new MongoDBError(
3✔
176
                ErrorCodes.AtlasSearchNotSupported,
3✔
177
                "Atlas Search is not supported in the current cluster."
3✔
178
            );
3✔
179
        }
3✔
180
    }
23✔
181

182
    get serviceProvider(): NodeDriverServiceProvider {
3✔
183
        if (this.isConnectedToMongoDB) {
250✔
184
            const state = this.connectionManager.currentConnectionState as ConnectionStateConnected;
250✔
185
            return state.serviceProvider;
250✔
186
        }
250!
187

188
        throw new MongoDBError(ErrorCodes.NotConnectedToMongoDB, "Not connected to MongoDB");
×
189
    }
250✔
190

191
    get connectedAtlasCluster(): AtlasClusterConnectionInfo | undefined {
3✔
192
        return this.connectionManager.currentConnectionState.connectedAtlasCluster;
1,210✔
193
    }
1,210✔
194

195
    get connectionStringAuthType(): ConnectionStringAuthType | undefined {
3✔
196
        return this.connectionManager.currentConnectionState.connectionStringAuthType;
24✔
197
    }
24✔
198
}
3✔
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