8000 feat(index-check): add index check functionality before query by Crushdada · Pull Request #309 · mongodb-js/mongodb-mcp-server · GitHub
[go: up one dir, main page]

Skip to content

feat(index-check): add index check functionality before query< 10000 /bdi> #309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Crushdada
Copy link

Summary

This PR adds a new indexCheck configuration option that enforces MongoDB queries to use indexes, preventing collection scans (COLLSCAN) operations.

Changes

  • ✅ Added indexCheck helper functions in src/helpers/indexCheck.ts
  • ✅ Updated 5 MongoDB operations to support index checking: deleteMany, aggregate, count, find, updateMany
  • ✅ Added configuration support in .smithery/smithery.yaml
  • ✅ Updated README.md with comprehensive documentation
  • ✅ Added comprehensive test suite with 7 passing tests

Features

  • Uses MongoDB's explain functionality to analyze query plans
  • Configurable via environment variables, CLI args, or platform config
  • Comprehensive error messages for debugging
  • Only applies to query operations (not inserts)

Testing

  • All existing tests pass
  • New unit tests achieve 57.89% code coverage
  • Integration tested with MCP server

Related Issues

Resolves #287

Documentation

  • Updated README.md with indexCheck configuration details
  • Added comprehensive examples and usage instructions
  • Updated .smithery/smithery.yaml following project patterns

@Crushdada Crushdada requested a review from a team as a code owner June 18, 2025 14:43
Copy link
Collaborator
@kmruiz kmruiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job so far! Thanks a lot!

I've requested a few small changes that should make things more correct for newest MongoDB versions and one QoL that should simplify your code a bit.

Thanks a lot for contributing!

* @param explainResult The result of the explain query
* @returns true if an index is used, false if it's a full collection scan
*/
export function usesIndex(explainResult: Document): boolean {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will be situations where this doesn't work in MongoDB 8.0+, as we have a few more stages that are like an index scan. Can you add them? These are:

"EXPRESS_IXSCAN"
"EXPRESS_CLUSTERED_IXSCAN"
"EXPRESS_UPDATE"
"EXPRESS_DELETE"

Also, not related to 8.0, but there is a stage called IDHACK that is also like an index scan.

const explainResult = await explainCallback();

if (!usesIndex(explainResult)) {
throw new Error(getIndexCheckErrorMessage(database, collection, operation));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new Error(getIndexCheckErrorMessage(database, collection, operation));
throw new MongoDBError(ErrorCodes.ForbiddenCollscan, getIndexCheckErrorMessage(database, collection, operation));

Here it's better to use MongoDBError, this way you can rethrow it without taking a look at the message, and it's also what we use as a facade with the MCP Client, so it should be safe to throw anytime!

You'll need to add the error code in src/errors.ts

@Crushdada
Copy link
Author

@kmruiz :) Thank you for the detailed code review and suggestions! I have completed the following changes according to your feedback:

✅ Added ForbiddenCollscan error code and replaced generic Error with MongoDBError
✅ Extended index scan stage detection to support MongoDB 8.0+ stages (EXPRESS_IXSCAN, EXPRESS_CLUSTERED_IXSCAN, EXPRESS_UPDATE, EXPRESS_DELETE, IDHACK)
✅ Added comprehensive unit tests for all new index scan stages

Please review again, and feel free to provide any additional suggestions. Thank you again for your guidance !

Copy link
Collaborator
@kmruiz kmruiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good @Crushdada ! I'm going to run the workflows and if everything is green and you don't mind, I'll merge the PR.

Thanks a lot for contributing! Really appreciate it!

@kmruiz
Copy link
Collaborator
kmruiz commented Jun 20, 2025

@Crushdada I see that there are a few issues with the formatting and the usage of any. Would you mind fixing them?

You can run npm run check in your branch to see all the issues in your changes. Once you fix them I will run the tests and merge!

Thanks!

@Crushdada
10000 Copy link
Author

@kmruiz Thanks for catching that! Can I use "string | undefined" to solve the "any" type of problem?

@kmruiz
Copy link
Collaborator
kmruiz commented Jun 20, 2025

Sure! ideally if you are working on an object with an unknown shape, ideally you should define a type and cast it so we know what is the basic shape for the object. For primitives, you can use the type and undefined. However we are not really strict here, if it's clear the purpose and the type, it will be fine.

Copy link
Collaborator
@himanshusinghs himanshusinghs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this @Crushdada 🚀 Added small comments. It would be nice to add a few integration tests for the added config change as well?

// Check if delete operation uses an index if enabled
if (this.config.indexCheck) {
await checkIndexUsage(provider, database, collection, "deleteMany", async () => {
return provider.mongoClient.db(database).command({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provider instance here provides interfaces (runCommand and runCommandWithCheck) for command execution. Please prefer those over accessing methods directly on MongoClient. The same applies to other instances of the MongoClient.db().command() usages.

I believe what you need here is runCommandWithCheck

Copy link
Author
@Crushdada Crushdada Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing out this issue, I have revised it. But I encountered a problem that confused me that the "code health" check failed. Should we increase the timeout at tests/integration/tools/mongodb/mongodbHelpers.ts:94 ?

Crushdada and others added 2 commits June 21, 2025 00:30
Co-authored-by: Himanshu Singh <himanshu.singhs@outlook.in>
@Crushdada Crushdada requested a review from himanshusinghs June 21, 2025 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request]: Add index check before query
3 participants
0