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

mongodb-js / mongodb-mcp-server / 19902400895

03 Dec 2025 05:11PM UTC coverage: 79.891% (-0.7%) from 80.606%
19902400895

Pull #777

github

web-flow
Merge b33f697b4 into b218e57a0
Pull Request #777: chore: adopt strict validation for all command line arguments MCP-298

1447 of 1886 branches covered (76.72%)

Branch coverage included in aggregate %.

75 of 111 new or added lines in 6 files covered. (67.57%)

17 existing lines in 2 files now uncovered.

6598 of 8184 relevant lines covered (80.62%)

77.56 hits per line

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

79.43
/src/common/config/createUserConfig.ts
1
import { type CliOptions, generateConnectionInfoFromCliArgs } from "@mongosh/arg-parser";
1!
2
import { Keychain } from "../keychain.js";
1✔
3
import type { Secret } from "../keychain.js";
4
import { matchingConfigKey } from "./configUtils.js";
1✔
5
import { UserConfigSchema, type UserConfig } from "./userConfig.js";
1✔
6
import {
1✔
7
    defaultParserOptions,
8
    parseArgsWithCliOptions,
9
    CliOptionsSchema,
10
    UnknownArgumentError,
11
} from "@mongosh/arg-parser/arg-parser";
12
import type { z as z4 } from "zod/v4";
13

14
export function createUserConfig({ args }: { args: string[] }): {
1✔
15
    warnings: string[];
16
    parsed: UserConfig | undefined;
17
    error: string | undefined;
18
} {
136✔
19
    const { error: parseError, warnings, parsed } = parseUserConfigSources(args);
136✔
20

21
    if (parseError) {
136!
NEW
22
        return { error: parseError, warnings, parsed: undefined };
×
UNCOV
23
    }
×
24

25
    // If we have a connectionSpecifier, which can only appear as the positional
26
    // argument, then that has to be used on priority to construct the
27
    // connection string. In this case, if there is a connection string provided
28
    // by the env variable or config file, that will be overridden.
29
    const { connectionSpecifier } = parsed;
136✔
30
    if (connectionSpecifier) {
136✔
31
        const connectionInfo = generateConnectionInfoFromCliArgs({ ...parsed, connectionSpecifier });
9✔
32
        parsed.connectionString = connectionInfo.connectionString;
9✔
33
    }
9✔
34

35
    const configParseResult = UserConfigSchema.safeParse(parsed);
136✔
36
    const mongoshArguments = CliOptionsSchema.safeParse(parsed);
136✔
37
    const error = configParseResult.error || mongoshArguments.error;
136✔
38
    if (error) {
136✔
39
        return {
11✔
40
            error: `Invalid configuration for the following fields:\n${error.issues.map((issue) => `${issue.path.join(".")} - ${issue.message}`).join("\n")}`,
11✔
41
            warnings,
11✔
42
            parsed: undefined,
11✔
43
        };
11✔
44
    }
11✔
45

46
    // TODO: Separate correctly parsed user config from all other valid
47
    // arguments relevant to mongosh's args-parser.
48
    const userConfig: UserConfig = { ...parsed, ...configParseResult.data };
125✔
49
    warnings.push(...warnIfVectorSearchNotEnabledCorrectly(userConfig));
125✔
50
    registerKnownSecretsInRootKeychain(userConfig);
125✔
51
    return {
125✔
52
        parsed: userConfig,
125✔
53
        warnings,
125✔
54
        error: undefined,
125✔
55
    };
125✔
56
}
125✔
57

58
function parseUserConfigSources(cliArguments: string[]): {
136✔
59
    error: string | undefined;
60
    warnings: string[];
61
    parsed: Partial<CliOptions & z4.infer<typeof UserConfigSchema>>;
62
} {
136✔
63
    let parsed: Partial<CliOptions & z4.infer<typeof UserConfigSchema>>;
136✔
64
    let deprecated: Record<string, keyof UserConfig>;
136✔
65
    try {
136✔
66
        const { parsed: parsedResult, deprecated: deprecatedResult } = parseArgsWithCliOptions({
136✔
67
            args: cliArguments,
136✔
68
            schema: UserConfigSchema,
136✔
69
            parserOptions: {
136✔
70
                // This helps parse the relevant environment variables.
71
                envPrefix: "MDB_MCP_",
136✔
72
                configuration: {
136✔
73
                    ...defaultParserOptions.configuration,
136✔
74
                    // To avoid populating `_` with end-of-flag arguments we explicitly
75
                    // populate `--` variable and altogether ignore them later.
76
                    "populate--": true,
136✔
77
                },
136✔
78
            },
136✔
79
        });
136✔
80
        parsed = parsedResult;
136✔
81
        deprecated = deprecatedResult;
136✔
82

83
        // Delete fileNames - this is a field populated by mongosh but not used by us.
84
        delete parsed.fileNames;
136✔
85
    } catch (error) {
136!
NEW
86
        let errorMessage: string | undefined;
×
NEW
87
        if (error instanceof UnknownArgumentError) {
×
NEW
88
            const matchingKey = matchingConfigKey(error.argument.replace(/^(--)/, ""));
×
NEW
89
            if (matchingKey) {
×
NEW
90
                errorMessage = `Error: Invalid command line argument '${error.argument}'. Did you mean '--${matchingKey}'?`;
×
NEW
91
            } else {
×
NEW
92
                errorMessage = `Error: Invalid command line argument '${error.argument}'.`;
×
NEW
93
            }
×
NEW
94
        }
×
95

NEW
96
        return {
×
NEW
97
            error: errorMessage,
×
NEW
98
            warnings: [],
×
NEW
99
            parsed: {},
×
NEW
100
        };
×
UNCOV
101
    }
×
102

103
    const deprecationWarnings = [
136✔
104
        ...(cliArguments.find((argument: string) => argument.startsWith("--connectionString"))
136✔
105
            ? [
6✔
106
                  "Warning: The --connectionString argument is deprecated. Prefer using the MDB_MCP_CONNECTION_STRING environment variable or the first positional argument for the connection string.",
6✔
107
              ]
6✔
108
            : []),
130✔
109
        ...Object.entries(deprecated).map(([deprecated, replacement]) => {
136✔
110
            return `Warning: The --${deprecated} argument is deprecated. Use --${replacement} instead.`;
9✔
111
        }),
136✔
112
    ];
136✔
113

114
    return {
136✔
115
        error: undefined,
136✔
116
        warnings: deprecationWarnings,
136✔
117
        parsed,
136✔
118
    };
136✔
119
}
136✔
120

121
function registerKnownSecretsInRootKeychain(userConfig: Partial<UserConfig>): void {
125✔
122
    const keychain = Keychain.root;
125✔
123

124
    const maybeRegister = (value: string | undefined, kind: Secret["kind"]): void => {
125✔
125
        if (value) {
1,500✔
126
            keychain.register(value, kind);
24✔
127
        }
24✔
128
    };
1,500✔
129

130
    maybeRegister(userConfig.apiClientId, "user");
125✔
131
    maybeRegister(userConfig.apiClientSecret, "password");
125✔
132
    maybeRegister(userConfig.awsAccessKeyId, "password");
125✔
133
    maybeRegister(userConfig.awsIamSessionToken, "password");
125✔
134
    maybeRegister(userConfig.awsSecretAccessKey, "password");
125✔
135
    maybeRegister(userConfig.awsSessionToken, "password");
125✔
136
    maybeRegister(userConfig.password, "password");
125✔
137
    maybeRegister(userConfig.tlsCAFile, "url");
125✔
138
    maybeRegister(userConfig.tlsCRLFile, "url");
125✔
139
    maybeRegister(userConfig.tlsCertificateKeyFile, "url");
125✔
140
    maybeRegister(userConfig.tlsCertificateKeyFilePassword, "password");
125✔
141
    maybeRegister(userConfig.username, "user");
125✔
142
}
125✔
143

144
function warnIfVectorSearchNotEnabledCorrectly(config: UserConfig): string[] {
125✔
145
    const searchEnabled = config.previewFeatures.includes("search");
125✔
146
    const embeddingsProviderConfigured = !!config.voyageApiKey;
125✔
147
    const warnings = [];
125✔
148
    if (searchEnabled && !embeddingsProviderConfigured) {
125!
NEW
149
        warnings.push(`\
×
150
Warning: Vector search is enabled but no embeddings provider is configured.
151
- Set an embeddings provider configuration option to enable auto-embeddings during document insertion and text-based queries with $vectorSearch.\
UNCOV
152
`);
×
UNCOV
153
    }
×
154

155
    if (!searchEnabled && embeddingsProviderConfigured) {
125!
NEW
156
        warnings.push(`\
×
157
Warning: An embeddings provider is configured but the 'search' preview feature is not enabled.
158
- Enable vector search by adding 'search' to the 'previewFeatures' configuration option, or remove the embeddings provider configuration if not needed.\
UNCOV
159
`);
×
UNCOV
160
    }
×
161
    return warnings;
125✔
162
}
125✔
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