mongodb-mcp-server 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/.github/pull_request_template.md +5 -0
  2. package/.github/workflows/accuracy-tests.yml +55 -0
  3. package/.github/workflows/check.yml +1 -1
  4. package/.github/workflows/code_health.yaml +4 -4
  5. package/.github/workflows/code_health_fork.yaml +0 -14
  6. package/.github/workflows/dependabot_pr.yaml +26 -0
  7. package/.github/workflows/docker.yaml +1 -1
  8. package/.github/workflows/jira-issue.yml +72 -0
  9. package/.smithery/smithery.yaml +10 -0
  10. package/.vscode/extensions.json +1 -1
  11. package/.vscode/launch.json +11 -1
  12. package/.vscode/settings.json +1 -11
  13. package/Dockerfile +1 -0
  14. package/README.md +132 -31
  15. package/dist/common/atlas/accessListUtils.js +36 -0
  16. package/dist/common/atlas/accessListUtils.js.map +1 -0
  17. package/dist/common/atlas/apiClient.js +25 -6
  18. package/dist/common/atlas/apiClient.js.map +1 -1
  19. package/dist/common/atlas/cluster.js +1 -1
  20. package/dist/common/atlas/cluster.js.map +1 -1
  21. package/dist/{config.js → common/config.js} +8 -1
  22. package/dist/common/config.js.map +1 -0
  23. package/dist/{errors.js → common/errors.js} +1 -0
  24. package/dist/common/errors.js.map +1 -0
  25. package/dist/{logger.js → common/logger.js} +20 -19
  26. package/dist/common/logger.js.map +1 -0
  27. package/dist/common/managedTimeout.js +20 -0
  28. package/dist/common/managedTimeout.js.map +1 -0
  29. package/dist/common/packageInfo.js.map +1 -0
  30. package/dist/{session.js → common/session.js} +20 -21
  31. package/dist/common/session.js.map +1 -0
  32. package/dist/common/sessionStore.js +73 -0
  33. package/dist/common/sessionStore.js.map +1 -0
  34. package/dist/helpers/container.js +28 -0
  35. package/dist/helpers/container.js.map +1 -0
  36. package/dist/helpers/generatePassword.js.map +1 -0
  37. package/dist/helpers/indexCheck.js +63 -0
  38. package/dist/helpers/indexCheck.js.map +1 -0
  39. package/dist/index.js +30 -37
  40. package/dist/index.js.map +1 -1
  41. package/dist/server.js +44 -7
  42. package/dist/server.js.map +1 -1
  43. package/dist/telemetry/constants.js +1 -1
  44. package/dist/telemetry/constants.js.map +1 -1
  45. package/dist/telemetry/telemetry.js +86 -116
  46. package/dist/telemetry/telemetry.js.map +1 -1
  47. package/dist/tools/atlas/atlasTool.js +3 -3
  48. package/dist/tools/atlas/atlasTool.js.map +1 -1
  49. package/dist/tools/atlas/connect/connectCluster.js +198 -0
  50. package/dist/tools/atlas/connect/connectCluster.js.map +1 -0
  51. package/dist/tools/atlas/create/createAccessList.js +9 -10
  52. package/dist/tools/atlas/create/createAccessList.js.map +1 -1
  53. package/dist/tools/atlas/create/createDBUser.js +3 -1
  54. package/dist/tools/atlas/create/createDBUser.js.map +1 -1
  55. package/dist/tools/atlas/create/createFreeCluster.js +2 -0
  56. package/dist/tools/atlas/create/createFreeCluster.js.map +1 -1
  57. package/dist/tools/atlas/create/createProject.js.map +1 -1
  58. package/dist/tools/atlas/read/inspectAccessList.js.map +1 -1
  59. package/dist/tools/atlas/read/inspectCluster.js.map +1 -1
  60. package/dist/tools/atlas/read/listAlerts.js.map +1 -1
  61. package/dist/tools/atlas/read/listClusters.js.map +1 -1
  62. package/dist/tools/atlas/read/listDBUsers.js.map +1 -1
  63. package/dist/tools/atlas/read/listOrgs.js.map +1 -1
  64. package/dist/tools/atlas/read/listProjects.js.map +1 -1
  65. package/dist/tools/atlas/tools.js +1 -1
  66. package/dist/tools/atlas/tools.js.map +1 -1
  67. package/dist/tools/mongodb/{metadata → connect}/connect.js +7 -4
  68. package/dist/tools/mongodb/connect/connect.js.map +1 -0
  69. package/dist/tools/mongodb/create/createCollection.js.map +1 -1
  70. package/dist/tools/mongodb/create/createIndex.js +1 -1
  71. package/dist/tools/mongodb/create/createIndex.js.map +1 -1
  72. package/dist/tools/mongodb/create/insertMany.js +1 -1
  73. package/dist/tools/mongodb/create/insertMany.js.map +1 -1
  74. package/dist/tools/mongodb/delete/deleteMany.js +20 -1
  75. package/dist/tools/mongodb/delete/deleteMany.js.map +1 -1
  76. package/dist/tools/mongodb/delete/dropCollection.js.map +1 -1
  77. package/dist/tools/mongodb/delete/dropDatabase.js.map +1 -1
  78. package/dist/tools/mongodb/metadata/collectionSchema.js.map +1 -1
  79. package/dist/tools/mongodb/metadata/collectionStorageSize.js.map +1 -1
  80. package/dist/tools/mongodb/metadata/dbStats.js.map +1 -1
  81. package/dist/tools/mongodb/metadata/explain.js +2 -2
  82. package/dist/tools/mongodb/metadata/explain.js.map +1 -1
  83. package/dist/tools/mongodb/metadata/listCollections.js.map +1 -1
  84. package/dist/tools/mongodb/metadata/listDatabases.js.map +1 -1
  85. package/dist/tools/mongodb/metadata/logs.js.map +1 -1
  86. package/dist/tools/mongodb/mongodbTool.js +47 -10
  87. package/dist/tools/mongodb/mongodbTool.js.map +1 -1
  88. package/dist/tools/mongodb/read/aggregate.js +10 -1
  89. package/dist/tools/mongodb/read/aggregate.js.map +1 -1
  90. package/dist/tools/mongodb/read/collectionIndexes.js.map +1 -1
  91. package/dist/tools/mongodb/read/count.js +15 -1
  92. package/dist/tools/mongodb/read/count.js.map +1 -1
  93. package/dist/tools/mongodb/read/find.js +14 -4
  94. package/dist/tools/mongodb/read/find.js.map +1 -1
  95. package/dist/tools/mongodb/tools.js +1 -1
  96. package/dist/tools/mongodb/tools.js.map +1 -1
  97. package/dist/tools/mongodb/update/renameCollection.js.map +1 -1
  98. package/dist/tools/mongodb/update/updateMany.js +24 -2
  99. package/dist/tools/mongodb/update/updateMany.js.map +1 -1
  100. package/dist/tools/tool.js +12 -9
  101. package/dist/tools/tool.js.map +1 -1
  102. package/dist/transports/base.js +26 -0
  103. package/dist/transports/base.js.map +1 -0
  104. package/dist/{helpers/EJsonTransport.js → transports/stdio.js} +24 -2
  105. package/dist/transports/stdio.js.map +1 -0
  106. package/dist/transports/streamableHttp.js +140 -0
  107. package/dist/transports/streamableHttp.js.map +1 -0
  108. package/eslint.config.js +13 -4
  109. package/package.json +43 -33
  110. package/resources/test-summary-template.html +415 -0
  111. package/scripts/accuracy/generateTestSummary.ts +335 -0
  112. package/scripts/accuracy/runAccuracyTests.sh +45 -0
  113. package/scripts/accuracy/updateAccuracyRunStatus.ts +21 -0
  114. package/src/common/atlas/accessListUtils.ts +54 -0
  115. package/src/common/atlas/apiClient.ts +25 -6
  116. package/src/common/atlas/cluster.ts +1 -1
  117. package/src/{config.ts → common/config.ts} +16 -2
  118. package/src/{errors.ts → common/errors.ts} +1 -0
  119. package/src/{logger.ts → common/logger.ts} +21 -24
  120. package/src/common/managedTimeout.ts +27 -0
  121. package/src/{session.ts → common/session.ts} +24 -26
  122. package/src/common/sessionStore.ts +111 -0
  123. package/src/helpers/container.ts +35 -0
  124. package/src/helpers/indexCheck.ts +83 -0
  125. package/src/index.ts +30 -40
  126. package/src/server.ts +55 -11
  127. package/src/telemetry/constants.ts +1 -1
  128. package/src/telemetry/telemetry.ts +109 -153
  129. package/src/telemetry/types.ts +2 -1
  130. package/src/tools/atlas/atlasTool.ts +4 -4
  131. package/src/tools/atlas/connect/connectCluster.ts +259 -0
  132. package/src/tools/atlas/create/createAccessList.ts +15 -13
  133. package/src/tools/atlas/create/createDBUser.ts +5 -3
  134. package/src/tools/atlas/create/createFreeCluster.ts +4 -2
  135. package/src/tools/atlas/create/createProject.ts +2 -2
  136. package/src/tools/atlas/read/inspectAccessList.ts +2 -2
  137. package/src/tools/atlas/read/inspectCluster.ts +2 -2
  138. package/src/tools/atlas/read/listAlerts.ts +2 -2
  139. package/src/tools/atlas/read/listClusters.ts +2 -2
  140. package/src/tools/atlas/read/listDBUsers.ts +2 -2
  141. package/src/tools/atlas/read/listOrgs.ts +2 -2
  142. package/src/tools/atlas/read/listProjects.ts +2 -2
  143. package/src/tools/atlas/tools.ts +1 -1
  144. package/src/tools/mongodb/{metadata → connect}/connect.ts +12 -9
  145. package/src/tools/mongodb/create/createCollection.ts +2 -2
  146. package/src/tools/mongodb/create/createIndex.ts +3 -3
  147. package/src/tools/mongodb/create/insertMany.ts +3 -3
  148. package/src/tools/mongodb/delete/deleteMany.ts +24 -3
  149. package/src/tools/mongodb/delete/dropCollection.ts +2 -2
  150. package/src/tools/mongodb/delete/dropDatabase.ts +2 -2
  151. package/src/tools/mongodb/metadata/collectionSchema.ts +2 -2
  152. package/src/tools/mongodb/metadata/collectionStorageSize.ts +2 -2
  153. package/src/tools/mongodb/metadata/dbStats.ts +2 -2
  154. package/src/tools/mongodb/metadata/explain.ts +4 -4
  155. package/src/tools/mongodb/metadata/listCollections.ts +2 -2
  156. package/src/tools/mongodb/metadata/listDatabases.ts +2 -2
  157. package/src/tools/mongodb/metadata/logs.ts +2 -2
  158. package/src/tools/mongodb/mongodbTool.ts +60 -14
  159. package/src/tools/mongodb/read/aggregate.ts +14 -3
  160. package/src/tools/mongodb/read/collectionIndexes.ts +2 -2
  161. package/src/tools/mongodb/read/count.ts +19 -3
  162. package/src/tools/mongodb/read/find.ts +20 -6
  163. package/src/tools/mongodb/tools.ts +1 -1
  164. package/src/tools/mongodb/update/renameCollection.ts +2 -2
  165. package/src/tools/mongodb/update/updateMany.ts +28 -4
  166. package/src/tools/tool.ts +23 -18
  167. package/src/transports/base.ts +34 -0
  168. package/src/{helpers/EJsonTransport.ts → transports/stdio.ts} +30 -1
  169. package/src/transports/streamableHttp.ts +178 -0
  170. package/tests/accuracy/aggregate.test.ts +27 -0
  171. package/tests/accuracy/collectionIndexes.test.ts +40 -0
  172. package/tests/accuracy/collectionSchema.test.ts +28 -0
  173. package/tests/accuracy/collectionStorageSize.test.ts +41 -0
  174. package/tests/accuracy/count.test.ts +44 -0
  175. package/tests/accuracy/createCollection.test.ts +46 -0
  176. package/tests/accuracy/createIndex.test.ts +37 -0
  177. package/tests/accuracy/dbStats.test.ts +15 -0
  178. package/tests/accuracy/deleteMany.test.ts +44 -0
  179. package/tests/accuracy/dropCollection.test.ts +74 -0
  180. package/tests/accuracy/dropDatabase.test.ts +41 -0
  181. package/tests/accuracy/explain.test.ts +73 -0
  182. package/tests/accuracy/find.test.ts +114 -0
  183. package/tests/accuracy/insertMany.test.ts +48 -0
  184. package/tests/accuracy/listCollections.test.ts +60 -0
  185. package/tests/accuracy/listDatabases.test.ts +31 -0
  186. package/tests/accuracy/logs.test.ts +28 -0
  187. package/tests/accuracy/renameCollection.test.ts +31 -0
  188. package/tests/accuracy/sdk/accuracyResultStorage/diskStorage.ts +189 -0
  189. package/tests/accuracy/sdk/accuracyResultStorage/getAccuracyResultStorage.ts +11 -0
  190. package/tests/accuracy/sdk/accuracyResultStorage/mongodbStorage.ts +151 -0
  191. package/tests/accuracy/sdk/accuracyResultStorage/resultStorage.ts +117 -0
  192. package/tests/accuracy/sdk/accuracyScorer.ts +93 -0
  193. package/tests/accuracy/sdk/accuracyTestingClient.ts +94 -0
  194. package/tests/accuracy/sdk/agent.ts +56 -0
  195. package/tests/accuracy/sdk/constants.ts +26 -0
  196. package/tests/accuracy/sdk/describeAccuracyTests.ts +126 -0
  197. package/tests/accuracy/sdk/gitInfo.ts +7 -0
  198. package/tests/accuracy/sdk/matcher.ts +193 -0
  199. package/tests/accuracy/sdk/models.ts +95 -0
  200. package/tests/accuracy/test-data-dumps/comics.books.json +417 -0
  201. package/tests/accuracy/test-data-dumps/comics.characters.json +402 -0
  202. package/tests/accuracy/test-data-dumps/mflix.movies.json +496 -0
  203. package/tests/accuracy/test-data-dumps/mflix.shows.json +572 -0
  204. package/tests/accuracy/updateMany.test.ts +42 -0
  205. package/tests/integration/helpers.ts +9 -9
  206. package/tests/integration/indexCheck.test.ts +464 -0
  207. package/tests/integration/server.test.ts +6 -4
  208. package/tests/integration/telemetry.test.ts +29 -0
  209. package/tests/integration/tools/atlas/accessLists.test.ts +22 -2
  210. package/tests/integration/tools/atlas/alerts.test.ts +3 -2
  211. package/tests/integration/tools/atlas/atlasHelpers.ts +3 -0
  212. package/tests/integration/tools/atlas/clusters.test.ts +68 -16
  213. package/tests/integration/tools/atlas/dbUsers.test.ts +14 -1
  214. package/tests/integration/tools/atlas/orgs.test.ts +2 -1
  215. package/tests/integration/tools/atlas/projects.test.ts +4 -3
  216. package/tests/integration/tools/mongodb/{metadata → connect}/connect.test.ts +34 -3
  217. package/tests/integration/tools/mongodb/create/createCollection.test.ts +1 -0
  218. package/tests/integration/tools/mongodb/create/createIndex.test.ts +1 -0
  219. package/tests/integration/tools/mongodb/create/insertMany.test.ts +1 -0
  220. package/tests/integration/tools/mongodb/delete/deleteMany.test.ts +1 -0
  221. package/tests/integration/tools/mongodb/delete/dropCollection.test.ts +1 -1
  222. package/tests/integration/tools/mongodb/delete/dropDatabase.test.ts +1 -0
  223. package/tests/integration/tools/mongodb/metadata/collectionSchema.test.ts +1 -0
  224. package/tests/integration/tools/mongodb/metadata/collectionStorageSize.test.ts +1 -0
  225. package/tests/integration/tools/mongodb/metadata/dbStats.test.ts +1 -0
  226. package/tests/integration/tools/mongodb/metadata/explain.test.ts +1 -0
  227. package/tests/integration/tools/mongodb/metadata/listCollections.test.ts +1 -0
  228. package/tests/integration/tools/mongodb/metadata/listDatabases.test.ts +3 -2
  229. package/tests/integration/tools/mongodb/metadata/logs.test.ts +1 -0
  230. package/tests/integration/tools/mongodb/mongodbHelpers.ts +67 -2
  231. package/tests/integration/tools/mongodb/read/aggregate.test.ts +2 -1
  232. package/tests/integration/tools/mongodb/read/collectionIndexes.test.ts +1 -0
  233. package/tests/integration/tools/mongodb/read/count.test.ts +1 -0
  234. package/tests/integration/tools/mongodb/read/find.test.ts +2 -1
  235. package/tests/integration/tools/mongodb/update/renameCollection.test.ts +1 -0
  236. package/tests/integration/tools/mongodb/update/updateMany.test.ts +1 -0
  237. package/tests/integration/transports/stdio.test.ts +40 -0
  238. package/tests/integration/transports/streamableHttp.test.ts +56 -0
  239. package/tests/matchers/toIncludeSameMembers.test.ts +59 -0
  240. package/tests/matchers/toIncludeSameMembers.ts +12 -0
  241. package/tests/setup.ts +7 -0
  242. package/tests/unit/accessListUtils.test.ts +39 -0
  243. package/tests/unit/accuracyScorer.test.ts +390 -0
  244. package/tests/unit/{apiClient.test.ts → common/apiClient.test.ts} +15 -15
  245. package/tests/unit/common/managedTimeout.test.ts +67 -0
  246. package/tests/unit/{session.test.ts → common/session.test.ts} +7 -12
  247. package/tests/unit/helpers/indexCheck.test.ts +150 -0
  248. package/tests/unit/telemetry.test.ts +99 -137
  249. package/tests/unit/{EJsonTransport.test.ts → transports/stdio.test.ts} +4 -4
  250. package/tests/vitest.d.ts +11 -0
  251. package/tsconfig.json +0 -1
  252. package/{tsconfig.jest.json → tsconfig.test.json} +1 -2
  253. package/vitest.config.ts +41 -0
  254. package/dist/common/atlas/generatePassword.js.map +0 -1
  255. package/dist/config.js.map +0 -1
  256. package/dist/errors.js.map +0 -1
  257. package/dist/helpers/EJsonTransport.js.map +0 -1
  258. package/dist/helpers/packageInfo.js.map +0 -1
  259. package/dist/logger.js.map +0 -1
  260. package/dist/session.js.map +0 -1
  261. package/dist/tools/atlas/metadata/connectCluster.js +0 -100
  262. package/dist/tools/atlas/metadata/connectCluster.js.map +0 -1
  263. package/dist/tools/mongodb/metadata/connect.js.map +0 -1
  264. package/global.d.ts +0 -1
  265. package/jest.config.cjs +0 -22
  266. package/src/tools/atlas/metadata/connectCluster.ts +0 -121
  267. /package/dist/{helpers → common}/packageInfo.js +0 -0
  268. /package/dist/{common/atlas → helpers}/generatePassword.js +0 -0
  269. /package/src/{helpers → common}/packageInfo.ts +0 -0
  270. /package/src/{common/atlas → helpers}/generatePassword.ts +0 -0
@@ -2,13 +2,12 @@ import { z } from "zod";
2
2
  import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { AtlasToolBase } from "../atlasTool.js";
4
4
  import { ToolArgs, OperationType } from "../../tool.js";
5
-
6
- const DEFAULT_COMMENT = "Added by Atlas MCP";
5
+ import { makeCurrentIpAccessListEntry, DEFAULT_ACCESS_LIST_COMMENT } from "../../../common/atlas/accessListUtils.js";
7
6
 
8
7
  export class CreateAccessListTool extends AtlasToolBase {
9
- protected name = "atlas-create-access-list";
8
+ public name = "atlas-create-access-list";
10
9
  protected description = "Allow Ip/CIDR ranges to access your MongoDB Atlas clusters.";
11
- protected operationType: OperationType = "create";
10
+ public operationType: OperationType = "create";
12
11
  protected argsShape = {
13
12
  projectId: z.string().describe("Atlas project ID"),
14
13
  ipAddresses: z
@@ -17,7 +16,11 @@ export class CreateAccessListTool extends AtlasToolBase {
17
16
  .optional(),
18
17
  cidrBlocks: z.array(z.string().cidr()).describe("CIDR blocks to allow access from").optional(),
19
18
  currentIpAddress: z.boolean().describe("Add the current IP address").default(false),
20
- comment: z.string().describe("Comment for the access list entries").default(DEFAULT_COMMENT).optional(),
19
+ comment: z
20
+ .string()
21
+ .describe("Comment for the access list entries")
22
+ .default(DEFAULT_ACCESS_LIST_COMMENT)
23
+ .optional(),
21
24
  };
22
25
 
23
26
  protected async execute({
@@ -34,23 +37,22 @@ export class CreateAccessListTool extends AtlasToolBase {
34
37
  const ipInputs = (ipAddresses || []).map((ipAddress) => ({
35
38
  groupId: projectId,
36
39
  ipAddress,
37
- comment: comment || DEFAULT_COMMENT,
40
+ comment: comment || DEFAULT_ACCESS_LIST_COMMENT,
38
41
  }));
39
42
 
40
43
  if (currentIpAddress) {
41
- const currentIp = await this.session.apiClient.getIpInfo();
42
- const input = {
43
- groupId: projectId,
44
- ipAddress: currentIp.currentIpv4Address,
45
- comment: comment || DEFAULT_COMMENT,
46
- };
44
+ const input = await makeCurrentIpAccessListEntry(
45
+ this.session.apiClient,
46
+ projectId,
47
+ comment || DEFAULT_ACCESS_LIST_COMMENT
48
+ );
47
49
  ipInputs.push(input);
48
50
  }
49
51
 
50
52
  const cidrInputs = (cidrBlocks || []).map((cidrBlock) => ({
51
53
  groupId: projectId,
52
54
  cidrBlock,
53
- comment: comment || DEFAULT_COMMENT,
55
+ comment: comment || DEFAULT_ACCESS_LIST_COMMENT,
54
56
  }));
55
57
 
56
58
  const inputs = [...ipInputs, ...cidrInputs];
@@ -3,12 +3,13 @@ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { AtlasToolBase } from "../atlasTool.js";
4
4
  import { ToolArgs, OperationType } from "../../tool.js";
5
5
  import { CloudDatabaseUser, DatabaseUserRole } from "../../../common/atlas/openapi.js";
6
- import { generateSecurePassword } from "../../../common/atlas/generatePassword.js";
6
+ import { generateSecurePassword } from "../../../helpers/generatePassword.js";
7
+ import { ensureCurrentIpInAccessList } from "../../../common/atlas/accessListUtils.js";
7
8
 
8
9
  export class CreateDBUserTool extends AtlasToolBase {
9
- protected name = "atlas-create-db-user";
10
+ public name = "atlas-create-db-user";
10
11
  protected description = "Create an MongoDB Atlas database user";
11
- protected operationType: OperationType = "create";
12
+ public operationType: OperationType = "create";
12
13
  protected argsShape = {
13
14
  projectId: z.string().describe("Atlas project ID"),
14
15
  username: z.string().describe("Username for the new user"),
@@ -44,6 +45,7 @@ export class CreateDBUserTool extends AtlasToolBase {
44
45
  roles,
45
46
  clusters,
46
47
  }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
48
+ await ensureCurrentIpInAccessList(this.session.apiClient, projectId);
47
49
  const shouldGeneratePassword = !password;
48
50
  if (shouldGeneratePassword) {
49
51
  password = await generateSecurePassword();
@@ -3,11 +3,12 @@ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { AtlasToolBase } from "../atlasTool.js";
4
4
  import { ToolArgs, OperationType } from "../../tool.js";
5
5
  import { ClusterDescription20240805 } from "../../../common/atlas/openapi.js";
6
+ import { ensureCurrentIpInAccessList } from "../../../common/atlas/accessListUtils.js";
6
7
 
7
8
  export class CreateFreeClusterTool extends AtlasToolBase {
8
- protected name = "atlas-create-free-cluster";
9
+ public name = "atlas-create-free-cluster";
9
10
  protected description = "Create a free MongoDB Atlas cluster";
10
- protected operationType: OperationType = "create";
11
+ public operationType: OperationType = "create";
11
12
  protected argsShape = {
12
13
  projectId: z.string().describe("Atlas project ID to create the cluster in"),
13
14
  name: z.string().describe("Name of the cluster"),
@@ -37,6 +38,7 @@ export class CreateFreeClusterTool extends AtlasToolBase {
37
38
  terminationProtectionEnabled: false,
38
39
  } as unknown as ClusterDescription20240805;
39
40
 
41
+ await ensureCurrentIpInAccessList(this.session.apiClient, projectId);
40
42
  await this.session.apiClient.createCluster({
41
43
  params: {
42
44
  path: {
@@ -5,9 +5,9 @@ import { ToolArgs, OperationType } from "../../tool.js";
5
5
  import { Group } from "../../../common/atlas/openapi.js";
6
6
 
7
7
  export class CreateProjectTool extends AtlasToolBase {
8
- protected name = "atlas-create-project";
8
+ public name = "atlas-create-project";
9
9
  protected description = "Create a MongoDB Atlas project";
10
- protected operationType: OperationType = "create";
10
+ public operationType: OperationType = "create";
11
11
  protected argsShape = {
12
12
  projectName: z.string().optional().describe("Name for the new project"),
13
13
  organizationId: z.string().optional().describe("Organization ID for the new project"),
@@ -4,9 +4,9 @@ import { AtlasToolBase } from "../atlasTool.js";
4
4
  import { ToolArgs, OperationType } from "../../tool.js";
5
5
 
6
6
  export class InspectAccessListTool extends AtlasToolBase {
7
- protected name = "atlas-inspect-access-list";
7
+ public name = "atlas-inspect-access-list";
8
8
  protected description = "Inspect Ip/CIDR ranges with access to your MongoDB Atlas clusters.";
9
- protected operationType: OperationType = "read";
9
+ public operationType: OperationType = "read";
10
10
  protected argsShape = {
11
11
  projectId: z.string().describe("Atlas project ID"),
12
12
  };
@@ -5,9 +5,9 @@ import { ToolArgs, OperationType } from "../../tool.js";
5
5
  import { Cluster, inspectCluster } from "../../../common/atlas/cluster.js";
6
6
 
7
7
  export class InspectClusterTool extends AtlasToolBase {
8
- protected name = "atlas-inspect-cluster";
8
+ public name = "atlas-inspect-cluster";
9
9
  protected description = "Inspect MongoDB Atlas cluster";
10
- protected operationType: OperationType = "read";
10
+ public operationType: OperationType = "read";
11
11
  protected argsShape = {
12
12
  projectId: z.string().describe("Atlas project ID"),
13
13
  clusterName: z.string().describe("Atlas cluster name"),
@@ -4,9 +4,9 @@ import { AtlasToolBase } from "../atlasTool.js";
4
4
  import { ToolArgs, OperationType } from "../../tool.js";
5
5
 
6
6
  export class ListAlertsTool extends AtlasToolBase {
7
- protected name = "atlas-list-alerts";
7
+ public name = "atlas-list-alerts";
8
8
  protected description = "List MongoDB Atlas alerts";
9
- protected operationType: OperationType = "read";
9
+ public operationType: OperationType = "read";
10
10
  protected argsShape = {
11
11
  projectId: z.string().describe("Atlas project ID to list alerts for"),
12
12
  };
@@ -11,9 +11,9 @@ import {
11
11
  import { formatCluster, formatFlexCluster } from "../../../common/atlas/cluster.js";
12
12
 
13
13
  export class ListClustersTool extends AtlasToolBase {
14
- protected name = "atlas-list-clusters";
14
+ public name = "atlas-list-clusters";
15
15
  protected description = "List MongoDB Atlas clusters";
16
- protected operationType: OperationType = "read";
16
+ public operationType: OperationType = "read";
17
17
  protected argsShape = {
18
18
  projectId: z.string().describe("Atlas project ID to filter clusters").optional(),
19
19
  };
@@ -5,9 +5,9 @@ import { ToolArgs, OperationType } from "../../tool.js";
5
5
  import { DatabaseUserRole, UserScope } from "../../../common/atlas/openapi.js";
6
6
 
7
7
  export class ListDBUsersTool extends AtlasToolBase {
8
- protected name = "atlas-list-db-users";
8
+ public name = "atlas-list-db-users";
9
9
  protected description = "List MongoDB Atlas database users";
10
- protected operationType: OperationType = "read";
10
+ public operationType: OperationType = "read";
11
11
  protected argsShape = {
12
12
  projectId: z.string().describe("Atlas project ID to filter DB users"),
13
13
  };
@@ -3,9 +3,9 @@ import { AtlasToolBase } from "../atlasTool.js";
3
3
  import { OperationType } from "../../tool.js";
4
4
 
5
5
  export class ListOrganizationsTool extends AtlasToolBase {
6
- protected name = "atlas-list-orgs";
6
+ public name = "atlas-list-orgs";
7
7
  protected description = "List MongoDB Atlas organizations";
8
- protected operationType: OperationType = "read";
8
+ public operationType: OperationType = "read";
9
9
  protected argsShape = {};
10
10
 
11
11
  protected async execute(): Promise<CallToolResult> {
@@ -5,9 +5,9 @@ import { z } from "zod";
5
5
  import { ToolArgs } from "../../tool.js";
6
6
 
7
7
  export class ListProjectsTool extends AtlasToolBase {
8
- protected name = "atlas-list-projects";
8
+ public name = "atlas-list-projects";
9
9
  protected description = "List MongoDB Atlas projects";
10
- protected operationType: OperationType = "read";
10
+ public operationType: OperationType = "read";
11
11
  protected argsShape = {
12
12
  orgId: z.string().describe("Atlas organization ID to filter projects").optional(),
13
13
  };
@@ -8,7 +8,7 @@ import { ListDBUsersTool } from "./read/listDBUsers.js";
8
8
  import { CreateDBUserTool } from "./create/createDBUser.js";
9
9
  import { CreateProjectTool } from "./create/createProject.js";
10
10
  import { ListOrganizationsTool } from "./read/listOrgs.js";
11
- import { ConnectClusterTool } from "./metadata/connectCluster.js";
11
+ import { ConnectClusterTool } from "./connect/connectCluster.js";
12
12
  import { ListAlertsTool } from "./read/listAlerts.js";
13
13
 
14
14
  export const AtlasTools = [
@@ -2,11 +2,11 @@ import { z } from "zod";
2
2
  import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { MongoDBToolBase } from "../mongodbTool.js";
4
4
  import { ToolArgs, OperationType } from "../../tool.js";
5
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
5
  import assert from "assert";
7
- import { UserConfig } from "../../../config.js";
6
+ import { UserConfig } from "../../../common/config.js";
8
7
  import { Telemetry } from "../../../telemetry/telemetry.js";
9
- import { Session } from "../../../session.js";
8
+ import { Session } from "../../../common/session.js";
9
+ import { Server } from "../../../server.js";
10
10
 
11
11
  const disconnectedSchema = z
12
12
  .object({
@@ -33,7 +33,7 @@ const connectedDescription =
33
33
  const disconnectedDescription = "Connect to a MongoDB instance";
34
34
 
35
35
  export class ConnectTool extends MongoDBToolBase {
36
- protected name: typeof connectedName | typeof disconnectedName = disconnectedName;
36
+ public name: typeof connectedName | typeof disconnectedName = disconnectedName;
37
37
  protected description: typeof connectedDescription | typeof disconnectedDescription = disconnectedDescription;
38
38
 
39
39
  // Here the default is empty just to trigger registration, but we're going to override it with the correct
@@ -42,11 +42,11 @@ export class ConnectTool extends MongoDBToolBase {
42
42
  connectionString: z.string().optional(),
43
43
  };
44
44
 
45
- protected operationType: OperationType = "metadata";
45
+ public operationType: OperationType = "connect";
46
46
 
47
47
  constructor(session: Session, config: UserConfig, telemetry: Telemetry) {
48
48
  super(session, config, telemetry);
49
- session.on("close", () => {
49
+ session.on("disconnect", () => {
50
50
  this.updateMetadata();
51
51
  });
52
52
  }
@@ -72,10 +72,13 @@ export class ConnectTool extends MongoDBToolBase {
72
72
  };
73
73
  }
74
74
 
75
- public register(server: McpServer): void {
76
- super.register(server);
75
+ public register(server: Server): boolean {
76
+ if (super.register(server)) {
77
+ this.updateMetadata();
78
+ return true;
79
+ }
77
80
 
78
- this.updateMetadata();
81
+ return false;
79
82
  }
80
83
 
81
84
  private updateMetadata(): void {
@@ -3,12 +3,12 @@ import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
3
3
  import { OperationType, ToolArgs } from "../../tool.js";
4
4
 
5
5
  export class CreateCollectionTool extends MongoDBToolBase {
6
- protected name = "create-collection";
6
+ public name = "create-collection";
7
7
  protected description =
8
8
  "Creates a new collection in a database. If the database doesn't exist, it will be created automatically.";
9
9
  protected argsShape = DbOperationArgs;
10
10
 
11
- protected operationType: OperationType = "create";
11
+ public operationType: OperationType = "create";
12
12
 
13
13
  protected async execute({ collection, database }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
14
14
  const provider = await this.ensureConnected();
@@ -5,15 +5,15 @@ import { ToolArgs, OperationType } from "../../tool.js";
5
5
  import { IndexDirection } from "mongodb";
6
6
 
7
7
  export class CreateIndexTool extends MongoDBToolBase {
8
- protected name = "create-index";
8
+ public name = "create-index";
9
9
  protected description = "Create an index for a collection";
10
10
  protected argsShape = {
11
11
  ...DbOperationArgs,
12
- keys: z.record(z.string(), z.custom<IndexDirection>()).describe("The index definition"),
12
+ keys: z.object({}).catchall(z.custom<IndexDirection>()).describe("The index definition"),
13
13
  name: z.string().optional().describe("The name of the index"),
14
14
  };
15
15
 
16
- protected operationType: OperationType = "create";
16
+ public operationType: OperationType = "create";
17
17
 
18
18
  protected async execute({
19
19
  database,
@@ -4,17 +4,17 @@ import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
4
4
  import { ToolArgs, OperationType } from "../../tool.js";
5
5
 
6
6
  export class InsertManyTool extends MongoDBToolBase {
7
- protected name = "insert-many";
7
+ public name = "insert-many";
8
8
  protected description = "Insert an array of documents into a MongoDB collection";
9
9
  protected argsShape = {
10
10
  ...DbOperationArgs,
11
11
  documents: z
12
- .array(z.record(z.string(), z.unknown()).describe("An individual MongoDB document"))
12
+ .array(z.object({}).passthrough().describe("An individual MongoDB document"))
13
13
  .describe(
14
14
  "The array of documents to insert, matching the syntax of the document argument of db.collection.insertMany()"
15
15
  ),
16
16
  };
17
- protected operationType: OperationType = "create";
17
+ public operationType: OperationType = "create";
18
18
 
19
19
  protected async execute({
20
20
  database,
@@ -2,20 +2,22 @@ import { z } from "zod";
2
2
  import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
4
4
  import { ToolArgs, OperationType } from "../../tool.js";
5
+ import { checkIndexUsage } from "../../../helpers/indexCheck.js";
5
6
 
6
7
  export class DeleteManyTool extends MongoDBToolBase {
7
- protected name = "delete-many";
8
+ public name = "delete-many";
8
9
  protected description = "Removes all documents that match the filter from a MongoDB collection";
9
10
  protected argsShape = {
10
11
  ...DbOperationArgs,
11
12
  filter: z
12
- .record(z.string(), z.unknown())
13
+ .object({})
14
+ .passthrough()
13
15
  .optional()
14
16
  .describe(
15
17
  "The query filter, specifying the deletion criteria. Matches the syntax of the filter argument of db.collection.deleteMany()"
16
18
  ),
17
19
  };
18
- protected operationType: OperationType = "delete";
20
+ public operationType: OperationType = "delete";
19
21
 
20
22
  protected async execute({
21
23
  database,
@@ -23,6 +25,25 @@ export class DeleteManyTool extends MongoDBToolBase {
23
25
  filter,
24
26
  }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
25
27
  const provider = await this.ensureConnected();
28
+
29
+ // Check if delete operation uses an index if enabled
30
+ if (this.config.indexCheck) {
31
+ await checkIndexUsage(provider, database, collection, "deleteMany", async () => {
32
+ return provider.runCommandWithCheck(database, {
33
+ explain: {
34
+ delete: collection,
35
+ deletes: [
36
+ {
37
+ q: filter || {},
38
+ limit: 0, // 0 means delete all matching documents
39
+ },
40
+ ],
41
+ },
42
+ verbosity: "queryPlanner",
43
+ });
44
+ });
45
+ }
46
+
26
47
  const result = await provider.deleteMany(database, collection, filter);
27
48
 
28
49
  return {
@@ -3,13 +3,13 @@ import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
3
3
  import { ToolArgs, OperationType } from "../../tool.js";
4
4
 
5
5
  export class DropCollectionTool extends MongoDBToolBase {
6
- protected name = "drop-collection";
6
+ public name = "drop-collection";
7
7
  protected description =
8
8
  "Removes a collection or view from the database. The method also removes any indexes associated with the dropped collection.";
9
9
  protected argsShape = {
10
10
  ...DbOperationArgs,
11
11
  };
12
- protected operationType: OperationType = "delete";
12
+ public operationType: OperationType = "delete";
13
13
 
14
14
  protected async execute({ database, collection }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
15
15
  const provider = await this.ensureConnected();
@@ -3,12 +3,12 @@ import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
3
3
  import { ToolArgs, OperationType } from "../../tool.js";
4
4
 
5
5
  export class DropDatabaseTool extends MongoDBToolBase {
6
- protected name = "drop-database";
6
+ public name = "drop-database";
7
7
  protected description = "Removes the specified database, deleting the associated data files";
8
8
  protected argsShape = {
9
9
  database: DbOperationArgs.database,
10
10
  };
11
- protected operationType: OperationType = "delete";
11
+ public operationType: OperationType = "delete";
12
12
 
13
13
  protected async execute({ database }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
14
14
  const provider = await this.ensureConnected();
@@ -4,11 +4,11 @@ import { ToolArgs, OperationType } from "../../tool.js";
4
4
  import { getSimplifiedSchema } from "mongodb-schema";
5
5
 
6
6
  export class CollectionSchemaTool extends MongoDBToolBase {
7
- protected name = "collection-schema";
7
+ public name = "collection-schema";
8
8
  protected description = "Describe the schema for a collection";
9
9
  protected argsShape = DbOperationArgs;
10
10
 
11
- protected operationType: OperationType = "metadata";
11
+ public operationType: OperationType = "metadata";
12
12
 
13
13
  protected async execute({ database, collection }: ToolArgs<typeof DbOperationArgs>): Promise<CallToolResult> {
14
14
  const provider = await this.ensureConnected();
@@ -3,11 +3,11 @@ import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
3
3
  import { ToolArgs, OperationType } from "../../tool.js";
4
4
 
5
5
  export class CollectionStorageSizeTool extends MongoDBToolBase {
6
- protected name = "collection-storage-size";
6
+ public name = "collection-storage-size";
7
7
  protected description = "Gets the size of the collection";
8
8
  protected argsShape = DbOperationArgs;
9
9
 
10
- protected operationType: OperationType = "metadata";
10
+ public operationType: OperationType = "metadata";
11
11
 
12
12
  protected async execute({ database, collection }: ToolArgs<typeof DbOperationArgs>): Promise<CallToolResult> {
13
13
  const provider = await this.ensureConnected();
@@ -4,13 +4,13 @@ import { ToolArgs, OperationType } from "../../tool.js";
4
4
  import { EJSON } from "bson";
5
5
 
6
6
  export class DbStatsTool extends MongoDBToolBase {
7
- protected name = "db-stats";
7
+ public name = "db-stats";
8
8
  protected description = "Returns statistics that reflect the use state of a single database";
9
9
  protected argsShape = {
10
10
  database: DbOperationArgs.database,
11
11
  };
12
12
 
13
- protected operationType: OperationType = "metadata";
13
+ public operationType: OperationType = "metadata";
14
14
 
15
15
  protected async execute({ database }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
16
16
  const provider = await this.ensureConnected();
@@ -8,7 +8,7 @@ import { FindArgs } from "../read/find.js";
8
8
  import { CountArgs } from "../read/count.js";
9
9
 
10
10
  export class ExplainTool extends MongoDBToolBase {
11
- protected name = "explain";
11
+ public name = "explain";
12
12
  protected description =
13
13
  "Returns statistics describing the execution of the winning plan chosen by the query optimizer for the evaluated method";
14
14
 
@@ -16,7 +16,7 @@ export class ExplainTool extends MongoDBToolBase {
16
16
  ...DbOperationArgs,
17
17
  method: z
18
18
  .array(
19
- z.union([
19
+ z.discriminatedUnion("name", [
20
20
  z.object({
21
21
  name: z.literal("aggregate"),
22
22
  arguments: z.object(AggregateArgs),
@@ -34,7 +34,7 @@ export class ExplainTool extends MongoDBToolBase {
34
34
  .describe("The method and its arguments to run"),
35
35
  };
36
36
 
37
- protected operationType: OperationType = "metadata";
37
+ public operationType: OperationType = "metadata";
38
38
 
39
39
  static readonly defaultVerbosity = ExplainVerbosity.queryPlanner;
40
40
 
@@ -76,7 +76,7 @@ export class ExplainTool extends MongoDBToolBase {
76
76
  }
77
77
  case "count": {
78
78
  const { query } = method.arguments;
79
- result = await provider.mongoClient.db(database).command({
79
+ result = await provider.runCommandWithCheck(database, {
80
80
  explain: {
81
81
  count: collection,
82
82
  query,
@@ -3,13 +3,13 @@ import { DbOperationArgs, MongoDBToolBase } from "../mongodbTool.js";
3
3
  import { ToolArgs, OperationType } from "../../tool.js";
4
4
 
5
5
  export class ListCollectionsTool extends MongoDBToolBase {
6
- protected name = "list-collections";
6
+ public name = "list-collections";
7
7
  protected description = "List all collections for a given database";
8
8
  protected argsShape = {
9
9
  database: DbOperationArgs.database,
10
10
  };
11
11
 
12
- protected operationType: OperationType = "metadata";
12
+ public operationType: OperationType = "metadata";
13
13
 
14
14
  protected async execute({ database }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
15
15
  const provider = await this.ensureConnected();
@@ -4,10 +4,10 @@ import * as bson from "bson";
4
4
  import { OperationType } from "../../tool.js";
5
5
 
6
6
  export class ListDatabasesTool extends MongoDBToolBase {
7
- protected name = "list-databases";
7
+ public name = "list-databases";
8
8
  protected description = "List all databases for a MongoDB connection";
9
9
  protected argsShape = {};
10
- protected operationType: OperationType = "metadata";
10
+ public operationType: OperationType = "metadata";
11
11
 
12
12
  protected async execute(): Promise<CallToolResult> {
13
13
  const provider = await this.ensureConnected();
@@ -4,7 +4,7 @@ import { ToolArgs, OperationType } from "../../tool.js";
4
4
  import { z } from "zod";
5
5
 
6
6
  export class LogsTool extends MongoDBToolBase {
7
- protected name = "mongodb-logs";
7
+ public name = "mongodb-logs";
8
8
  protected description = "Returns the most recent logged mongod events";
9
9
  protected argsShape = {
10
10
  type: z
@@ -24,7 +24,7 @@ export class LogsTool extends MongoDBToolBase {
24
24
  .describe("The maximum number of log entries to return."),
25
25
  };
26
26
 
27
- protected operationType: OperationType = "metadata";
27
+ public operationType: OperationType = "metadata";
28
28
 
29
29
  protected async execute({ type, limit }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
30
30
  const provider = await this.ensureConnected();