Skip to content

Commit b6ade3c

Browse files
chore: have a default connection manager factory
1 parent bea4835 commit b6ade3c

File tree

7 files changed

+41
-23
lines changed

7 files changed

+41
-23
lines changed

eslint-rules/no-config-imports.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ const allowedConfigValueImportFiles = [
1010
"src/index.ts",
1111
// Config resource definition that works with the some config values
1212
"src/resources/common/config.ts",
13+
// The file exports, a factory function to create MCPConnectionManager and
14+
// it relies on driver options generator and default driver options from
15+
// config file.
16+
"src/common/connectionManager.ts",
1317
];
1418

1519
// Ref: https://eslint.org/docs/latest/extend/custom-rules

src/common/connectionManager.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import ConnectionString from "mongodb-connection-string-url";
44
import { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
55
import { type ConnectionInfo, generateConnectionInfoFromCliArgs } from "@mongosh/arg-parser";
66
import type { DeviceId } from "../helpers/deviceId.js";
7-
import type { DriverOptions, UserConfig } from "./config.js";
7+
import { defaultDriverOptions, setupDriverConfig, type DriverOptions, type UserConfig } from "./config.js";
88
import { MongoDBError, ErrorCodes } from "./errors.js";
99
import { type LoggerBase, LogId } from "./logger.js";
1010
import { packageInfo } from "./packageInfo.js";
@@ -360,3 +360,23 @@ export class MCPConnectionManager extends ConnectionManager {
360360
}
361361
}
362362
}
363+
364+
/**
365+
* Consumers of MCP server library have option to bring their own connection
366+
* management if they need to. To support that, we enable injecting connection
367+
* manager implementation through a factory function.
368+
*/
369+
export type ConnectionManagerFactoryFn = (createParams: {
370+
logger: LoggerBase;
371+
deviceId: DeviceId;
372+
userConfig: UserConfig;
373+
}) => Promise<ConnectionManager>;
374+
375+
export const createMCPConnectionManager: ConnectionManagerFactoryFn = ({ logger, deviceId, userConfig }) => {
376+
const driverOptions = setupDriverConfig({
377+
config: userConfig,
378+
defaults: defaultDriverOptions,
379+
});
380+
381+
return Promise.resolve(new MCPConnectionManager(userConfig, driverOptions, logger, deviceId));
382+
};

src/index.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,20 @@ function enableFipsIfRequested(): void {
3636
enableFipsIfRequested();
3737

3838
import { ConsoleLogger, LogId } from "./common/logger.js";
39-
import { config, driverOptions } from "./common/config.js";
39+
import { config } from "./common/config.js";
4040
import crypto from "crypto";
4141
import { packageInfo } from "./common/packageInfo.js";
4242
import { StdioRunner } from "./transports/stdio.js";
4343
import { StreamableHttpRunner } from "./transports/streamableHttp.js";
4444
import { systemCA } from "@mongodb-js/devtools-proxy-support";
45-
import type { ConnectionManagerFactoryFn } from "./transports/base.js";
46-
import { MCPConnectionManager } from "./common/connectionManager.js";
4745

4846
async function main(): Promise<void> {
4947
systemCA().catch(() => undefined); // load system CA asynchronously as in mongosh
5048

5149
assertHelpMode();
5250
assertVersionMode();
5351

54-
const createConnectionManager: ConnectionManagerFactoryFn = ({ logger, deviceId }) =>
55-
Promise.resolve(new MCPConnectionManager(config, driverOptions, logger, deviceId));
56-
57-
const transportRunner =
58-
config.transport === "stdio"
59-
? new StdioRunner(config, createConnectionManager)
60-
: new StreamableHttpRunner(config, createConnectionManager);
52+
const transportRunner = config.transport === "stdio" ? new StdioRunner(config) : new StreamableHttpRunner(config);
6153
const shutdown = (): void => {
6254
transportRunner.logger.info({
6355
id: LogId.serverCloseRequested,

src/lib.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ export { Session, type SessionOptions } from "./common/session.js";
33
export { defaultUserConfig, type UserConfig } from "./common/config.js";
44
export { LoggerBase, type LogPayload, type LoggerType, type LogLevel } from "./common/logger.js";
55
export { StreamableHttpRunner } from "./transports/streamableHttp.js";
6-
export { type ConnectionManagerFactoryFn } from "./transports/base.js";
76
export {
87
ConnectionManager,
98
type AnyConnectionState,
109
type ConnectionState,
1110
type ConnectionStateDisconnected,
11+
type ConnectionStateErrored,
12+
type ConnectionManagerFactoryFn,
1213
} from "./common/connectionManager.js";
1314
export { Telemetry } from "./telemetry/telemetry.js";

src/transports/base.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,8 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
77
import type { LoggerBase } from "../common/logger.js";
88
import { CompositeLogger, ConsoleLogger, DiskLogger, McpLogger } from "../common/logger.js";
99
import { ExportsManager } from "../common/exportsManager.js";
10-
import type { ConnectionManager } from "../common/connectionManager.js";
1110
import { DeviceId } from "../helpers/deviceId.js";
12-
13-
export type ConnectionManagerFactoryFn = (createParams: {
14-
logger: LoggerBase;
15-
deviceId: DeviceId;
16-
}) => Promise<ConnectionManager>;
11+
import { type ConnectionManagerFactoryFn } from "../common/connectionManager.js";
1712

1813
export abstract class TransportRunnerBase {
1914
public logger: LoggerBase;
@@ -51,7 +46,11 @@ export abstract class TransportRunnerBase {
5146

5247
const logger = new CompositeLogger(this.logger);
5348
const exportsManager = ExportsManager.init(this.userConfig, logger);
54-
const connectionManager = await this.createConnectionManager({ logger, deviceId: this.deviceId });
49+
const connectionManager = await this.createConnectionManager({
50+
logger,
51+
userConfig: this.userConfig,
52+
deviceId: this.deviceId,
53+
});
5554

5655
const session = new Session({
5756
apiBaseUrl: this.userConfig.apiBaseUrl,

src/transports/stdio.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import { JSONRPCMessageSchema } from "@modelcontextprotocol/sdk/types.js";
44
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
55
import { type LoggerBase, LogId } from "../common/logger.js";
66
import type { Server } from "../server.js";
7-
import { type ConnectionManagerFactoryFn, TransportRunnerBase } from "./base.js";
7+
import { TransportRunnerBase } from "./base.js";
88
import { type UserConfig } from "../common/config.js";
9+
import { createMCPConnectionManager, type ConnectionManagerFactoryFn } from "../common/connectionManager.js";
910

1011
// This is almost a copy of ReadBuffer from @modelcontextprotocol/sdk
1112
// but it uses EJSON.parse instead of JSON.parse to handle BSON types
@@ -56,7 +57,7 @@ export class StdioRunner extends TransportRunnerBase {
5657

5758
constructor(
5859
userConfig: UserConfig,
59-
createConnectionManager: ConnectionManagerFactoryFn,
60+
createConnectionManager: ConnectionManagerFactoryFn = createMCPConnectionManager,
6061
additionalLoggers: LoggerBase[] = []
6162
) {
6263
super(userConfig, createConnectionManager, additionalLoggers);

src/transports/streamableHttp.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
66
import { LogId, type LoggerBase } from "../common/logger.js";
77
import { type UserConfig } from "../common/config.js";
88
import { SessionStore } from "../common/sessionStore.js";
9-
import { type ConnectionManagerFactoryFn, TransportRunnerBase } from "./base.js";
9+
import { TransportRunnerBase } from "./base.js";
10+
import { createMCPConnectionManager, type ConnectionManagerFactoryFn } from "../common/connectionManager.js";
1011

1112
const JSON_RPC_ERROR_CODE_PROCESSING_REQUEST_FAILED = -32000;
1213
const JSON_RPC_ERROR_CODE_SESSION_ID_REQUIRED = -32001;
@@ -20,7 +21,7 @@ export class StreamableHttpRunner extends TransportRunnerBase {
2021

2122
constructor(
2223
userConfig: UserConfig,
23-
createConnectionManager: ConnectionManagerFactoryFn,
24+
createConnectionManager: ConnectionManagerFactoryFn = createMCPConnectionManager,
2425
additionalLoggers: LoggerBase[] = []
2526
) {
2627
super(userConfig, createConnectionManager, additionalLoggers);

0 commit comments

Comments
 (0)