Skip to main content
Glama

MongoDB MCP Server

by 1RB
index.ts7.6 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { MongoClient, Db } from "mongodb"; import { z } from "zod"; // Import tools import { ListCollectionsTool } from "./tools/mongodb/ListCollectionsTool.js"; import { FindTool } from "./tools/mongodb/FindTool.js"; import { InsertOneTool } from "./tools/mongodb/InsertOneTool.js"; import { UpdateOneTool } from "./tools/mongodb/UpdateOneTool.js"; import { DeleteOneTool } from "./tools/mongodb/DeleteOneTool.js"; import { CreateIndexTool } from "./tools/mongodb/CreateIndexTool.js"; import { DropIndexTool } from "./tools/mongodb/DropIndexTool.js"; import { ListIndexesTool } from "./tools/mongodb/ListIndexesTool.js"; // Define environment variable schema using zod const EnvSchema = z.object({ MONGO_URI: z.string().optional(), MONGO_DB_NAME: z.string().default('test'), MONGO_MAX_POOL_SIZE: z.coerce.number().default(10), MONGO_ALLOWED_DATABASES: z.string().optional().transform(val => val ? val.split(',') : undefined), MONGO_ALLOWED_COLLECTIONS: z.string().optional().transform(val => val ? val.split(',') : undefined), DEBUG: z.string().optional().transform(val => val === 'true'), }); // Client and DB variables let client: MongoClient; let db: Db; // Connect to MongoDB async function connectToMongoDB(databaseUrl: string): Promise<Db> { try { // Get database name from connection URL if possible const dbName = process.env.MONGO_DB_NAME || 'test'; const env = EnvSchema.parse(process.env); // MongoDB connection options const options = { maxPoolSize: env.MONGO_MAX_POOL_SIZE, }; client = new MongoClient(databaseUrl, options); await client.connect(); db = client.db(dbName); if (env.DEBUG) { console.error(`Connected to MongoDB database: ${dbName}`); } return db; } catch (error) { console.error("Error connecting to MongoDB:", error); process.exit(1); } } // Cleanup function to close MongoDB connection async function closeMongoDB() { if (client) { try { await client.close(); if (EnvSchema.parse(process.env).DEBUG) { console.error("MongoDB connection closed"); } } catch (error) { console.error("Error closing MongoDB connection:", error); } } } async function main() { try { // Get MongoDB URI from command line argument or env variable const mongoUri = process.argv[2] || process.env.MONGO_URI; if (!mongoUri) { console.error("MongoDB URI is required. Please provide it as a command line argument or set the MONGO_URI environment variable."); process.exit(1); } // Connect to MongoDB db = await connectToMongoDB(mongoUri); const env = EnvSchema.parse(process.env); // Initialize MCP server const server = new Server( { name: "MongoDB MCP Server", version: "1.0.2" }, { capabilities: { resources: {}, tools: { list: true, call: true, }, }, } ); // Create tools const tools = [ new ListCollectionsTool(), new FindTool(), new InsertOneTool(), new UpdateOneTool(), new DeleteOneTool(), new CreateIndexTool(), new DropIndexTool(), new ListIndexesTool(), ]; // Set up request handlers server.setRequestHandler(ListToolsRequestSchema, async () => { // Get schemas from all tools const schemas = tools.map(tool => ({ name: tool.getName(), description: tool.getDescription(), inputSchema: tool.inputSchema, })); return { tools: schemas, _meta: {} }; }); server.setRequestHandler(CallToolRequestSchema, async (request) => { const name = request.params.name; const args = request.params.arguments ?? {}; // Check database and collection access based on env vars if (args && typeof args === 'object' && 'collection' in args) { const collection = String(args.collection || ""); // Check if collection is allowed if (env.MONGO_ALLOWED_COLLECTIONS && !env.MONGO_ALLOWED_COLLECTIONS.includes(collection)) { return { toolResult: { content: [ { type: "text", text: `Access to collection '${collection}' is not allowed` } ], isError: true } }; } } // Create tool map const toolMap = { "mcp__listCollections": new ListCollectionsTool(), "mcp__find": new FindTool(), "mcp__insertOne": new InsertOneTool(), "mcp__updateOne": new UpdateOneTool(), "mcp__deleteOne": new DeleteOneTool(), "mcp__createIndex": new CreateIndexTool(), "mcp__dropIndex": new DropIndexTool(), "mcp__indexes": new ListIndexesTool(), }; const tool = toolMap[name as keyof typeof toolMap]; if (!tool) { return { toolResult: { content: [ { type: "text", text: `Tool '${name}' not found` } ], isError: true } }; } try { // Execute the tool // Ensure args has the required collection property for tools that need it if (name.includes('find') || name.includes('insert') || name.includes('update') || name.includes('delete') || name.includes('createIndex') || name.includes('dropIndex') || name.includes('indexes')) { // Make sure collection is set if not already if (!args.collection) { return { toolResult: { content: [ { type: "text", text: `Collection name is required for tool '${name}'` } ], isError: true } }; } } const result = await tool.execute(args as any); return { toolResult: result }; } catch (error) { console.error(`Error executing tool ${name}:`, error); return { toolResult: { content: [ { type: "text", text: error instanceof Error ? error.message : String(error) } ], isError: true } }; } }); // Set up transport const transport = new StdioServerTransport(); await server.connect(transport); console.error("MongoDB MCP server running on stdio"); // Set up process handlers for cleanup process.on('SIGINT', async () => { await closeMongoDB(); process.exit(0); }); process.on('SIGTERM', async () => { await closeMongoDB(); process.exit(0); }); // Handle unhandled promise rejections process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection at:', promise, 'reason:', reason); }); } catch (error) { console.error("Server error:", error); process.exit(1); } } main().catch(error => { console.error("Fatal error:", error); process.exit(1); });

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/1RB/mongo-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server