diff --git a/src/tools/mongodb/read/collectionSearchIndexes.ts b/src/tools/mongodb/read/collectionSearchIndexes.ts new file mode 100644 index 00000000..b6a3665e --- /dev/null +++ b/src/tools/mongodb/read/collectionSearchIndexes.ts @@ -0,0 +1,61 @@ +import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js"; +import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; +import { ToolArgs, OperationType } from "../../tool.js"; +import { z } from "zod"; + +export const ListSearchIndexesArgs = { + indexName: z + .string() + .default("") + .optional() + .describe( + "The name of the index to return information about. Returns all indexes on collection if not provided." + ), +}; +export interface SearchIndex { + name: string; + latestDefinition: Record; +} + +export class CollectionSearchIndexesTool extends MongoDBToolBase { + protected name = "collection-search-indexes"; + protected description = "Describe the search indexes for a collection"; + protected argsShape = { + ...DbOperationArgs, + ...ListSearchIndexesArgs, + }; + + protected operationType: OperationType = "read"; + + protected async execute({ + database, + collection, + indexName, + }: ToolArgs): Promise { + const provider = await this.ensureConnected(); + + const indexes: SearchIndex[] = ( + (await provider.getSearchIndexes(database, collection, indexName)) as SearchIndex[] + ).map((doc) => ({ + name: doc.name, + latestDefinition: doc.latestDefinition, + })); + + return { + content: [ + { + text: indexName + ? `Found ${indexes.length} search indexes in the collection "${collection}" with name "${indexName}":` + : `Found ${indexes.length} search indexes in the collection "${collection}"`, + type: "text", + }, + ...(indexes.map((indexDefinition) => { + return { + text: `\nName: "${indexDefinition.name}"\nDefinition: ${JSON.stringify(indexDefinition.latestDefinition, null, 2)}\n`, + type: "text", + }; + }) as { text: string; type: "text" }[]), + ], + }; + } +} diff --git a/src/tools/mongodb/tools.ts b/src/tools/mongodb/tools.ts index d64d53ea..cf1e52d3 100644 --- a/src/tools/mongodb/tools.ts +++ b/src/tools/mongodb/tools.ts @@ -18,12 +18,14 @@ import { DropCollectionTool } from "./delete/dropCollection.js"; import { ExplainTool } from "./metadata/explain.js"; import { CreateCollectionTool } from "./create/createCollection.js"; import { LogsTool } from "./metadata/logs.js"; +import { CollectionSearchIndexesTool } from "./read/collectionSearchIndexes.js"; export const MongoDbTools = [ ConnectTool, ListCollectionsTool, ListDatabasesTool, CollectionIndexesTool, + CollectionSearchIndexesTool, CreateIndexTool, CollectionSchemaTool, FindTool, diff --git a/tests/integration/helpers.ts b/tests/integration/helpers.ts index 9d529376..179f75bb 100644 --- a/tests/integration/helpers.ts +++ b/tests/integration/helpers.ts @@ -182,6 +182,17 @@ export const databaseCollectionParameters: ParameterInfo[] = [ { name: "collection", type: "string", description: "Collection name", required: true }, ]; +export const collectionWithSearchIndexParameters: ParameterInfo[] = [ + ...databaseCollectionParameters, + { + name: "indexName", + type: "string", + description: + "The name of the index to return information about. Returns all indexes on collection if not provided.", + required: false, + }, +]; + export const databaseCollectionInvalidArgs = [ {}, { database: "test" }, diff --git a/tests/integration/tools/atlas-search/read/collectionSearchIndexes.test.ts b/tests/integration/tools/atlas-search/read/collectionSearchIndexes.test.ts new file mode 100644 index 00000000..1a422e59 --- /dev/null +++ b/tests/integration/tools/atlas-search/read/collectionSearchIndexes.test.ts @@ -0,0 +1,19 @@ +import { describeWithMongoDB } from "../../mongodb/mongodbHelpers.js"; +import { + databaseCollectionInvalidArgs, + validateThrowsForInvalidArguments, + validateToolMetadata, + collectionWithSearchIndexParameters, +} from "../../../helpers.js"; + +describeWithMongoDB("collectionSearchIndexes tool", (integration) => { + validateToolMetadata( + integration, + "collection-search-indexes", + "Describe the search indexes for a collection", + collectionWithSearchIndexParameters + ); + validateThrowsForInvalidArguments(integration, "collection-search-indexes", databaseCollectionInvalidArgs); + + // Real tests to be added once search indexes are supported in test env. +});