Skip to main content
Glama
mongodb-js

MongoDB MCP Server

Official
by mongodb-js
server.test.ts9.35 kB
import { MCPConnectionManager } from "../../src/common/connectionManager.js"; import { ExportsManager } from "../../src/common/exportsManager.js"; import { CompositeLogger } from "../../src/common/logger.js"; import { DeviceId } from "../../src/helpers/deviceId.js"; import { Session } from "../../src/common/session.js"; import { defaultTestConfig, expectDefined } from "./helpers.js"; import { describeWithMongoDB } from "./tools/mongodb/mongodbHelpers.js"; import { afterEach, describe, expect, it } from "vitest"; import { Elicitation, Keychain, Telemetry } from "../../src/lib.js"; import { VectorSearchEmbeddingsManager } from "../../src/common/search/vectorSearchEmbeddingsManager.js"; import { defaultCreateAtlasLocalClient } from "../../src/common/atlasLocal.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { Server } from "../../src/server.js"; import { connectionErrorHandler } from "../../src/common/connectionErrorHandler.js"; import { type OperationType, ToolBase, type ToolCategory, type ToolClass } from "../../src/tools/tool.js"; import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; import type { TelemetryToolMetadata } from "../../src/telemetry/types.js"; import { InMemoryTransport } from "../../src/transports/inMemoryTransport.js"; import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; class TestToolOne extends ToolBase { public name = "test-tool-one"; protected description = "A test tool one for verification tests"; static category: ToolCategory = "mongodb"; static operationType: OperationType = "delete"; protected argsShape = {}; protected async execute(): Promise<CallToolResult> { return Promise.resolve({ content: [ { type: "text", text: "Test tool one executed successfully", }, ], }); } protected resolveTelemetryMetadata(): TelemetryToolMetadata { return {}; } } class TestToolTwo extends ToolBase { public name = "test-tool-two"; protected description = "A test tool two for verification tests"; static category: ToolCategory = "mongodb"; static operationType: OperationType = "delete"; protected argsShape = {}; protected async execute(): Promise<CallToolResult> { return Promise.resolve({ content: [ { type: "text", text: "Test tool two executed successfully", }, ], }); } protected resolveTelemetryMetadata(): TelemetryToolMetadata { return {}; } } describe("Server integration test", () => { describeWithMongoDB( "without atlas", (integration) => { it("should return positive number of tools and have no atlas tools", async () => { const tools = await integration.mcpClient().listTools(); expectDefined(tools); expect(tools.tools.length).toBeGreaterThan(0); const atlasTools = tools.tools.filter( (tool) => tool.name.startsWith("atlas-") && !tool.name.startsWith("atlas-local-") ); expect(atlasTools.length).toBeLessThanOrEqual(0); }); }, { getUserConfig: () => ({ ...defaultTestConfig, apiClientId: undefined, apiClientSecret: undefined, }), } ); describeWithMongoDB( "with atlas", (integration) => { describe("list capabilities", () => { it("should return positive number of tools and have some atlas tools", async () => { const tools = await integration.mcpClient().listTools(); expectDefined(tools); expect(tools.tools.length).toBeGreaterThan(0); const atlasTools = tools.tools.filter((tool) => tool.name.startsWith("atlas-")); expect(atlasTools.length).toBeGreaterThan(0); }); it("should return no prompts", async () => { await expect(() => integration.mcpClient().listPrompts()).rejects.toMatchObject({ message: "MCP error -32601: Method not found", }); }); it("should return capabilities", () => { const capabilities = integration.mcpClient().getServerCapabilities(); expectDefined(capabilities); expectDefined(capabilities?.logging); expectDefined(capabilities?.completions); expectDefined(capabilities?.tools); expectDefined(capabilities?.resources); expect(capabilities.experimental).toBeUndefined(); expect(capabilities.prompts).toBeUndefined(); }); }); }, { getUserConfig: () => ({ ...defaultTestConfig, apiClientId: "test", apiClientSecret: "test", }), } ); describeWithMongoDB( "with read-only mode", (integration) => { it("should only register read and metadata operation tools when read-only mode is enabled", async () => { const tools = await integration.mcpClient().listTools(); expectDefined(tools); expect(tools.tools.length).toBeGreaterThan(0); // Check that we have some tools available (the read and metadata ones) expect(tools.tools.some((tool) => tool.name === "find")).toBe(true); expect(tools.tools.some((tool) => tool.name === "collection-schema")).toBe(true); expect(tools.tools.some((tool) => tool.name === "list-databases")).toBe(true); expect(tools.tools.some((tool) => tool.name === "atlas-list-orgs")).toBe(true); expect(tools.tools.some((tool) => tool.name === "atlas-list-projects")).toBe(true); // Check that non-read tools are NOT available expect(tools.tools.some((tool) => tool.name === "insert-many")).toBe(false); expect(tools.tools.some((tool) => tool.name === "update-many")).toBe(false); expect(tools.tools.some((tool) => tool.name === "delete-many")).toBe(false); expect(tools.tools.some((tool) => tool.name === "drop-collection")).toBe(false); }); }, { getUserConfig: () => ({ ...defaultTestConfig, readOnly: true, apiClientId: "test", apiClientSecret: "test", }), } ); describe("with additional tools", () => { const initServerWithTools = async (tools: ToolClass[]): Promise<{ server: Server; transport: Transport }> => { const logger = new CompositeLogger(); const deviceId = DeviceId.create(logger); const connectionManager = new MCPConnectionManager(defaultTestConfig, logger, deviceId); const exportsManager = ExportsManager.init(defaultTestConfig, logger); const session = new Session({ userConfig: defaultTestConfig, logger, exportsManager, connectionManager, keychain: Keychain.root, vectorSearchEmbeddingsManager: new VectorSearchEmbeddingsManager(defaultTestConfig, connectionManager), atlasLocalClient: await defaultCreateAtlasLocalClient(), }); const telemetry = Telemetry.create(session, defaultTestConfig, deviceId); const mcpServerInstance = new McpServer({ name: "test", version: "1.0" }); const elicitation = new Elicitation({ server: mcpServerInstance.server }); const server = new Server({ session, userConfig: defaultTestConfig, telemetry, mcpServer: mcpServerInstance, elicitation, connectionErrorHandler, tools: [...tools], }); const transport = new InMemoryTransport(); return { transport, server }; }; let server: Server | undefined; let transport: Transport | undefined; afterEach(async () => { await transport?.close(); }); it("should start server with only the tools provided", async () => { ({ server, transport } = await initServerWithTools([TestToolOne])); await server.connect(transport); expect(server.tools).toHaveLength(1); }); it("should throw error before starting when provided tools have name conflict", async () => { ({ server, transport } = await initServerWithTools([ TestToolOne, class TestToolTwoButOne extends TestToolTwo { public name = "test-tool-one"; }, ])); await expect(server.connect(transport)).rejects.toThrow(/Tool test-tool-one is already registered/); }); }); });

Latest Blog Posts

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