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

mongodb-js / mongodb-mcp-server / 14653844929

24 Apr 2025 11:51PM UTC coverage: 84.922%. First build
14653844929

Pull #118

github

nirinchev
provide a better hint when the connection string is misconfigured
Pull Request #118: feat: update the connect tool based on connectivity status

128 of 202 branches covered (63.37%)

Branch coverage included in aggregate %.

61 of 68 new or added lines in 9 files covered. (89.71%)

745 of 826 relevant lines covered (90.19%)

103.05 hits per line

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

87.8
/src/server.ts
1
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
import { Session } from "./session.js";
3
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
4
import { AtlasTools } from "./tools/atlas/tools.js";
62✔
5
import { MongoDbTools } from "./tools/mongodb/tools.js";
62✔
6
import logger, { initializeLogger, LogId } from "./logger.js";
62✔
7
import { ObjectId } from "mongodb";
62✔
8
import { Telemetry } from "./telemetry/telemetry.js";
62✔
9
import { UserConfig } from "./config.js";
10
import { CallToolRequestSchema, CallToolResult } from "@modelcontextprotocol/sdk/types.js";
62✔
11
import assert from "assert";
62✔
12

13
export interface ServerOptions {
14
    session: Session;
15
    userConfig: UserConfig;
16
    mcpServer: McpServer;
17
}
18

19
export class Server {
62✔
20
    public readonly session: Session;
21
    private readonly mcpServer: McpServer;
22
    private readonly telemetry: Telemetry;
23
    public readonly userConfig: UserConfig;
24

25
    constructor({ session, mcpServer, userConfig }: ServerOptions) {
26
        this.session = session;
56✔
27
        this.telemetry = new Telemetry(session);
56✔
28
        this.mcpServer = mcpServer;
56✔
29
        this.userConfig = userConfig;
56✔
30
    }
31

32
    async connect(transport: Transport) {
33
        this.mcpServer.server.registerCapabilities({ logging: {} });
56✔
34
        this.registerTools();
56✔
35
        this.registerResources();
56✔
36

37
        // This is a workaround for an issue we've seen with some models, where they'll see that everything in the `arguments`
38
        // object is optional, and then not pass it at all. However, the MCP server expects the `arguments` object to be if
39
        // the tool accepts any arguments, even if they're all optional.
40
        //
41
        // see: https://github.com/modelcontextprotocol/typescript-sdk/blob/131776764536b5fdca642df51230a3746fb4ade0/src/server/mcp.ts#L705
42
        // Since paramsSchema here is not undefined, the server will create a non-optional z.object from it.
43
        const existingHandler = (
44
            this.mcpServer.server["_requestHandlers"] as Map<
56✔
45
                string,
46
                (request: unknown, extra: unknown) => Promise<CallToolResult>
47
            >
48
        ).get(CallToolRequestSchema.shape.method.value);
49

50
        assert(existingHandler, "No existing handler found for CallToolRequestSchema");
56✔
51

52
        this.mcpServer.server.setRequestHandler(CallToolRequestSchema, (request, extra): Promise<CallToolResult> => {
56✔
53
            if (!request.params.arguments) {
694✔
54
                request.params.arguments = {};
2✔
55
            }
56

57
            return existingHandler(request, extra);
694✔
58
        });
59

60
        await initializeLogger(this.mcpServer, this.userConfig.logPath);
56✔
61

62
        await this.mcpServer.connect(transport);
56✔
63

64
        this.mcpServer.server.oninitialized = () => {
56✔
65
            this.session.setAgentRunner(this.mcpServer.server.getClientVersion());
56✔
66
            this.session.sessionId = new ObjectId().toString();
56✔
67

68
            logger.info(
56✔
69
                LogId.serverInitialized,
70
                "server",
71
                `Server started with transport ${transport.constructor.name} and agent runner ${this.session.agentRunner?.name}`
72
            );
73
        };
74
    }
75

76
    async close(): Promise<void> {
77
        await this.session.close();
56✔
78
        await this.mcpServer.close();
56✔
79
    }
80

81
    private registerTools() {
82
        for (const tool of [...AtlasTools, ...MongoDbTools]) {
56✔
83
            new tool(this.session, this.userConfig, this.telemetry).register(this.mcpServer);
1,680✔
84
        }
85
    }
86

87
    private registerResources() {
88
        this.mcpServer.resource(
56✔
89
            "config",
90
            "config://config",
91
            {
92
                description:
93
                    "Server configuration, supplied by the user either as environment variables or as startup arguments",
94
            },
95
            (uri) => {
NEW
96
                const result = {
×
97
                    telemetry: this.userConfig.telemetry,
98
                    logPath: this.userConfig.logPath,
99
                    connectionString: this.userConfig.connectionString
×
100
                        ? "set; no explicit connect needed, use switch-connection tool to connect to a different connection if necessary"
101
                        : "not set; before using any mongodb tool, you need to call the connect tool with a connection string",
102
                    connectOptions: this.userConfig.connectOptions,
103
                };
NEW
104
                return {
×
105
                    contents: [
106
                        {
107
                            text: JSON.stringify(result),
108
                            uri: uri.href,
109
                        },
110
                    ],
111
                };
112
            }
113
        );
114
        if (this.userConfig.connectionString) {
56✔
115
            this.mcpServer.resource(
2✔
116
                "connection-string",
117
                "config://connection-string",
118
                {
119
                    description: "Preconfigured connection string that will be used as a default in the `connect` tool",
120
                },
121
                (uri) => {
122
                    return {
×
123
                        contents: [
124
                            {
125
                                text: `Preconfigured connection string: ${this.userConfig.connectionString}`,
126
                                uri: uri.href,
127
                            },
128
                        ],
129
                    };
130
                }
131
            );
132
        }
133
    }
134
}
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