Skip to content

Commit f3d8538

Browse files
chore: addresses PR feedback
1 parent bc16c95 commit f3d8538

File tree

2 files changed

+61
-23
lines changed

2 files changed

+61
-23
lines changed

src/tools/mongodb/delete/dropIndex.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1+
import z from "zod";
12
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
23
import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
3-
import type { ToolArgs, OperationType } from "../../tool.js";
4-
import { CommonArgs } from "../../args.js";
4+
import { type ToolArgs, type OperationType, formatUntrustedData } from "../../tool.js";
55

66
export class DropIndexTool extends MongoDBToolBase {
77
public name = "drop-index";
88
protected description = "Drop an index for the provided database and collection.";
99
protected argsShape = {
1010
...DbOperationArgs,
11-
indexName: CommonArgs.string().nonempty().describe("The name of the index to be dropped."),
11+
indexName: z.string().nonempty().describe("The name of the index to be dropped."),
1212
};
1313
public operationType: OperationType = "delete";
1414

@@ -24,12 +24,12 @@ export class DropIndexTool extends MongoDBToolBase {
2424
});
2525

2626
return {
27-
content: [
28-
{
29-
text: `${result.ok ? "Successfully dropped" : "Failed to drop"} the index with name "${indexName}" from the provided namespace "${database}.${collection}".`,
30-
type: "text",
31-
},
32-
],
27+
content: formatUntrustedData(
28+
`${result.ok ? "Successfully dropped" : "Failed to drop"} the index.`,
29+
JSON.stringify({
30+
indexName,
31+
})
32+
),
3333
isError: result.ok ? undefined : true,
3434
};
3535
}

tests/integration/tools/mongodb/delete/dropIndex.test.ts

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import {
55
databaseCollectionParameters,
66
defaultDriverOptions,
77
defaultTestConfig,
8+
getDataFromUntrustedContent,
89
getResponseContent,
910
setupIntegrationTest,
1011
validateThrowsForInvalidArguments,
1112
validateToolMetadata,
1213
} from "../../../helpers.js";
13-
import { describeWithMongoDB } from "../mongodbHelpers.js";
14+
import { describeWithMongoDB, setupMongoDBIntegrationTest } from "../mongodbHelpers.js";
1415
import { createMockElicitInput } from "../../../../utils/elicitationMocks.js";
1516
import { Elicitation } from "../../../../../src/elicitation.js";
1617

@@ -35,13 +36,6 @@ describeWithMongoDB("drop-index tool", (integration) => {
3536
});
3637

3738
afterEach(async () => {
38-
try {
39-
await moviesCollection.dropIndex(indexName);
40-
} catch (error) {
41-
if (error instanceof Error && !error.message.includes("index not found with name")) {
42-
throw error;
43-
}
44-
}
4539
await moviesCollection.drop();
4640
});
4741

@@ -112,32 +106,76 @@ describeWithMongoDB("drop-index tool", (integration) => {
112106
});
113107
expect(response.isError).toBe(undefined);
114108
const content = getResponseContent(response.content);
115-
expect(content).toEqual(
116-
`Successfully dropped the index with name "${indexName}" from the provided namespace "mflix.movies".`
117-
);
109+
expect(content).toContain(`Successfully dropped the index.`);
110+
const data = getDataFromUntrustedContent(content);
111+
expect(JSON.parse(data)).toMatchObject({ indexName });
118112
});
119113
});
120114
});
121115

122-
describe("drop-search-index tool - when invoked via an elicitation enabled client", () => {
116+
describe("drop-index tool - when invoked via an elicitation enabled client", () => {
123117
const mockElicitInput = createMockElicitInput();
118+
const mdbIntegration = setupMongoDBIntegrationTest();
124119
const integration = setupIntegrationTest(
125120
() => defaultTestConfig,
126121
() => defaultDriverOptions,
127122
{ elicitInput: mockElicitInput }
128123
);
124+
let moviesCollection: Collection;
125+
let indexName: string;
126+
127+
beforeEach(async () => {
128+
moviesCollection = mdbIntegration.mongoClient().db("mflix").collection("movies");
129+
await moviesCollection.insertMany([
130+
{ name: "Movie1", year: 1994 },
131+
{ name: "Movie2", year: 2001 },
132+
]);
133+
indexName = await moviesCollection.createIndex({ year: 1 });
134+
await integration.mcpClient().callTool({
135+
name: "connect",
136+
arguments: {
137+
connectionString: mdbIntegration.connectionString(),
138+
},
139+
});
140+
});
141+
142+
afterEach(async () => {
143+
await moviesCollection.drop();
144+
});
129145

130146
it("should ask for confirmation before proceeding with tool call", async () => {
147+
expect(await moviesCollection.listIndexes().toArray()).toHaveLength(2);
131148
mockElicitInput.confirmYes();
132149
await integration.mcpClient().callTool({
133150
name: "drop-index",
134-
arguments: { database: "any", collection: "foo", indexName: "default" },
151+
arguments: { database: "mflix", collection: "movies", indexName },
152+
});
153+
expect(mockElicitInput.mock).toHaveBeenCalledTimes(1);
154+
expect(mockElicitInput.mock).toHaveBeenCalledWith({
155+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
156+
message: expect.stringContaining(
157+
"You are about to drop the `year_1` index from the `mflix.movies` namespace"
158+
),
159+
requestedSchema: Elicitation.CONFIRMATION_SCHEMA,
160+
});
161+
expect(await moviesCollection.listIndexes().toArray()).toHaveLength(1);
162+
});
163+
164+
it("should not drop the index if the confirmation was not provided", async () => {
165+
expect(await moviesCollection.listIndexes().toArray()).toHaveLength(2);
166+
mockElicitInput.confirmNo();
167+
await integration.mcpClient().callTool({
168+
name: "drop-index",
169+
arguments: { database: "mflix", collection: "movies", indexName },
135170
});
136171
expect(mockElicitInput.mock).toHaveBeenCalledTimes(1);
137172
expect(mockElicitInput.mock).toHaveBeenCalledWith({
138173
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
139-
message: expect.stringContaining("You are about to drop the `default` index from the `any.foo` namespace"),
174+
message: expect.stringContaining(
175+
"You are about to drop the `year_1` index from the `mflix.movies` namespace"
176+
),
140177
requestedSchema: Elicitation.CONFIRMATION_SCHEMA,
141178
});
179+
expect(await moviesCollection.listIndexes().toArray()).toHaveLength(2);
142180
});
143181
});

0 commit comments

Comments
 (0)