feat(config): add maxTimeMs configuration for query timeout protection#830
feat(config): add maxTimeMs configuration for query timeout protection#830jahales wants to merge 6 commits intomongodb-js:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a maxTimeMs configuration option to protect against long-running MongoDB queries by automatically terminating find and aggregate operations after a specified duration. The default timeout is 30 seconds, and setting it to 0 disables the feature.
Key changes:
- Added
maxTimeMsconfig parameter with safe override behavior usingonlyLowerThanBaseValueOverride() - Updated
find,aggregate, andexporttools to apply the timeout viamaxTimeMScursor option - Added comprehensive integration tests verifying both enabled and disabled timeout scenarios
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/common/config/userConfig.ts | Adds the maxTimeMs configuration schema with a 30-second default |
| src/tools/mongodb/read/find.ts | Applies maxTimeMS to find cursor operations |
| src/tools/mongodb/read/aggregate.ts | Applies maxTimeMS to aggregate operations |
| src/tools/mongodb/read/export.ts | Applies maxTimeMS to both find and aggregate cursors in export operations |
| tests/unit/common/config.test.ts | Updates expected defaults to include the new maxTimeMs setting |
| tests/integration/tools/mongodb/read/find.test.ts | Adds integration tests for find tool with maxTimeMs enabled and disabled |
| tests/integration/tools/mongodb/read/aggregate.test.ts | Adds integration tests for aggregate tool with maxTimeMs enabled and disabled |
| README.md | Documents the new configuration option |
src/tools/mongodb/read/aggregate.ts
Outdated
| aggregationCursor = provider.aggregate(database, collection, cappedResultsPipeline); | ||
| aggregationCursor = provider.aggregate(database, collection, cappedResultsPipeline, { | ||
| maxTimeMS: this.config.maxTimeMs || undefined, | ||
| }); |
There was a problem hiding this comment.
Since the option is set on the MCP-server-wide config, should we set it on the MongoClient or NodeDriverServiceProvider instead? Or otherwise, if it's not meant to apply to all operations and really only find and aggregate, should it be named differently so it's clear that it's not the standard driver maxTimeMs option?
There was a problem hiding this comment.
Great question! After checking, the MongoDB driver's maxTimeMS option is per-operation, not a MongoClient-level setting, so setting it globally on the client isn't directly possible.
Given that, I see a few options:
- Rename to clarify scope - Something like
queryMaxTimeMsorreadMaxTimeMsto indicate it only applies to find/aggregate/export operations - Extend to more operations - Apply maxTimeMS to other read operations like count, listCollections, etc.
- Keep as-is - The current name matches the MongoDB driver option name, which might be intuitive for users familiar with MongoDB
What would you prefer? I'm happy to adjust based on your guidance.
There was a problem hiding this comment.
We have timeoutMS that is being set to 30s when constructing the driver options:
Should this be the thing we configure instead?
There was a problem hiding this comment.
Yeah, that should be the right place to consume this if we make it configurable
I was also wondering about maxTimeMS vs timeoutMS here, for a lot of devtools things the former is what makes the most sense since the primary concern is avoiding runaway tasks on the cluster and it's generally fine if the rest of the operation (e.g. network handling) takes a bit longer, I think a similar logic applies for MCP but I could see an argument to be made that if a response doesn't come within a specific amount of time, it's fine to fail it
There was a problem hiding this comment.
I intentionally use maxTimeMS (per-operation) rather than timeoutMS (client-wide) because the goal is server-side protection against expensive AI-generated queries. maxTimeMS is enforced by MongoDB itself and only counts server execution time, whereas timeoutMS includes network latency and is client-enforced.
That said, I think making timeoutMS configurable makes sense as a separate feature for controlling deterministic MCP behavior (i.e., "the MCP should respond within X ms or fail"). Happy to add that in a follow-up PR if there's interest.
For this PR, I can rename the config to queryMaxTimeMs to clarify it applies to query operations (find/aggregate) and isn't the standard driver option. I can also extend it to other potentially expensive read operations like count and listCollections.
There was a problem hiding this comment.
@addaleax @nirinchev Updated the PR: queryMaxTimeMs & applied to key read operations
|
Note this PR was generated with LLM assistance (Claude Opus 4.5) |
- Add queryMaxTimeMs config option for server-side query timeout - Apply to read operations: find, aggregate, count, export - Default: 30 seconds, set to 0 to disable - Update README documentation - Add unit and integration tests
81c98d7 to
ac5126a
Compare
|
This PR has gone 30 days without any activity and meets the project's definition of "stale". This will be auto-closed if there is no new activity over the next 30 days. If the issue is still relevant and active, you can simply comment with a "bump" to keep it open, or add the label "not_stale". Thanks for keeping our repository healthy! |
Description
Add a
maxTimeMsconfiguration option to automatically terminate long-runningfindandaggregateoperations after a specified duration. This provides resource protection for AI-generated queries that may inadvertently perform expensive operations.Closes #829
Jira: MCP-349
Motivation
When using the MongoDB MCP server with AI assistants, there's a risk of generating queries that scan large collections or perform expensive aggregations. Without a timeout, these queries can:
Changes
Configuration
maxTimeMsconfig option (default: 30000ms / 30 seconds)0disables the timeoutonlyLowerThanBaseValueOverridefor safe config mergingTools Updated
maxTimeMSto cursor optionsmaxTimeMSto aggregate optionsmaxTimeMSto both find and aggregate cursorsTests
config.test.tswith maxTimeMs in expectedDefaultsDocumentation
Example Configuration
{ "maxTimeMs": 30000 }Checklist
pnpm run check)maxTimeMSConfiguration Option for Query Timeout #829)