11import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js" ;
22import { DbOperationArgs , MongoDBToolBase } from "../mongodbTool.js" ;
33import type { ToolArgs , OperationType } from "../../tool.js" ;
4- import { formatUntrustedData } from "../../tool.js" ;
4+ import { FeatureFlags , formatUntrustedData } from "../../tool.js" ;
5+
6+ type SearchIndexStatus = {
7+ name : string ;
8+ type : string ;
9+ status : string ;
10+ queryable : boolean ;
11+ latestDefinition : Document ;
12+ } ;
13+
14+ type IndexStatus = {
15+ name : string ;
16+ key : Document ;
17+ } ;
518
619export class CollectionIndexesTool extends MongoDBToolBase {
720 public name = "collection-indexes" ;
@@ -12,12 +25,30 @@ export class CollectionIndexesTool extends MongoDBToolBase {
1225 protected async execute ( { database, collection } : ToolArgs < typeof DbOperationArgs > ) : Promise < CallToolResult > {
1326 const provider = await this . ensureConnected ( ) ;
1427 const indexes = await provider . getIndexes ( database , collection ) ;
28+ const indexDefinitions : IndexStatus [ ] = indexes . map ( ( index ) => ( {
29+ name : index . name as string ,
30+ key : index . key as Document ,
31+ } ) ) ;
32+
33+ const searchIndexDefinitions : SearchIndexStatus [ ] = [ ] ;
34+ if ( this . isFeatureFlagEnabled ( FeatureFlags . VectorSearch ) && ( await this . session . isSearchSupported ( ) ) ) {
35+ const searchIndexes = await provider . getSearchIndexes ( database , collection ) ;
36+ searchIndexDefinitions . push ( ...this . extractSearchIndexDetails ( searchIndexes ) ) ;
37+ }
1538
1639 return {
17- content : formatUntrustedData (
18- `Found ${ indexes . length } indexes in the collection "${ collection } ":` ,
19- ...indexes . map ( ( index ) => `Name: "${ index . name } ", definition: ${ JSON . stringify ( index . key ) } ` )
20- ) ,
40+ content : [
41+ ...formatUntrustedData (
42+ `Found ${ indexDefinitions . length } indexes in the collection "${ collection } ":` ,
43+ ...indexDefinitions . map ( ( i ) => JSON . stringify ( i ) )
44+ ) ,
45+ ...( searchIndexDefinitions . length > 0
46+ ? formatUntrustedData (
47+ `Found ${ searchIndexDefinitions . length } search and vector search indexes in the collection "${ collection } ":` ,
48+ ...searchIndexDefinitions . map ( ( i ) => JSON . stringify ( i ) )
49+ )
50+ : [ ] ) ,
51+ ] ,
2152 } ;
2253 }
2354
@@ -39,4 +70,20 @@ export class CollectionIndexesTool extends MongoDBToolBase {
3970
4071 return super . handleError ( error , args ) ;
4172 }
73+
74+ /**
75+ * Atlas Search index status contains a lot of information that is not relevant for the agent at this stage.
76+ * Like for example, the status on each of the dedicated nodes. We only care about the main status, if it's
77+ * queryable and the index name. We are also picking the index definition as it can be used by the agent to
78+ * understand which fields are available for searching.
79+ **/
80+ protected extractSearchIndexDetails ( indexes : Record < string , unknown > [ ] ) : SearchIndexStatus [ ] {
81+ return indexes . map ( ( index ) => ( {
82+ name : ( index [ "name" ] ?? "default" ) as string ,
83+ type : ( index [ "type" ] ?? "UNKNOWN" ) as string ,
84+ status : ( index [ "status" ] ?? "UNKNOWN" ) as string ,
85+ queryable : ( index [ "queryable" ] ?? false ) as boolean ,
86+ latestDefinition : index [ "latestDefinition" ] as Document ,
87+ } ) ) ;
88+ }
4289}
0 commit comments