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

mongodb-js / mongodb-mcp-server / 15063490200

16 May 2025 07:51AM UTC coverage: 73.774%. First build
15063490200

Pull #258

github

web-flow
Merge 047c85483 into 298adf4a5
Pull Request #258: feat: listSearchIndexes now lists index status info

209 of 368 branches covered (56.79%)

Branch coverage included in aggregate %.

0 of 1 new or added line in 1 file covered. (0.0%)

829 of 1039 relevant lines covered (79.79%)

54.59 hits per line

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

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

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

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

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

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

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

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

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

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