Skip to main content
Glama

MongoDB MCP Server

Official
by mongodb-js
mongodbClusterProcess.ts4.67 kB
import fs from "fs/promises"; import path from "path"; import type { MongoClusterOptions } from "mongodb-runner"; import { GenericContainer } from "testcontainers"; import { MongoCluster } from "mongodb-runner"; import { ShellWaitStrategy } from "testcontainers/build/wait-strategies/shell-wait-strategy.js"; export type MongoRunnerConfiguration = { runner: true; downloadOptions: MongoClusterOptions["downloadOptions"]; serverArgs: string[]; }; export type MongoSearchConfiguration = { search: true; image?: string }; export type MongoClusterConfiguration = MongoRunnerConfiguration | MongoSearchConfiguration; const DOWNLOAD_RETRIES = 10; const DEFAULT_LOCAL_IMAGE = "mongodb/mongodb-atlas-local:8"; export class MongoDBClusterProcess { static async spinUp(config: MongoClusterConfiguration): Promise<MongoDBClusterProcess> { if (MongoDBClusterProcess.isSearchOptions(config)) { const runningContainer = await new GenericContainer(config.image ?? DEFAULT_LOCAL_IMAGE) .withExposedPorts(27017) .withCommand(["/usr/local/bin/runner", "server"]) .withWaitStrategy(new ShellWaitStrategy(`mongosh --eval 'db.test.getSearchIndexes()'`)) .start(); return new MongoDBClusterProcess( () => runningContainer.stop(), () => `mongodb://${runningContainer.getHost()}:${runningContainer.getMappedPort(27017)}/?directConnection=true` ); } else if (MongoDBClusterProcess.isMongoRunnerOptions(config)) { const { downloadOptions, serverArgs } = config; const tmpDir = path.join(__dirname, "..", "..", "..", "tmp"); await fs.mkdir(tmpDir, { recursive: true }); let dbsDir = path.join(tmpDir, "mongodb-runner", "dbs"); for (let i = 0; i < DOWNLOAD_RETRIES; i++) { try { const mongoCluster = await MongoCluster.start({ tmpDir: dbsDir, logDir: path.join(tmpDir, "mongodb-runner", "logs"), topology: "standalone", version: downloadOptions?.version ?? "8.0.12", downloadOptions, args: serverArgs, }); return new MongoDBClusterProcess( () => mongoCluster.close(), () => mongoCluster.connectionString ); } catch (err) { if (i < 5) { // Just wait a little bit and retry // eslint-disable-next-line @typescript-eslint/restrict-template-expressions console.error(`Failed to start cluster in ${dbsDir}, attempt ${i}: ${err}`); await new Promise((resolve) => setTimeout(resolve, 1000)); } else { // If we still fail after 5 seconds, try another db dir console.error( // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Failed to start cluster in ${dbsDir}, attempt ${i}: ${err}. Retrying with a new db dir.` ); dbsDir = path.join(tmpDir, "mongodb-runner", `dbs${i - 5}`); } } } throw new Error(`Could not download cluster with configuration: ${JSON.stringify(config)}`); } else { throw new Error(`Unsupported configuration: ${JSON.stringify(config)}`); } } private constructor( private readonly tearDownFunction: () => Promise<unknown>, private readonly connectionStringFunction: () => string ) {} connectionString(): string { return this.connectionStringFunction(); } async close(): Promise<void> { await this.tearDownFunction(); } static isConfigurationSupportedInCurrentEnv(config: MongoClusterConfiguration): boolean { if (MongoDBClusterProcess.isSearchOptions(config) && process.env.GITHUB_ACTIONS === "true") { return process.platform === "linux"; } return true; } private static isSearchOptions(opt: MongoClusterConfiguration): opt is MongoSearchConfiguration { return (opt as MongoSearchConfiguration)?.search === true; } private static isMongoRunnerOptions(opt: MongoClusterConfiguration): opt is MongoRunnerConfiguration { return (opt as MongoRunnerConfiguration)?.runner === true; } }

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