mongodb-mcp-server 0.0.4 → 0.0.6

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 (185) hide show
  1. package/.github/CODEOWNERS +3 -0
  2. package/.github/dependabot.yml +10 -0
  3. package/.github/workflows/code_health.yaml +53 -22
  4. package/.github/workflows/code_health_fork.yaml +106 -0
  5. package/.github/workflows/codeql.yml +34 -0
  6. package/.github/workflows/lint.yml +37 -0
  7. package/.github/workflows/prepare_release.yaml +6 -4
  8. package/.github/workflows/publish.yaml +6 -3
  9. package/.prettierrc.json +1 -1
  10. package/README.md +18 -0
  11. package/dist/common/atlas/apiClient.js +28 -4
  12. package/dist/common/atlas/apiClient.js.map +1 -1
  13. package/dist/config.js +4 -7
  14. package/dist/config.js.map +1 -1
  15. package/dist/errors.js +1 -1
  16. package/dist/errors.js.map +1 -1
  17. package/dist/index.js +12 -7
  18. package/dist/index.js.map +1 -1
  19. package/dist/logger.js +72 -28
  20. package/dist/logger.js.map +1 -1
  21. package/dist/packageInfo.js +6 -0
  22. package/dist/packageInfo.js.map +1 -0
  23. package/dist/server.js +114 -10
  24. package/dist/server.js.map +1 -1
  25. package/dist/session.js +66 -16
  26. package/dist/session.js.map +1 -1
  27. package/dist/telemetry/constants.js +15 -0
  28. package/dist/telemetry/constants.js.map +1 -0
  29. package/dist/telemetry/eventCache.js +53 -0
  30. package/dist/telemetry/eventCache.js.map +1 -0
  31. package/dist/telemetry/telemetry.js +97 -0
  32. package/dist/telemetry/telemetry.js.map +1 -0
  33. package/dist/telemetry/types.js +2 -0
  34. package/dist/telemetry/types.js.map +1 -0
  35. package/dist/tools/atlas/atlasTool.js +8 -3
  36. package/dist/tools/atlas/atlasTool.js.map +1 -1
  37. package/dist/tools/atlas/{createAccessList.js → create/createAccessList.js} +1 -2
  38. package/dist/tools/atlas/create/createAccessList.js.map +1 -0
  39. package/dist/tools/atlas/{createDBUser.js → create/createDBUser.js} +1 -2
  40. package/dist/tools/atlas/create/createDBUser.js.map +1 -0
  41. package/dist/tools/atlas/{createFreeCluster.js → create/createFreeCluster.js} +5 -3
  42. package/dist/tools/atlas/create/createFreeCluster.js.map +1 -0
  43. package/dist/tools/atlas/{createProject.js → create/createProject.js} +1 -2
  44. package/dist/tools/atlas/create/createProject.js.map +1 -0
  45. package/dist/tools/atlas/metadata/connectCluster.js +97 -0
  46. package/dist/tools/atlas/metadata/connectCluster.js.map +1 -0
  47. package/dist/tools/atlas/{inspectAccessList.js → read/inspectAccessList.js} +1 -2
  48. package/dist/tools/atlas/read/inspectAccessList.js.map +1 -0
  49. package/dist/tools/atlas/{inspectCluster.js → read/inspectCluster.js} +1 -2
  50. package/dist/tools/atlas/read/inspectCluster.js.map +1 -0
  51. package/dist/tools/atlas/{listClusters.js → read/listClusters.js} +1 -2
  52. package/dist/tools/atlas/read/listClusters.js.map +1 -0
  53. package/dist/tools/atlas/{listDBUsers.js → read/listDBUsers.js} +1 -2
  54. package/dist/tools/atlas/read/listDBUsers.js.map +1 -0
  55. package/dist/tools/atlas/{listOrgs.js → read/listOrgs.js} +1 -2
  56. package/dist/tools/atlas/read/listOrgs.js.map +1 -0
  57. package/dist/tools/atlas/{listProjects.js → read/listProjects.js} +11 -5
  58. package/dist/tools/atlas/read/listProjects.js.map +1 -0
  59. package/dist/tools/atlas/tools.js +12 -10
  60. package/dist/tools/atlas/tools.js.map +1 -1
  61. package/dist/tools/mongodb/create/insertMany.js +1 -1
  62. package/dist/tools/mongodb/create/insertMany.js.map +1 -1
  63. package/dist/tools/mongodb/delete/deleteMany.js +1 -2
  64. package/dist/tools/mongodb/delete/deleteMany.js.map +1 -1
  65. package/dist/tools/mongodb/metadata/collectionSchema.js +15 -13
  66. package/dist/tools/mongodb/metadata/collectionSchema.js.map +1 -1
  67. package/dist/tools/mongodb/metadata/collectionStorageSize.js +32 -3
  68. package/dist/tools/mongodb/metadata/collectionStorageSize.js.map +1 -1
  69. package/dist/tools/mongodb/metadata/connect.js +59 -72
  70. package/dist/tools/mongodb/metadata/connect.js.map +1 -1
  71. package/dist/tools/mongodb/metadata/dbStats.js +6 -1
  72. package/dist/tools/mongodb/metadata/dbStats.js.map +1 -1
  73. package/dist/tools/mongodb/metadata/explain.js +14 -7
  74. package/dist/tools/mongodb/metadata/explain.js.map +1 -1
  75. package/dist/tools/mongodb/metadata/logs.js +45 -0
  76. package/dist/tools/mongodb/metadata/logs.js.map +1 -0
  77. package/dist/tools/mongodb/mongodbTool.js +42 -36
  78. package/dist/tools/mongodb/mongodbTool.js.map +1 -1
  79. package/dist/tools/mongodb/read/aggregate.js +4 -4
  80. package/dist/tools/mongodb/read/aggregate.js.map +1 -1
  81. package/dist/tools/mongodb/read/collectionIndexes.js +24 -5
  82. package/dist/tools/mongodb/read/collectionIndexes.js.map +1 -1
  83. package/dist/tools/mongodb/read/count.js +1 -2
  84. package/dist/tools/mongodb/read/count.js.map +1 -1
  85. package/dist/tools/mongodb/read/find.js +5 -6
  86. package/dist/tools/mongodb/read/find.js.map +1 -1
  87. package/dist/tools/mongodb/tools.js +6 -2
  88. package/dist/tools/mongodb/tools.js.map +1 -1
  89. package/dist/tools/mongodb/update/renameCollection.js +28 -4
  90. package/dist/tools/mongodb/update/renameCollection.js.map +1 -1
  91. package/dist/tools/mongodb/update/updateMany.js +7 -11
  92. package/dist/tools/mongodb/update/updateMany.js.map +1 -1
  93. package/dist/tools/tool.js +68 -15
  94. package/dist/tools/tool.js.map +1 -1
  95. package/eslint.config.js +29 -10
  96. package/global.d.ts +1 -0
  97. package/package.json +7 -3
  98. package/scripts/apply.ts +9 -7
  99. package/scripts/filter.ts +3 -2
  100. package/src/common/atlas/apiClient.ts +44 -11
  101. package/src/config.ts +16 -17
  102. package/src/errors.ts +1 -1
  103. package/src/index.ts +12 -8
  104. package/src/logger.ts +92 -29
  105. package/src/packageInfo.ts +6 -0
  106. package/src/server.ts +160 -11
  107. package/src/session.ts +102 -22
  108. package/src/telemetry/constants.ts +15 -0
  109. package/src/telemetry/eventCache.ts +62 -0
  110. package/src/telemetry/telemetry.ts +125 -0
  111. package/src/telemetry/types.ts +77 -0
  112. package/src/tools/atlas/atlasTool.ts +7 -5
  113. package/src/tools/atlas/{createAccessList.ts → create/createAccessList.ts} +2 -4
  114. package/src/tools/atlas/{createDBUser.ts → create/createDBUser.ts} +3 -5
  115. package/src/tools/atlas/{createFreeCluster.ts → create/createFreeCluster.ts} +7 -6
  116. package/src/tools/atlas/{createProject.ts → create/createProject.ts} +3 -4
  117. package/src/tools/atlas/metadata/connectCluster.ts +114 -0
  118. package/src/tools/atlas/{inspectAccessList.ts → read/inspectAccessList.ts} +2 -4
  119. package/src/tools/atlas/{inspectCluster.ts → read/inspectCluster.ts} +3 -5
  120. package/src/tools/atlas/{listClusters.ts → read/listClusters.ts} +3 -5
  121. package/src/tools/atlas/{listDBUsers.ts → read/listDBUsers.ts} +3 -5
  122. package/src/tools/atlas/{listOrgs.ts → read/listOrgs.ts} +2 -4
  123. package/src/tools/atlas/{listProjects.ts → read/listProjects.ts} +15 -7
  124. package/src/tools/atlas/tools.ts +12 -10
  125. package/src/tools/mongodb/create/insertMany.ts +1 -1
  126. package/src/tools/mongodb/delete/deleteMany.ts +1 -2
  127. package/src/tools/mongodb/metadata/collectionSchema.ts +16 -14
  128. package/src/tools/mongodb/metadata/collectionStorageSize.ts +41 -3
  129. package/src/tools/mongodb/metadata/connect.ts +78 -76
  130. package/src/tools/mongodb/metadata/dbStats.ts +6 -1
  131. package/src/tools/mongodb/metadata/explain.ts +20 -7
  132. package/src/tools/mongodb/metadata/logs.ts +55 -0
  133. package/src/tools/mongodb/mongodbTool.ts +47 -40
  134. package/src/tools/mongodb/read/aggregate.ts +4 -4
  135. package/src/tools/mongodb/read/collectionIndexes.ts +29 -5
  136. package/src/tools/mongodb/read/count.ts +1 -2
  137. package/src/tools/mongodb/read/find.ts +5 -6
  138. package/src/tools/mongodb/tools.ts +6 -2
  139. package/src/tools/mongodb/update/renameCollection.ts +33 -4
  140. package/src/tools/mongodb/update/updateMany.ts +7 -11
  141. package/src/tools/tool.ts +89 -26
  142. package/tests/integration/helpers.ts +94 -107
  143. package/tests/integration/inMemoryTransport.ts +3 -2
  144. package/tests/integration/server.test.ts +75 -23
  145. package/tests/integration/tools/atlas/accessLists.test.ts +13 -15
  146. package/tests/integration/tools/atlas/atlasHelpers.ts +10 -13
  147. package/tests/integration/tools/atlas/clusters.test.ts +79 -16
  148. package/tests/integration/tools/atlas/dbUsers.test.ts +9 -9
  149. package/tests/integration/tools/atlas/orgs.test.ts +4 -4
  150. package/tests/integration/tools/atlas/projects.test.ts +10 -12
  151. package/tests/integration/tools/mongodb/create/createCollection.test.ts +19 -62
  152. package/tests/integration/tools/mongodb/create/createIndex.test.ts +41 -87
  153. package/tests/integration/tools/mongodb/create/insertMany.test.ts +35 -78
  154. package/tests/integration/tools/mongodb/delete/deleteMany.test.ts +25 -62
  155. package/tests/integration/tools/mongodb/delete/dropCollection.test.ts +22 -71
  156. package/tests/integration/tools/mongodb/delete/dropDatabase.test.ts +29 -63
  157. package/tests/integration/tools/mongodb/metadata/collectionSchema.test.ts +154 -0
  158. package/tests/integration/tools/mongodb/metadata/collectionStorageSize.test.ts +86 -0
  159. package/tests/integration/tools/mongodb/metadata/connect.test.ts +88 -93
  160. package/tests/integration/tools/mongodb/metadata/dbStats.test.ts +104 -0
  161. package/tests/integration/tools/mongodb/metadata/explain.test.ts +171 -0
  162. package/tests/integration/tools/mongodb/metadata/listCollections.test.ts +28 -56
  163. package/tests/integration/tools/mongodb/metadata/listDatabases.test.ts +32 -26
  164. package/tests/integration/tools/mongodb/metadata/logs.test.ts +83 -0
  165. package/tests/integration/tools/mongodb/mongodbHelpers.ts +176 -0
  166. package/tests/integration/tools/mongodb/read/aggregate.test.ts +99 -0
  167. package/tests/integration/tools/mongodb/read/collectionIndexes.test.ts +99 -0
  168. package/tests/integration/tools/mongodb/read/count.test.ts +31 -79
  169. package/tests/integration/tools/mongodb/read/find.test.ts +182 -0
  170. package/tests/integration/tools/mongodb/update/renameCollection.test.ts +194 -0
  171. package/tests/integration/tools/mongodb/update/updateMany.test.ts +238 -0
  172. package/tests/unit/telemetry.test.ts +200 -0
  173. package/tsconfig.jest.json +2 -1
  174. package/tsconfig.json +1 -1
  175. package/tsconfig.lint.json +8 -0
  176. package/dist/tools/atlas/createAccessList.js.map +0 -1
  177. package/dist/tools/atlas/createDBUser.js.map +0 -1
  178. package/dist/tools/atlas/createFreeCluster.js.map +0 -1
  179. package/dist/tools/atlas/createProject.js.map +0 -1
  180. package/dist/tools/atlas/inspectAccessList.js.map +0 -1
  181. package/dist/tools/atlas/inspectCluster.js.map +0 -1
  182. package/dist/tools/atlas/listClusters.js.map +0 -1
  183. package/dist/tools/atlas/listDBUsers.js.map +0 -1
  184. package/dist/tools/atlas/listOrgs.js.map +0 -1
  185. package/dist/tools/atlas/listProjects.js.map +0 -1
package/dist/logger.js CHANGED
@@ -1,7 +1,21 @@
1
1
  import fs from "fs/promises";
2
- import { MongoLogManager } from "mongodb-log-writer";
3
- import config from "./config.js";
2
+ import { mongoLogId, MongoLogManager } from "mongodb-log-writer";
4
3
  import redact from "mongodb-redact";
4
+ export const LogId = {
5
+ serverStartFailure: mongoLogId(1000001),
6
+ serverInitialized: mongoLogId(1000002),
7
+ atlasCheckCredentials: mongoLogId(1001001),
8
+ atlasDeleteDatabaseUserFailure: mongoLogId(1001002),
9
+ telemetryDisabled: mongoLogId(1002001),
10
+ telemetryEmitFailure: mongoLogId(1002002),
11
+ telemetryEmitStart: mongoLogId(1002003),
12
+ telemetryEmitSuccess: mongoLogId(1002004),
13
+ toolExecute: mongoLogId(1003001),
14
+ toolExecuteFailure: mongoLogId(1003002),
15
+ toolDisabled: mongoLogId(1003003),
16
+ mongodbConnectFailure: mongoLogId(1004001),
17
+ mongodbDisconnectFailure: mongoLogId(1004002),
18
+ };
5
19
  class LoggerBase {
6
20
  info(id, context, message) {
7
21
  this.log("info", id, context, message);
@@ -34,20 +48,29 @@ class ConsoleLogger extends LoggerBase {
34
48
  console.error(`[${level.toUpperCase()}] ${id.__value} - ${context}: ${message}`);
35
49
  }
36
50
  }
37
- class Logger extends LoggerBase {
38
- constructor(logWriter, server) {
51
+ class DiskLogger extends LoggerBase {
52
+ constructor(logWriter) {
39
53
  super();
40
54
  this.logWriter = logWriter;
41
- this.server = server;
55
+ }
56
+ static async fromPath(logPath) {
57
+ await fs.mkdir(logPath, { recursive: true });
58
+ const manager = new MongoLogManager({
59
+ directory: logPath,
60
+ retentionDays: 30,
61
+ onwarn: console.warn,
62
+ onerror: console.error,
63
+ gzip: false,
64
+ retentionGB: 1,
65
+ });
66
+ await manager.cleanupOldLogFiles();
67
+ const logWriter = await manager.createLogWriter();
68
+ return new DiskLogger(logWriter);
42
69
  }
43
70
  log(level, id, context, message) {
44
71
  message = redact(message);
45
72
  const mongoDBLevel = this.mapToMongoDBLogLevel(level);
46
73
  this.logWriter[mongoDBLevel]("MONGODB-MCP", id, context, message);
47
- void this.server.server.sendLoggingMessage({
48
- level,
49
- data: `[${context}]: ${message}`,
50
- });
51
74
  }
52
75
  mapToMongoDBLogLevel(level) {
53
76
  switch (level) {
@@ -69,29 +92,50 @@ class Logger extends LoggerBase {
69
92
  }
70
93
  }
71
94
  }
72
- class ProxyingLogger extends LoggerBase {
73
- constructor() {
74
- super(...arguments);
75
- this.internalLogger = new ConsoleLogger();
95
+ class McpLogger extends LoggerBase {
96
+ constructor(server) {
97
+ super();
98
+ this.server = server;
99
+ }
100
+ log(level, _, context, message) {
101
+ // Only log if the server is connected
102
+ if (!this.server?.isConnected()) {
103
+ return;
104
+ }
105
+ void this.server.server.sendLoggingMessage({
106
+ level,
107
+ data: `[${context}]: ${message}`,
108
+ });
109
+ }
110
+ }
111
+ class CompositeLogger extends LoggerBase {
112
+ constructor(...loggers) {
113
+ super();
114
+ if (loggers.length === 0) {
115
+ // default to ConsoleLogger
116
+ this.loggers = [new ConsoleLogger()];
117
+ return;
118
+ }
119
+ this.loggers = [...loggers];
120
+ }
121
+ setLoggers(...loggers) {
122
+ if (loggers.length === 0) {
123
+ throw new Error("At least one logger must be provided");
124
+ }
125
+ this.loggers = [...loggers];
76
126
  }
77
127
  log(level, id, context, message) {
78
- this.internalLogger.log(level, id, context, message);
128
+ for (const logger of this.loggers) {
129
+ logger.log(level, id, context, message);
130
+ }
79
131
  }
80
132
  }
81
- const logger = new ProxyingLogger();
133
+ const logger = new CompositeLogger();
82
134
  export default logger;
83
- export async function initializeLogger(server) {
84
- await fs.mkdir(config.logPath, { recursive: true });
85
- const manager = new MongoLogManager({
86
- directory: config.logPath,
87
- retentionDays: 30,
88
- onwarn: console.warn,
89
- onerror: console.error,
90
- gzip: false,
91
- retentionGB: 1,
92
- });
93
- await manager.cleanupOldLogFiles();
94
- const logWriter = await manager.createLogWriter();
95
- logger["internalLogger"] = new Logger(logWriter, server);
135
+ export async function initializeLogger(server, logPath) {
136
+ const diskLogger = await DiskLogger.fromPath(logPath);
137
+ const mcpLogger = new McpLogger(server);
138
+ logger.setLoggers(mcpLogger, diskLogger);
139
+ return logger;
96
140
  }
97
141
  //# sourceMappingURL=logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import packageJson from "../package.json" with { type: "json" };
2
+ export const packageInfo = {
3
+ version: packageJson.version,
4
+ mcpServerName: "MongoDB MCP Server",
5
+ };
6
+ //# sourceMappingURL=packageInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageInfo.js","sourceRoot":"","sources":["../src/packageInfo.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEhE,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,OAAO,EAAE,WAAW,CAAC,OAAO;IAC5B,aAAa,EAAE,oBAAoB;CACtC,CAAC"}
package/dist/server.js CHANGED
@@ -1,39 +1,124 @@
1
1
  import { AtlasTools } from "./tools/atlas/tools.js";
2
2
  import { MongoDbTools } from "./tools/mongodb/tools.js";
3
- import logger, { initializeLogger } from "./logger.js";
4
- import { mongoLogId } from "mongodb-log-writer";
5
- import config from "./config.js";
3
+ import logger, { initializeLogger, LogId } from "./logger.js";
4
+ import { ObjectId } from "mongodb";
5
+ import { Telemetry } from "./telemetry/telemetry.js";
6
+ import { CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
7
+ import assert from "assert";
6
8
  export class Server {
7
- constructor({ mcpServer, session }) {
8
- this.mcpServer = mcpServer;
9
+ constructor({ session, mcpServer, userConfig }) {
10
+ this.startTime = Date.now();
9
11
  this.session = session;
12
+ this.telemetry = new Telemetry(session);
13
+ this.mcpServer = mcpServer;
14
+ this.userConfig = userConfig;
10
15
  }
11
16
  async connect(transport) {
12
17
  this.mcpServer.server.registerCapabilities({ logging: {} });
13
18
  this.registerTools();
14
19
  this.registerResources();
15
- await initializeLogger(this.mcpServer);
20
+ // This is a workaround for an issue we've seen with some models, where they'll see that everything in the `arguments`
21
+ // object is optional, and then not pass it at all. However, the MCP server expects the `arguments` object to be if
22
+ // the tool accepts any arguments, even if they're all optional.
23
+ //
24
+ // see: https://github.com/modelcontextprotocol/typescript-sdk/blob/131776764536b5fdca642df51230a3746fb4ade0/src/server/mcp.ts#L705
25
+ // Since paramsSchema here is not undefined, the server will create a non-optional z.object from it.
26
+ const existingHandler = this.mcpServer.server["_requestHandlers"].get(CallToolRequestSchema.shape.method.value);
27
+ assert(existingHandler, "No existing handler found for CallToolRequestSchema");
28
+ this.mcpServer.server.setRequestHandler(CallToolRequestSchema, (request, extra) => {
29
+ if (!request.params.arguments) {
30
+ request.params.arguments = {};
31
+ }
32
+ return existingHandler(request, extra);
33
+ });
34
+ await initializeLogger(this.mcpServer, this.userConfig.logPath);
16
35
  await this.mcpServer.connect(transport);
17
- logger.info(mongoLogId(1000004), "server", `Server started with transport ${transport.constructor.name}`);
36
+ this.mcpServer.server.oninitialized = () => {
37
+ this.session.setAgentRunner(this.mcpServer.server.getClientVersion());
38
+ this.session.sessionId = new ObjectId().toString();
39
+ logger.info(LogId.serverInitialized, "server", `Server started with transport ${transport.constructor.name} and agent runner ${this.session.agentRunner?.name}`);
40
+ this.emitServerEvent("start", Date.now() - this.startTime);
41
+ };
42
+ this.mcpServer.server.onclose = () => {
43
+ const closeTime = Date.now();
44
+ this.emitServerEvent("stop", Date.now() - closeTime);
45
+ };
46
+ this.mcpServer.server.onerror = (error) => {
47
+ const closeTime = Date.now();
48
+ this.emitServerEvent("stop", Date.now() - closeTime, error);
49
+ };
50
+ await this.validateConfig();
18
51
  }
19
52
  async close() {
20
53
  await this.session.close();
21
54
  await this.mcpServer.close();
22
55
  }
56
+ /**
57
+ * Emits a server event
58
+ * @param command - The server command (e.g., "start", "stop", "register", "deregister")
59
+ * @param additionalProperties - Additional properties specific to the event
60
+ */
61
+ emitServerEvent(command, commandDuration, error) {
62
+ const event = {
63
+ timestamp: new Date().toISOString(),
64
+ source: "mdbmcp",
65
+ properties: {
66
+ ...this.telemetry.getCommonProperties(),
67
+ result: "success",
68
+ duration_ms: commandDuration,
69
+ component: "server",
70
+ category: "other",
71
+ command: command,
72
+ },
73
+ };
74
+ if (command === "start") {
75
+ event.properties.startup_time_ms = commandDuration;
76
+ event.properties.read_only_mode = this.userConfig.readOnly || false;
77
+ event.properties.disallowed_tools = this.userConfig.disabledTools || [];
78
+ }
79
+ if (command === "stop") {
80
+ event.properties.runtime_duration_ms = Date.now() - this.startTime;
81
+ if (error) {
82
+ event.properties.result = "failure";
83
+ event.properties.reason = error.message;
84
+ }
85
+ }
86
+ this.telemetry.emitEvents([event]).catch(() => { });
87
+ }
23
88
  registerTools() {
24
89
  for (const tool of [...AtlasTools, ...MongoDbTools]) {
25
- new tool(this.session).register(this.mcpServer);
90
+ new tool(this.session, this.userConfig, this.telemetry).register(this.mcpServer);
26
91
  }
27
92
  }
28
93
  registerResources() {
29
- if (config.connectionString) {
94
+ this.mcpServer.resource("config", "config://config", {
95
+ description: "Server configuration, supplied by the user either as environment variables or as startup arguments",
96
+ }, (uri) => {
97
+ const result = {
98
+ telemetry: this.userConfig.telemetry,
99
+ logPath: this.userConfig.logPath,
100
+ connectionString: this.userConfig.connectionString
101
+ ? "set; no explicit connect needed, use switch-connection tool to connect to a different connection if necessary"
102
+ : "not set; before using any mongodb tool, you need to call the connect tool with a connection string",
103
+ connectOptions: this.userConfig.connectOptions,
104
+ };
105
+ return {
106
+ contents: [
107
+ {
108
+ text: JSON.stringify(result),
109
+ uri: uri.href,
110
+ },
111
+ ],
112
+ };
113
+ });
114
+ if (this.userConfig.connectionString) {
30
115
  this.mcpServer.resource("connection-string", "config://connection-string", {
31
116
  description: "Preconfigured connection string that will be used as a default in the `connect` tool",
32
117
  }, (uri) => {
33
118
  return {
34
119
  contents: [
35
120
  {
36
- text: `Preconfigured connection string: ${config.connectionString}`,
121
+ text: `Preconfigured connection string: ${this.userConfig.connectionString}`,
37
122
  uri: uri.href,
38
123
  },
39
124
  ],
@@ -41,5 +126,24 @@ export class Server {
41
126
  });
42
127
  }
43
128
  }
129
+ async validateConfig() {
130
+ const isAtlasConfigured = this.userConfig.apiClientId && this.userConfig.apiClientSecret;
131
+ const isMongoDbConfigured = this.userConfig.connectionString;
132
+ if (!isAtlasConfigured && !isMongoDbConfigured) {
133
+ console.error("Either Atlas Client Id or a MongoDB connection string must be configured - you can provide them as environment variables or as startup arguments. \n" +
134
+ "Provide the Atlas credentials as `MDB_MCP_API_CLIENT_ID` and `MDB_MCP_API_CLIENT_SECRET` environment variables or as `--apiClientId` and `--apiClientSecret` startup arguments. \n" +
135
+ "Provide the MongoDB connection string as `MDB_MCP_CONNECTION_STRING` environment variable or as `--connectionString` startup argument.");
136
+ throw new Error("Either Atlas Client Id or a MongoDB connection string must be configured");
137
+ }
138
+ if (this.userConfig.connectionString) {
139
+ try {
140
+ await this.session.connectToMongoDB(this.userConfig.connectionString, this.userConfig.connectOptions);
141
+ }
142
+ catch (error) {
143
+ console.error("Failed to connect to MongoDB instance using the connection string from the config: ", error);
144
+ throw new Error("Failed to connect to MongoDB instance using the connection string from the config");
145
+ }
146
+ }
147
+ }
44
148
  }
45
149
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,MAAM,EAAE,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,OAAO,MAAM;IAIf,YAAY,EAAE,SAAS,EAAE,OAAO,EAA8C;QAC1E,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAoB;QAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAE5D,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,MAAM,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEvC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAExC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAS,CAAC,EAAE,QAAQ,EAAE,iCAAiC,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAChH,CAAC;IAED,KAAK,CAAC,KAAK;QACP,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACjC,CAAC;IAEO,aAAa;QACjB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC;YAClD,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC;IACL,CAAC;IAEO,iBAAiB;QACrB,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,SAAS,CAAC,QAAQ,CACnB,mBAAmB,EACnB,4BAA4B,EAC5B;gBACI,WAAW,EAAE,sFAAsF;aACtG,EACD,CAAC,GAAG,EAAE,EAAE;gBACJ,OAAO;oBACH,QAAQ,EAAE;wBACN;4BACI,IAAI,EAAE,oCAAoC,MAAM,CAAC,gBAAgB,EAAE;4BACnE,GAAG,EAAE,GAAG,CAAC,IAAI;yBAChB;qBACJ;iBACJ,CAAC;YACN,CAAC,CACJ,CAAC;QACN,CAAC;IACL,CAAC;CACJ"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,MAAM,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAIrD,OAAO,EAAE,qBAAqB,EAAkB,MAAM,oCAAoC,CAAC;AAC3F,OAAO,MAAM,MAAM,QAAQ,CAAC;AAQ5B,MAAM,OAAO,MAAM;IAOf,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAiB;QACzD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAoB;QAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAE5D,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,sHAAsH;QACtH,mHAAmH;QACnH,gEAAgE;QAChE,EAAE;QACF,mIAAmI;QACnI,oGAAoG;QACpG,MAAM,eAAe,GACjB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAI3C,CAAC,GAAG,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,eAAe,EAAE,qDAAqD,CAAC,CAAC;QAE/E,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,CAAC,OAAO,EAAE,KAAK,EAA2B,EAAE;YACvG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC5B,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;YAClC,CAAC;YAED,OAAO,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,MAAM,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAEhE,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAExC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,GAAG,GAAG,EAAE;YACvC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;YACtE,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC;YAEnD,MAAM,CAAC,IAAI,CACP,KAAK,CAAC,iBAAiB,EACvB,QAAQ,EACR,iCAAiC,SAAS,CAAC,WAAW,CAAC,IAAI,qBAAqB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CACnH,CAAC;YAEF,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/D,CAAC,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;YACjC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QACzD,CAAC,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,KAAY,EAAE,EAAE;YAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,KAAK,CAAC,CAAC;QAChE,CAAC,CAAC;QAEF,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,KAAK;QACP,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,OAAsB,EAAE,eAAuB,EAAE,KAAa;QAC1E,MAAM,KAAK,GAAgB;YACvB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE;gBACR,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE;gBACvC,MAAM,EAAE,SAAS;gBACjB,WAAW,EAAE,eAAe;gBAC5B,SAAS,EAAE,QAAQ;gBACnB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,OAAO;aACnB;SACJ,CAAC;QAEF,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACtB,KAAK,CAAC,UAAU,CAAC,eAAe,GAAG,eAAe,CAAC;YACnD,KAAK,CAAC,UAAU,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,IAAI,KAAK,CAAC;YACpE,KAAK,CAAC,UAAU,CAAC,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,IAAI,EAAE,CAAC;QAC5E,CAAC;QACD,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;YACrB,KAAK,CAAC,UAAU,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YACnE,IAAI,KAAK,EAAE,CAAC;gBACR,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC;gBACpC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;YAC5C,CAAC;QACL,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACvD,CAAC;IAEO,aAAa;QACjB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC;YAClD,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrF,CAAC;IACL,CAAC;IAEO,iBAAiB;QACrB,IAAI,CAAC,SAAS,CAAC,QAAQ,CACnB,QAAQ,EACR,iBAAiB,EACjB;YACI,WAAW,EACP,oGAAoG;SAC3G,EACD,CAAC,GAAG,EAAE,EAAE;YACJ,MAAM,MAAM,GAAG;gBACX,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS;gBACpC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO;gBAChC,gBAAgB,EAAE,IAAI,CAAC,UAAU,CAAC,gBAAgB;oBAC9C,CAAC,CAAC,+GAA+G;oBACjH,CAAC,CAAC,oGAAoG;gBAC1G,cAAc,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc;aACjD,CAAC;YACF,OAAO;gBACH,QAAQ,EAAE;oBACN;wBACI,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;wBAC5B,GAAG,EAAE,GAAG,CAAC,IAAI;qBAChB;iBACJ;aACJ,CAAC;QACN,CAAC,CACJ,CAAC;QACF,IAAI,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,QAAQ,CACnB,mBAAmB,EACnB,4BAA4B,EAC5B;gBACI,WAAW,EAAE,sFAAsF;aACtG,EACD,CAAC,GAAG,EAAE,EAAE;gBACJ,OAAO;oBACH,QAAQ,EAAE;wBACN;4BACI,IAAI,EAAE,oCAAoC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;4BAC5E,GAAG,EAAE,GAAG,CAAC,IAAI;yBAChB;qBACJ;iBACJ,CAAC;YACN,CAAC,CACJ,CAAC;QACN,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,cAAc;QACxB,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;QACzF,MAAM,mBAAmB,GAAG,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC;QAC7D,IAAI,CAAC,iBAAiB,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7C,OAAO,CAAC,KAAK,CACT,sJAAsJ;gBAClJ,oLAAoL;gBACpL,wIAAwI,CAC/I,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAChG,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;YACnC,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAC1G,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CACT,qFAAqF,EACrF,KAAK,CACR,CAAC;gBACF,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;YACzG,CAAC;QACL,CAAC;IACL,CAAC;CACJ"}
package/dist/session.js CHANGED
@@ -1,30 +1,80 @@
1
+ import { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
1
2
  import { ApiClient } from "./common/atlas/apiClient.js";
2
- import config from "./config.js";
3
- export class Session {
4
- ensureAuthenticated() {
5
- if (!this.apiClient) {
6
- if (!config.apiClientId || !config.apiClientSecret) {
7
- throw new Error("Not authenticated make sure to configure MCP server with MDB_MCP_API_CLIENT_ID and MDB_MCP_API_CLIENT_SECRET environment variables.");
3
+ import logger, { LogId } from "./logger.js";
4
+ import EventEmitter from "events";
5
+ export class Session extends EventEmitter {
6
+ constructor({ apiBaseUrl, apiClientId, apiClientSecret }) {
7
+ super();
8
+ const credentials = apiClientId && apiClientSecret
9
+ ? {
10
+ clientId: apiClientId,
11
+ clientSecret: apiClientSecret,
8
12
  }
9
- this.apiClient = new ApiClient({
10
- baseUrl: config.apiBaseUrl,
11
- credentials: {
12
- clientId: config.apiClientId,
13
- clientSecret: config.apiClientSecret,
14
- },
15
- });
13
+ : undefined;
14
+ this.apiClient = new ApiClient({
15
+ baseUrl: apiBaseUrl,
16
+ credentials,
17
+ });
18
+ }
19
+ setAgentRunner(agentRunner) {
20
+ if (agentRunner?.name && agentRunner?.version) {
21
+ this.agentRunner = {
22
+ name: agentRunner.name,
23
+ version: agentRunner.version,
24
+ };
16
25
  }
17
26
  }
18
- async close() {
27
+ async disconnect() {
19
28
  if (this.serviceProvider) {
20
29
  try {
21
30
  await this.serviceProvider.close(true);
22
31
  }
23
- catch (error) {
24
- console.error("Error closing service provider:", error);
32
+ catch (err) {
33
+ const error = err instanceof Error ? err : new Error(String(err));
34
+ logger.error(LogId.mongodbDisconnectFailure, "Error closing service provider:", error.message);
25
35
  }
26
36
  this.serviceProvider = undefined;
27
37
  }
38
+ if (!this.connectedAtlasCluster) {
39
+ this.emit("disconnect");
40
+ return;
41
+ }
42
+ try {
43
+ await this.apiClient.deleteDatabaseUser({
44
+ params: {
45
+ path: {
46
+ groupId: this.connectedAtlasCluster.projectId,
47
+ username: this.connectedAtlasCluster.username,
48
+ databaseName: "admin",
49
+ },
50
+ },
51
+ });
52
+ }
53
+ catch (err) {
54
+ const error = err instanceof Error ? err : new Error(String(err));
55
+ logger.error(LogId.atlasDeleteDatabaseUserFailure, "atlas-connect-cluster", `Error deleting previous database user: ${error.message}`);
56
+ }
57
+ this.connectedAtlasCluster = undefined;
58
+ this.emit("disconnect");
59
+ }
60
+ async close() {
61
+ await this.disconnect();
62
+ this.emit("close");
63
+ }
64
+ async connectToMongoDB(connectionString, connectOptions) {
65
+ const provider = await NodeDriverServiceProvider.connect(connectionString, {
66
+ productDocsLink: "https://docs.mongodb.com/todo-mcp",
67
+ productName: "MongoDB MCP",
68
+ readConcern: {
69
+ level: connectOptions.readConcern,
70
+ },
71
+ readPreference: connectOptions.readPreference,
72
+ writeConcern: {
73
+ w: connectOptions.writeConcern,
74
+ },
75
+ timeoutMS: connectOptions.timeoutMS,
76
+ });
77
+ this.serviceProvider = provider;
28
78
  }
29
79
  }
30
80
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,OAAO,OAAO;IAIhB,mBAAmB;QACf,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;gBACjD,MAAM,IAAI,KAAK,CACX,qIAAqI,CACxI,CAAC;YACN,CAAC;YAED,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC;gBAC3B,OAAO,EAAE,MAAM,CAAC,UAAU;gBAC1B,WAAW,EAAE;oBACT,QAAQ,EAAE,MAAM,CAAC,WAAW;oBAC5B,YAAY,EAAE,MAAM,CAAC,eAAe;iBACvC;aACJ,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACP,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACrC,CAAC;IACL,CAAC;CACJ"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { getMachineIdSync } from "native-machine-id";
2
+ import { packageInfo } from "../packageInfo.js";
3
+ /**
4
+ * Machine-specific metadata formatted for telemetry
5
+ */
6
+ export const MACHINE_METADATA = {
7
+ device_id: getMachineIdSync(),
8
+ mcp_server_version: packageInfo.version,
9
+ mcp_server_name: packageInfo.mcpServerName,
10
+ platform: process.platform,
11
+ arch: process.arch,
12
+ os_type: process.platform,
13
+ os_version: process.version,
14
+ };
15
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/telemetry/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACpD,SAAS,EAAE,gBAAgB,EAAE;IAC7B,kBAAkB,EAAE,WAAW,CAAC,OAAO;IACvC,eAAe,EAAE,WAAW,CAAC,aAAa;IAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;IAClB,OAAO,EAAE,OAAO,CAAC,QAAQ;IACzB,UAAU,EAAE,OAAO,CAAC,OAAO;CACrB,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { LRUCache } from "lru-cache";
2
+ /**
3
+ * Singleton class for in-memory telemetry event caching
4
+ * Provides a central storage for telemetry events that couldn't be sent
5
+ * Uses LRU cache to automatically drop oldest events when limit is exceeded
6
+ */
7
+ export class EventCache {
8
+ constructor() {
9
+ this.nextId = 0;
10
+ this.cache = new LRUCache({
11
+ max: EventCache.MAX_EVENTS,
12
+ // Using FIFO eviction strategy for events
13
+ allowStale: false,
14
+ updateAgeOnGet: false,
15
+ });
16
+ }
17
+ /**
18
+ * Gets the singleton instance of EventCache
19
+ * @returns The EventCache instance
20
+ */
21
+ static getInstance() {
22
+ if (!EventCache.instance) {
23
+ EventCache.instance = new EventCache();
24
+ }
25
+ return EventCache.instance;
26
+ }
27
+ /**
28
+ * Gets a copy of the currently cached events
29
+ * @returns Array of cached BaseEvent objects
30
+ */
31
+ getEvents() {
32
+ return Array.from(this.cache.values());
33
+ }
34
+ /**
35
+ * Appends new events to the cached events
36
+ * LRU cache automatically handles dropping oldest events when limit is exceeded
37
+ * @param events - The events to append
38
+ */
39
+ appendEvents(events) {
40
+ for (const event of events) {
41
+ this.cache.set(this.nextId++, event);
42
+ }
43
+ }
44
+ /**
45
+ * Clears all cached events
46
+ */
47
+ clearEvents() {
48
+ this.cache.clear();
49
+ this.nextId = 0;
50
+ }
51
+ }
52
+ EventCache.MAX_EVENTS = 1000;
53
+ //# sourceMappingURL=eventCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventCache.js","sourceRoot":"","sources":["../../src/telemetry/eventCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC;;;;GAIG;AACH,MAAM,OAAO,UAAU;IAOnB;QAFQ,WAAM,GAAG,CAAC,CAAC;QAGf,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC;YACtB,GAAG,EAAE,UAAU,CAAC,UAAU;YAC1B,0CAA0C;YAC1C,UAAU,EAAE,KAAK;YACjB,cAAc,EAAE,KAAK;SACxB,CAAC,CAAC;IACP,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,WAAW;QACrB,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YACvB,UAAU,CAAC,QAAQ,GAAG,IAAI,UAAU,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACI,SAAS;QACZ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED;;;;OAIG;IACI,YAAY,CAAC,MAAmB;QACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,WAAW;QACd,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACpB,CAAC;;AAlDuB,qBAAU,GAAG,IAAI,AAAP,CAAQ"}
@@ -0,0 +1,97 @@
1
+ import { config } from "../config.js";
2
+ import logger, { LogId } from "../logger.js";
3
+ import { MACHINE_METADATA } from "./constants.js";
4
+ import { EventCache } from "./eventCache.js";
5
+ export class Telemetry {
6
+ constructor(session, eventCache = EventCache.getInstance()) {
7
+ this.session = session;
8
+ this.eventCache = eventCache;
9
+ this.commonProperties = {
10
+ ...MACHINE_METADATA,
11
+ };
12
+ }
13
+ /**
14
+ * Checks if telemetry is currently enabled
15
+ * This is a method rather than a constant to capture runtime config changes
16
+ *
17
+ * Follows the Console Do Not Track standard (https://consoledonottrack.com/)
18
+ * by respecting the DO_NOT_TRACK environment variable
19
+ */
20
+ static isTelemetryEnabled() {
21
+ // Check if telemetry is explicitly disabled in config
22
+ if (config.telemetry === "disabled") {
23
+ return false;
24
+ }
25
+ const doNotTrack = process.env.DO_NOT_TRACK;
26
+ if (doNotTrack) {
27
+ const value = doNotTrack.toLowerCase();
28
+ // Telemetry should be disabled if DO_NOT_TRACK is "1", "true", or "yes"
29
+ if (value === "1" || value === "true" || value === "yes") {
30
+ return false;
31
+ }
32
+ }
33
+ return true;
34
+ }
35
+ /**
36
+ * Emits events through the telemetry pipeline
37
+ * @param events - The events to emit
38
+ */
39
+ async emitEvents(events) {
40
+ try {
41
+ if (!Telemetry.isTelemetryEnabled()) {
42
+ return;
43
+ }
44
+ await this.emit(events);
45
+ }
46
+ catch {
47
+ logger.debug(LogId.telemetryEmitFailure, "telemetry", `Error emitting telemetry events.`);
48
+ }
49
+ }
50
+ /**
51
+ * Gets the common properties for events
52
+ * @returns Object containing common properties for all events
53
+ */
54
+ getCommonProperties() {
55
+ return {
56
+ ...this.commonProperties,
57
+ mcp_client_version: this.session.agentRunner?.version,
58
+ mcp_client_name: this.session.agentRunner?.name,
59
+ session_id: this.session.sessionId,
60
+ config_atlas_auth: this.session.apiClient.hasCredentials() ? "true" : "false",
61
+ config_connection_string: config.connectionString ? "true" : "false",
62
+ };
63
+ }
64
+ /**
65
+ * Attempts to emit events through authenticated and unauthenticated clients
66
+ * Falls back to caching if both attempts fail
67
+ */
68
+ async emit(events) {
69
+ const cachedEvents = this.eventCache.getEvents();
70
+ const allEvents = [...cachedEvents, ...events];
71
+ logger.debug(LogId.telemetryEmitStart, "telemetry", `Attempting to send ${allEvents.length} events (${cachedEvents.length} cached)`);
72
+ const result = await this.sendEvents(this.session.apiClient, allEvents);
73
+ if (result.success) {
74
+ this.eventCache.clearEvents();
75
+ logger.debug(LogId.telemetryEmitSuccess, "telemetry", `Sent ${allEvents.length} events successfully`);
76
+ return;
77
+ }
78
+ logger.debug(LogId.telemetryEmitFailure, "telemetry", `Error sending event to client: ${result.error instanceof Error ? result.error.message : String(result.error)}`);
79
+ this.eventCache.appendEvents(events);
80
+ }
81
+ /**
82
+ * Attempts to send events through the provided API client
83
+ */
84
+ async sendEvents(client, events) {
85
+ try {
86
+ await client.sendEvents(events);
87
+ return { success: true };
88
+ }
89
+ catch (error) {
90
+ return {
91
+ success: false,
92
+ error: error instanceof Error ? error : new Error(String(error)),
93
+ };
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/telemetry/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/telemetry/types.ts"],"names":[],"mappings":""}