From 873560f95126f1cce3bbbcb559952353fe5be124 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 15 May 2025 11:48:36 +0200 Subject: [PATCH 1/7] 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/7] 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/7] 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", [ {}, From 44b9374b2128986ae9ecfa575b4e9af6293efe0b Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Fri, 16 May 2025 11:37:01 +0200 Subject: [PATCH 4/7] Revert "update description tests" This reverts commit fec735f3790a9f4ab36958869327230d02e5f15f. --- src/tools/mongodb/read/count.ts | 2 +- .../tools/mongodb/read/count.test.ts | 37 ++++++++----------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/tools/mongodb/read/count.ts b/src/tools/mongodb/read/count.ts index 19782ce1..90666e78 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 using countDocuments()"; + protected description = "Gets the number of documents in a MongoDB collection"; 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 1f9e942a..eb273295 100644 --- a/tests/integration/tools/mongodb/read/count.test.ts +++ b/tests/integration/tools/mongodb/read/count.test.ts @@ -8,27 +8,22 @@ 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", [ + { + name: "query", + description: + "The query filter to count documents. Matches the syntax of the filter argument of db.collection.count()", + type: "object", + required: false, + }, + { + name: "filter", + description: "Alternative name for query parameter. The query filter to count documents.", + type: "object", + required: false, + }, + ...databaseCollectionParameters, + ]); validateThrowsForInvalidArguments(integration, "count", [ {}, From a110273a5d708dd40bf174ae8833af8698a9b63b Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Fri, 16 May 2025 11:38:39 +0200 Subject: [PATCH 5/7] Revert "fix: updates count tool" This reverts commit 873560f95126f1cce3bbbcb559952353fe5be124. --- src/tools/mongodb/read/count.ts | 19 ++------ .../tools/mongodb/read/count.test.ts | 43 ------------------- 2 files changed, 4 insertions(+), 58 deletions(-) diff --git a/src/tools/mongodb/read/count.ts b/src/tools/mongodb/read/count.ts index 90666e78..bd86169b 100644 --- a/src/tools/mongodb/read/count.ts +++ b/src/tools/mongodb/read/count.ts @@ -4,16 +4,12 @@ import { ToolArgs, OperationType } from "../../tool.js"; import { z } from "zod"; export const CountArgs = { - filter: z + query: z .record(z.string(), z.unknown()) .optional() .describe( - "The query filter to count documents. Matches the syntax of the filter argument of db.collection.countDocuments()" + "The query filter to count documents. Matches the syntax of the filter argument of db.collection.count()" ), - 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 { @@ -26,16 +22,9 @@ export class CountTool extends MongoDBToolBase { protected operationType: OperationType = "read"; - protected async execute({ - database, - collection, - query, - filter, - }: ToolArgs): Promise { + protected async execute({ database, collection, query }: ToolArgs): Promise { const provider = await this.ensureConnected(); - // use either filter or query, since we're using countDocuments, prefer filter - const queryFilter = filter || query; - const count = await provider.countDocuments(database, collection, queryFilter); + const count = await provider.count(database, collection, query); return { content: [ diff --git a/tests/integration/tools/mongodb/read/count.test.ts b/tests/integration/tools/mongodb/read/count.test.ts index eb273295..5b288448 100644 --- a/tests/integration/tools/mongodb/read/count.test.ts +++ b/tests/integration/tools/mongodb/read/count.test.ts @@ -16,12 +16,6 @@ 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, ]); @@ -85,43 +79,6 @@ 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 39b23db003b2d23ca65a0fc92d60a9d525e67f45 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Mon, 19 May 2025 18:14:44 +0100 Subject: [PATCH 6/7] diff approach: update prompts --- src/tools/mongodb/read/count.ts | 4 ++-- tests/integration/tools/mongodb/read/count.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/mongodb/read/count.ts b/src/tools/mongodb/read/count.ts index bd86169b..15fc4a80 100644 --- a/src/tools/mongodb/read/count.ts +++ b/src/tools/mongodb/read/count.ts @@ -8,13 +8,13 @@ export const CountArgs = { .record(z.string(), z.unknown()) .optional() .describe( - "The query filter to count documents. Matches the syntax of the filter argument of db.collection.count()" + "A filter/query parameter. Allows users to filter the documents to count. Matches the syntax of the filter argument of db.collection.count()." ), }; 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 db.collection.count() and query as an optional filter parameter"; 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 5b288448..29c383bc 100644 --- a/tests/integration/tools/mongodb/read/count.test.ts +++ b/tests/integration/tools/mongodb/read/count.test.ts @@ -8,11 +8,11 @@ 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 db.collection.count() and query as an optional filter parameter", [ { name: "query", description: - "The query filter to count documents. Matches the syntax of the filter argument of db.collection.count()", + "A filter/query parameter. Allows users to filter the documents to count. Matches the syntax of the filter argument of db.collection.count().", type: "object", required: false, }, From 1cc51de2af4c644c4ba779ad2a7596a1975b42cb Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Mon, 19 May 2025 18:57:54 +0100 Subject: [PATCH 7/7] reformat --- src/tools/mongodb/read/count.ts | 3 ++- .../tools/mongodb/read/count.test.ts | 25 +++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/tools/mongodb/read/count.ts b/src/tools/mongodb/read/count.ts index 15fc4a80..5d97afa9 100644 --- a/src/tools/mongodb/read/count.ts +++ b/src/tools/mongodb/read/count.ts @@ -14,7 +14,8 @@ export const CountArgs = { export class CountTool extends MongoDBToolBase { protected name = "count"; - protected description = "Gets the number of documents in a MongoDB collection using db.collection.count() and query as an optional filter parameter"; + protected description = + "Gets the number of documents in a MongoDB collection using db.collection.count() and query as an optional filter parameter"; 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 29c383bc..39b88607 100644 --- a/tests/integration/tools/mongodb/read/count.test.ts +++ b/tests/integration/tools/mongodb/read/count.test.ts @@ -8,16 +8,21 @@ import { } from "../../../helpers.js"; describeWithMongoDB("count tool", (integration) => { - validateToolMetadata(integration, "count", "Gets the number of documents in a MongoDB collection using db.collection.count() and query as an optional filter parameter", [ - { - name: "query", - description: - "A filter/query parameter. Allows users to filter the documents to count. Matches the syntax of the filter argument of db.collection.count().", - type: "object", - required: false, - }, - ...databaseCollectionParameters, - ]); + validateToolMetadata( + integration, + "count", + "Gets the number of documents in a MongoDB collection using db.collection.count() and query as an optional filter parameter", + [ + { + name: "query", + description: + "A filter/query parameter. Allows users to filter the documents to count. Matches the syntax of the filter argument of db.collection.count().", + type: "object", + required: false, + }, + ...databaseCollectionParameters, + ] + ); validateThrowsForInvalidArguments(integration, "count", [ {},