@@ -2,11 +2,17 @@ import { z } from "zod";
22import { CallToolResult } from "@modelcontextprotocol/sdk/types.js" ;
33import { AtlasToolBase } from "../atlasTool.js" ;
44import { ToolArgs , OperationType } from "../../tool.js" ;
5- import { sleep } from "../../../common/utils.js" ;
5+ import { randomBytes } from "crypto" ;
6+ import { promisify } from "util" ;
67
7- function generateSecurePassword ( ) : string {
8- // TODO: use a better password generator
9- return `pwdMcp${ Math . floor ( Math . random ( ) * 100000 ) } ` ;
8+ const EXPIRY_MS = 1000 * 60 * 60 * 12 ; // 12 hours
9+
10+ const randomBytesAsync = promisify ( randomBytes ) ;
11+
12+ async function generateSecurePassword ( ) : Promise < string > {
13+ const buf = await randomBytesAsync ( 16 ) ;
14+ const pass = buf . toString ( "base64url" ) ;
15+ return pass ;
1016}
1117
1218export class ConnectClusterTool extends AtlasToolBase {
@@ -19,6 +25,8 @@ export class ConnectClusterTool extends AtlasToolBase {
1925 } ;
2026
2127 protected async execute ( { projectId, clusterName } : ToolArgs < typeof this . argsShape > ) : Promise < CallToolResult > {
28+ await this . session . disconnect ( ) ;
29+
2230 const cluster = await this . session . apiClient . getCluster ( {
2331 params : {
2432 path : {
@@ -32,15 +40,16 @@ export class ConnectClusterTool extends AtlasToolBase {
3240 throw new Error ( "Cluster not found" ) ;
3341 }
3442
35- if ( ! cluster . connectionStrings ?. standardSrv || ! cluster . connectionStrings ?. standard ) {
43+ const baseConnectionString = cluster . connectionStrings ?. standardSrv || cluster . connectionStrings ?. standard ;
44+
45+ if ( ! baseConnectionString ) {
3646 throw new Error ( "Connection string not available" ) ;
3747 }
3848
3949 const username = `usrMcp${ Math . floor ( Math . random ( ) * 100000 ) } ` ;
40- const password = generateSecurePassword ( ) ;
50+ const password = await generateSecurePassword ( ) ;
4151
42- const expiryMs = 1000 * 60 * 60 * 12 ; // 12 hours
43- const expiryDate = new Date ( Date . now ( ) + expiryMs ) ;
52+ const expiryDate = new Date ( Date . now ( ) + EXPIRY_MS ) ;
4453
4554 await this . session . apiClient . createDatabaseUser ( {
4655 params : {
@@ -68,19 +77,18 @@ export class ConnectClusterTool extends AtlasToolBase {
6877 } ,
6978 } ) ;
7079
71- void sleep ( expiryMs ) . then ( async ( ) => {
72- // disconnect after 12 hours
73- if ( this . session . serviceProvider ) {
74- await this . session . serviceProvider . close ( true ) ;
75- this . session . serviceProvider = undefined ;
76- }
77- } ) ;
80+ this . session . connectedAtlasCluster = {
81+ username,
82+ projectId,
83+ clusterName,
84+ expiryDate,
85+ } ;
7886
79- const connectionString =
80- ( cluster . connectionStrings . standardSrv || cluster . connectionStrings . standard || "" ) . replace (
81- "://" ,
82- `:// ${ username } : ${ password } @`
83- ) + `?authSource=admin` ;
87+ const cn = new URL ( baseConnectionString ) ;
88+ cn . username = username ;
89+ cn . password = password ;
90+ cn . searchParams . set ( "authSource" , "admin" ) ;
91+ const connectionString = cn . toString ( ) ;
8492
8593 await this . connectToMongoDB ( connectionString ) ;
8694
0 commit comments