• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb-js / mongodb-mcp-server / 18482155309

14 Oct 2025 12:55AM UTC coverage: 82.392% (+0.2%) from 82.215%
18482155309

Pull #621

github

web-flow
Merge 428d37342 into faad36d48
Pull Request #621: feat: add ability to create vector search indexes MCP-234

1173 of 1554 branches covered (75.48%)

Branch coverage included in aggregate %.

116 of 119 new or added lines in 2 files covered. (97.48%)

37 existing lines in 2 files now uncovered.

5729 of 6823 relevant lines covered (83.97%)

68.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.24
/src/tools/mongodb/create/createIndex.ts
1
import type { ZodDiscriminatedUnionOption } from "zod";
2
import { z } from "zod";
2✔
3
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
4
import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
2✔
5
import { type ToolArgs, type OperationType, type ToolConstructorParams, FeatureFlags } from "../../tool.js";
2✔
6
import type { IndexDirection } from "mongodb";
7

8
const classicIndexDefinition = z.object({
2✔
9
    type: z.literal("classic"),
2✔
10
    keys: z.object({}).catchall(z.custom<IndexDirection>()).describe("The index definition"),
2✔
11
});
2✔
12

13
const vectorSearchIndexDefinition = z.object({
2✔
14
    type: z.literal("vectorSearch"),
2✔
15
    fields: z
2✔
16
        .array(
2✔
17
            z.discriminatedUnion("type", [
2✔
18
                z
2✔
19
                    .object({
2✔
20
                        type: z.literal("filter"),
2✔
21
                        path: z
2✔
22
                            .string()
2✔
23
                            .describe(
2✔
24
                                "Name of the field to index. For nested fields, use dot notation to specify path to embedded fields"
2✔
25
                            ),
2✔
26
                    })
2✔
27
                    .strict(),
2✔
28
                z
2✔
29
                    .object({
2✔
30
                        type: z.literal("vector"),
2✔
31
                        path: z
2✔
32
                            .string()
2✔
33
                            .describe(
2✔
34
                                "Name of the field to index. For nested fields, use dot notation to specify path to embedded fields"
2✔
35
                            ),
2✔
36
                        numDimensions: z
2✔
37
                            .number()
2✔
38
                            .min(1)
2✔
39
                            .max(8192)
2✔
40
                            .describe(
2✔
41
                                "Number of vector dimensions that MongoDB Vector Search enforces at index-time and query-time"
2✔
42
                            ),
2✔
43
                        similarity: z
2✔
44
                            .enum(["cosine", "euclidean", "dotProduct"])
2✔
45
                            .default("cosine")
2✔
46
                            .describe(
2✔
47
                                "Vector similarity function to use to search for top K-nearest neighbors. You can set this field only for vector-type fields."
2✔
48
                            ),
2✔
49
                        quantization: z
2✔
50
                            .enum(["none", "scalar", "binary"])
2✔
51
                            .optional()
2✔
52
                            .default("none")
2✔
53
                            .describe(
2✔
54
                                "Type of automatic vector quantization for your vectors. Use this setting only if your embeddings are float or double vectors."
2✔
55
                            ),
2✔
56
                    })
2✔
57
                    .strict(),
2✔
58
            ])
2✔
59
        )
2✔
60
        .nonempty()
2✔
61
        .refine((fields) => fields.some((f) => f.type === "vector"), {
2✔
62
            message: "At least one vector field must be defined",
2✔
63
        })
2✔
64
        .describe(
2✔
65
            "Definitions for the vector and filter fields to index, one definition per document. You must specify `vector` for fields that contain vector embeddings and `filter` for additional fields to filter on. At least one vector-type field definition is required."
2✔
66
        ),
2✔
67
});
2✔
68

69
export class CreateIndexTool extends MongoDBToolBase {
2✔
70
    public name = "create-index";
2✔
71
    protected description = "Create an index for a collection";
2✔
72
    protected argsShape;
73

74
    constructor(params: ToolConstructorParams) {
2✔
75
        super(params);
83✔
76

77
        const additionalIndexDefinitions: ZodDiscriminatedUnionOption<"type">[] = [];
83✔
78
        if (this.isFeatureFlagEnabled(FeatureFlags.VectorSearch)) {
83!
79
            additionalIndexDefinitions.push(vectorSearchIndexDefinition);
3✔
80
        }
3✔
81

82
        this.argsShape = {
83✔
83
            ...DbOperationArgs,
83✔
84
            name: z.string().optional().describe("The name of the index"),
83✔
85
            definition: z
83✔
86
                .array(z.discriminatedUnion("type", [classicIndexDefinition, ...additionalIndexDefinitions]))
83✔
87
                .describe(
83✔
88
                    "The index definition. Use 'classic' for standard indexes and 'vectorSearch' for vector search indexes"
83✔
89
                ),
83✔
90
        };
83✔
91
    }
83✔
92

93
    public operationType: OperationType = "create";
2✔
94

95
    protected async execute({
2✔
96
        database,
19✔
97
        collection,
19✔
98
        name,
19✔
99
        definition: definitions,
19✔
100
    }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
19✔
101
        const provider = await this.ensureConnected();
19✔
102
        let indexes: string[] = [];
18✔
103
        const definition = definitions[0];
18✔
104
        if (!definition) {
19!
NEW
105
            throw new Error("Index definition not provided. Expected one of the following: `classic`, `vectorSearch`");
×
NEW
106
        }
✔
107

108
        switch (definition.type) {
18✔
109
            case "classic":
19✔
110
                {
15✔
111
                    const typedDefinition = definition as z.infer<typeof classicIndexDefinition>;
15✔
112
                    indexes = await provider.createIndexes(database, collection, [
15✔
113
                        {
15✔
114
                            key: typedDefinition.keys,
15✔
115
                            name,
15✔
116
                        },
15✔
117
                    ]);
15✔
118
                }
15✔
119
                break;
15✔
120
            case "vectorSearch":
19✔
121
                {
3✔
122
                    const typedDefinition = definition as z.infer<typeof vectorSearchIndexDefinition>;
3✔
123
                    indexes = await provider.createSearchIndexes(database, collection, [
3✔
124
                        {
3✔
125
                            name,
3✔
126
                            definition: {
3✔
127
                                fields: typedDefinition.fields,
3✔
128
                            },
3✔
129
                            type: "vectorSearch",
3✔
130
                        },
3✔
131
                    ]);
3✔
132
                }
1✔
133

134
                break;
1✔
135
        }
19✔
136

137
        return {
16✔
138
            content: [
16✔
139
                {
16✔
140
                    text: `Created the index "${indexes[0]}" on collection "${collection}" in database "${database}"`,
16✔
141
                    type: "text",
16✔
142
                },
16✔
143
            ],
16✔
144
        };
16✔
145
    }
19✔
146
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc