Skip to content

Feature Request: Add maxTimeMS Configuration Option for Query Timeout #829

@jahales

Description

@jahales

Feature Request: Add maxTimeMS Configuration Option for Query Timeout

Summary

Add a configuration option (MDB_MCP_MAX_TIME_MS / --maxTimeMs) that applies MongoDB's maxTimeMS parameter to all find() and aggregate() operations, automatically terminating long-running queries after a specified duration.

Motivation

When using the MCP server with AI assistants (e.g., GitHub Copilot, Claude), there's a risk of:

  1. Runaway queries - AI-generated queries may unintentionally cause collection scans or inefficient operations on large collections
  2. Resource exhaustion - Long-running queries can lock up connections and consume server resources
  3. Hanging sessions - Users have no way to recover from stuck queries without restarting the MCP server

The existing safeguards (--indexCheck, --maxDocumentsPerQuery, --maxBytesPerQuery) help but don't address execution time.

Proposed Solution

Add a new configuration option:

Config Default Description
MDB_MCP_MAX_TIME_MS / --maxTimeMs 30000 (30s) Maximum execution time in milliseconds for find and aggregate operations. Uses MongoDB's maxTimeMS cursor option.

Implementation Details

After analyzing the codebase, this would be a low-complexity change with well-defined modification points:

1. Add Config Option (src/common/config/userConfig.ts)

Add alongside existing timeout configs (idleTimeoutMs, exportTimeoutMs, etc.):

maxTimeMs: z4.coerce
    .number()
    .default(30_000)
    .describe(
        "Maximum execution time in milliseconds for find and aggregate operations. Set to 0 to disable."
    )
    .register(configRegistry, { overrideBehavior: onlyLowerThanBaseValueOverride() }),

2. Modify Find Tool (src/tools/mongodb/read/find.ts, ~line 66)

The find cursor is already created with options - just add maxTimeMS:

  findCursor = provider.find(database, collection, filter, {
      projection,
      limit: limitOnFindCursor.limit,
      sort,
+     maxTimeMS: this.config.maxTimeMs || undefined,
  });

3. Modify Aggregate Tool (src/tools/mongodb/read/aggregate.ts, ~line 115)

Same pattern:

- aggregationCursor = provider.aggregate(database, collection, cappedResultsPipeline);
+ aggregationCursor = provider.aggregate(database, collection, cappedResultsPipeline, {
+     maxTimeMS: this.config.maxTimeMs || undefined,
+ });

4. Modify Export Tool (src/tools/mongodb/read/export.ts, ~lines 70-82)

Add to both find and aggregate cursor creation:

  cursor = provider.find(database, collection, filter ?? {}, {
      projection,
      sort,
      limit,
      promoteValues: false,
      bsonRegExp: true,
+     maxTimeMS: this.config.maxTimeMs || undefined,
  });

  cursor = provider.aggregate(database, collection, pipeline, {
      promoteValues: false,
      bsonRegExp: true,
      allowDiskUse: true,
+     maxTimeMS: this.config.maxTimeMs || undefined,
  });

5. Update Constants (src/helpers/constants.ts)

Add documentation/reference:

export const DEFAULT_MAX_TIME_MS: number = 30_000;

Existing Patterns to Follow

The codebase already uses maxTimeMS in two places (hardcoded for count operations):

  • QUERY_COUNT_MAX_TIME_MS_CAP = 10_000 for countDocuments in find
  • AGG_COUNT_MAX_TIME_MS_CAP = 60_000 for aggregation count

This shows the pattern is already established and tested.

Estimated Effort

Task Complexity
Add config option Low - follows existing patterns in userConfig.ts
Update find.ts Trivial - add one option
Update aggregate.ts Trivial - add options object
Update export.ts Low - two small changes
Add tests Medium - follow existing test patterns
Update README Low - add to config table

Total estimate: 1-2 hours for implementation + tests

Benefits

  • Safety by default - Prevents runaway queries from blocking the MCP server
  • Configurable - Users can adjust or disable (0) based on their needs
  • Follows existing patterns - Aligns with other _MS configuration options like idleTimeoutMs, exportTimeoutMs
  • Native MongoDB support - Uses built-in MongoDB functionality, no custom timeout logic needed
  • Override behavior - Using onlyLowerThanBaseValueOverride() means client configs can only reduce the timeout, not increase it beyond server limits

Additional Context

This would complement the existing --indexCheck option which prevents collection scans. Together they provide comprehensive query protection:

  • --indexCheck prevents obviously inefficient queries (COLLSCAN)
  • --maxTimeMs catches queries that are slow for other reasons (complex aggregations, lock contention, large result sets, etc.)

Related

  • MongoDB documentation: cursor.maxTimeMS()
  • Existing option: MDB_MCP_INDEX_CHECK (related safety feature)
  • Existing timeout configs: idleTimeoutMs, notificationTimeoutMs, exportTimeoutMs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions