• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb-js / mongodb-mcp-server / 16275099623

14 Jul 2025 06:42PM UTC coverage: 77.524% (+2.3%) from 75.27%
16275099623

Pull #363

github

web-flow
Merge 3f10cbde7 into 184841400
Pull Request #363: chore(tests): switch to vitest

499 of 688 branches covered (72.53%)

Branch coverage included in aggregate %.

0 of 26 new or added lines in 2 files covered. (0.0%)

291 existing lines in 26 files now uncovered.

2833 of 3610 relevant lines covered (78.48%)

28.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.0
/src/helpers/indexCheck.ts
1
import { Document } from "mongodb";
2
import { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
3
import { ErrorCodes, MongoDBError } from "../common/errors.js";
2✔
4

5
/**
6
 * Check if the query plan uses an index
7
 * @param explainResult The result of the explain query
8
 * @returns true if an index is used, false if it's a full collection scan
9
 */
10
export function usesIndex(explainResult: Document): boolean {
2✔
11
    const queryPlanner = explainResult?.queryPlanner as Document | undefined;
26✔
12
    const winningPlan = queryPlanner?.winningPlan as Document | undefined;
26✔
13
    const stage = winningPlan?.stage as string | undefined;
26✔
14
    const inputStage = winningPlan?.inputStage as Document | undefined;
26✔
15

16
    // Check for index scan stages (including MongoDB 8.0+ stages)
17
    const indexScanStages = [
26✔
18
        "IXSCAN",
26✔
19
        "COUNT_SCAN",
26✔
20
        "EXPRESS_IXSCAN",
26✔
21
        "EXPRESS_CLUSTERED_IXSCAN",
26✔
22
        "EXPRESS_UPDATE",
26✔
23
        "EXPRESS_DELETE",
26✔
24
        "IDHACK",
26✔
25
    ];
26✔
26

27
    if (stage && indexScanStages.includes(stage)) {
26✔
28
        return true;
8✔
29
    }
8✔
30

31
    if (inputStage && inputStage.stage && indexScanStages.includes(inputStage.stage as string)) {
26✔
32
        return true;
7✔
33
    }
7✔
34

35
    // Recursively check deeper stages
36
    if (inputStage && inputStage.inputStage) {
26✔
37
        return usesIndex({ queryPlanner: { winningPlan: inputStage } });
3✔
38
    }
3✔
39

40
    if (stage === "COLLSCAN") {
26✔
41
        return false;
1✔
42
    }
1✔
43

44
    // Default to false (conservative approach)
45
    return false;
7✔
46
}
7✔
47

48
/**
49
 * Generate an error message for index check failure
50
 */
51
export function getIndexCheckErrorMessage(database: string, collection: string, operation: string): string {
2✔
52
    return `Index check failed: The ${operation} operation on "${database}.${collection}" performs a collection scan (COLLSCAN) instead of using an index. Consider adding an index for better performance. Use 'explain' tool for query plan analysis or 'collection-indexes' to view existing indexes. To disable this check, set MDB_MCP_INDEX_CHECK to false.`;
6✔
53
}
6✔
54

55
/**
56
 * Generic function to perform index usage check
57
 */
58
export async function checkIndexUsage(
11✔
59
    provider: NodeDriverServiceProvider,
11✔
60
    database: string,
11✔
61
    collection: string,
11✔
62
    operation: string,
11✔
63
    explainCallback: () => Promise<Document>
11✔
64
): Promise<void> {
11✔
65
    try {
11✔
66
        const explainResult = await explainCallback();
11✔
67

68
        if (!usesIndex(explainResult)) {
11✔
69
            throw new MongoDBError(
5✔
70
                ErrorCodes.ForbiddenCollscan,
5✔
71
                getIndexCheckErrorMessage(database, collection, operation)
5✔
72
            );
5✔
73
        }
5✔
74
    } catch (error) {
11✔
75
        if (error instanceof MongoDBError && error.code === ErrorCodes.ForbiddenCollscan) {
5✔
76
            throw error;
5✔
77
        }
5!
78

79
        // If explain itself fails, log but do not prevent query execution
80
        // This avoids blocking normal queries in special cases (e.g., permission issues)
81
        console.warn(`Index check failed to execute explain for ${operation} on ${database}.${collection}:`, error);
×
UNCOV
82
    }
×
83
}
11✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc