From 13bd9d21ca3e031376d45eb1488c38ec4f2e1acc Mon Sep 17 00:00:00 2001 From: nirinchev Date: Thu, 20 Nov 2025 22:36:12 +0100 Subject: [PATCH 1/2] chore: bump mcp sdk --- package-lock.json | 90 +++++++++++++-- package.json | 4 +- src/server.ts | 19 ---- src/tools/tool.ts | 2 - src/transports/base.ts | 20 ++++ tests/integration/helpers.ts | 24 ++-- .../atlas-local/connectDeployment.test.ts | 22 ++-- .../tools/mongodb/connect/connect.test.ts | 2 + .../mongodb/create/createCollection.test.ts | 1 + .../tools/mongodb/create/createIndex.test.ts | 4 +- .../tools/mongodb/create/insertMany.test.ts | 106 ++++++++++-------- .../tools/mongodb/delete/deleteMany.test.ts | 1 + .../mongodb/delete/dropCollection.test.ts | 1 + .../tools/mongodb/delete/dropDatabase.test.ts | 1 + .../tools/mongodb/delete/dropIndex.test.ts | 1 + .../metadata/collectionIndexes.test.ts | 1 + .../mongodb/metadata/collectionSchema.test.ts | 2 +- .../metadata/collectionStorageSize.test.ts | 1 + .../tools/mongodb/metadata/dbStats.test.ts | 1 + .../tools/mongodb/metadata/explain.test.ts | 1 + .../mongodb/metadata/listCollections.test.ts | 1 + .../tools/mongodb/metadata/logs.test.ts | 2 +- .../tools/mongodb/read/aggregate.test.ts | 4 +- .../tools/mongodb/read/count.test.ts | 1 + .../tools/mongodb/read/export.test.ts | 1 + .../tools/mongodb/read/find.test.ts | 2 +- .../mongodb/update/renameCollection.test.ts | 2 +- .../tools/mongodb/update/updateMany.test.ts | 1 + 28 files changed, 209 insertions(+), 109 deletions(-) diff --git a/package-lock.json b/package-lock.json index 594388adf..b554582d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.2.0", "license": "Apache-2.0", "dependencies": { - "@modelcontextprotocol/sdk": "^1.17.4", + "@modelcontextprotocol/sdk": "^1.22.0", "@mongodb-js/device-id": "^0.3.1", "@mongodb-js/devtools-proxy-support": "^0.5.3", "@mongosh/arg-parser": "^3.19.0", @@ -58,7 +58,7 @@ "globals": "^16.3.0", "husky": "^9.1.7", "knip": "^5.63.1", - "mongodb": "^6.19.0", + "mongodb": "^6.21.0", "mongodb-runner": "^5.9.2", "openapi-types": "^12.1.3", "openapi-typescript": "^7.9.1", @@ -1378,12 +1378,13 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.19.1.tgz", - "integrity": "sha512-3Y2h3MZKjec1eAqSTBclATlX+AbC6n1LgfVzRMJLt3v6w0RCYgwLrjbxPDbhsYHt6Wdqc/aCceNJYgj448ELQQ==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.22.0.tgz", + "integrity": "sha512-VUpl106XVTCpDmTBil2ehgJZjhyLY2QZikzF8NvTXtLRF1CvO5iEE2UNZdVIUer35vFOwMKYeUGbjJtvPWan3g==", "license": "MIT", "dependencies": { - "ajv": "^6.12.6", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", @@ -1398,6 +1399,47 @@ }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, "node_modules/@modelcontextprotocol/sdk/node_modules/pkce-challenge": { @@ -1639,6 +1681,7 @@ "resolved": "https://registry.npmjs.org/@mongodb-js/oidc-plugin/-/oidc-plugin-2.0.4.tgz", "integrity": "sha512-mB7kEK80+DD2QrB01GmtFKm02ItJpIO9j7OARMHI4RL+rVQD3Ey9giluf3xQtuSdcmg7a+bf5fkJgQZCWMvRPg==", "license": "Apache-2.0", + "peer": true, "dependencies": { "express": "^5.1.0", "node-fetch": "^3.3.2", @@ -1892,6 +1935,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=8.0.0" } @@ -4033,6 +4077,7 @@ "integrity": "sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.14.0" } @@ -4998,6 +5043,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5059,7 +5105,9 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5110,6 +5158,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, "license": "MIT" }, "node_modules/ansi-colors": { @@ -5776,6 +5825,7 @@ "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz", "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=16.20.1" } @@ -7282,6 +7332,7 @@ "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -7343,6 +7394,7 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -7656,6 +7708,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", @@ -7749,6 +7802,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, "license": "MIT" }, "node_modules/fast-safe-stringify": { @@ -7762,7 +7816,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "dev": true, "funding": [ { "type": "github", @@ -9365,7 +9418,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { @@ -9941,6 +9993,7 @@ "integrity": "sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g==", "dev": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -9999,10 +10052,11 @@ } }, "node_modules/mongodb": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz", - "integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.21.0.tgz", + "integrity": "sha512-URyb/VXMjJ4da46OeSXg+puO39XH9DeQpWCslifrRn9JWugy0D+DvvBvkm2WxmHe61O/H19JM66p1z7RHVkZ6A==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@mongodb-js/saslprep": "^1.3.0", "bson": "^6.10.4", @@ -10152,6 +10206,7 @@ "resolved": "https://registry.npmjs.org/mongodb-log-writer/-/mongodb-log-writer-2.4.2.tgz", "integrity": "sha512-jXKSNG/z3sBgD42p2puOoBHKcxKHJhiIVfvGhSlwNezJIr7aL74kpKowQ3kG8Oq+nljhjfDNru8Meeq24Em3lg==", "license": "Apache-2.0", + "peer": true, "dependencies": { "heap-js": "^2.3.0" }, @@ -11208,6 +11263,7 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -11492,6 +11548,7 @@ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -11505,6 +11562,7 @@ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -11859,7 +11917,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -13110,6 +13167,7 @@ "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@emotion/is-prop-valid": "1.2.2", "@emotion/unitless": "0.8.1", @@ -13722,6 +13780,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -13910,6 +13969,7 @@ "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" @@ -14063,6 +14123,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14218,6 +14279,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -14335,6 +14397,7 @@ "integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -14451,6 +14514,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -14493,6 +14557,7 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", @@ -15100,6 +15165,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 4257c4d88..46371a10d 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "globals": "^16.3.0", "husky": "^9.1.7", "knip": "^5.63.1", - "mongodb": "^6.19.0", + "mongodb": "^6.21.0", "mongodb-runner": "^5.9.2", "openapi-types": "^12.1.3", "openapi-typescript": "^7.9.1", @@ -112,7 +112,7 @@ "vitest": "^3.2.4" }, "dependencies": { - "@modelcontextprotocol/sdk": "^1.17.4", + "@modelcontextprotocol/sdk": "^1.22.0", "@mongodb-js/device-id": "^0.3.1", "@mongodb-js/devtools-proxy-support": "^0.5.3", "@mongosh/arg-parser": "^3.19.0", diff --git a/src/server.ts b/src/server.ts index 3ae209d4e..3c99b376a 100644 --- a/src/server.ts +++ b/src/server.ts @@ -100,7 +100,6 @@ export class Server { this.mcpServer.server.registerCapabilities({ logging: {}, resources: { listChanged: true, subscribe: true }, - instructions: this.getInstructions(), }); // TODO: Eventually we might want to make tools reactive too instead of relying on custom logic. @@ -301,24 +300,6 @@ export class Server { } } - private getInstructions(): string { - let instructions = ` - This is the MongoDB MCP server. - `; - if (this.userConfig.connectionString) { - instructions += ` - This MCP server was configured with a MongoDB connection string, and you can assume that you are connected to a MongoDB cluster. - `; - } - - if (this.userConfig.apiClientId && this.userConfig.apiClientSecret) { - instructions += ` - This MCP server was configured with MongoDB Atlas API credentials.`; - } - - return instructions; - } - private async connectToConfigConnectionString(): Promise { if (this.userConfig.connectionString) { try { diff --git a/src/tools/tool.ts b/src/tools/tool.ts index bd0708f5e..6917020eb 100644 --- a/src/tools/tool.ts +++ b/src/tools/tool.ts @@ -60,7 +60,6 @@ export abstract class ToolBase { protected get annotations(): ToolAnnotations { const annotations: ToolAnnotations = { title: this.name, - description: this.description, }; switch (this.operationType) { @@ -200,7 +199,6 @@ export abstract class ToolBase { } if (updates.description) { - existingTool.annotations.description = updates.description; existingTool.description = updates.description; this.description = updates.description; } diff --git a/src/transports/base.ts b/src/transports/base.ts index f9b00f758..71803401a 100644 --- a/src/transports/base.ts +++ b/src/transports/base.ts @@ -98,6 +98,8 @@ export abstract class TransportRunnerBase { const mcpServer = new McpServer({ name: packageInfo.mcpServerName, version: packageInfo.version, + }, { + instructions: TransportRunnerBase.getInstructions(userConfig), }); const logger = new CompositeLogger(this.logger); @@ -154,4 +156,22 @@ export abstract class TransportRunnerBase { this.deviceId.close(); } } + + private static getInstructions(config: UserConfig): string { + let instructions = ` + This is the MongoDB MCP server. + `; + if (config.connectionString) { + instructions += ` + This MCP server was configured with a MongoDB connection string, and you can assume that you are connected to a MongoDB cluster. + `; + } + + if (config.apiClientId && config.apiClientSecret) { + instructions += ` + This MCP server was configured with MongoDB Atlas API credentials.`; + } + + return instructions; + } } diff --git a/tests/integration/helpers.ts b/tests/integration/helpers.ts index 41e585a7b..ec21e5bc9 100644 --- a/tests/integration/helpers.ts +++ b/tests/integration/helpers.ts @@ -19,6 +19,7 @@ import type { MockClientCapabilities, createMockElicitInput } from "../utils/eli import { VectorSearchEmbeddingsManager } from "../../src/common/search/vectorSearchEmbeddingsManager.js"; import { defaultCreateAtlasLocalClient } from "../../src/common/atlasLocal.js"; import { UserConfigSchema } from "../../src/common/config/userConfig.js"; +import { OperationType } from "../../src/tools/tool.js"; interface Parameter { name: string; @@ -281,6 +282,7 @@ export function validateToolMetadata( integration: IntegrationTest, name: string, description: string, + operationType: OperationType, parameters: ParameterInfo[] ): void { it("should have correct metadata", async () => { @@ -289,7 +291,7 @@ export function validateToolMetadata( expectDefined(tool); expect(tool.description).toBe(description); - validateToolAnnotations(tool, name, description); + validateToolAnnotations(tool, name, operationType); const toolParameters = getParameters(tool); expect(toolParameters).toHaveLength(parameters.length); expect(toolParameters).toIncludeSameMembers(parameters); @@ -304,16 +306,11 @@ export function validateThrowsForInvalidArguments( describe("with invalid arguments", () => { for (const arg of args) { it(`throws a schema error for: ${JSON.stringify(arg)}`, async () => { - try { - await integration.mcpClient().callTool({ name, arguments: arg }); - throw new Error("Expected an error to be thrown"); - } catch (error) { - expect((error as Error).message).not.toEqual("Expected an error to be thrown"); - expect(error).toBeInstanceOf(McpError); - const mcpError = error as McpError; - expect(mcpError.code).toEqual(-32602); - expect(mcpError.message).toContain(`Invalid arguments for tool ${name}`); - } + const result = await integration.mcpClient().callTool({ name, arguments: arg }); + expect(result.isError).toBe(true); + const message = getResponseContent(result.content); + expect(message).toContain("-32602"); + expect(message).toContain(`Invalid arguments for tool ${name}`); }); } }); @@ -325,12 +322,11 @@ export function expectDefined(arg: T): asserts arg is Exclude { - validateToolMetadata(integration, "atlas-local-connect-deployment", "Connect to a MongoDB Atlas Local deployment", [ - { - name: "deploymentName", - type: "string", - description: "Name of the deployment to connect to", - required: true, - }, - ]); + validateToolMetadata( + integration, + "atlas-local-connect-deployment", + "Connect to a MongoDB Atlas Local deployment", + "connect", + [ + { + name: "deploymentName", + type: "string", + description: "Name of the deployment to connect to", + required: true, + }, + ] + ); it("should have the atlas-local-connect-deployment tool", async () => { const { tools } = await integration.mcpClient().listTools(); diff --git a/tests/integration/tools/mongodb/connect/connect.test.ts b/tests/integration/tools/mongodb/connect/connect.test.ts index a995d3d4a..c197c63a9 100644 --- a/tests/integration/tools/mongodb/connect/connect.test.ts +++ b/tests/integration/tools/mongodb/connect/connect.test.ts @@ -22,6 +22,7 @@ describeWithMongoDB( integration, "switch-connection", "Switch to a different MongoDB connection. If the user has configured a connection string or has previously called the connect tool, a connection is already established and there's no need to call this tool unless the user has explicitly requested to switch to a new instance.", + "connect", [ { name: "connectionString", @@ -160,6 +161,7 @@ describeWithMongoDB("Connect tool", (integration) => { integration, "connect", "Connect to a MongoDB instance. The config resource captures if the server is already connected to a MongoDB cluster. If the user has configured a connection string or has previously called the connect tool, a connection is already established and there's no need to call this tool unless the user has explicitly requested to switch to a new MongoDB cluster.", + "connect", [ { name: "connectionString", diff --git a/tests/integration/tools/mongodb/create/createCollection.test.ts b/tests/integration/tools/mongodb/create/createCollection.test.ts index 1f9786e22..feffada50 100644 --- a/tests/integration/tools/mongodb/create/createCollection.test.ts +++ b/tests/integration/tools/mongodb/create/createCollection.test.ts @@ -14,6 +14,7 @@ describeWithMongoDB("createCollection tool", (integration) => { integration, "create-collection", "Creates a new collection in a database. If the database doesn't exist, it will be created automatically.", + "create", databaseCollectionParameters ); diff --git a/tests/integration/tools/mongodb/create/createIndex.test.ts b/tests/integration/tools/mongodb/create/createIndex.test.ts index a4c4a7bef..ee344b7d5 100644 --- a/tests/integration/tools/mongodb/create/createIndex.test.ts +++ b/tests/integration/tools/mongodb/create/createIndex.test.ts @@ -13,7 +13,7 @@ import { ObjectId, type Collection, type Document, type IndexDirection } from "m import { afterEach, beforeEach, describe, expect, it } from "vitest"; describeWithMongoDB("createIndex tool when search is not enabled", (integration) => { - validateToolMetadata(integration, "create-index", "Create an index for a collection", [ + validateToolMetadata(integration, "create-index", "Create an index for a collection", "create", [ ...databaseCollectionParameters, { name: "definition", @@ -109,7 +109,7 @@ describeWithMongoDB( describeWithMongoDB( "createIndex tool with classic indexes", (integration) => { - validateToolMetadata(integration, "create-index", "Create an index for a collection", [ + validateToolMetadata(integration, "create-index", "Create an index for a collection", "create", [ ...databaseCollectionParameters, { name: "definition", diff --git a/tests/integration/tools/mongodb/create/insertMany.test.ts b/tests/integration/tools/mongodb/create/insertMany.test.ts index fdee8163e..95fd6cbb1 100644 --- a/tests/integration/tools/mongodb/create/insertMany.test.ts +++ b/tests/integration/tools/mongodb/create/insertMany.test.ts @@ -19,16 +19,22 @@ import { ObjectId } from "bson"; import type { Collection } from "mongodb"; describeWithMongoDB("insertMany tool when search is disabled", (integration) => { - validateToolMetadata(integration, "insert-many", "Insert an array of documents into a MongoDB collection", [ - ...databaseCollectionParameters, - { - name: "documents", - type: "array", - description: - "The array of documents to insert, matching the syntax of the document argument of db.collection.insertMany().", - required: true, - }, - ]); + validateToolMetadata( + integration, + "insert-many", + "Insert an array of documents into a MongoDB collection", + "create", + [ + ...databaseCollectionParameters, + { + name: "documents", + type: "array", + description: + "The array of documents to insert, matching the syntax of the document argument of db.collection.insertMany().", + required: true, + }, + ] + ); validateThrowsForInvalidArguments(integration, "insert-many", [ {}, @@ -124,23 +130,29 @@ describeWithMongoDB( await collection.drop(); }); - validateToolMetadata(integration, "insert-many", "Insert an array of documents into a MongoDB collection", [ - ...databaseCollectionParameters, - { - name: "documents", - type: "array", - description: - "The array of documents to insert, matching the syntax of the document argument of db.collection.insertMany().", - required: true, - }, - { - name: "embeddingParameters", - type: "object", - description: - "The embedding model and its parameters to use to generate embeddings for fields with vector search indexes. Note to LLM: If unsure which embedding model to use, ask the user before providing one.", - required: false, - }, - ]); + validateToolMetadata( + integration, + "insert-many", + "Insert an array of documents into a MongoDB collection", + "create", + [ + ...databaseCollectionParameters, + { + name: "documents", + type: "array", + description: + "The array of documents to insert, matching the syntax of the document argument of db.collection.insertMany().", + required: true, + }, + { + name: "embeddingParameters", + type: "object", + description: + "The embedding model and its parameters to use to generate embeddings for fields with vector search indexes. Note to LLM: If unsure which embedding model to use, ask the user before providing one.", + required: false, + }, + ] + ); it("inserts a document when the embedding is correct", async () => { await createVectorSearchIndexAndWait(integration.mongoClient(), database, "test", [ @@ -632,23 +644,29 @@ describeWithMongoDB( describeWithMongoDB( "insertMany tool when vector search is enabled", (integration) => { - validateToolMetadata(integration, "insert-many", "Insert an array of documents into a MongoDB collection", [ - ...databaseCollectionParameters, - { - name: "documents", - type: "array", - description: - "The array of documents to insert, matching the syntax of the document argument of db.collection.insertMany().", - required: true, - }, - { - name: "embeddingParameters", - type: "object", - description: - "The embedding model and its parameters to use to generate embeddings for fields with vector search indexes. Note to LLM: If unsure which embedding model to use, ask the user before providing one.", - required: false, - }, - ]); + validateToolMetadata( + integration, + "insert-many", + "Insert an array of documents into a MongoDB collection", + "create", + [ + ...databaseCollectionParameters, + { + name: "documents", + type: "array", + description: + "The array of documents to insert, matching the syntax of the document argument of db.collection.insertMany().", + required: true, + }, + { + name: "embeddingParameters", + type: "object", + description: + "The embedding model and its parameters to use to generate embeddings for fields with vector search indexes. Note to LLM: If unsure which embedding model to use, ask the user before providing one.", + required: false, + }, + ] + ); }, { getUserConfig: () => ({ diff --git a/tests/integration/tools/mongodb/delete/deleteMany.test.ts b/tests/integration/tools/mongodb/delete/deleteMany.test.ts index 00709fbc3..39a0c5150 100644 --- a/tests/integration/tools/mongodb/delete/deleteMany.test.ts +++ b/tests/integration/tools/mongodb/delete/deleteMany.test.ts @@ -13,6 +13,7 @@ describeWithMongoDB("deleteMany tool", (integration) => { integration, "delete-many", "Removes all documents that match the filter from a MongoDB collection", + "delete", [ ...databaseCollectionParameters, { diff --git a/tests/integration/tools/mongodb/delete/dropCollection.test.ts b/tests/integration/tools/mongodb/delete/dropCollection.test.ts index 245e4b890..a44809483 100644 --- a/tests/integration/tools/mongodb/delete/dropCollection.test.ts +++ b/tests/integration/tools/mongodb/delete/dropCollection.test.ts @@ -13,6 +13,7 @@ describeWithMongoDB("dropCollection tool", (integration) => { integration, "drop-collection", "Removes a collection or view from the database. The method also removes any indexes associated with the dropped collection.", + "delete", databaseCollectionParameters ); diff --git a/tests/integration/tools/mongodb/delete/dropDatabase.test.ts b/tests/integration/tools/mongodb/delete/dropDatabase.test.ts index 9547b8840..2a4187054 100644 --- a/tests/integration/tools/mongodb/delete/dropDatabase.test.ts +++ b/tests/integration/tools/mongodb/delete/dropDatabase.test.ts @@ -15,6 +15,7 @@ describeWithMongoDB("dropDatabase tool", (integration) => { integration, "drop-database", "Removes the specified database, deleting the associated data files", + "delete", databaseParameters ); diff --git a/tests/integration/tools/mongodb/delete/dropIndex.test.ts b/tests/integration/tools/mongodb/delete/dropIndex.test.ts index 9bee2457e..0b9369938 100644 --- a/tests/integration/tools/mongodb/delete/dropIndex.test.ts +++ b/tests/integration/tools/mongodb/delete/dropIndex.test.ts @@ -97,6 +97,7 @@ describe.each([{ vectorSearchEnabled: false }, { vectorSearchEnabled: true }])( integration, "drop-index", "Drop an index for the provided database and collection.", + "delete", [ ...databaseCollectionParameters, { diff --git a/tests/integration/tools/mongodb/metadata/collectionIndexes.test.ts b/tests/integration/tools/mongodb/metadata/collectionIndexes.test.ts index 59a801055..8170b71d0 100644 --- a/tests/integration/tools/mongodb/metadata/collectionIndexes.test.ts +++ b/tests/integration/tools/mongodb/metadata/collectionIndexes.test.ts @@ -29,6 +29,7 @@ describeWithMongoDB("collectionIndexes tool", (integration) => { integration, "collection-indexes", "Describe the indexes for a collection", + "metadata", databaseCollectionParameters ); diff --git a/tests/integration/tools/mongodb/metadata/collectionSchema.test.ts b/tests/integration/tools/mongodb/metadata/collectionSchema.test.ts index f23cce19f..d927be4ba 100644 --- a/tests/integration/tools/mongodb/metadata/collectionSchema.test.ts +++ b/tests/integration/tools/mongodb/metadata/collectionSchema.test.ts @@ -15,7 +15,7 @@ import type { SimplifiedSchema } from "mongodb-schema"; import { describe, expect, it } from "vitest"; describeWithMongoDB("collectionSchema tool", (integration) => { - validateToolMetadata(integration, "collection-schema", "Describe the schema for a collection", [ + validateToolMetadata(integration, "collection-schema", "Describe the schema for a collection", "metadata", [ ...databaseCollectionParameters, { name: "sampleSize", diff --git a/tests/integration/tools/mongodb/metadata/collectionStorageSize.test.ts b/tests/integration/tools/mongodb/metadata/collectionStorageSize.test.ts index 30eb88652..4adfe8133 100644 --- a/tests/integration/tools/mongodb/metadata/collectionStorageSize.test.ts +++ b/tests/integration/tools/mongodb/metadata/collectionStorageSize.test.ts @@ -16,6 +16,7 @@ describeWithMongoDB("collectionStorageSize tool", (integration) => { integration, "collection-storage-size", "Gets the size of the collection", + "metadata", databaseCollectionParameters ); diff --git a/tests/integration/tools/mongodb/metadata/dbStats.test.ts b/tests/integration/tools/mongodb/metadata/dbStats.test.ts index 915d8ea18..bad86e8d3 100644 --- a/tests/integration/tools/mongodb/metadata/dbStats.test.ts +++ b/tests/integration/tools/mongodb/metadata/dbStats.test.ts @@ -16,6 +16,7 @@ describeWithMongoDB("dbStats tool", (integration) => { integration, "db-stats", "Returns statistics that reflect the use state of a single database", + "metadata", databaseParameters ); diff --git a/tests/integration/tools/mongodb/metadata/explain.test.ts b/tests/integration/tools/mongodb/metadata/explain.test.ts index ba5b32197..8cf109397 100644 --- a/tests/integration/tools/mongodb/metadata/explain.test.ts +++ b/tests/integration/tools/mongodb/metadata/explain.test.ts @@ -12,6 +12,7 @@ describeWithMongoDB("explain tool", (integration) => { integration, "explain", "Returns statistics describing the execution of the winning plan chosen by the query optimizer for the evaluated method", + "metadata", [ ...databaseCollectionParameters, diff --git a/tests/integration/tools/mongodb/metadata/listCollections.test.ts b/tests/integration/tools/mongodb/metadata/listCollections.test.ts index 3f30f3847..77f106708 100644 --- a/tests/integration/tools/mongodb/metadata/listCollections.test.ts +++ b/tests/integration/tools/mongodb/metadata/listCollections.test.ts @@ -15,6 +15,7 @@ describeWithMongoDB("listCollections tool", (integration) => { integration, "list-collections", "List all collections for a given database", + "metadata", databaseParameters ); diff --git a/tests/integration/tools/mongodb/metadata/logs.test.ts b/tests/integration/tools/mongodb/metadata/logs.test.ts index aa7e4ea44..683a8c669 100644 --- a/tests/integration/tools/mongodb/metadata/logs.test.ts +++ b/tests/integration/tools/mongodb/metadata/logs.test.ts @@ -8,7 +8,7 @@ import { import { describeWithMongoDB, validateAutoConnectBehavior } from "../mongodbHelpers.js"; describeWithMongoDB("logs tool", (integration) => { - validateToolMetadata(integration, "mongodb-logs", "Returns the most recent logged mongod events", [ + validateToolMetadata(integration, "mongodb-logs", "Returns the most recent logged mongod events", "metadata", [ { type: "string", name: "type", diff --git a/tests/integration/tools/mongodb/read/aggregate.test.ts b/tests/integration/tools/mongodb/read/aggregate.test.ts index a2317ad78..a18654fb2 100644 --- a/tests/integration/tools/mongodb/read/aggregate.test.ts +++ b/tests/integration/tools/mongodb/read/aggregate.test.ts @@ -23,7 +23,7 @@ describeWithMongoDB("aggregate tool", (integration) => { integration.mcpServer().userConfig.disabledTools = []; }); - validateToolMetadata(integration, "aggregate", "Run an aggregation against a MongoDB collection", [ + validateToolMetadata(integration, "aggregate", "Run an aggregation against a MongoDB collection", "read", [ ...databaseCollectionParameters, { name: "pipeline", @@ -394,7 +394,7 @@ describeWithMongoDB( await integration.mongoClient().db(integration.randomDbName()).collection("databases").drop(); }); - validateToolMetadata(integration, "aggregate", "Run an aggregation against a MongoDB collection", [ + validateToolMetadata(integration, "aggregate", "Run an aggregation against a MongoDB collection", "read", [ ...databaseCollectionParameters, { name: "pipeline", diff --git a/tests/integration/tools/mongodb/read/count.test.ts b/tests/integration/tools/mongodb/read/count.test.ts index f5b92620a..eb5f88142 100644 --- a/tests/integration/tools/mongodb/read/count.test.ts +++ b/tests/integration/tools/mongodb/read/count.test.ts @@ -13,6 +13,7 @@ describeWithMongoDB("count tool", (integration) => { integration, "count", "Gets the number of documents in a MongoDB collection using db.collection.count() and query as an optional filter parameter", + "read", [ { name: "query", diff --git a/tests/integration/tools/mongodb/read/export.test.ts b/tests/integration/tools/mongodb/read/export.test.ts index 2c0310b6e..641bb15e5 100644 --- a/tests/integration/tools/mongodb/read/export.test.ts +++ b/tests/integration/tools/mongodb/read/export.test.ts @@ -54,6 +54,7 @@ describeWithMongoDB( integration, "export", "Export a query or aggregation results in the specified EJSON format.", + "read", [ ...databaseCollectionParameters, { diff --git a/tests/integration/tools/mongodb/read/find.test.ts b/tests/integration/tools/mongodb/read/find.test.ts index c7aaf3da9..e758df94c 100644 --- a/tests/integration/tools/mongodb/read/find.test.ts +++ b/tests/integration/tools/mongodb/read/find.test.ts @@ -26,7 +26,7 @@ export async function freshInsertDocuments({ } describeWithMongoDB("find tool with default configuration", (integration) => { - validateToolMetadata(integration, "find", "Run a find query against a MongoDB collection", [ + validateToolMetadata(integration, "find", "Run a find query against a MongoDB collection", "read", [ ...databaseCollectionParameters, { diff --git a/tests/integration/tools/mongodb/update/renameCollection.test.ts b/tests/integration/tools/mongodb/update/renameCollection.test.ts index 77b368a20..01ae69fa5 100644 --- a/tests/integration/tools/mongodb/update/renameCollection.test.ts +++ b/tests/integration/tools/mongodb/update/renameCollection.test.ts @@ -8,7 +8,7 @@ import { describe, expect, it } from "vitest"; import { describeWithMongoDB, validateAutoConnectBehavior } from "../mongodbHelpers.js"; describeWithMongoDB("renameCollection tool", (integration) => { - validateToolMetadata(integration, "rename-collection", "Renames a collection in a MongoDB database", [ + validateToolMetadata(integration, "rename-collection", "Renames a collection in a MongoDB database", "update", [ ...databaseCollectionParameters, { diff --git a/tests/integration/tools/mongodb/update/updateMany.test.ts b/tests/integration/tools/mongodb/update/updateMany.test.ts index 709c32e7e..af40e5aeb 100644 --- a/tests/integration/tools/mongodb/update/updateMany.test.ts +++ b/tests/integration/tools/mongodb/update/updateMany.test.ts @@ -12,6 +12,7 @@ describeWithMongoDB("updateMany tool", (integration) => { integration, "update-many", "Updates all documents that match the specified filter for a collection", + "update", [ ...databaseCollectionParameters, From e145de917e7c6c9bfad1ec80b6a95b5ce4ef0ae3 Mon Sep 17 00:00:00 2001 From: nirinchev Date: Thu, 20 Nov 2025 22:58:17 +0100 Subject: [PATCH 2/2] fix lint/type errors --- src/transports/base.ts | 15 +++++++------ tests/integration/helpers.ts | 7 +++++-- .../resources/exportedData.test.ts | 13 +++++++----- .../tools/mongodb/read/export.test.ts | 21 +++++++------------ 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/transports/base.ts b/src/transports/base.ts index 71803401a..15b36bd30 100644 --- a/src/transports/base.ts +++ b/src/transports/base.ts @@ -95,12 +95,15 @@ export abstract class TransportRunnerBase { // fetch or modify configuration before session initialization const userConfig = this.createSessionConfig ? await this.createSessionConfig(this.userConfig) : this.userConfig; - const mcpServer = new McpServer({ - name: packageInfo.mcpServerName, - version: packageInfo.version, - }, { - instructions: TransportRunnerBase.getInstructions(userConfig), - }); + const mcpServer = new McpServer( + { + name: packageInfo.mcpServerName, + version: packageInfo.version, + }, + { + instructions: TransportRunnerBase.getInstructions(userConfig), + } + ); const logger = new CompositeLogger(this.logger); const exportsManager = ExportsManager.init(userConfig, logger); diff --git a/tests/integration/helpers.ts b/tests/integration/helpers.ts index ec21e5bc9..24d0d25a4 100644 --- a/tests/integration/helpers.ts +++ b/tests/integration/helpers.ts @@ -7,7 +7,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { InMemoryTransport } from "./inMemoryTransport.js"; import { type UserConfig } from "../../src/common/config/userConfig.js"; -import { McpError, ResourceUpdatedNotificationSchema } from "@modelcontextprotocol/sdk/types.js"; +import { ResourceUpdatedNotificationSchema } from "@modelcontextprotocol/sdk/types.js"; import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest"; import type { ConnectionManager, ConnectionState } from "../../src/common/connectionManager.js"; import { MCPConnectionManager } from "../../src/common/connectionManager.js"; @@ -19,7 +19,7 @@ import type { MockClientCapabilities, createMockElicitInput } from "../utils/eli import { VectorSearchEmbeddingsManager } from "../../src/common/search/vectorSearchEmbeddingsManager.js"; import { defaultCreateAtlasLocalClient } from "../../src/common/atlasLocal.js"; import { UserConfigSchema } from "../../src/common/config/userConfig.js"; -import { OperationType } from "../../src/tools/tool.js"; +import type { OperationType } from "../../src/tools/tool.js"; interface Parameter { name: string; @@ -340,6 +340,9 @@ function validateToolAnnotations(tool: ToolInfo, name: string, operationType: Op case "update": expect(tool.annotations.readOnlyHint).toBe(false); expect(tool.annotations.destructiveHint).toBe(false); + break; + case "connect": + break; } } diff --git a/tests/integration/resources/exportedData.test.ts b/tests/integration/resources/exportedData.test.ts index 5903fb23d..297724d49 100644 --- a/tests/integration/resources/exportedData.test.ts +++ b/tests/integration/resources/exportedData.test.ts @@ -56,7 +56,8 @@ describeWithMongoDB( }); expect(response.isError).toEqual(true); expect(response.contents[0]?.uri).toEqual(exportURI); - expect(response.contents[0]?.text).toEqual( + const text = (response.contents[0] as { text: string }).text; + expect(text).toEqual( `Error reading ${exportURI}: Requested export has either expired or does not exist.` ); }); @@ -95,7 +96,8 @@ describeWithMongoDB( expect(response.isError).toEqual(true); expect(response.contents[0]?.uri).toEqual(exportedResourceURI); - expect(response.contents[0]?.text).toMatch(`Error reading ${exportedResourceURI}:`); + const text = (response.contents[0] as { text: string }).text; + expect(text).toMatch(`Error reading ${exportedResourceURI}:`); break; } }); @@ -128,9 +130,10 @@ describeWithMongoDB( expect(response.isError).toBeFalsy(); expect(response.contents[0]?.mimeType).toEqual("application/json"); - expect(response.contents[0]?.text).toContain(`The exported data contains ${docs.length} documents.`); - expect(response.contents[0]?.text).toContain(" { return part.type === "resource_link"; }); } -export function contentWithExportPath( - content: CallToolResult["content"] -): CallToolResult["content"][number] | undefined { - return content.find((part) => { - return ( - part.type === "text" && - part.text.startsWith( +export function contentWithExportPath(content: CallToolResult["content"]): { text: string } | undefined { + return content + .filter((part) => part.type === "text") + .find((part) => { + return part.text.startsWith( `Optionally, when the export is finished, the exported data can also be accessed under path -` - ) - ); - }); + ); + }); } describeWithMongoDB(