Skip to content

Conversation

kylelai1
Copy link
Collaborator

@kylelai1 kylelai1 commented Sep 8, 2025

Proposed changes

This PR adds the atlas-list-performance-advisor tool to the MCP server, which retrieves the following performance advisor recommendations from the admin API: index suggestions, drop index suggestions, schema suggestions, slow query logs.

This PR merges the changes into the atlas-list-performance-advisor-tool branch.

Testing

  • Manually tested that the MCP server is able to retrieve performance advisor suggestions.

Checklist

@kylelai1 kylelai1 marked this pull request as ready for review September 8, 2025 20:24
@kylelai1 kylelai1 requested a review from a team as a code owner September 8, 2025 20:24
@kylelai1 kylelai1 requested a review from blva September 8, 2025 20:24
@kylelai1 kylelai1 changed the title Adds the atlas-list-performance-advisor base tool feat: Adds the atlas-list-performance-advisor base tool Sep 8, 2025
Copy link
Collaborator

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a quick pass - overall, looks reasonable, but I'm worried that it might not be too LLM-friendly. I suggest testing it thoroughly with different agents/models and confirming it's outputting meaningful insights.

@kylelai1 kylelai1 requested a review from nirinchev September 15, 2025 16:42
Copy link
Collaborator

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks reasonable, but it can be significantly simplified if we remove the duplicate type definitions and drop the data formatting logic (as we don't have much evidence to suggest models understand tables better than json).

},
});
return {
suggestedIndexes: (response as SuggestedIndexesResponse).content.suggestedIndexes ?? [],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is concerning - why are we recasting the response to a different shape? This seems to indicate the definitions we've generated from the open api spec are not correct.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's correct. I've manually tested this with the MCP server tool, and separately by making requests to the admin api (v2), and found that the response from the open API spec is not correct. It is missing the content field, which I've added when accessing the suggestedIndexes. This applies to the 4 different PA endpoints we're calling as a part of this tool.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why the other responses from the API client don't have the same problem. @blva's team owns that part of the codebase, so perhaps something to look into?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see content in ApiPerformanceAdvisorResponseView (schema name PerformanceAdvisorResponse) shape in MMS.

Why are we adding this interface and why do we need this content field? I think you should be able to use the openapi specs as they are.

interface SuggestedIndexesResponse {
    content: components["schemas"]["PerformanceAdvisorResponse"];
}

You don't need to import content: components["schemas"]["PerformanceAdvisorResponse"]; here, you should probably use PerformanceAdvisorResponse from openapi.d.ts, right?

Copy link
Collaborator

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking better. I've left more suggestions for further deduplicating the types. The only major thing that remains is figuring out why the openapi definitions are wrong and what it would take to fix them.

@kylelai1 kylelai1 requested a review from nirinchev September 18, 2025 17:17
Copy link
Collaborator

@kmruiz kmruiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far looks good, but I think there are a few things to improve here in terms of user experience and maintainability of the actual tool.

Great job @kylelai1, we know it's still complicated to implement new tools but you've been doing great so far.

Comment on lines 40 to 51
projectId: z.string().describe("Atlas project ID to list performance advisor recommendations"),
clusterName: z.string().describe("Atlas cluster name to list performance advisor recommendations"),
operations: z
.array(PerformanceAdvisorOperationType)
.default(PerformanceAdvisorOperationType.options)
.describe("Operations to list performance advisor recommendations"),
since: z.date().describe("Date to list slow query logs since").optional(),
namespaces: z
.array(z.string())
.describe("Namespaces to list slow query logs. Only relevant for the slowQueryLogs operation.")
.optional(),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this requires some second thoughts.

When the user is connected to an Atlas Cluster, we have already the projectId and clusterName, which should be enough. I think we should leverage this as a default. This would make projectId and clusterName optional.

You can retrieve the current connected cluster from the session:

this.session.connectedAtlasCluster

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user has an atlas cluster already connected, the LLM should be able to provide the projectId and clusterName already without any additional user input. If there hasn't been a specified cluster, then the LLM will prompt the user to provide the projectId and clusterName.

if we were to make the projectId and clusterName default, then we'd need to build it in to the tool to retrieve this from the connected cluster as you said.

Do we find that the LLM prompting the user for this is something we want to avoid, and that we want to instead have the tool handle as much of that as possible? Even if the projectId and clusterName are not optionals, the LLM will still provide these if there was already a previous connected cluster.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's an explicit expectation that the user should be connected to the cluster (via a mongodb connection) before they're able to ask for performance advice. Additionally, many other Atlas tools follow the same pattern of requiring a cluster name and project id, so I think leaving things as they are makes sense.

Copy link
Collaborator

@kmruiz kmruiz Sep 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arguably this is the first tool that is actually relevant for a single cluster where the user is connected.

However, I am not going to die on this hill, but at least I would suggest to use the AtlasArgs types we have in args.ts, instead of Zod primitives, to align to what other Atlas tools do.

Edit:

The Atlas connect tool does not provide the projectId of the cluster, so my guess is that we trust the agent to provide it from another place after somehow listing projects and clusters.

I think this could be avoided and simplified making these args optional, so a prompt as easy as: give me the performance suggestions of the current cluster" would work even if rhe user never queried for other projects, action that might not have permissions to do.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is already a connected cluster, then a simple prompt should be able to be understood by the LLM without prompting for the projectID and clusterName again. We can revisit this during QA when we manually test the tool with a connected cluster or without a connected cluster to see if it will prompt the user for the projectId and clusterName again.

Looks like AtlasArgs was not created when I started work for this ticket, so thanks for pointing that out! I'll make that change.

Copy link
Collaborator

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Final nits from me. We should investigate the .content issue, but I'd be fine if that's resolved in a follow-up PR.

Copy link
Collaborator

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... Looks like you'd need to update the base branch to latest main, otherwise this PR brings in a bunch of stuff, making it harder to review.

@kylelai1 kylelai1 merged commit 173c587 into atlas-list-performance-advisor-tool Sep 19, 2025
11 checks passed
@kylelai1 kylelai1 deleted the atlas-list-performance-advisor-base-tool branch September 19, 2025 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants