Skip to content

Conversation

@gagik
Copy link
Collaborator

@gagik gagik commented Dec 2, 2025

This will not work until mongodb-js/mongosh#2589 is released but making it available for early reviews.

This gets rid of our hardcoded dependency on OPTIONS for both internal and mongosh-related argument parsing and instead relies completely on our (and mongosh's) Zod schema.

This provides the following advantages:

  1. We no longer need to manually append the OPTIONS array when adding new config fields which is easy to forget. This actually revealed that we had forgotten to add i.e. vectorSearchDimensions to this array before because of the redundancy involved.
  2. We can reliably validate both our and mongosh argument types.
  3. We can ensure we're keep up with changes to mongosh's connection string cases.
  4. We get "out-of-the-box" support for more complex types like objects with --object.field=3 which would otherwise have require us to manually specify different scenarios in the OPTIONS array.

As a consequence of some of these advantages, this PR also...:

  1. Adds support to set httpHeaders using the CLI (or env), either as --httpHeaders='{ "test": "1" }' or --httpHeaders.test='1'!
  2. Better alignment with some of the mongosh logic - for example ssl-related fields actually get replaced with tls equivalents; and some fields are also unsupported. We would correctly throw an error in this case (which we weren't doing before).
  3. We likely got some new type checking options now.

Some considerations:

  1. For the future, we might want to consider adopting a subset of mongosh's arguments; in that case it's important to make sure that this subset can cover all usecases.
  2. There's a general risk of clashing names. For example readonly exists in both. By default our configuration takes precedence; just something to keep in mind

@gagik gagik requested a review from a team as a code owner December 2, 2025 18:35
Copilot AI review requested due to automatic review settings December 2, 2025 18:35
@gagik gagik marked this pull request as draft December 2, 2025 18:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adopts strict validation for command-line arguments by relying entirely on Zod schemas instead of hardcoded OPTIONS configurations, eliminating redundancy and enabling type-safe argument parsing for both internal and mongosh-related arguments.

Key changes include:

  • Removal of manual OPTIONS array and the argsParserOptions.ts file
  • Integration with @mongosh/arg-parser for unified CLI argument parsing
  • Support for complex types like objects via CLI (e.g., --httpHeaders='{"test":"1"}' or --httpHeaders.test='1')
  • Better alignment with mongosh's connection string handling (e.g., ssl arguments map to tls equivalents)
  • Improved error handling that returns structured validation results instead of directly calling process.exit()

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tsconfig.cjs.json Updated module system from commonjs to node16
tests/utils/index.ts Added createEnvironment helper for managing test environment variables
tests/unit/common/config.test.ts Refactored tests to use new createUserConfig API returning structured results instead of throwing errors
tests/e2e/e2eUtils.ts Added CLI runner utility for e2e tests
tests/e2e/cli.test.ts Converted warning/error tests from unit to e2e tests
src/index.ts Updated to handle structured validation results from createUserConfig
src/common/config/userConfig.ts Introduced UserConfigSchemaWithCliOptions merging internal and mongosh schemas
src/common/config/createUserConfig.ts Replaced manual argument parsing with parseArgsWithCliOptions from mongosh
src/common/config/configUtils.ts Removed isConnectionSpecifier function, now handled by mongosh
src/common/config/argsParserOptions.ts Deleted file - manual OPTIONS array no longer needed
server.json Updated format fields to correct types (boolean/number instead of string) and added missing configuration options
scripts/generateArguments.ts Updated to derive argument types from Zod schemas instead of OPTIONS
scripts/apply.ts Migrated from yargs-parser to @mongosh/arg-parser
package.json Removed yargs-parser dependency
eslint-rules/enforce-zod-v4.js Added createUserConfig.ts to allowed files for zod/v4 imports
README.md Updated configuration table with new/corrected options

.DS_Store

# Development tool files
.yalc
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like yalc so would be great if this is gitgnored

gagik and others added 2 commits December 2, 2025 19:44
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
});
});

describe("Warning and Error messages", () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to e2e tests instead

- Refer to https://www.mongodb.com/docs/mcp-server/get-started/ for setting up the MCP Server.
`;
onError(errorMessage);
return closeProcess(1);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed this callback-based logic to instead be returning information to be used at a higher level

{
cli: ["--sslCertificateSelector", "pem=pom"],
expected: { sslCertificateSelector: "pem=pom" },
expected: { tlsCertificateSelector: "pem=pom" },
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is what the actually happens in mongosh since ssl arguments are deprecated

"description": "Idle timeout for a client to disconnect (only applies to http transport).",
"isRequired": false,
"format": "string",
"format": "number",
Copy link
Collaborator Author

@gagik gagik Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like there were some issues with the server.json generation before 🤷

@gagik gagik marked this pull request as ready for review December 3, 2025 12:17
Comment on lines 221 to 224
export const UserConfigSchemaWithCliOptions = z4.object({
...UserConfigSchema.shape,
...CliOptionsSchema.shape,
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to at-least deprecate nodb here otherwise that will hinder the rightful parsing of a connection specifier.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gagik did you find a way to deprecate this? I notice that we now have a warning message but the argument still end up deflecting the positional connection string.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deprecation to me means the behavior continues to work. We warn them to remove this so we can eventually throw an error. Otherwise we're breaking behavior

Copy link
Collaborator

@himanshusinghs himanshusinghs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are amazing changes @gagik. I left one additional note for tsconfig consideration.

import { join, dirname } from "path";
import { fileURLToPath } from "url";
import { UserConfigSchema, configRegistry } from "../src/common/config/userConfig.js";
import { UserConfigSchemaWithCliOptions, configRegistry } from "../src/common/config/userConfig.js";
Copy link
Collaborator

@himanshusinghs himanshusinghs Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using the UserConfig schema together with CliOptions schema, yet, in the final server.json I don't see the entries from CliOptions schema? We should expect those right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmmm..... I guess in server.json we should; should we have any fields in the README?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's follow-up on this. otherwise we're going to dump a bunch of unrelated fields into it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea - I am also unsure if they deserve a place in server.json and README but worth noting that somehow with this script they don't end up there. Happy to address this as a follow up.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is existing behavior and I think the code is self-explanatory, let's follow up on this later

@coveralls
Copy link
Collaborator

coveralls commented Dec 3, 2025

Pull Request Test Coverage Report for Build 19928292758

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 82 of 121 (67.77%) changed or added relevant lines in 8 files are covered.
  • 18 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.4%) to 80.172%

Changes Missing Coverage Covered Lines Changed/Added Lines %
eslint.config.js 0 1 0.0%
src/index.ts 0 16 0.0%
src/common/config/createUserConfig.ts 62 84 73.81%
Files with Coverage Reduction New Missed Lines %
src/common/config/createUserConfig.ts 7 75.17%
src/common/config/configUtils.ts 11 84.66%
Totals Coverage Status
Change from base Build 19925770219: -0.4%
Covered Lines: 6640
Relevant Lines: 8200

💛 - Coveralls

Co-authored-by: Himanshu Singh <himanshu.singhs@outlook.in>
@gagik gagik force-pushed the gagik/parse-mongosh branch 2 times, most recently from a5438af to b009bb3 Compare December 4, 2025 11:02
}

if (parsed.nodb) {
return {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ended up being more manual because of some mongosh type integrity stuff. We will need to follow-up to make this and more arguments use a subset of functionality

@gagik gagik force-pushed the gagik/parse-mongosh branch from b009bb3 to 9263486 Compare December 4, 2025 11:06
Copy link
Collaborator

@himanshusinghs himanshusinghs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noice 🚀

@gagik gagik force-pushed the gagik/parse-mongosh branch from fad86b9 to 52b5c39 Compare December 4, 2025 11:39
@gagik gagik enabled auto-merge (squash) December 4, 2025 12:06
@gagik gagik merged commit 8b9cc4e into main Dec 4, 2025
17 checks passed
@gagik gagik deleted the gagik/parse-mongosh branch December 4, 2025 12:06
Copy link
Collaborator

@cveticm cveticm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM and thanks for the descriptive summary, gave great context on the issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants