Skip to content

Commit 90caa25

Browse files
committed
Merge remote-tracking branch 'origin/main' into telemetry
2 parents a15eeb6 + 9ba243d commit 90caa25

21 files changed

+46
-100
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ You may experiment asking `Can you connect to my mongodb instance?`.
109109
- `atlas-list-db-users` - List MongoDB Atlas database users
110110
- `atlas-create-db-user` - List MongoDB Atlas database users
111111

112+
NOTE: atlas tools are only available when you set credentials on [configuration](#configuration) section.
113+
112114
#### MongoDB Database Tools
113115

114116
- `connect` - Connect to a MongoDB instance

src/common/atlas/apiClient.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import logger from "../../logger.js";
1010

1111
const ATLAS_API_VERSION = "2025-03-12";
1212

13+
export interface ApiClientCredentials {
14+
clientId: string;
15+
clientSecret: string;
16+
}
17+
1318
export interface ApiClientOptions {
14-
credentials?: {
15-
clientId: string;
16-
clientSecret: string;
17-
};
19+
credentials?: ApiClientCredentials;
1820
baseUrl?: string;
1921
userAgent?: string;
2022
}

src/session.ts

Lines changed: 19 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
import { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
2-
import { ApiClient } from "./common/atlas/apiClient.js";
3-
import defaultConfig from "./config.js";
2+
import { ApiClient, ApiClientCredentials } from "./common/atlas/apiClient.js";
43
import { Implementation } from "@modelcontextprotocol/sdk/types.js";
5-
6-
// Define the type for configuration used by Session
7-
interface SessionConfig {
8-
apiBaseUrl?: string;
9-
apiClientId?: string;
10-
apiClientSecret?: string;
11-
[key: string]: unknown;
12-
}
4+
import config from "./config.js";
135

146
export class Session {
157
sessionId?: string;
@@ -19,59 +11,31 @@ export class Session {
1911
name: string;
2012
version: string;
2113
};
22-
private credentials?: { clientId: string; clientSecret: string };
23-
private baseUrl: string;
24-
private readonly config: SessionConfig;
25-
26-
constructor(config: SessionConfig = defaultConfig as SessionConfig) {
27-
this.config = config;
28-
this.baseUrl = this.config.apiBaseUrl ?? "https://cloud.mongodb.com/";
29-
30-
// Store credentials if available
31-
if (this.config.apiClientId && this.config.apiClientSecret) {
32-
this.credentials = {
33-
clientId: this.config.apiClientId,
34-
clientSecret: this.config.apiClientSecret,
35-
};
36-
37-
// Initialize API client with credentials
38-
this.apiClient = new ApiClient({
39-
baseUrl: this.baseUrl,
40-
credentials: this.credentials,
41-
});
42-
return;
43-
}
4414

45-
// Initialize API client without credentials
46-
this.apiClient = new ApiClient({ baseUrl: this.baseUrl });
15+
constructor() {
16+
const credentials: ApiClientCredentials | undefined =
17+
config.apiClientId && config.apiClientSecret
18+
? {
19+
clientId: config.apiClientId,
20+
clientSecret: config.apiClientSecret,
21+
}
22+
: undefined;
23+
24+
this.apiClient = new ApiClient({
25+
baseUrl: config.apiBaseUrl,
26+
credentials,
27+
});
4728
}
4829

49-
setAgentRunner(agentClient: Implementation | undefined) {
50-
if (agentClient?.name && agentClient?.version) {
30+
setAgentRunner(agentRunner: Implementation | undefined) {
31+
if (agentRunner?.name && agentRunner?.version) {
5132
this.agentRunner = {
52-
name: agentClient.name,
53-
version: agentClient.version,
33+
name: agentRunner.name,
34+
version: agentRunner.version,
5435
};
5536
}
5637
}
5738

58-
ensureAuthenticated(): asserts this is { apiClient: ApiClient } {
59-
if (!this.apiClient.hasCredentials()) {
60-
if (!this.credentials) {
61-
throw new Error(
62-
"Not authenticated make sure to configure MCP server with MDB_MCP_API_CLIENT_ID and MDB_MCP_API_CLIENT_SECRET environment variables."
63-
);
64-
}
65-
66-
// Reinitialize API client with the stored credentials
67-
// This can happen if the server was configured without credentials but the env variables are later set
68-
this.apiClient = new ApiClient({
69-
baseUrl: this.baseUrl,
70-
credentials: this.credentials,
71-
});
72-
}
73-
}
74-
7539
async close(): Promise<void> {
7640
if (this.serviceProvider) {
7741
try {

src/tools/atlas/atlasTool.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
import { ToolBase, ToolCategory } from "../tool.js";
22
import { Session } from "../../session.js";
3+
import config from "../../config.js";
34

45
export abstract class AtlasToolBase extends ToolBase {
56
constructor(protected readonly session: Session) {
67
super(session);
78
}
89

910
protected category: ToolCategory = "atlas";
11+
12+
protected verifyAllowed(): boolean {
13+
if (!config.apiClientId || !config.apiClientSecret) {
14+
return false;
15+
}
16+
return super.verifyAllowed();
17+
}
1018
}

src/tools/atlas/createAccessList.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ export class CreateAccessListTool extends AtlasToolBase {
2727
comment,
2828
currentIpAddress,
2929
}: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
30-
this.session.ensureAuthenticated();
31-
3230
if (!ipAddresses?.length && !cidrBlocks?.length && !currentIpAddress) {
3331
throw new Error("One of ipAddresses, cidrBlocks, currentIpAddress must be provided.");
3432
}

src/tools/atlas/createDBUser.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ export class CreateDBUserTool extends AtlasToolBase {
3434
roles,
3535
clusters,
3636
}: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
37-
this.session.ensureAuthenticated();
38-
3937
const input = {
4038
groupId: projectId,
4139
awsIAMType: "NONE",

src/tools/atlas/createFreeCluster.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ export class CreateFreeClusterTool extends AtlasToolBase {
1515
};
1616

1717
protected async execute({ projectId, name, region }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
18-
this.session.ensureAuthenticated();
19-
2018
const input = {
2119
groupId: projectId,
2220
name,

src/tools/atlas/createProject.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export class CreateProjectTool extends AtlasToolBase {
1414
};
1515

1616
protected async execute({ projectName, organizationId }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
17-
this.session.ensureAuthenticated();
1817
let assumedOrg = false;
1918

2019
if (!projectName) {

src/tools/atlas/inspectAccessList.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ export class InspectAccessListTool extends AtlasToolBase {
1212
};
1313

1414
protected async execute({ projectId }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
15-
this.session.ensureAuthenticated();
16-
1715
const accessList = await this.session.apiClient.listProjectIpAccessLists({
1816
params: {
1917
path: {

src/tools/atlas/inspectCluster.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ export class InspectClusterTool extends AtlasToolBase {
1414
};
1515

1616
protected async execute({ projectId, clusterName }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
17-
this.session.ensureAuthenticated();
18-
1917
const cluster = await this.session.apiClient.getCluster({
2018
params: {
2119
path: {

0 commit comments

Comments
 (0)