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

mongodb-js / mongodb-mcp-server / 17161333946

22 Aug 2025 05:03PM UTC coverage: 81.909% (-0.1%) from 82.022%
17161333946

Pull #471

github

web-flow
Merge 903825dd4 into 49707be70
Pull Request #471: fix: atlas connectCluster defaults to readOnly DB roles - MCP-125

874 of 1092 branches covered (80.04%)

Branch coverage included in aggregate %.

25 of 25 new or added lines in 2 files covered. (100.0%)

49 existing lines in 10 files now uncovered.

4360 of 5298 relevant lines covered (82.3%)

70.64 hits per line

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

56.07
/src/tools/atlas/read/listClusters.ts
1
import { z } from "zod";
2✔
2
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
import { AtlasToolBase } from "../atlasTool.js";
2✔
4
import type { ToolArgs, OperationType } from "../../tool.js";
5
import { formatUntrustedData } from "../../tool.js";
2✔
6
import type {
7
    PaginatedClusterDescription20240805,
8
    PaginatedOrgGroupView,
9
    Group,
10
    PaginatedFlexClusters20241113,
11
} from "../../../common/atlas/openapi.js";
12
import { formatCluster, formatFlexCluster } from "../../../common/atlas/cluster.js";
2✔
13

14
export class ListClustersTool extends AtlasToolBase {
2✔
15
    public name = "atlas-list-clusters";
80✔
16
    protected description = "List MongoDB Atlas clusters";
80✔
17
    public operationType: OperationType = "read";
80✔
18
    protected argsShape = {
80✔
19
        projectId: z.string().describe("Atlas project ID to filter clusters").optional(),
80✔
20
    };
80✔
21

22
    protected async execute({ projectId }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
2✔
23
        if (!projectId) {
1!
UNCOV
24
            const data = await this.session.apiClient.listClustersForAllProjects();
×
25

UNCOV
26
            return this.formatAllClustersTable(data);
×
27
        } else {
1✔
28
            const project = await this.session.apiClient.getProject({
1✔
29
                params: {
1✔
30
                    path: {
1✔
31
                        groupId: projectId,
1✔
32
                    },
1✔
33
                },
1✔
34
            });
1✔
35

36
            if (!project?.id) {
1!
37
                throw new Error(`Project with ID "${projectId}" not found.`);
×
UNCOV
38
            }
×
39

40
            const data = await this.session.apiClient.listClusters({
1✔
41
                params: {
1✔
42
                    path: {
1✔
43
                        groupId: project.id || "",
1!
44
                    },
1✔
45
                },
1✔
46
            });
1✔
47

48
            return this.formatClustersTable(project, data);
1✔
49
        }
1✔
50
    }
1✔
51

52
    private formatAllClustersTable(clusters?: PaginatedOrgGroupView): CallToolResult {
2✔
53
        if (!clusters?.results?.length) {
×
54
            throw new Error("No clusters found.");
×
55
        }
×
56
        const formattedClusters = clusters.results
×
57
            .map((result) => {
×
58
                return (result.clusters || []).map((cluster) => {
×
59
                    return { ...result, ...cluster, clusters: undefined };
×
60
                });
×
61
            })
×
62
            .flat();
×
63
        if (!formattedClusters.length) {
×
64
            throw new Error("No clusters found.");
×
65
        }
×
66
        const rows = formattedClusters
×
67
            .map((cluster) => {
×
68
                return `${cluster.groupName} (${cluster.groupId}) | ${cluster.name}`;
×
69
            })
×
70
            .join("\n");
×
71
        return {
×
72
            content: [
×
73
                {
×
74
                    type: "text",
×
UNCOV
75
                    text: `Project | Cluster Name
×
76
----------------|----------------
77
${rows}`,
×
78
                },
×
79
            ],
×
80
        };
×
UNCOV
81
    }
×
82

83
    private formatClustersTable(
2✔
84
        project: Group,
1✔
85
        clusters?: PaginatedClusterDescription20240805,
1✔
86
        flexClusters?: PaginatedFlexClusters20241113
1✔
87
    ): CallToolResult {
1✔
88
        // Check if both traditional clusters and flex clusters are absent
89
        if (!clusters?.results?.length && !flexClusters?.results?.length) {
1!
90
            return {
×
UNCOV
91
                content: [{ type: "text", text: "No clusters found." }],
×
UNCOV
92
            };
×
UNCOV
93
        }
×
94
        const formattedClusters = clusters?.results?.map((cluster) => formatCluster(cluster)) || [];
1!
95
        const formattedFlexClusters = flexClusters?.results?.map((cluster) => formatFlexCluster(cluster)) || [];
1!
96
        const rows = [...formattedClusters, ...formattedFlexClusters]
1✔
97
            .map((formattedCluster) => {
1✔
98
                return `${formattedCluster.name || "Unknown"} | ${formattedCluster.instanceType} | ${formattedCluster.instanceSize || "N/A"} | ${formattedCluster.state || "UNKNOWN"} | ${formattedCluster.mongoDBVersion || "N/A"} | ${formattedCluster.connectionString || "N/A"}`;
1!
99
            })
1✔
100
            .join("\n");
1✔
101
        return {
1✔
102
            content: formatUntrustedData(
1✔
103
                `Found ${rows.length} clusters in project "${project.name}" (${project.id}):`,
1✔
104
                `Cluster Name | Cluster Type | Tier | State | MongoDB Version | Connection String
1✔
105
----------------|----------------|----------------|----------------|----------------|----------------
106
${rows}`
1✔
107
            ),
1✔
108
        };
1✔
109
    }
1✔
110
}
2✔
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