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

mongodb-js / mongodb-mcp-server / 17330103427

29 Aug 2025 05:17PM UTC coverage: 80.912% (-1.1%) from 82.036%
17330103427

push

github

web-flow
ci: add ipAccessList after creating project (#496)

889 of 1182 branches covered (75.21%)

Branch coverage included in aggregate %.

4520 of 5503 relevant lines covered (82.14%)

39.79 hits per line

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

76.03
/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

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

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

35
export class Session extends EventEmitter<SessionEvents> {
2✔
36
    readonly sessionId: string = new ObjectId().toString();
2✔
37
    readonly exportsManager: ExportsManager;
38
    readonly connectionManager: ConnectionManager;
39
    readonly apiClient: ApiClient;
40
    mcpClient?: {
41
        name?: string;
42
        version?: string;
43
        title?: string;
44
    };
45

46
    public logger: CompositeLogger;
47

48
    constructor({
2✔
49
        apiBaseUrl,
56✔
50
        apiClientId,
56✔
51
        apiClientSecret,
56✔
52
        logger,
56✔
53
        connectionManager,
56✔
54
        exportsManager,
56✔
55
    }: SessionOptions) {
56✔
56
        super();
56✔
57

58
        this.logger = logger;
56✔
59
        const credentials: ApiClientCredentials | undefined =
56✔
60
            apiClientId && apiClientSecret
56✔
61
                ? {
8✔
62
                      clientId: apiClientId,
8✔
63
                      clientSecret: apiClientSecret,
8✔
64
                  }
8!
65
                : undefined;
48✔
66

67
        this.apiClient = new ApiClient({ baseUrl: apiBaseUrl, credentials }, logger);
56✔
68
        this.exportsManager = exportsManager;
56✔
69
        this.connectionManager = connectionManager;
56✔
70
        this.connectionManager.events.on("connection-success", () => this.emit("connect"));
56✔
71
        this.connectionManager.events.on("connection-time-out", (error) => this.emit("connection-error", error));
56✔
72
        this.connectionManager.events.on("connection-close", () => this.emit("disconnect"));
56✔
73
        this.connectionManager.events.on("connection-error", (error) => this.emit("connection-error", error));
56✔
74
    }
56✔
75

76
    setMcpClient(mcpClient: Implementation | undefined): void {
2✔
77
        if (!mcpClient) {
49!
78
            this.connectionManager.setClientName("unknown");
×
79
            this.logger.debug({
×
80
                id: LogId.serverMcpClientSet,
×
81
                context: "session",
×
82
                message: "MCP client info not found",
×
83
            });
×
84
        }
×
85

86
        this.mcpClient = {
49✔
87
            name: mcpClient?.name || "unknown",
49!
88
            version: mcpClient?.version || "unknown",
49!
89
            title: mcpClient?.title || "unknown",
49✔
90
        };
49✔
91

92
        // Set the client name on the connection manager for appName generation
93
        this.connectionManager.setClientName(this.mcpClient.name || "unknown");
49!
94
    }
49✔
95

96
    async disconnect(): Promise<void> {
2✔
97
        const atlasCluster = this.connectedAtlasCluster;
420✔
98

99
        try {
420✔
100
            await this.connectionManager.disconnect();
420✔
101
        } catch (err: unknown) {
420!
102
            const error = err instanceof Error ? err : new Error(String(err));
×
103
            this.logger.error({
×
104
                id: LogId.mongodbDisconnectFailure,
×
105
                context: "session",
×
106
                message: `Error closing service provider: ${error.message}`,
×
107
            });
×
108
        }
×
109

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

132
    async close(): Promise<void> {
2✔
133
        await this.disconnect();
48✔
134
        await this.apiClient.close();
48✔
135
        await this.exportsManager.close();
48✔
136
        this.emit("close");
48✔
137
    }
48✔
138

139
    async connectToMongoDB(settings: ConnectionSettings): Promise<void> {
2✔
140
        await this.connectionManager.connect({ ...settings });
202✔
141
    }
202✔
142

143
    get isConnectedToMongoDB(): boolean {
2✔
144
        return this.connectionManager.currentConnectionState.tag === "connected";
1,110✔
145
    }
1,110✔
146

147
    get serviceProvider(): NodeDriverServiceProvider {
2✔
148
        if (this.isConnectedToMongoDB) {
153✔
149
            const state = this.connectionManager.currentConnectionState as ConnectionStateConnected;
153✔
150
            return state.serviceProvider;
153✔
151
        }
153!
152

153
        throw new MongoDBError(ErrorCodes.NotConnectedToMongoDB, "Not connected to MongoDB");
×
154
    }
153✔
155

156
    get connectedAtlasCluster(): AtlasClusterConnectionInfo | undefined {
2✔
157
        return this.connectionManager.currentConnectionState.connectedAtlasCluster;
548✔
158
    }
548✔
159
}
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