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

mongodb-js / mongodb-mcp-server / 16271253098

14 Jul 2025 03:37PM UTC coverage: 75.779%. First build
16271253098

Pull #359

github

web-flow
Merge f0a83b00b into b10990b77
Pull Request #359: feat: add streamable http [MCP-55]

388 of 602 branches covered (64.45%)

Branch coverage included in aggregate %.

24 of 30 new or added lines in 2 files covered. (80.0%)

901 of 1099 relevant lines covered (81.98%)

114.56 hits per line

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

62.5
/src/common/config.ts
1
import path from "path";
2
import os from "os";
3
import argv from "yargs-parser";
4

5
import { ReadConcernLevel, ReadPreferenceMode, W } from "mongodb";
6

7
export interface ConnectOptions {
8
    readConcern: ReadConcernLevel;
9
    readPreference: ReadPreferenceMode;
10
    writeConcern: W;
11
    timeoutMS: number;
12
}
13

14
// If we decide to support non-string config options, we'll need to extend the mechanism for parsing
15
// env variables.
16
export interface UserConfig {
17
    apiBaseUrl: string;
18
    apiClientId?: string;
19
    apiClientSecret?: string;
20
    telemetry: "enabled" | "disabled";
21
    logPath: string;
22
    connectionString?: string;
23
    connectOptions: ConnectOptions;
24
    disabledTools: Array<string>;
25
    readOnly?: boolean;
26
    indexCheck?: boolean;
27
    transport: "stdio" | "http";
28
    httpPort: number;
29
    httpHost: string;
30
    loggers: Array<"stderr" | "disk" | "mcp">;
31
}
32

33
const defaults: UserConfig = {
74✔
34
    apiBaseUrl: "https://cloud.mongodb.com/",
35
    logPath: getLogPath(),
36
    connectOptions: {
37
        readConcern: "local",
38
        readPreference: "secondaryPreferred",
39
        writeConcern: "majority",
40
        timeoutMS: 30_000,
41
    },
42
    disabledTools: [],
43
    telemetry: "enabled",
44
    readOnly: false,
45
    indexCheck: false,
46
    transport: "stdio",
47
    httpPort: 3000,
48
    httpHost: "127.0.0.1",
49
    loggers: ["disk", "mcp"],
50
};
51

52
export const config = {
74✔
53
    ...defaults,
54
    ...getEnvConfig(),
55
    ...getCliConfig(),
56
};
57

58
function getLogPath(): string {
59
    const localDataPath =
60
        process.platform === "win32"
74!
61
            ? path.join(process.env.LOCALAPPDATA || process.env.APPDATA || os.homedir(), "mongodb")
×
62
            : path.join(os.homedir(), ".mongodb");
63

64
    const logPath = path.join(localDataPath, "mongodb-mcp", ".app-logs");
74✔
65

66
    return logPath;
74✔
67
}
68

69
// Gets the config supplied by the user as environment variables. The variable names
70
// are prefixed with `MDB_MCP_` and the keys match the UserConfig keys, but are converted
71
// to SNAKE_UPPER_CASE.
72
function getEnvConfig(): Partial<UserConfig> {
73
    function setValue(obj: Record<string, unknown>, path: string[], value: string): void {
74
        const currentField = path.shift();
36✔
75
        if (!currentField) {
36!
76
            return;
×
77
        }
78
        if (path.length === 0) {
36!
79
            const numberValue = Number(value);
36✔
80
            if (!isNaN(numberValue)) {
36!
81
                obj[currentField] = numberValue;
×
82
                return;
×
83
            }
84

85
            const booleanValue = value.toLocaleLowerCase();
36✔
86
            if (booleanValue === "true" || booleanValue === "false") {
36!
87
                obj[currentField] = booleanValue === "true";
×
88
                return;
×
89
            }
90

91
            // Try to parse an array of values
92
            if (value.indexOf(",") !== -1) {
36!
93
                obj[currentField] = value.split(",").map((v) => v.trim());
×
94
                return;
×
95
            }
96

97
            obj[currentField] = value;
36✔
98
            return;
36✔
99
        }
100

101
        if (!obj[currentField]) {
×
102
            obj[currentField] = {};
×
103
        }
104

105
        setValue(obj[currentField] as Record<string, unknown>, path, value);
×
106
    }
107

108
    const result: Record<string, unknown> = {};
74✔
109
    const mcpVariables = Object.entries(process.env).filter(
74✔
110
        ([key, value]) => value !== undefined && key.startsWith("MDB_MCP_")
10,248✔
111
    ) as [string, string][];
112
    for (const [key, value] of mcpVariables) {
74✔
113
        const fieldPath = key
36✔
114
            .replace("MDB_MCP_", "")
115
            .split(".")
116
            .map((part) => SNAKE_CASE_toCamelCase(part));
36✔
117

118
        setValue(result, fieldPath, value);
36✔
119
    }
120

121
    return result;
74✔
122
}
123

124
function SNAKE_CASE_toCamelCase(str: string): string {
125
    return str.toLowerCase().replace(/([-_][a-z])/g, (group) => group.toUpperCase().replace("_", ""));
72✔
126
}
127

128
// Reads the cli args and parses them into a UserConfig object.
129
function getCliConfig() {
130
    return argv(process.argv.slice(2), {
74✔
131
        array: ["disabledTools"],
132
    }) as unknown as Partial<UserConfig>;
133
}
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