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
@@ -0,0 +1,178 @@
1
+ import express from "express";
2
+ import http from "http";
3
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
5
+ import { TransportRunnerBase } from "./base.js";
6
+ import { UserConfig } from "../common/config.js";
7
+ import logger, { LogId } from "../common/logger.js";
8
+ import { randomUUID } from "crypto";
9
+ import { SessionStore } from "../common/sessionStore.js";
10
+
11
+ const JSON_RPC_ERROR_CODE_PROCESSING_REQUEST_FAILED = -32000;
12
+ const JSON_RPC_ERROR_CODE_SESSION_ID_REQUIRED = -32001;
13
+ const JSON_RPC_ERROR_CODE_SESSION_ID_INVALID = -32002;
14
+ const JSON_RPC_ERROR_CODE_SESSION_NOT_FOUND = -32003;
15
+ const JSON_RPC_ERROR_CODE_INVALID_REQUEST = -32004;
16
+
17
+ function withErrorHandling(
18
+ fn: (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void>
19
+ ) {
20
+ return (req: express.Request, res: express.Response, next: express.NextFunction) => {
21
+ fn(req, res, next).catch((error) => {
22
+ logger.error(
23
+ LogId.streamableHttpTransportRequestFailure,
24
+ "streamableHttpTransport",
25
+ `Error handling request: ${error instanceof Error ? error.message : String(error)}`
26
+ );
27
+ res.status(400).json({
28
+ jsonrpc: "2.0",
29
+ error: {
30
+ code: JSON_RPC_ERROR_CODE_PROCESSING_REQUEST_FAILED,
31
+ message: `failed to handle request`,
32
+ data: error instanceof Error ? error.message : String(error),
33
+ },
34
+ });
35
+ });
36
+ };
37
+ }
38
+
39
+ export class StreamableHttpRunner extends TransportRunnerBase {
40
+ private httpServer: http.Server | undefined;
41
+ private sessionStore: SessionStore;
42
+
43
+ constructor(private userConfig: UserConfig) {
44
+ super();
45
+ this.sessionStore = new SessionStore(this.userConfig.idleTimeoutMs, this.userConfig.notificationTimeoutMs);
46
+ }
47
+
48
+ async start() {
49
+ const app = express();
50
+ app.enable("trust proxy"); // needed for reverse proxy support
51
+ app.use(express.json());
52
+
53
+ const handleSessionRequest = async (req: express.Request, res: express.Response) => {
54
+ const sessionId = req.headers["mcp-session-id"];
55
+ if (!sessionId) {
56
+ res.status(400).json({
57
+ jsonrpc: "2.0",
58
+ error: {
59
+ code: JSON_RPC_ERROR_CODE_SESSION_ID_REQUIRED,
60
+ message: `session id is required`,
61
+ },
62
+ });
63
+ return;
64
+ }
65
+ if (typeof sessionId !== "string") {
66
+ res.status(400).json({
67
+ jsonrpc: "2.0",
68
+ error: {
69
+ code: JSON_RPC_ERROR_CODE_SESSION_ID_INVALID,
70
+ message: `session id is invalid`,
71
+ },
72
+ });
73
+ return;
74
+ }
75
+ const transport = this.sessionStore.getSession(sessionId);
76
+ if (!transport) {
77
+ res.status(404).json({
78
+ jsonrpc: "2.0",
79
+ error: {
80
+ code: JSON_RPC_ERROR_CODE_SESSION_NOT_FOUND,
81
+ message: `session not found`,
82
+ },
83
+ });
84
+ return;
85
+ }
86
+ await transport.handleRequest(req, res, req.body);
87
+ };
88
+
89
+ app.post(
90
+ "/mcp",
91
+ withErrorHandling(async (req: express.Request, res: express.Response) => {
92
+ const sessionId = req.headers["mcp-session-id"];
93
+ if (sessionId) {
94
+ await handleSessionRequest(req, res);
95
+ return;
96
+ }
97
+
98
+ if (!isInitializeRequest(req.body)) {
99
+ res.status(400).json({
100
+ jsonrpc: "2.0",
101
+ error: {
102
+ code: JSON_RPC_ERROR_CODE_INVALID_REQUEST,
103
+ message: `invalid request`,
104
+ },
105
+ });
106
+ return;
107
+ }
108
+
109
+ const server = this.setupServer(this.userConfig);
110
+ const transport = new StreamableHTTPServerTransport({
111
+ sessionIdGenerator: () => randomUUID().toString(),
112
+ onsessioninitialized: (sessionId) => {
113
+ this.sessionStore.setSession(sessionId, transport, server.mcpServer);
114
+ },
115
+ onsessionclosed: async (sessionId) => {
116
+ try {
117
+ await this.sessionStore.closeSession(sessionId, false);
118
+ } catch (error) {
119
+ logger.error(
120
+ LogId.streamableHttpTransportSessionCloseFailure,
121
+ "streamableHttpTransport",
122
+ `Error closing session: ${error instanceof Error ? error.message : String(error)}`
123
+ );
124
+ }
125
+ },
126
+ });
127
+
128
+ transport.onclose = () => {
129
+ server.close().catch((error) => {
130
+ logger.error(
131
+ LogId.streamableHttpTransportCloseFailure,
132
+ "streamableHttpTransport",
133
+ `Error closing server: ${error instanceof Error ? error.message : String(error)}`
134
+ );
135
+ });
136
+ };
137
+
138
+ await server.connect(transport);
139
+
140
+ await transport.handleRequest(req, res, req.body);
141
+ })
142
+ );
143
+
144
+ app.get("/mcp", withErrorHandling(handleSessionRequest));
145
+ app.delete("/mcp", withErrorHandling(handleSessionRequest));
146
+
147
+ this.httpServer = await new Promise<http.Server>((resolve, reject) => {
148
+ const result = app.listen(this.userConfig.httpPort, this.userConfig.httpHost, (err?: Error) => {
149
+ if (err) {
150
+ reject(err);
151
+ return;
152
+ }
153
+ resolve(result);
154
+ });
155
+ });
156
+
157
+ logger.info(
158
+ LogId.streamableHttpTransportStarted,
159
+ "streamableHttpTransport",
160
+ `Server started on http://${this.userConfig.httpHost}:${this.userConfig.httpPort}`
161
+ );
162
+ }
163
+
164
+ async close(): Promise<void> {
165
+ await Promise.all([
166
+ this.sessionStore.closeAllSessions(),
167
+ new Promise<void>((resolve, reject) => {
168
+ this.httpServer?.close((err) => {
169
+ if (err) {
170
+ reject(err);
171
+ return;
172
+ }
173
+ resolve();
174
+ });
175
+ }),
176
+ ]);
177
+ }
178
+ }
@@ -0,0 +1,27 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+ import { Matcher } from "./sdk/matcher.js";
3
+
4
+ describeAccuracyTests([
5
+ {
6
+ prompt: "Group all the movies in 'mflix.movies' namespace by 'release_year' and give me a count of them",
7
+ expectedToolCalls: [
8
+ {
9
+ toolName: "aggregate",
10
+ parameters: {
11
+ database: "mflix",
12
+ collection: "movies",
13
+ pipeline: [
14
+ { $group: { _id: "$release_year", count: { $sum: 1 } } },
15
+ // For the sake of accuracy, we allow any sort order
16
+ Matcher.anyOf(
17
+ Matcher.undefined,
18
+ Matcher.value({
19
+ $sort: Matcher.anyValue,
20
+ })
21
+ ),
22
+ ],
23
+ },
24
+ },
25
+ ],
26
+ },
27
+ ]);
@@ -0,0 +1,40 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+
3
+ describeAccuracyTests([
4
+ {
5
+ prompt: "How many indexes do I have in 'mflix.movies' namespace?",
6
+ expectedToolCalls: [
7
+ {
8
+ toolName: "collection-indexes",
9
+ parameters: {
10
+ database: "mflix",
11
+ collection: "movies",
12
+ },
13
+ },
14
+ ],
15
+ },
16
+ {
17
+ prompt: "List all the indexes in movies collection in mflix database",
18
+ expectedToolCalls: [
19
+ {
20
+ toolName: "collection-indexes",
21
+ parameters: {
22
+ database: "mflix",
23
+ collection: "movies",
24
+ },
25
+ },
26
+ ],
27
+ },
28
+ {
29
+ prompt: `Is the following query: ${JSON.stringify({ runtime: { $lt: 100 } })} on the namespace 'mflix.movies' indexed?`,
30
+ expectedToolCalls: [
31
+ {
32
+ toolName: "collection-indexes",
33
+ parameters: {
34
+ database: "mflix",
35
+ collection: "movies",
36
+ },
37
+ },
38
+ ],
39
+ },
40
+ ]);
@@ -0,0 +1,28 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+
3
+ describeAccuracyTests([
4
+ {
5
+ prompt: "Is there a title field in 'mflix.movies' namespace?",
6
+ expectedToolCalls: [
7
+ {
8
+ toolName: "collection-schema",
9
+ parameters: {
10
+ database: "mflix",
11
+ collection: "movies",
12
+ },
13
+ },
14
+ ],
15
+ },
16
+ {
17
+ prompt: "What is the type of value stored in title field in movies collection in mflix database?",
18
+ expectedToolCalls: [
19
+ {
20
+ toolName: "collection-schema",
21
+ parameters: {
22
+ database: "mflix",
23
+ collection: "movies",
24
+ },
25
+ },
26
+ ],
27
+ },
28
+ ]);
@@ -0,0 +1,41 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+
3
+ describeAccuracyTests([
4
+ {
5
+ prompt: "What is the size of 'mflix.movies' namespace",
6
+ expectedToolCalls: [
7
+ {
8
+ toolName: "collection-storage-size",
9
+ parameters: {
10
+ database: "mflix",
11
+ collection: "movies",
12
+ },
13
+ },
14
+ ],
15
+ },
16
+ {
17
+ prompt: "How much size is each collection in comics database",
18
+ expectedToolCalls: [
19
+ {
20
+ toolName: "list-collections",
21
+ parameters: {
22
+ database: "comics",
23
+ },
24
+ },
25
+ {
26
+ toolName: "collection-storage-size",
27
+ parameters: {
28
+ database: "comics",
29
+ collection: "books",
30
+ },
31
+ },
32
+ {
33
+ toolName: "collection-storage-size",
34
+ parameters: {
35
+ database: "comics",
36
+ collection: "characters",
37
+ },
38
+ },
39
+ ],
40
+ },
41
+ ]);
@@ -0,0 +1,44 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+ import { Matcher } from "./sdk/matcher.js";
3
+
4
+ describeAccuracyTests([
5
+ {
6
+ prompt: "Count number of documents in 'mflix.movies' namespace.",
7
+ expectedToolCalls: [
8
+ {
9
+ toolName: "count",
10
+ parameters: {
11
+ database: "mflix",
12
+ collection: "movies",
13
+ query: Matcher.emptyObjectOrUndefined,
14
+ },
15
+ },
16
+ ],
17
+ },
18
+ {
19
+ prompt: "How many documents are there in 'characters' collection in 'comics' database?",
20
+ expectedToolCalls: [
21
+ {
22
+ toolName: "count",
23
+ parameters: {
24
+ database: "comics",
25
+ collection: "characters",
26
+ query: Matcher.emptyObjectOrUndefined,
27
+ },
28
+ },
29
+ ],
30
+ },
31
+ {
32
+ prompt: "Count all the documents in 'mflix.movies' namespace with runtime less than 100?",
33
+ expectedToolCalls: [
34
+ {
35
+ toolName: "count",
36
+ parameters: {
37
+ database: "mflix",
38
+ collection: "movies",
39
+ query: { runtime: { $lt: 100 } },
40
+ },
41
+ },
42
+ ],
43
+ },
44
+ ]);
@@ -0,0 +1,46 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+
3
+ describeAccuracyTests([
4
+ {
5
+ prompt: "Create a new namespace 'mflix.documentaries'",
6
+ expectedToolCalls: [
7
+ {
8
+ toolName: "create-collection",
9
+ parameters: {
10
+ database: "mflix",
11
+ collection: "documentaries",
12
+ },
13
+ },
14
+ ],
15
+ },
16
+ {
17
+ prompt: "Create a new collection villains in comics database",
18
+ expectedToolCalls: [
19
+ {
20
+ toolName: "create-collection",
21
+ parameters: {
22
+ database: "comics",
23
+ collection: "villains",
24
+ },
25
+ },
26
+ ],
27
+ },
28
+ {
29
+ prompt: "If and only if, the namespace 'mflix.documentaries' does not exist, then create it",
30
+ expectedToolCalls: [
31
+ {
32
+ toolName: "list-collections",
33
+ parameters: {
34
+ database: "mflix",
35
+ },
36
+ },
37
+ {
38
+ toolName: "create-collection",
39
+ parameters: {
40
+ database: "mflix",
41
+ collection: "documentaries",
42
+ },
43
+ },
44
+ ],
45
+ },
46
+ ]);
@@ -0,0 +1,37 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+ import { Matcher } from "./sdk/matcher.js";
3
+
4
+ describeAccuracyTests([
5
+ {
6
+ prompt: "Create an index that covers the following query on 'mflix.movies' namespace - { \"release_year\": 1992 }",
7
+ expectedToolCalls: [
8
+ {
9
+ toolName: "create-index",
10
+ parameters: {
11
+ database: "mflix",
12
+ collection: "movies",
13
+ name: Matcher.anyOf(Matcher.undefined, Matcher.string()),
14
+ keys: {
15
+ release_year: 1,
16
+ },
17
+ },
18
+ },
19
+ ],
20
+ },
21
+ {
22
+ prompt: "Create a text index on title field in 'mflix.movies' namespace",
23
+ expectedToolCalls: [
24
+ {
25
+ toolName: "create-index",
26
+ parameters: {
27
+ database: "mflix",
28
+ collection: "movies",
29
+ name: Matcher.anyOf(Matcher.undefined, Matcher.string()),
30
+ keys: {
31
+ title: "text",
32
+ },
33
+ },
34
+ },
35
+ ],
36
+ },
37
+ ]);
@@ -0,0 +1,15 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+
3
+ describeAccuracyTests([
4
+ {
5
+ prompt: "What is the size occupied by database mflix?",
6
+ expectedToolCalls: [
7
+ {
8
+ toolName: "db-stats",
9
+ parameters: {
10
+ database: "mflix",
11
+ },
12
+ },
13
+ ],
14
+ },
15
+ ]);
@@ -0,0 +1,44 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+ import { Matcher } from "./sdk/matcher.js";
3
+
4
+ describeAccuracyTests([
5
+ {
6
+ prompt: "Delete all the documents from 'mflix.movies' namespace",
7
+ expectedToolCalls: [
8
+ {
9
+ toolName: "delete-many",
10
+ parameters: {
11
+ database: "mflix",
12
+ collection: "movies",
13
+ filter: Matcher.emptyObjectOrUndefined,
14
+ },
15
+ },
16
+ ],
17
+ },
18
+ {
19
+ prompt: "Purge the collection 'movies' in database 'mflix'",
20
+ expectedToolCalls: [
21
+ {
22
+ toolName: "delete-many",
23
+ parameters: {
24
+ database: "mflix",
25
+ collection: "movies",
26
+ filter: Matcher.emptyObjectOrUndefined,
27
+ },
28
+ },
29
+ ],
30
+ },
31
+ {
32
+ prompt: "Remove all the documents from namespace 'mflix.movies' where runtime is less than 100",
33
+ expectedToolCalls: [
34
+ {
35
+ toolName: "delete-many",
36
+ parameters: {
37
+ database: "mflix",
38
+ collection: "movies",
39
+ filter: { runtime: { $lt: 100 } },
40
+ },
41
+ },
42
+ ],
43
+ },
44
+ ]);
@@ -0,0 +1,74 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+
3
+ describeAccuracyTests([
4
+ {
5
+ prompt: "Remove mflix.movies namespace from my cluster.",
6
+ expectedToolCalls: [
7
+ {
8
+ toolName: "drop-collection",
9
+ parameters: {
10
+ database: "mflix",
11
+ collection: "movies",
12
+ },
13
+ },
14
+ ],
15
+ },
16
+ {
17
+ prompt: "Drop movies collection from mflix database.",
18
+ expectedToolCalls: [
19
+ {
20
+ toolName: "drop-collection",
21
+ parameters: {
22
+ database: "mflix",
23
+ collection: "movies",
24
+ },
25
+ },
26
+ ],
27
+ },
28
+ {
29
+ prompt: "Remove books collection from which ever database contains it.",
30
+ expectedToolCalls: [
31
+ {
32
+ toolName: "list-databases",
33
+ parameters: {},
34
+ },
35
+ {
36
+ toolName: "list-collections",
37
+ parameters: {
38
+ database: "admin",
39
+ },
40
+ },
41
+ {
42
+ toolName: "list-collections",
43
+ parameters: {
44
+ database: "comics",
45
+ },
46
+ },
47
+ {
48
+ toolName: "list-collections",
49
+ parameters: {
50
+ database: "config",
51
+ },
52
+ },
53
+ {
54
+ toolName: "list-collections",
55
+ parameters: {
56
+ database: "local",
57
+ },
58
+ },
59
+ {
60
+ toolName: "list-collections",
61
+ parameters: {
62
+ database: "mflix",
63
+ },
64
+ },
65
+ {
66
+ toolName: "drop-collection",
67
+ parameters: {
68
+ database: "comics",
69
+ collection: "books",
70
+ },
71
+ },
72
+ ],
73
+ },
74
+ ]);
@@ -0,0 +1,41 @@
1
+ import { describeAccuracyTests } from "./sdk/describeAccuracyTests.js";
2
+
3
+ describeAccuracyTests([
4
+ {
5
+ prompt: "Remove mflix database from my cluster.",
6
+ expectedToolCalls: [
7
+ {
8
+ toolName: "drop-database",
9
+ parameters: {
10
+ database: "mflix",
11
+ },
12
+ },
13
+ ],
14
+ },
15
+ {
16
+ prompt: "Drop database named mflix.",
17
+ expectedToolCalls: [
18
+ {
19
+ toolName: "drop-database",
20
+ parameters: {
21
+ database: "mflix",
22
+ },
23
+ },
24
+ ],
25
+ },
26
+ {
27
+ prompt: "If there is a mflix database in my cluster then drop it.",
28
+ expectedToolCalls: [
29
+ {
30
+ toolName: "list-databases",
31
+ parameters: {},
32
+ },
33
+ {
34
+ toolName: "drop-database",
35
+ parameters: {
36
+ database: "mflix",
37
+ },
38
+ },
39
+ ],
40
+ },
41
+ ]);