create_atlas_user
Create a new database user with admin privileges for an existing MongoDB Atlas project to manage database access and permissions.
Instructions
Creates a new database user for an existing Atlas project. User will have atlasAdmin role.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | The ID of the Atlas project. | |
| username | Yes | The username for the database user. | |
| password | Yes | The password for the database user. | |
| roles | No | An array of roles for the user. Default is [atlasAdmin]. |
Implementation Reference
- src/index.ts:187-213 (handler)The core handler function that implements the 'create_atlas_user' tool logic. It constructs a POST request to the MongoDB Atlas API to create a database user in the admin database with specified roles.private async createAtlasUser(input: CreateUserInput) { try { const url = `https://cloud.mongodb.com/api/atlas/v1.0/groups/${input.projectId}/databaseUsers`; const body = { databaseName: "admin", username: input.username, password: input.password, roles: input.roles.map(role => ({ databaseName: 'admin', roleName: role })) }; 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:25-30 (schema)TypeScript interface defining the expected input structure for the createAtlasUser handler.interface CreateUserInput { projectId: string; username: string; password: string; roles: string[]; }
- src/index.ts:431-459 (registration)MCP tool registration in the ListToolsRequestSchema handler, defining the tool name, description, and JSON inputSchema.{ name: 'create_atlas_user', description: 'Creates a new database user for an existing Atlas project. User will have atlasAdmin role.', inputSchema: { type: 'object', properties: { projectId: { type: 'string', description: 'The ID of the Atlas project.', }, username: { type: 'string', description: 'The username for the database user.', }, password: { type: 'string', description: 'The password for the database user.', }, roles: { type: 'array', items: { type: 'string', }, description: 'An array of roles for the user. Default is [atlasAdmin].', } }, required: ['projectId', 'username', 'password'], }, },
- src/index.ts:555-556 (registration)Dispatcher logic in CallToolRequestSchema that routes the tool call to the createAtlasUser handler.case 'create_atlas_user': result = await this.createAtlasUser(input as unknown as CreateUserInput);
- src/index.ts:55-113 (helper)Shared helper method for making authenticated requests to the Atlas API using Digest authentication, used by the createAtlasUser 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}`); } }