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

mongodb-js / mongodb-mcp-server / 18166080320

01 Oct 2025 02:47PM UTC coverage: 82.501% (-0.06%) from 82.561%
18166080320

Pull #606

github

web-flow
Merge 1f91cf025 into c86de4094
Pull Request #606: chore: remove smithery from documentation

1097 of 1441 branches covered (76.13%)

Branch coverage included in aggregate %.

5296 of 6308 relevant lines covered (83.96%)

67.78 hits per line

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

81.02
/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,
85✔
54
        apiClientId,
85✔
55
        apiClientSecret,
85✔
56
        logger,
85✔
57
        connectionManager,
85✔
58
        exportsManager,
85✔
59
        keychain,
85✔
60
    }: SessionOptions) {
85✔
61
        super();
85✔
62

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

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

82
    setMcpClient(mcpClient: Implementation | undefined): void {
2✔
83
        if (!mcpClient) {
77!
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 = {
77✔
93
            name: mcpClient?.name || "unknown",
77!
94
            version: mcpClient?.version || "unknown",
77!
95
            title: mcpClient?.title || "unknown",
77✔
96
        };
77✔
97

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

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

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

107
        if (atlasCluster?.username && atlasCluster?.projectId) {
535!
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
    }
535✔
128

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

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

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

144
    get serviceProvider(): NodeDriverServiceProvider {
2✔
145
        if (this.isConnectedToMongoDB) {
200✔
146
            const state = this.connectionManager.currentConnectionState as ConnectionStateConnected;
200✔
147
            return state.serviceProvider;
200✔
148
        }
200!
149

150
        throw new MongoDBError(ErrorCodes.NotConnectedToMongoDB, "Not connected to MongoDB");
×
151
    }
200✔
152

153
    get connectedAtlasCluster(): AtlasClusterConnectionInfo | undefined {
2✔
154
        return this.connectionManager.currentConnectionState.connectedAtlasCluster;
653✔
155
    }
653✔
156
}
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

© 2025 Coveralls, Inc