Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/generateArguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { fileURLToPath } from "url";
import { UserConfigSchema, configRegistry } from "../src/common/config.js";
import assert from "assert";
import { execSync } from "child_process";
import { OPTIONS } from "../src/common/argsParserOptions.js";
import { OPTIONS } from "../src/common/config/argsParserOptions.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Expand Down
34 changes: 3 additions & 31 deletions src/common/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import argv from "yargs-parser";
import type { CliOptions, ConnectionInfo } from "@mongosh/arg-parser";
import type { CliOptions } from "@mongosh/arg-parser";
import { generateConnectionInfoFromCliArgs } from "@mongosh/arg-parser";
import { Keychain } from "./keychain.js";
import type { Secret } from "./keychain.js";
Expand All @@ -11,8 +11,8 @@ import {
getLogPath,
isConnectionSpecifier,
validateConfigKey,
} from "./configUtils.js";
import { OPTIONS } from "./argsParserOptions.js";
} from "./config/configUtils.js";
import { OPTIONS } from "./config/argsParserOptions.js";
import { similarityValues, previewFeatureValues } from "./schemas.js";

export const configRegistry = z4.registry<ConfigFieldMeta>();
Expand Down Expand Up @@ -183,20 +183,6 @@ export const config = setupUserConfig({
env: process.env,
});

export type DriverOptions = ConnectionInfo["driverOptions"];
export const defaultDriverOptions: DriverOptions = {
readConcern: {
level: "local",
},
readPreference: "secondaryPreferred",
writeConcern: {
w: "majority",
},
timeoutMS: 30_000,
proxy: { useEnvironmentVariableProxies: true },
applyProxyToOIDC: true,
};

// Gets the config supplied by the user as environment variables. The variable names
// are prefixed with `MDB_MCP_` and the keys match the UserConfig keys, but are converted
// to SNAKE_UPPER_CASE.
Expand Down Expand Up @@ -414,17 +400,3 @@ export function setupUserConfig({ cli, env }: { cli: string[]; env: Record<strin
registerKnownSecretsInRootKeychain(userConfig);
return userConfig;
}

export function setupDriverConfig({
config,
defaults,
}: {
config: UserConfig;
defaults: Partial<DriverOptions>;
}): DriverOptions {
const { driverOptions } = generateConnectionInfoFromCliArgs(config);
return {
...defaults,
...driverOptions,
};
}
File renamed without changes.
26 changes: 9 additions & 17 deletions src/common/connectionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { EventEmitter } from "events";
import type { MongoClientOptions } from "mongodb";
import { ConnectionString } from "mongodb-connection-string-url";
import { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
import { type ConnectionInfo, generateConnectionInfoFromCliArgs } from "@mongosh/arg-parser";
import { type ConnectionInfo } from "@mongosh/arg-parser";
import type { DeviceId } from "../helpers/deviceId.js";
import { defaultDriverOptions, setupDriverConfig, type DriverOptions, type UserConfig } from "./config.js";
import { type UserConfig } from "./config.js";
import { MongoDBError, ErrorCodes } from "./errors.js";
import { type LoggerBase, LogId } from "./logger.js";
import { packageInfo } from "./packageInfo.js";
Expand All @@ -17,8 +17,8 @@ export interface AtlasClusterConnectionInfo {
expiryDate: Date;
}

export interface ConnectionSettings {
connectionString: string;
export interface ConnectionSettings extends Omit<ConnectionInfo, "driverOptions"> {
driverOptions?: ConnectionInfo["driverOptions"];
atlas?: AtlasClusterConnectionInfo;
}

Expand Down Expand Up @@ -136,7 +136,6 @@ export class MCPConnectionManager extends ConnectionManager {

constructor(
private userConfig: UserConfig,
private driverOptions: DriverOptions,
private logger: LoggerBase,
deviceId: DeviceId,
bus?: EventEmitter
Expand All @@ -157,7 +156,6 @@ export class MCPConnectionManager extends ConnectionManager {
}

let serviceProvider: Promise<NodeDriverServiceProvider>;
let connectionInfo: ConnectionInfo;
let connectionStringAuthType: ConnectionStringAuthType = "scram";

try {
Expand All @@ -173,11 +171,10 @@ export class MCPConnectionManager extends ConnectionManager {
components: appNameComponents,
});

connectionInfo = generateConnectionInfoFromCliArgs({
...this.userConfig,
...this.driverOptions,
connectionSpecifier: settings.connectionString,
});
const connectionInfo = {
connectionString: settings.connectionString,
driverOptions: settings.driverOptions ?? {},
};

if (connectionInfo.driverOptions.oidc) {
connectionInfo.driverOptions.oidc.allowedFlows ??= ["auth-code"];
Expand Down Expand Up @@ -394,10 +391,5 @@ export type ConnectionManagerFactoryFn = (createParams: {
}) => Promise<ConnectionManager>;

export const createMCPConnectionManager: ConnectionManagerFactoryFn = ({ logger, deviceId, userConfig }) => {
const driverOptions = setupDriverConfig({
config: userConfig,
defaults: defaultDriverOptions,
});

return Promise.resolve(new MCPConnectionManager(userConfig, driverOptions, logger, deviceId));
return Promise.resolve(new MCPConnectionManager(userConfig, logger, deviceId));
};
7 changes: 4 additions & 3 deletions src/resources/common/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ReactiveResource } from "../resource.js";
import { defaultDriverOptions } from "../../common/config.js";
import type { UserConfig } from "../../common/config.js";
import type { Telemetry } from "../../telemetry/telemetry.js";
import type { Session } from "../../lib.js";
import { generateConnectionInfoFromCliArgs } from "@mongosh/arg-parser";

export class ConfigResource extends ReactiveResource<UserConfig, readonly []> {
constructor(session: Session, config: UserConfig, telemetry: Telemetry) {
Expand Down Expand Up @@ -32,13 +32,14 @@ export class ConfigResource extends ReactiveResource<UserConfig, readonly []> {
}

toOutput(): string {
const connectionInfo = generateConnectionInfoFromCliArgs(this.current);
const result = {
telemetry: this.current.telemetry,
logPath: this.current.logPath,
connectionString: this.current.connectionString
connectionString: connectionInfo.connectionString
? "set; access to MongoDB tools are currently available to use"
: "not set; before using any MongoDB tool, you need to configure a connection string, alternatively you can setup MongoDB Atlas access, more info at 'https://github.com/mongodb-js/mongodb-mcp-server'.",
connectOptions: defaultDriverOptions,
connectOptions: connectionInfo.driverOptions,
atlas:
this.current.apiClientId && this.current.apiClientSecret
? "set; MongoDB Atlas tools are currently available to use"
Expand Down
7 changes: 5 additions & 2 deletions src/server.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { generateConnectionInfoFromCliArgs } from "@mongosh/arg-parser";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import type { Session } from "./common/session.js";
import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
Expand Down Expand Up @@ -308,9 +309,11 @@ export class Server {
context: "server",
message: `Detected a MongoDB connection string in the configuration, trying to connect...`,
});
await this.session.connectToMongoDB({
connectionString: this.userConfig.connectionString,
const connectionInfo = generateConnectionInfoFromCliArgs({
...this.userConfig,
connectionSpecifier: this.userConfig.connectionString,
});
await this.session.connectToMongoDB(connectionInfo);
} catch (error) {
// We don't throw an error here because we want to allow the server to start even if the connection string is invalid.
this.session.logger.error({
Expand Down
Loading
Loading