Skip to main content
Glama

MongoDB MCP Server

Official
by mongodb-js
exportedData.test.ts8.28 kB
import path from "path"; import fs from "fs/promises"; import { EJSON, Long, ObjectId } from "bson"; import { describe, expect, it, beforeEach, afterAll } from "vitest"; import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; import { defaultTestConfig, getDataFromUntrustedContent, resourceChangedNotification, timeout } from "../helpers.js"; import { describeWithMongoDB } from "../tools/mongodb/mongodbHelpers.js"; import { contentWithResourceURILink } from "../tools/mongodb/read/export.test.js"; import type { UserConfig } from "../../../src/lib.js"; const userConfig: UserConfig = { ...defaultTestConfig, exportsPath: path.join(path.dirname(defaultTestConfig.exportsPath), `exports-${Date.now()}`), exportTimeoutMs: 200, exportCleanupIntervalMs: 300, }; describeWithMongoDB( "exported-data resource", (integration) => { let docs: { _id: ObjectId; name: string; longNumber?: Long; bigInt?: Long }[]; let collection: string; beforeEach(async () => { const mongoClient = integration.mongoClient(); collection = new ObjectId().toString(); docs = [ { name: "foo", longNumber: new Long(1234), _id: new ObjectId() }, { name: "bar", bigInt: new Long(123412341234), _id: new ObjectId() }, ]; await mongoClient.db("db").collection(collection).insertMany(docs); }); afterAll(async () => { await fs.rm(userConfig.exportsPath, { recursive: true, force: true }); }); it("should be able to list resource template", async () => { await integration.connectMcpClient(); const response = await integration.mcpClient().listResourceTemplates(); expect(response.resourceTemplates).toEqual([ { name: "exported-data", uriTemplate: "exported-data://{exportName}", description: "Data files exported in the current session.", }, ]); }); describe("when requesting non-existent resource", () => { it("should return an error", async () => { const exportURI = "exported-data://db.coll.json"; await integration.connectMcpClient(); const response = await integration.mcpClient().readResource({ uri: exportURI, }); expect(response.isError).toEqual(true); expect(response.contents[0]?.uri).toEqual(exportURI); expect(response.contents[0]?.text).toEqual( `Error reading ${exportURI}: Requested export has either expired or does not exist.` ); }); }); describe("when requesting an expired resource", () => { it("should return an error", async () => { await integration.connectMcpClient(); const exportResponse = await integration.mcpClient().callTool({ name: "export", arguments: { database: "db", collection, exportTitle: "Export for db.coll", exportTarget: [{ name: "find", arguments: {} }], }, }); const exportedResourceURI = (exportResponse as CallToolResult).content.find( (part) => part.type === "resource_link" )?.uri; expect(exportedResourceURI).toBeDefined(); // wait for export expired for (let tries = 0; tries < 10; tries++) { await timeout(300); const response = await integration.mcpClient().readResource({ uri: exportedResourceURI as string, }); // wait for an error from the MCP Server as it // means the resource is not available anymore if (response.isError !== true) { continue; } expect(response.isError).toEqual(true); expect(response.contents[0]?.uri).toEqual(exportedResourceURI); expect(response.contents[0]?.text).toMatch(`Error reading ${exportedResourceURI}:`); break; } }); }); describe("after requesting a fresh export", () => { it("should be able to read the resource", async () => { await integration.connectMcpClient(); const exportResponse = await integration.mcpClient().callTool({ name: "export", arguments: { database: "db", collection, exportTitle: "Export for db.coll", exportTarget: [{ name: "find", arguments: {} }], }, }); const content = exportResponse.content as CallToolResult["content"]; const exportURI = contentWithResourceURILink(content)?.uri as string; await resourceChangedNotification(integration.mcpClient(), exportURI); const exportedResourceURI = (exportResponse as CallToolResult).content.find( (part) => part.type === "resource_link" )?.uri; expect(exportedResourceURI).toBeDefined(); const response = await integration.mcpClient().readResource({ uri: exportedResourceURI as string, }); expect(response.isError).toBeFalsy(); expect(response.contents[0]?.mimeType).toEqual("application/json"); expect(response.contents[0]?.text).toContain(`The exported data contains ${docs.length} documents.`); expect(response.contents[0]?.text).toContain("<untrusted-user-data"); const exportContent = getDataFromUntrustedContent((response.contents[0]?.text as string) || ""); const exportedDocs = EJSON.parse(exportContent) as { name: string; _id: ObjectId }[]; const expectedDocs = docs as unknown as { name: string; _id: ObjectId }[]; expect(exportedDocs[0]?.name).toEqual(expectedDocs[0]?.name); expect(exportedDocs[0]?._id).toEqual(expectedDocs[0]?._id); expect(exportedDocs[1]?.name).toEqual(expectedDocs[1]?.name); expect(exportedDocs[1]?._id).toEqual(expectedDocs[1]?._id); }); it("should be able to autocomplete the resource", async () => { await integration.connectMcpClient(); const exportResponse = await integration.mcpClient().callTool({ name: "export", arguments: { database: "big", collection, exportTitle: "Export for big.coll", exportTarget: [{ name: "find", arguments: {} }], }, }); const content = exportResponse.content as CallToolResult["content"]; const exportURI = contentWithResourceURILink(content)?.uri as string; await resourceChangedNotification(integration.mcpClient(), exportURI); const exportedResourceURI = (exportResponse as CallToolResult).content.find( (part) => part.type === "resource_link" )?.uri; expect(exportedResourceURI).toBeDefined(); const completeResponse = await integration.mcpClient().complete({ ref: { type: "ref/resource", uri: "exported-data://{exportName}", }, argument: { name: "exportName", value: "big", }, }); expect(completeResponse.completion.total).toBeGreaterThanOrEqual(1); }); }); }, { getUserConfig: () => userConfig, } );

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