create_atlas_cluster
Automate the creation of a MongoDB Atlas cluster within an existing project by specifying project ID, cluster name, region, cloud provider, and instance size.
Instructions
Creates a new Atlas cluster in an existing Atlas project.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cloudProvider | Yes | The cloud provider (e.g., AWS, GCP, AZURE). | |
| clusterName | Yes | The name of the cluster to create. | |
| projectId | Yes | The ID of the Atlas project. | |
| region | Yes | The cloud provider region to deploy the cluster in. eg. US_EAST_1 | |
| tier | Yes | The instance size (e.g., M0, M2, M5). |
Implementation Reference
- src/index.ts:121-159 (handler)The core handler function that implements the logic to create a MongoDB Atlas cluster using the Atlas API, handling free tier restrictions and error cases.private async createAtlasCluster(input: CreateClusterInput) { if (input.tier === 'M0') { return { content: [{ type: 'text', text: 'M0 (Free Tier) clusters cannot be created via the API. Please use the MongoDB Atlas UI to create an M0 cluster.' }], isError: true }; } try { const url = `https://cloud.mongodb.com/api/atlas/v1.0/groups/${input.projectId}/clusters?pretty=true`; const body = { name: input.clusterName, providerSettings: { providerName: input.cloudProvider, instanceSizeName: input.tier, regionName: input.region } }; const result = await this.makeAtlasRequest(url, 'POST', body); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text', text: error.message }], isError: true }; } }
- src/index.ts:12-18 (schema)TypeScript interface defining the expected input structure for the createAtlasCluster handler.interface CreateClusterInput { projectId: string; clusterName: string; region: string; cloudProvider: string; tier: string; }
- src/index.ts:380-409 (registration)Tool registration in the ListTools response, including name, description, and input schema.{ name: 'create_atlas_cluster', description: 'Creates a new Atlas cluster in an existing Atlas project.', inputSchema: { type: 'object', properties: { projectId: { type: 'string', description: 'The ID of the Atlas project.', }, clusterName: { type: 'string', description: 'The name of the cluster to create.', }, region: { type: 'string', description: 'The cloud provider region to deploy the cluster in. eg. US_EAST_1', }, cloudProvider: { type: 'string', description: 'The cloud provider (e.g., AWS, GCP, AZURE).', }, tier: { type: 'string', description: 'The instance size (e.g., M0, M2, M5).', } }, required: ['projectId', 'clusterName', 'region', 'cloudProvider', 'tier'], }, },
- src/index.ts:41-48 (helper)Input validation function specifically for create_atlas_cluster arguments, used in the tool dispatcher.const isValidCreateClusterInput = (args: any): args is CreateClusterInput => typeof args === 'object' && args !== null && typeof args.projectId === 'string' && typeof args.clusterName === 'string' && typeof args.region === 'string' && typeof args.cloudProvider === 'string' && typeof args.tier === 'string';
- src/index.ts:55-113 (helper)Supporting utility for making authenticated requests to the Atlas API using Digest authentication, used by the createAtlasCluster handler.private async makeAtlasRequest(url: string, method: string, body?: any) { // Step 1: Make initial request to get digest challenge const initialResponse = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: body ? JSON.stringify(body) : undefined }); // Check if we got a 401 with WWW-Authenticate header (digest challenge) if (initialResponse.status === 401) { const wwwAuthHeader = initialResponse.headers.get('WWW-Authenticate'); if (!wwwAuthHeader || !wwwAuthHeader.startsWith('Digest ')) { throw new Error('Expected Digest authentication challenge not received'); } // Parse the digest challenge const authDetails: Record<string, string> = {}; wwwAuthHeader.substring(7).split(',').forEach(part => { const [key, value] = part.trim().split('='); // Remove quotes if present authDetails[key] = value.startsWith('"') ? value.slice(1, -1) : value; }); // Generate a random client nonce (cnonce) const cnonce = Math.random().toString(36).substring(2, 15); const nc = '00000001'; // nonce count, incremented for each request with the same nonce // Calculate the response hash const ha1 = this.md5(`${this.apiKey}:${authDetails.realm}:${this.privateKey}`); const ha2 = this.md5(`${method}:${new URL(url).pathname}`); const response = this.md5(`${ha1}:${authDetails.nonce}:${nc}:${cnonce}:${authDetails.qop}:${ha2}`); // Build the Authorization header const authHeader = `Digest username="${this.apiKey}", realm="${authDetails.realm}", nonce="${authDetails.nonce}", uri="${new URL(url).pathname}", qop=${authDetails.qop}, nc=${nc}, cnonce="${cnonce}", response="${response}", algorithm=${authDetails.algorithm || 'MD5'}`; // Make the actual request with the digest authentication const digestResponse = await fetch(url, { method, headers: { 'Content-Type': 'application/json', 'Authorization': authHeader }, body: body ? JSON.stringify(body) : undefined }); if (!digestResponse.ok) { throw new Error(`Atlas API error: ${digestResponse.statusText}`); } return digestResponse.json(); } else if (initialResponse.ok) { // If the initial request succeeded without authentication (unlikely) return initialResponse.json(); } else { throw new Error(`Atlas API error: ${initialResponse.statusText}`); } }