From 873560f95126f1cce3bbbcb559952353fe5be124 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 15 May 2025 11:48:36 +0200 Subject: [PATCH 1/3] fix: updates count tool --- src/tools/mongodb/read/count.ts | 19 ++++++-- .../tools/mongodb/read/count.test.ts | 43 +++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/tools/mongodb/read/count.ts b/src/tools/mongodb/read/count.ts index bd86169b..90666e78 100644 --- a/src/tools/mongodb/read/count.ts +++ b/src/tools/mongodb/read/count.ts @@ -4,12 +4,16 @@ import { ToolArgs, OperationType } from "../../tool.js"; import { z } from "zod"; export const CountArgs = { - query: z + filter: z .record(z.string(), z.unknown()) .optional() .describe( - "The query filter to count documents. Matches the syntax of the filter argument of db.collection.count()" + "The query filter to count documents. Matches the syntax of the filter argument of db.collection.countDocuments()" ), + query: z + .record(z.string(), z.unknown()) + .optional() + .describe("Alternative old name for filter. Will be used in db.collection.countDocuments()"), }; export class CountTool extends MongoDBToolBase { @@ -22,9 +26,16 @@ export class CountTool extends MongoDBToolBase { protected operationType: OperationType = "read"; - protected async execute({ database, collection, query }: ToolArgs): Promise { + protected async execute({ + database, + collection, + query, + filter, + }: ToolArgs): Promise { const provider = await this.ensureConnected(); - const count = await provider.count(database, collection, query); + // use either filter or query, since we're using countDocuments, prefer filter + const queryFilter = filter || query; + const count = await provider.countDocuments(database, collection, queryFilter); return { content: [ diff --git a/tests/integration/tools/mongodb/read/count.test.ts b/tests/integration/tools/mongodb/read/count.test.ts index 5b288448..eb273295 100644 --- a/tests/integration/tools/mongodb/read/count.test.ts +++ b/tests/integration/tools/mongodb/read/count.test.ts @@ -16,6 +16,12 @@ describeWithMongoDB("count tool", (integration) => { type: "object", required: false, }, + { + name: "filter", + description: "Alternative name for query parameter. The query filter to count documents.", + type: "object", + required: false, + }, ...databaseCollectionParameters, ]); @@ -79,6 +85,43 @@ describeWithMongoDB("count tool", (integration) => { expect(content).toEqual(`Found ${testCase.expectedCount} documents in the collection "foo"`); }); } + + it("correctly filters documents when using 'filter' parameter", async () => { + await integration.connectMcpClient(); + + // Using 'filter' parameter - should work correctly after the fix + const response = await integration.mcpClient().callTool({ + name: "count", + arguments: { + database: integration.randomDbName(), + collection: "foo", + filter: { age: { $lt: 15 } }, + }, + }); + + const content = getResponseContent(response.content); + expect(content).toEqual('Found 2 documents in the collection "foo"'); + }); + + it("prioritizes filter over query when both are provided", async () => { + await integration.connectMcpClient(); + + // Using both 'filter' and 'query' parameters + const response = await integration.mcpClient().callTool({ + name: "count", + arguments: { + database: integration.randomDbName(), + collection: "foo", + filter: { age: { $lt: 15 } }, + query: { age: { $gt: 10 } }, + }, + }); + + const content = getResponseContent(response.content); + // Filter takes precedence over query + // Filter is { age: { $lt: 15 } } which matches 2 documents + expect(content).toEqual('Found 2 documents in the collection "foo"'); + }); }); validateAutoConnectBehavior(integration, "count", () => { From fec735f3790a9f4ab36958869327230d02e5f15f Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 15 May 2025 12:00:18 +0200 Subject: [PATCH 2/3] update description tests --- src/tools/mongodb/read/count.ts | 2 +- tests/integration/tools/mongodb/read/count.test.ts | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/tools/mongodb/read/count.ts b/src/tools/mongodb/read/count.ts index 90666e78..19782ce1 100644 --- a/src/tools/mongodb/read/count.ts +++ b/src/tools/mongodb/read/count.ts @@ -18,7 +18,7 @@ export const CountArgs = { export class CountTool extends MongoDBToolBase { protected name = "count"; - protected description = "Gets the number of documents in a MongoDB collection"; + protected description = "Gets the number of documents in a MongoDB collection using countDocuments()"; protected argsShape = { ...DbOperationArgs, ...CountArgs, diff --git a/tests/integration/tools/mongodb/read/count.test.ts b/tests/integration/tools/mongodb/read/count.test.ts index eb273295..879cc807 100644 --- a/tests/integration/tools/mongodb/read/count.test.ts +++ b/tests/integration/tools/mongodb/read/count.test.ts @@ -8,17 +8,16 @@ import { } from "../../../helpers.js"; describeWithMongoDB("count tool", (integration) => { - validateToolMetadata(integration, "count", "Gets the number of documents in a MongoDB collection", [ + validateToolMetadata(integration, "count", "Gets the number of documents in a MongoDB collection using countDocuments()", [ { - name: "query", - description: - "The query filter to count documents. Matches the syntax of the filter argument of db.collection.count()", + name: "filter", + description: "The query filter to count documents. Matches the syntax of the filter argument of db.collection.countDocuments()", type: "object", required: false, }, { - name: "filter", - description: "Alternative name for query parameter. The query filter to count documents.", + name: "query", + description: "Alternative old name for filter. Will be used in db.collection.countDocuments()", type: "object", required: false, }, From 2e8c9910f26f7a0c0d5930a001eb53f12670e59f Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 15 May 2025 12:01:49 +0200 Subject: [PATCH 3/3] lint --- .../tools/mongodb/read/count.test.ts | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/tests/integration/tools/mongodb/read/count.test.ts b/tests/integration/tools/mongodb/read/count.test.ts index 879cc807..1f9e942a 100644 --- a/tests/integration/tools/mongodb/read/count.test.ts +++ b/tests/integration/tools/mongodb/read/count.test.ts @@ -8,21 +8,27 @@ import { } from "../../../helpers.js"; describeWithMongoDB("count tool", (integration) => { - validateToolMetadata(integration, "count", "Gets the number of documents in a MongoDB collection using countDocuments()", [ - { - name: "filter", - description: "The query filter to count documents. Matches the syntax of the filter argument of db.collection.countDocuments()", - type: "object", - required: false, - }, - { - name: "query", - description: "Alternative old name for filter. Will be used in db.collection.countDocuments()", - type: "object", - required: false, - }, - ...databaseCollectionParameters, - ]); + validateToolMetadata( + integration, + "count", + "Gets the number of documents in a MongoDB collection using countDocuments()", + [ + { + name: "filter", + description: + "The query filter to count documents. Matches the syntax of the filter argument of db.collection.countDocuments()", + type: "object", + required: false, + }, + { + name: "query", + description: "Alternative old name for filter. Will be used in db.collection.countDocuments()", + type: "object", + required: false, + }, + ...databaseCollectionParameters, + ] + ); validateThrowsForInvalidArguments(integration, "count", [ {},