MongoDB MCP Server

by 1RB
import { z } from 'zod'; import { Db } from 'mongodb'; export interface ToolResponse { content: Array<{ type: string; text: string; data?: unknown; }>; isError?: boolean; } export interface ToolMetadata { name: string; description: string; version: string; category: string; tags: string[]; } export abstract class BaseTool<T = unknown> { protected db: Db | null = null; constructor(protected metadata: ToolMetadata) {} abstract get inputSchema(): z.ZodType<T>; getName(): string { return this.metadata.name; } getDescription(): string { return this.metadata.description; } getVersion(): string { return this.metadata.version; } getCategory(): string { return this.metadata.category; } getTags(): string[] { return this.metadata.tags; } setDatabase(db: Db | null): void { this.db = db; } protected validateInput(input: unknown): T { return this.inputSchema.parse(input); } protected createSuccessResponse(text: string, data?: unknown): ToolResponse { return { content: [{ type: 'text', text, data }], isError: false }; } protected createErrorResponse(error: Error | string): ToolResponse { const errorMessage = error instanceof Error ? error.message : error; return { content: [{ type: 'text', text: errorMessage }], isError: true }; } protected async validateCollection(collectionName: string): Promise<void> { if (!this.db) { throw new Error('Database not connected'); } const collections = await this.db.listCollections().toArray(); if (!collections.some(col => col.name === collectionName)) { throw new Error(`Collection '${collectionName}' does not exist`); } } protected async validateDocument(collectionName: string, filter: object): Promise<void> { if (!this.db) { throw new Error('Database not connected'); } const count = await this.db.collection(collectionName).countDocuments(filter); if (count === 0) { throw new Error('Document not found'); } } abstract execute(params: T): Promise<ToolResponse>; }