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

mongodb-js / mongodb-mcp-server / 16876636630

11 Aug 2025 09:51AM UTC coverage: 81.999% (+0.6%) from 81.362%
16876636630

Pull #424

github

web-flow
Merge 602f1c199 into 7572ec5d6
Pull Request #424: feat: adds an export tool and exported-data resource MCP-16

784 of 1003 branches covered (78.17%)

Branch coverage included in aggregate %.

592 of 659 new or added lines in 13 files covered. (89.83%)

18 existing lines in 3 files now uncovered.

4072 of 4919 relevant lines covered (82.78%)

66.27 hits per line

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

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

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

25
export type SessionEvents = {
26
    connect: [];
27
    close: [];
28
    disconnect: [];
29
    "connection-error": [string];
30
};
31

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

42
    public logger: CompositeLogger;
43

44
    constructor({
2✔
45
        apiBaseUrl,
86✔
46
        apiClientId,
86✔
47
        apiClientSecret,
86✔
48
        logger,
86✔
49
        connectionManager,
86✔
50
        exportsManager,
86✔
51
    }: SessionOptions) {
86✔
52
        super();
86✔
53

54
        this.logger = logger;
86✔
55
        const credentials: ApiClientCredentials | undefined =
86✔
56
            apiClientId && apiClientSecret
86✔
57
                ? {
41✔
58
                      clientId: apiClientId,
41✔
59
                      clientSecret: apiClientSecret,
41✔
60
                  }
41✔
61
                : undefined;
45✔
62

63
        this.apiClient = new ApiClient({ baseUrl: apiBaseUrl, credentials }, logger);
86✔
64
        this.exportsManager = exportsManager;
86✔
65
        this.connectionManager = connectionManager;
86✔
66
        this.connectionManager.on("connection-succeeded", () => this.emit("connect"));
86✔
67
        this.connectionManager.on("connection-timed-out", (error) => this.emit("connection-error", error.errorReason));
86✔
68
        this.connectionManager.on("connection-closed", () => this.emit("disconnect"));
86✔
69
        this.connectionManager.on("connection-errored", (error) => this.emit("connection-error", error.errorReason));
86✔
70
    }
86✔
71

72
    setAgentRunner(agentRunner: Implementation | undefined): void {
2✔
73
        if (agentRunner?.name && agentRunner?.version) {
74✔
74
            this.agentRunner = {
74✔
75
                name: agentRunner.name,
74✔
76
                version: agentRunner.version,
74✔
77
            };
74✔
78
        }
74✔
79
    }
74✔
80

81
    async disconnect(): Promise<void> {
2✔
82
        const atlasCluster = this.connectedAtlasCluster;
764✔
83

84
        try {
764✔
85
            await this.connectionManager.disconnect();
764✔
86
        } catch (err: unknown) {
764!
87
            const error = err instanceof Error ? err : new Error(String(err));
×
88
            this.logger.error({
×
89
                id: LogId.mongodbDisconnectFailure,
×
90
                context: "session",
×
91
                message: `Error closing service provider: ${error.message}`,
×
92
            });
×
93
        }
×
94

95
        if (atlasCluster?.username && atlasCluster?.projectId) {
764✔
96
            void this.apiClient
1✔
97
                .deleteDatabaseUser({
1✔
98
                    params: {
1✔
99
                        path: {
1✔
100
                            groupId: atlasCluster.projectId,
1✔
101
                            username: atlasCluster.username,
1✔
102
                            databaseName: "admin",
1✔
103
                        },
1✔
104
                    },
1✔
105
                })
1✔
106
                .catch((err: unknown) => {
1✔
UNCOV
107
                    const error = err instanceof Error ? err : new Error(String(err));
×
UNCOV
108
                    this.logger.error({
×
UNCOV
109
                        id: LogId.atlasDeleteDatabaseUserFailure,
×
UNCOV
110
                        context: "session",
×
UNCOV
111
                        message: `Error deleting previous database user: ${error.message}`,
×
UNCOV
112
                    });
×
113
                });
1✔
114
        }
1✔
115
    }
764✔
116

117
    async close(): Promise<void> {
2✔
118
        await this.disconnect();
74✔
119
        await this.apiClient.close();
74✔
120
        await this.exportsManager.close();
73✔
121
        this.emit("close");
73✔
122
    }
74✔
123

124
    async connectToMongoDB(settings: ConnectionSettings): Promise<void> {
2✔
125
        try {
369✔
126
            await this.connectionManager.connect({ ...settings });
369✔
127
        } catch (error: unknown) {
369✔
128
            const message = error instanceof Error ? error.message : (error as string);
19!
129
            this.emit("connection-error", message);
19✔
130
            throw error;
19✔
131
        }
19✔
132
    }
369✔
133

134
    get isConnectedToMongoDB(): boolean {
2✔
135
        return this.connectionManager.currentConnectionState.tag === "connected";
2,079✔
136
    }
2,079✔
137

138
    get serviceProvider(): NodeDriverServiceProvider {
2✔
139
        if (this.isConnectedToMongoDB) {
296✔
140
            const state = this.connectionManager.currentConnectionState as ConnectionStateConnected;
296✔
141
            return state.serviceProvider;
296✔
142
        }
296!
143

144
        throw new MongoDBError(ErrorCodes.NotConnectedToMongoDB, "Not connected to MongoDB");
×
145
    }
296✔
146

147
    get connectedAtlasCluster(): AtlasClusterConnectionInfo | undefined {
2✔
148
        return this.connectionManager.currentConnectionState.connectedAtlasCluster;
948✔
149
    }
948✔
150
}
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