mcp-mongo-server 2.1.0 → 2.1.1

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.
package/README.md CHANGED
@@ -4,8 +4,6 @@
4
4
  ![NPM Version](https://img.shields.io/npm/v/mcp-mongo-server)
5
5
  ![NPM Downloads](https://img.shields.io/npm/dm/mcp-mongo-server)
6
6
  ![NPM License](https://img.shields.io/npm/l/mcp-mongo-server)
7
- [![smithery badge](https://smithery.ai/badge/mcp-mongo-server)](https://smithery.ai/server/mcp-mongo-server)
8
- [![Verified on MseeP](https://mseep.ai/badge.svg)](https://mseep.ai/app/e274a3dd-7fe6-4440-8c43-043bae668251)
9
7
 
10
8
  A Model Context Protocol server that enables LLMs to interact with MongoDB databases. This server provides capabilities for inspecting collection schemas and executing MongoDB operations through a standardized interface.
11
9
 
package/build/index.js CHANGED
@@ -64,6 +64,32 @@ var COLLECTION_OPERATIONS = [
64
64
  "count"
65
65
  ];
66
66
  var WRITE_OPERATIONS = ["update", "insert", "createIndex"];
67
+ var READONLY_FORBIDDEN_AGG_OPERATORS = /* @__PURE__ */ new Set([
68
+ "$out",
69
+ "$merge",
70
+ "$function",
71
+ "$accumulator",
72
+ "$where"
73
+ ]);
74
+ function findForbiddenAggOperator(value) {
75
+ if (Array.isArray(value)) {
76
+ for (const item of value) {
77
+ const found = findForbiddenAggOperator(item);
78
+ if (found) return found;
79
+ }
80
+ return null;
81
+ }
82
+ if (value && typeof value === "object") {
83
+ for (const [key, nested] of Object.entries(value)) {
84
+ if (READONLY_FORBIDDEN_AGG_OPERATORS.has(key)) {
85
+ return key;
86
+ }
87
+ const found = findForbiddenAggOperator(nested);
88
+ if (found) return found;
89
+ }
90
+ }
91
+ return null;
92
+ }
67
93
  async function handleCallToolRequest({
68
94
  request,
69
95
  client,
@@ -153,7 +179,13 @@ async function executeOperation(operation, collection, db, isReadOnlyMode, args,
153
179
  case "query":
154
180
  return handleQuery(collection, args, objectIdMode, signal);
155
181
  case "aggregate":
156
- return handleAggregate(collection, args, objectIdMode, signal);
182
+ return handleAggregate(
183
+ collection,
184
+ args,
185
+ objectIdMode,
186
+ isReadOnlyMode,
187
+ signal
188
+ );
157
189
  case "update":
158
190
  return handleUpdate(collection, args, objectIdMode, signal);
159
191
  case "serverInfo":
@@ -387,7 +419,7 @@ async function handleQuery(collection, args, objectIdMode = "auto", signal) {
387
419
  return handleError(error, "query", collection.collectionName);
388
420
  }
389
421
  }
390
- async function handleAggregate(collection, args, objectIdMode = "auto", signal) {
422
+ async function handleAggregate(collection, args, objectIdMode = "auto", isReadOnlyMode = false, signal) {
391
423
  if (!collection) {
392
424
  throw new Error("Collection is required for aggregate operation");
393
425
  }
@@ -395,6 +427,14 @@ async function handleAggregate(collection, args, objectIdMode = "auto", signal)
395
427
  if (!Array.isArray(pipeline)) {
396
428
  throw new Error("Pipeline must be an array");
397
429
  }
430
+ if (isReadOnlyMode) {
431
+ const forbidden = findForbiddenAggOperator(pipeline);
432
+ if (forbidden) {
433
+ throw new Error(
434
+ `ReadonlyError: Aggregation operator '${forbidden}' is not allowed in read-only mode`
435
+ );
436
+ }
437
+ }
398
438
  const processedPipeline = pipeline.map((stage) => {
399
439
  if (typeof stage === "object" && stage !== null) {
400
440
  return processObjectIdInFilter(
@@ -488,32 +528,28 @@ async function handleServerInfo(db, isReadOnlyMode, args, signal) {
488
528
  try {
489
529
  signal?.throwIfAborted();
490
530
  const buildInfo = await db.command({ buildInfo: 1 });
491
- let serverStatus = null;
492
- if (includeDebugInfo) {
493
- signal?.throwIfAborted();
494
- serverStatus = await db.command({ serverStatus: 1 });
495
- }
496
531
  const serverInfo = {
497
532
  version: buildInfo.version,
498
533
  gitVersion: buildInfo.gitVersion,
499
- modules: buildInfo.modules,
500
- allocator: buildInfo.allocator,
501
- javascriptEngine: buildInfo.javascriptEngine,
502
- sysInfo: buildInfo.sysInfo,
503
534
  storageEngines: buildInfo.storageEngines,
504
- debug: buildInfo.debug,
505
535
  maxBsonObjectSize: buildInfo.maxBsonObjectSize,
506
- openssl: buildInfo.openssl,
507
- buildEnvironment: buildInfo.buildEnvironment,
508
536
  bits: buildInfo.bits,
509
537
  ok: buildInfo.ok,
510
- status: {},
511
538
  connectionInfo: {
512
539
  readOnlyMode: isReadOnlyMode,
513
540
  readPreference: isReadOnlyMode ? "secondary" : "primary"
514
541
  }
515
542
  };
516
- if (serverStatus) {
543
+ if (includeDebugInfo) {
544
+ signal?.throwIfAborted();
545
+ const serverStatus = await db.command({ serverStatus: 1 });
546
+ serverInfo.modules = buildInfo.modules;
547
+ serverInfo.allocator = buildInfo.allocator;
548
+ serverInfo.javascriptEngine = buildInfo.javascriptEngine;
549
+ serverInfo.sysInfo = buildInfo.sysInfo;
550
+ serverInfo.debug = buildInfo.debug;
551
+ serverInfo.openssl = buildInfo.openssl;
552
+ serverInfo.buildEnvironment = buildInfo.buildEnvironment;
517
553
  serverInfo.status = {
518
554
  host: serverStatus.host,
519
555
  version: serverStatus.version,
@@ -1517,7 +1553,7 @@ function createServer(client, db, isReadOnlyMode = false, options = {}) {
1517
1553
  {
1518
1554
  name: "mongodb",
1519
1555
  title: "MongoDB MCP Server",
1520
- version: "2.1.0",
1556
+ version: "2.1.1",
1521
1557
  description: "MCP server for MongoDB: query, aggregate, and manage collections with read-only mode, progress notifications, cancellation, and task support",
1522
1558
  websiteUrl: "https://github.com/kiliczsh/mcp-mongo-server",
1523
1559
  ...options
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-mongo-server",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "A Model Context Protocol server for MongoDB connections",
5
5
  "private": false,
6
6
  "type": "module",