Skip to content

Commit 15a85b7

Browse files
committed
Merge branch 'main' into chore_add_atlas_tests
2 parents 1c567e5 + 58dc5bd commit 15a85b7

File tree

5 files changed

+169
-0
lines changed

5 files changed

+169
-0
lines changed

scripts/filter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ async function readStdin() {
1919
function filterOpenapi(openapi: OpenAPIV3_1.Document): OpenAPIV3_1.Document {
2020
const allowedOperations = [
2121
"listProjects",
22+
"listOrganizations",
2223
"getProject",
2324
"createProject",
2425
"listClusters",

src/common/atlas/apiClient.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,5 +184,10 @@ export class ApiClient {
184184
await this.client.DELETE("/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}", options);
185185
}
186186

187+
async listOrganizations(options?: FetchOptions<operations["listOrganizations"]>) {
188+
const { data } = await this.client.GET("/api/atlas/v2/orgs", options);
189+
return data;
190+
}
191+
187192
// DO NOT EDIT. This is auto-generated code.
188193
}

src/common/atlas/openapi.d.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,26 @@ export interface paths {
212212
patch?: never;
213213
trace?: never;
214214
};
215+
"/api/atlas/v2/orgs": {
216+
parameters: {
217+
query?: never;
218+
header?: never;
219+
path?: never;
220+
cookie?: never;
221+
};
222+
/**
223+
* Return All Organizations
224+
* @description Returns all organizations to which the requesting Service Account or API Key has access. To use this resource, the requesting Service Account or API Key must have the Organization Member role.
225+
*/
226+
get: operations["listOrganizations"];
227+
put?: never;
228+
post?: never;
229+
delete?: never;
230+
options?: never;
231+
head?: never;
232+
patch?: never;
233+
trace?: never;
234+
};
215235
}
216236
export type webhooks = Record<string, never>;
217237
export interface components {
@@ -598,6 +618,25 @@ export interface components {
598618
/** @description Application error message returned with this error. */
599619
readonly reason?: string;
600620
};
621+
/** @description Details that describe the organization. */
622+
AtlasOrganization: {
623+
/**
624+
* @description Unique 24-hexadecimal digit string that identifies the organization.
625+
* @example 32b6e34b3d91647abb20e7b8
626+
*/
627+
readonly id?: string;
628+
/** @description Flag that indicates whether this organization has been deleted. */
629+
readonly isDeleted?: boolean;
630+
/** @description List of one or more Uniform Resource Locators (URLs) that point to API sub-resources, related API resources, or both. RFC 5988 outlines these relationships. */
631+
readonly links?: components["schemas"]["Link"][];
632+
/** @description Human-readable label that identifies the organization. */
633+
name: string;
634+
/**
635+
* @description Disables automatic alert creation. When set to true, no organization level alerts will be created automatically.
636+
* @default false
637+
*/
638+
skipDefaultAlertsSettings: boolean;
639+
};
601640
/** Atlas Search Analyzer */
602641
AtlasSearchAnalyzer: {
603642
/** @description Filters that examine text one character at a time and perform filtering operations. */
@@ -3331,6 +3370,17 @@ export interface components {
33313370
*/
33323371
readonly totalCount?: number;
33333372
};
3373+
PaginatedOrganizationView: {
3374+
/** @description List of one or more Uniform Resource Locators (URLs) that point to API sub-resources, related API resources, or both. RFC 5988 outlines these relationships. */
3375+
readonly links?: components["schemas"]["Link"][];
3376+
/** @description List of returned documents that MongoDB Cloud provides when completing this request. */
3377+
readonly results?: components["schemas"]["AtlasOrganization"][];
3378+
/**
3379+
* Format: int32
3380+
* @description Total number of documents available. MongoDB Cloud omits this value if `includeCount` is set to `false`. The total number is an estimate and may not be exact.
3381+
*/
3382+
readonly totalCount?: number;
3383+
};
33343384
/**
33353385
* Periodic Cloud Provider Snapshot Source
33363386
* @description Scheduled Cloud Provider Snapshot as Source for a Data Lake Pipeline.
@@ -4876,6 +4926,7 @@ export type ApiAtlasClusterAdvancedConfigurationView = components['schemas']['Ap
48764926
export type ApiAtlasFtsAnalyzersViewManual = components['schemas']['ApiAtlasFTSAnalyzersViewManual'];
48774927
export type ApiAtlasFtsMappingsViewManual = components['schemas']['ApiAtlasFTSMappingsViewManual'];
48784928
export type ApiError = components['schemas']['ApiError'];
4929+
export type AtlasOrganization = components['schemas']['AtlasOrganization'];
48794930
export type AtlasSearchAnalyzer = components['schemas']['AtlasSearchAnalyzer'];
48804931
export type AzureCloudProviderContainer = components['schemas']['AzureCloudProviderContainer'];
48814932
export type AzureCloudProviderSettings = components['schemas']['AzureCloudProviderSettings'];
@@ -5003,6 +5054,7 @@ export type PaginatedAtlasGroupView = components['schemas']['PaginatedAtlasGroup
50035054
export type PaginatedClusterDescription20240805 = components['schemas']['PaginatedClusterDescription20240805'];
50045055
export type PaginatedNetworkAccessView = components['schemas']['PaginatedNetworkAccessView'];
50055056
export type PaginatedOrgGroupView = components['schemas']['PaginatedOrgGroupView'];
5057+
export type PaginatedOrganizationView = components['schemas']['PaginatedOrganizationView'];
50065058
export type PeriodicCpsSnapshotSource = components['schemas']['PeriodicCpsSnapshotSource'];
50075059
export type ReplicationSpec20240805 = components['schemas']['ReplicationSpec20240805'];
50085060
export type ResourceTag = components['schemas']['ResourceTag'];
@@ -5645,6 +5697,44 @@ export interface operations {
56455697
500: components["responses"]["internalServerError"];
56465698
};
56475699
};
5700+
listOrganizations: {
5701+
parameters: {
5702+
query?: {
5703+
/** @description Flag that indicates whether Application wraps the response in an `envelope` JSON object. Some API clients cannot access the HTTP response headers or status code. To remediate this, set envelope=true in the query. Endpoints that return a list of results use the results object as an envelope. Application adds the status parameter to the response body. */
5704+
envelope?: components["parameters"]["envelope"];
5705+
/** @description Flag that indicates whether the response returns the total number of items (**totalCount**) in the response. */
5706+
includeCount?: components["parameters"]["includeCount"];
5707+
/** @description Number of items that the response returns per page. */
5708+
itemsPerPage?: components["parameters"]["itemsPerPage"];
5709+
/** @description Number of the page that displays the current set of the total objects that the response returns. */
5710+
pageNum?: components["parameters"]["pageNum"];
5711+
/** @description Flag that indicates whether the response body should be in the prettyprint format. */
5712+
pretty?: components["parameters"]["pretty"];
5713+
/** @description Human-readable label of the organization to use to filter the returned list. Performs a case-insensitive search for an organization that starts with the specified name. */
5714+
name?: string;
5715+
};
5716+
header?: never;
5717+
path?: never;
5718+
cookie?: never;
5719+
};
5720+
requestBody?: never;
5721+
responses: {
5722+
/** @description OK */
5723+
200: {
5724+
headers: {
5725+
[name: string]: unknown;
5726+
};
5727+
content: {
5728+
"application/vnd.atlas.2023-01-01+json": components["schemas"]["PaginatedOrganizationView"];
5729+
};
5730+
};
5731+
400: components["responses"]["badRequest"];
5732+
401: components["responses"]["unauthorized"];
5733+
404: components["responses"]["notFound"];
5734+
409: components["responses"]["conflict"];
5735+
500: components["responses"]["internalServerError"];
5736+
};
5737+
};
56485738
}
56495739
type WithRequired<T, K extends keyof T> = T & {
56505740
[P in K]-?: T[P];

src/tools/atlas/createProject.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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 { Group } from "../../common/atlas/openapi.js";
6+
7+
export class CreateProjectTool extends AtlasToolBase {
8+
protected name = "atlas-create-project";
9+
protected description = "Create a MongoDB Atlas project";
10+
protected operationType: OperationType = "create";
11+
protected argsShape = {
12+
projectName: z.string().optional().describe("Name for the new project"),
13+
organizationId: z.string().optional().describe("Organization ID for the new project"),
14+
};
15+
16+
protected async execute({ projectName, organizationId }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
17+
this.session.ensureAuthenticated();
18+
let assumedOrg = false;
19+
20+
if (!projectName) {
21+
projectName = "Atlas Project";
22+
}
23+
24+
if (!organizationId) {
25+
try {
26+
const organizations = await this.session.apiClient.listOrganizations();
27+
if (!organizations?.results?.length) {
28+
return {
29+
content: [
30+
{
31+
type: "text",
32+
text: "No organizations were found in your MongoDB Atlas account. Please create an organization first.",
33+
},
34+
],
35+
isError: true,
36+
};
37+
}
38+
organizationId = organizations.results[0].id;
39+
assumedOrg = true;
40+
} catch {
41+
return {
42+
content: [
43+
{
44+
type: "text",
45+
text: "Could not search for organizations in your MongoDB Atlas account, please provide an organization ID or create one first.",
46+
},
47+
],
48+
isError: true,
49+
};
50+
}
51+
}
52+
53+
const input = {
54+
name: projectName,
55+
orgId: organizationId,
56+
} as Group;
57+
58+
await this.session.apiClient.createProject({
59+
body: input,
60+
});
61+
62+
return {
63+
content: [
64+
{
65+
type: "text",
66+
text: `Project "${projectName}" created successfully${assumedOrg ? ` (using organizationId ${organizationId}).` : ""}.`,
67+
},
68+
],
69+
};
70+
}
71+
}

src/tools/atlas/tools.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { CreateAccessListTool } from "./createAccessList.js";
66
import { InspectAccessListTool } from "./inspectAccessList.js";
77
import { ListDBUsersTool } from "./listDBUsers.js";
88
import { CreateDBUserTool } from "./createDBUser.js";
9+
import { CreateProjectTool } from "./createProject.js";
910

1011
export const AtlasTools = [
1112
ListClustersTool,
@@ -16,4 +17,5 @@ export const AtlasTools = [
1617
InspectAccessListTool,
1718
ListDBUsersTool,
1819
CreateDBUserTool,
20+
CreateProjectTool,
1921
];

0 commit comments

Comments
 (0)