mongo_tool
Perform MongoDB operations including CRUD queries, aggregation, indexing, and collection management through structured database interactions.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| dbName | Yes | MongoDB 数据库名称 | |
| collectionName | No | MongoDB 集合名称 | |
| queryType | No | MongoDB 查询类型 | |
| operationType | No | 数据库管理操作类型 (索引/集合管理) | |
| where | No | 查询条件 (BSON/JSON 对象) | |
| data | No | 用于插入或替换的数据 (单个对象或对象数组) | |
| updateOperators | No | 更新操作符 (例如: { $set: { field: 'value' } }) | |
| pipeline | No | 聚合管道阶段 (对象数组) | |
| field | No | 用于 distinct 操作的字段名 | |
| indexes | No | 索引规范 (例如: { field: 1 }) | |
| newName | No | 用于 renameCollection 的新名称 | |
| bulkOperations | No | 批量写入操作数组 | |
| options | No | 其他选项 (例如: { sort: { field: -1 }, limit: 10 }) |
Implementation Reference
- src/tools/mongo_tool.ts:93-239 (handler)Main execution logic for the mongo_tool, handling various MongoDB CRUD operations, aggregations, and administrative tasks based on input parameters like queryType or operationType.export default async (request: any) => { let client: MongoClient | null = null; try { const args = request.params.arguments || {}; const { dbName, collectionName, queryType, operationType, where = {}, data, updateOperators, pipeline, field, indexes, newName, bulkOperations, options = {} } = args; if (!operationType && !queryType) { throw new Error("必须提供 'operationType' 或 'queryType' 参数之一。"); } if (operationType && queryType) { throw new Error("'operationType' 和 'queryType' 参数不能同时提供。"); } client = await getClient(); const db: Db = client.db(dbName); const collection = collectionName ? db.collection(collectionName) : null; let results: any; if (operationType) { switch (operationType) { case "createIndex": if (!collection) throw new Error("创建索引需要 'collectionName'。"); if (!indexes) throw new Error("创建索引需要 'indexes' 对象。"); results = await collection.createIndex(indexes, options); break; case "dropIndex": if (!collection) throw new Error("删除索引需要 'collectionName'。"); if (!indexes) throw new Error("删除索引需要 'indexes' 对象或索引名称字符串。"); results = await collection.dropIndex(indexes, options); break; case "listIndexes": if (!collection) throw new Error("列出索引需要 'collectionName'。"); results = await collection.listIndexes().toArray(); break; case "listCollections": results = await db.listCollections(where, options).toArray(); break; case "createCollection": if (!collectionName) throw new Error("创建集合需要 'collectionName'。"); await db.createCollection(collectionName, options); results = { success: true, message: `集合 '${collectionName}' 创建成功。` }; break; case "dropCollection": if (!collectionName) throw new Error("删除集合需要 'collectionName'。"); results = await db.dropCollection(collectionName); break; case "renameCollection": if (!collection) throw new Error("重命名集合需要 'collectionName'。"); if (!newName) throw new Error("重命名集合需要 'newName'。"); await collection.rename(newName, options); results = { success: true, message: `集合 '${collectionName}' 已成功重命名为 '${newName}'。` }; break; case "collStats": if (!collectionName) throw new Error("获取集合状态需要 'collectionName'。"); results = await db.command({ collStats: collectionName }); break; case "dbStats": results = await db.command({ dbStats: 1 }); break; default: throw new Error(`不支持的操作类型: ${operationType}`); } } else { if (!collection) throw new Error("查询操作需要 'collectionName'。"); switch (queryType) { case "find": results = await collection.find(where, options).toArray(); break; case "findOne": results = await collection.findOne(where, options); break; case "aggregate": if (!pipeline) throw new Error("聚合操作需要 'pipeline' 数组。"); results = await collection.aggregate(pipeline, options).toArray(); break; case "count": results = await collection.countDocuments(where, options); break; case "distinct": if (!field) throw new Error("Distinct 操作需要 'field' 字段名。"); results = await collection.distinct(field, where, options); break; case "insertOne": if (!data) throw new Error("插入单条数据需要 'data' 对象。"); results = await collection.insertOne(data, options); break; case "updateOne": if (!updateOperators) throw new Error("更新单条数据需要 'updateOperators' 对象。"); results = await collection.updateOne(where, updateOperators, options); break; case "deleteOne": results = await collection.deleteOne(where, options); break; case "insertMany": if (!Array.isArray(data)) throw new Error("插入多条数据需要 'data' 数组。"); results = await collection.insertMany(data, options); break; case "updateMany": if (!updateOperators) throw new Error("更新多条数据需要 'updateOperators' 对象。"); results = await collection.updateMany(where, updateOperators, options); break; case "deleteMany": results = await collection.deleteMany(where, options); break; case "bulkWrite": if (!Array.isArray(bulkOperations)) throw new Error("批量写入需要 'bulkOperations' 数组。"); results = await collection.bulkWrite(bulkOperations, options); break; case "findOneAndUpdate": if (!updateOperators) throw new Error("查找并更新需要 'updateOperators' 对象。"); results = await collection.findOneAndUpdate(where, updateOperators, options); break; case "findOneAndDelete": results = await collection.findOneAndDelete(where, options); break; case "findOneAndReplace": if (!data) throw new Error("查找并替换需要 'data' 对象。"); results = await collection.findOneAndReplace(where, data, options); break; default: throw new Error(`不支持的查询类型: ${queryType}`); } } return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }], }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true, }; } finally { if (client) { await client.close(); } } };
- src/tools/mongo_tool.ts:9-77 (schema)Input schema defining parameters for MongoDB operations including dbName, collectionName, queryType, operationType, where, data, etc.export const schema = { name: "mongo_tool", description: "功能全面的MongoDB工具,支持CRUD查询、聚合、索引和集合管理。", type: "object", properties: { dbName: { type: "string", description: "MongoDB 数据库名称", }, collectionName: { type: "string", description: "MongoDB 集合名称", }, queryType: { type: "string", description: "MongoDB 查询类型", enum: [ "find", "findOne", "aggregate", "count", "distinct", "insertOne", "updateOne", "deleteOne", "insertMany", "updateMany", "deleteMany", "bulkWrite", "findOneAndUpdate", "findOneAndDelete", "findOneAndReplace" ] }, operationType: { type: "string", enum: [ "createIndex", "dropIndex", "listIndexes", "listCollections", "createCollection", "dropCollection", "renameCollection", "collStats", "dbStats" ], description: "数据库管理操作类型 (索引/集合管理)" }, where: { type: "object", description: "查询条件 (BSON/JSON 对象)", }, data: { type: ["object", "array"], description: "用于插入或替换的数据 (单个对象或对象数组)", }, updateOperators: { type: "object", description: "更新操作符 (例如: { $set: { field: 'value' } })", }, pipeline: { type: "array", description: "聚合管道阶段 (对象数组)" }, field: { type: "string", description: "用于 distinct 操作的字段名", }, indexes: { type: "object", description: "索引规范 (例如: { field: 1 })" }, newName: { type: "string", description: "用于 renameCollection 的新名称" }, bulkOperations: { type: "array", description: "批量写入操作数组" }, options: { type: "object", description: "其他选项 (例如: { sort: { field: -1 }, limit: 10 })", } }, required: ["dbName"] };
- src/handler/ToolHandler.ts:109-130 (registration)Dynamic registration of mongo_tool (and other tools) by importing from src/tools/*_tool.ts files and adding the handler and schema to global registries in loadTools().for (const file of toolFiles) { const toolPath = path.join(toolsDir, file); try { // 如果是重新加载,清除模块缓存 if (reload) clearModuleCache(toolPath); // 导入模块,重新加载时添加时间戳防止缓存 const importPath = 'file://' + toolPath + (reload ? `?update=${Date.now()}` : ''); const { default: tool, schema, destroy } = await import(importPath); const toolName = path.parse(toolPath).name; // 注册工具 tools.push({ name: toolName, description: tool.description, inputSchema: schema, destroy: destroy }); // 注册处理函数 handlers[toolName] = async (request: ToolRequest) => { return await tool(request); }; } catch (error) {
- src/tools/mongo_tool.ts:79-91 (helper)Helper function to establish and return a MongoDB client connection.async function getClient(): Promise<MongoClient> { if (!mongoUri) { throw new Error("环境变量 MONGO_URI 未设置,无法连接到 MongoDB。"); } const client = new MongoClient(mongoUri, { maxPoolSize: 5, maxIdleTimeMS: 60000, connectTimeoutMS: 30000, socketTimeoutMS: 45000 }); await client.connect(); return client; }
- src/tools/mongo_tool.ts:241-244 (helper)Cleanup function for the tool, called during reload.export async function destroy() { // No persistent client to destroy, so this function is intentionally empty. console.log("Destroy mongo_tool"); }