Skip to main content
Glama

MongoDB MCP Server

Official
by mongodb-js
createUserConfig.ts6.84 kB
import { type CliOptions, generateConnectionInfoFromCliArgs } from "@mongosh/arg-parser"; import { Keychain } from "../keychain.js"; import type { Secret } from "../keychain.js"; import { matchingConfigKey } from "./configUtils.js"; import { UserConfigSchema, type UserConfig } from "./userConfig.js"; import { defaultParserOptions, parseArgsWithCliOptions, CliOptionsSchema, UnknownArgumentError, } from "@mongosh/arg-parser/arg-parser"; import type { z as z4 } from "zod/v4"; export function createUserConfig({ args }: { args: string[] }): { warnings: string[]; parsed: UserConfig | undefined; error: string | undefined; } { const { error: parseError, warnings, parsed } = parseUserConfigSources(args); if (parseError) { return { error: parseError, warnings, parsed: undefined }; } if (parsed.nodb) { return { error: "Error: The --nodb argument is not supported in the MCP Server. Please remove it from your configuration.", warnings, parsed: undefined, }; } // If we have a connectionSpecifier, which can only appear as the positional // argument, then that has to be used on priority to construct the // connection string. In this case, if there is a connection string provided // by the env variable or config file, that will be overridden. const { connectionSpecifier } = parsed; if (connectionSpecifier) { const connectionInfo = generateConnectionInfoFromCliArgs({ ...parsed, connectionSpecifier }); parsed.connectionString = connectionInfo.connectionString; } const configParseResult = UserConfigSchema.safeParse(parsed); const mongoshArguments = CliOptionsSchema.safeParse(parsed); const error = configParseResult.error || mongoshArguments.error; if (error) { return { error: `Invalid configuration for the following fields:\n${error.issues.map((issue) => `${issue.path.join(".")} - ${issue.message}`).join("\n")}`, warnings, parsed: undefined, }; } // TODO: Separate correctly parsed user config from all other valid // arguments relevant to mongosh's args-parser. const userConfig: UserConfig = { ...parsed, ...configParseResult.data }; registerKnownSecretsInRootKeychain(userConfig); return { parsed: userConfig, warnings, error: undefined, }; } function parseUserConfigSources(cliArguments: string[]): { error: string | undefined; warnings: string[]; parsed: Partial<CliOptions & z4.infer<typeof UserConfigSchema>>; } { let parsed: Partial<CliOptions & z4.infer<typeof UserConfigSchema>>; let deprecated: Record<string, keyof UserConfig>; try { const { parsed: parsedResult, deprecated: deprecatedResult } = parseArgsWithCliOptions({ args: cliArguments, schema: UserConfigSchema, parserOptions: { // This helps parse the relevant environment variables. envPrefix: "MDB_MCP_", configuration: { ...defaultParserOptions.configuration, // To avoid populating `_` with end-of-flag arguments we explicitly // populate `--` variable and altogether ignore them later. "populate--": true, }, }, }); parsed = parsedResult; deprecated = deprecatedResult; // Delete fileNames - this is a field populated by mongosh but not used by us. delete parsed.fileNames; } catch (error) { let errorMessage: string | undefined; if (error instanceof UnknownArgumentError) { const matchingKey = matchingConfigKey(error.argument.replace(/^(--)/, "")); if (matchingKey) { errorMessage = `Error: Invalid command line argument '${error.argument}'. Did you mean '--${matchingKey}'?`; } else { errorMessage = `Error: Invalid command line argument '${error.argument}'.`; } } return { error: errorMessage, warnings: [], parsed: {}, }; } const deprecationWarnings = [ ...getWarnings(parsed, cliArguments), ...Object.entries(deprecated).map(([deprecated, replacement]) => { return `Warning: The --${deprecated} argument is deprecated. Use --${replacement} instead.`; }), ]; return { error: undefined, warnings: deprecationWarnings, parsed, }; } function registerKnownSecretsInRootKeychain(userConfig: Partial<UserConfig>): void { const keychain = Keychain.root; const maybeRegister = (value: string | undefined, kind: Secret["kind"]): void => { if (value) { keychain.register(value, kind); } }; maybeRegister(userConfig.apiClientId, "user"); maybeRegister(userConfig.apiClientSecret, "password"); maybeRegister(userConfig.awsAccessKeyId, "password"); maybeRegister(userConfig.awsIamSessionToken, "password"); maybeRegister(userConfig.awsSecretAccessKey, "password"); maybeRegister(userConfig.awsSessionToken, "password"); maybeRegister(userConfig.password, "password"); maybeRegister(userConfig.tlsCAFile, "url"); maybeRegister(userConfig.tlsCRLFile, "url"); maybeRegister(userConfig.tlsCertificateKeyFile, "url"); maybeRegister(userConfig.tlsCertificateKeyFilePassword, "password"); maybeRegister(userConfig.username, "user"); } function getWarnings(config: Partial<UserConfig>, cliArguments: string[]): string[] { const warnings = []; if (cliArguments.find((argument: string) => argument.startsWith("--connectionString"))) { warnings.push( "Warning: The --connectionString argument is deprecated. Prefer using the MDB_MCP_CONNECTION_STRING environment variable or the first positional argument for the connection string." ); } const searchEnabled = config.previewFeatures?.includes("search"); const embeddingsProviderConfigured = !!config.voyageApiKey; if (searchEnabled && !embeddingsProviderConfigured) { warnings.push(`\ Warning: Vector search is enabled but no embeddings provider is configured. - Set an embeddings provider configuration option to enable auto-embeddings during document insertion and text-based queries with $vectorSearch.\ `); } if (!searchEnabled && embeddingsProviderConfigured) { warnings.push(`\ Warning: An embeddings provider is configured but the 'search' preview feature is not enabled. - Enable vector search by adding 'search' to the 'previewFeatures' configuration option, or remove the embeddings provider configuration if not needed.\ `); } return warnings; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mongodb-js/mongodb-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server