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

mongodb-js / mongodb-mcp-server / 18714130420

22 Oct 2025 11:06AM UTC coverage: 80.129% (-1.8%) from 81.905%
18714130420

Pull #674

github

web-flow
Merge ec48e82c7 into 17b595b2f
Pull Request #674: chore: move perf advisor to long running tests - MCP-269

1317 of 1776 branches covered (74.16%)

Branch coverage included in aggregate %.

6018 of 7378 relevant lines covered (81.57%)

73.88 hits per line

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

32.46
/src/tools/atlas/read/getPerformanceAdvisor.ts
1
import { z } from "zod";
3✔
2
import { AtlasToolBase } from "../atlasTool.js";
3✔
3
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
4
import type { OperationType, ToolArgs } from "../../tool.js";
5
import { formatUntrustedData } from "../../tool.js";
3✔
6
import {
3✔
7
    getSuggestedIndexes,
8
    getDropIndexSuggestions,
9
    getSchemaAdvice,
10
    getSlowQueries,
11
    DEFAULT_SLOW_QUERY_LOGS_LIMIT,
12
    SUGGESTED_INDEXES_COPY,
13
    SLOW_QUERY_LOGS_COPY,
14
} from "../../../common/atlas/performanceAdvisorUtils.js";
15
import { AtlasArgs } from "../../args.js";
3✔
16

17
const PerformanceAdvisorOperationType = z.enum([
3✔
18
    "suggestedIndexes",
3✔
19
    "dropIndexSuggestions",
3✔
20
    "slowQueryLogs",
3✔
21
    "schemaSuggestions",
3✔
22
]);
3✔
23

24
export class GetPerformanceAdvisorTool extends AtlasToolBase {
3✔
25
    public name = "atlas-get-performance-advisor";
83✔
26
    protected description = `Get MongoDB Atlas performance advisor recommendations, which includes the operations: suggested indexes, drop index suggestions, schema suggestions, and a sample of the most recent (max ${DEFAULT_SLOW_QUERY_LOGS_LIMIT}) slow query logs`;
83✔
27
    public operationType: OperationType = "read";
83✔
28
    protected argsShape = {
83✔
29
        projectId: AtlasArgs.projectId().describe("Atlas project ID to get performance advisor recommendations"),
83✔
30
        clusterName: AtlasArgs.clusterName().describe("Atlas cluster name to get performance advisor recommendations"),
83✔
31
        operations: z
83✔
32
            .array(PerformanceAdvisorOperationType)
83✔
33
            .default(PerformanceAdvisorOperationType.options)
83✔
34
            .describe("Operations to get performance advisor recommendations"),
83✔
35
        since: z
83✔
36
            .string()
83✔
37
            .datetime()
83✔
38
            .describe(
83✔
39
                "Date to get slow query logs since. Must be a string in ISO 8601 format. Only relevant for the slowQueryLogs operation."
83✔
40
            )
83✔
41
            .optional(),
83✔
42
        namespaces: z
83✔
43
            .array(z.string())
83✔
44
            .describe("Namespaces to get slow query logs. Only relevant for the slowQueryLogs operation.")
83✔
45
            .optional(),
83✔
46
    };
83✔
47

48
    protected async execute({
3✔
49
        projectId,
×
50
        clusterName,
×
51
        operations,
×
52
        since,
×
53
        namespaces,
×
54
    }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
×
55
        try {
×
56
            const [suggestedIndexesResult, dropIndexSuggestionsResult, slowQueryLogsResult, schemaSuggestionsResult] =
×
57
                await Promise.allSettled([
×
58
                    operations.includes("suggestedIndexes")
×
59
                        ? getSuggestedIndexes(this.session.apiClient, projectId, clusterName)
×
60
                        : Promise.resolve(undefined),
×
61
                    operations.includes("dropIndexSuggestions")
×
62
                        ? getDropIndexSuggestions(this.session.apiClient, projectId, clusterName)
×
63
                        : Promise.resolve(undefined),
×
64
                    operations.includes("slowQueryLogs")
×
65
                        ? getSlowQueries(
×
66
                              this.session.apiClient,
×
67
                              projectId,
×
68
                              clusterName,
×
69
                              since ? new Date(since) : undefined,
×
70
                              namespaces
×
71
                          )
×
72
                        : Promise.resolve(undefined),
×
73
                    operations.includes("schemaSuggestions")
×
74
                        ? getSchemaAdvice(this.session.apiClient, projectId, clusterName)
×
75
                        : Promise.resolve(undefined),
×
76
                ]);
×
77

78
            const hasSuggestedIndexes =
×
79
                suggestedIndexesResult.status === "fulfilled" &&
×
80
                suggestedIndexesResult.value?.suggestedIndexes &&
×
81
                suggestedIndexesResult.value.suggestedIndexes.length > 0;
×
82
            const hasDropIndexSuggestions =
×
83
                dropIndexSuggestionsResult.status === "fulfilled" &&
×
84
                dropIndexSuggestionsResult.value?.hiddenIndexes &&
×
85
                dropIndexSuggestionsResult.value?.redundantIndexes &&
×
86
                dropIndexSuggestionsResult.value?.unusedIndexes &&
×
87
                (dropIndexSuggestionsResult.value.hiddenIndexes.length > 0 ||
×
88
                    dropIndexSuggestionsResult.value.redundantIndexes.length > 0 ||
×
89
                    dropIndexSuggestionsResult.value.unusedIndexes.length > 0);
×
90
            const hasSlowQueryLogs =
×
91
                slowQueryLogsResult.status === "fulfilled" &&
×
92
                slowQueryLogsResult.value?.slowQueryLogs &&
×
93
                slowQueryLogsResult.value.slowQueryLogs.length > 0;
×
94
            const hasSchemaSuggestions =
×
95
                schemaSuggestionsResult.status === "fulfilled" &&
×
96
                schemaSuggestionsResult.value?.recommendations &&
×
97
                schemaSuggestionsResult.value.recommendations.length > 0;
×
98

99
            // Inserts the performance advisor data with the relevant section header if it exists
100
            const performanceAdvisorData = [
×
101
                `## Suggested Indexes\n${
×
102
                    hasSuggestedIndexes
×
103
                        ? `${SUGGESTED_INDEXES_COPY}\n${JSON.stringify(suggestedIndexesResult.value?.suggestedIndexes)}`
×
104
                        : "No suggested indexes found."
×
105
                }`,
×
106
                `## Drop Index Suggestions\n${hasDropIndexSuggestions ? JSON.stringify(dropIndexSuggestionsResult.value) : "No drop index suggestions found."}`,
×
107
                `## Slow Query Logs\n${hasSlowQueryLogs ? `${SLOW_QUERY_LOGS_COPY}\n${JSON.stringify(slowQueryLogsResult.value?.slowQueryLogs)}` : "No slow query logs found."}`,
×
108
                `## Schema Suggestions\n${hasSchemaSuggestions ? JSON.stringify(schemaSuggestionsResult.value?.recommendations) : "No schema suggestions found."}`,
×
109
            ];
×
110

111
            if (performanceAdvisorData.length === 0) {
×
112
                return {
×
113
                    content: [{ type: "text", text: "No performance advisor recommendations found." }],
×
114
                };
×
115
            }
×
116

117
            return {
×
118
                content: formatUntrustedData("Performance advisor data", performanceAdvisorData.join("\n\n")),
×
119
            };
×
120
        } catch (error) {
×
121
            return {
×
122
                content: [
×
123
                    {
×
124
                        type: "text",
×
125
                        text: `Error retrieving performance advisor data: ${error instanceof Error ? error.message : String(error)}`,
×
126
                    },
×
127
                ],
×
128
            };
×
129
        }
×
130
    }
×
131
}
3✔
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