Skip to content

Commit bd69450

Browse files
committed
Add base atlas performance advisor MCP server tool
1 parent cfc606d commit bd69450

File tree

8 files changed

+891
-0
lines changed

8 files changed

+891
-0
lines changed

scripts/filter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ function filterOpenapi(openapi: OpenAPIV3_1.Document): OpenAPIV3_1.Document {
4141
"deleteProjectIpAccessList",
4242
"listOrganizationProjects",
4343
"listAlerts",
44+
"listDropIndexes",
45+
"listClusterSuggestedIndexes",
46+
"listSchemaAdvice",
47+
"listSlowQueries",
4448
];
4549

4650
const filteredPaths = {};

src/common/atlas/apiClient.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,42 @@ export class ApiClient {
428428
return data;
429429
}
430430

431+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
432+
async listDropIndexes(options: FetchOptions<operations["listDropIndexes"]>) {
433+
const { data, error, response } = await this.client.GET(
434+
"/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/dropIndexSuggestions",
435+
options
436+
);
437+
if (error) {
438+
throw ApiClientError.fromError(response, error);
439+
}
440+
return data;
441+
}
442+
443+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
444+
async listSchemaAdvice(options: FetchOptions<operations["listSchemaAdvice"]>) {
445+
const { data, error, response } = await this.client.GET(
446+
"/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/schemaAdvice",
447+
options
448+
);
449+
if (error) {
450+
throw ApiClientError.fromError(response, error);
451+
}
452+
return data;
453+
}
454+
455+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
456+
async listClusterSuggestedIndexes(options: FetchOptions<operations["listClusterSuggestedIndexes"]>) {
457+
const { data, error, response } = await this.client.GET(
458+
"/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/performanceAdvisor/suggestedIndexes",
459+
options
460+
);
461+
if (error) {
462+
throw ApiClientError.fromError(response, error);
463+
}
464+
return data;
465+
}
466+
431467
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
432468
async listDatabaseUsers(options: FetchOptions<operations["listDatabaseUsers"]>) {
433469
const { data, error, response } = await this.client.GET(
@@ -507,6 +543,18 @@ export class ApiClient {
507543
return data;
508544
}
509545

546+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
547+
async listSlowQueries(options: FetchOptions<operations["listSlowQueries"]>) {
548+
const { data, error, response } = await this.client.GET(
549+
"/api/atlas/v2/groups/{groupId}/processes/{processId}/performanceAdvisor/slowQueryLogs",
550+
options
551+
);
552+
if (error) {
553+
throw ApiClientError.fromError(response, error);
554+
}
555+
return data;
556+
}
557+
510558
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
511559
async listOrganizations(options?: FetchOptions<operations["listOrganizations"]>) {
512560
const { data, error, response } = await this.client.GET("/api/atlas/v2/orgs", options);

src/common/atlas/cluster.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,25 @@ export async function inspectCluster(apiClient: ApiClient, projectId: string, cl
9696
}
9797
}
9898
}
99+
100+
export async function getProcessIdFromCluster(
101+
apiClient: ApiClient,
102+
projectId: string,
103+
clusterName: string
104+
): Promise<string> {
105+
try {
106+
// Reuse existing inspectCluster method
107+
const cluster = await inspectCluster(apiClient, projectId, clusterName);
108+
if (!cluster.connectionString) {
109+
throw new Error("No connection string available for cluster");
110+
}
111+
// Extract host:port from connection string
112+
const url = new URL(cluster.connectionString);
113+
const processId = `${url.hostname}:${url.port || "27017"}`;
114+
return processId;
115+
} catch (error) {
116+
throw new Error(
117+
`Failed to get processId from cluster: ${error instanceof Error ? error.message : String(error)}`
118+
);
119+
}
120+
}

0 commit comments

Comments
 (0)