invite-user
Create and invite new users to a Descope project by generating invitation links and managing user details like login IDs, roles, and contact information.
Instructions
Create and invite a new user to the Descope project
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| loginId | Yes | Primary login identifier for the user | |
| additionalLoginIds | No | Additional login identifiers | |
| No | User's email address | ||
| verifiedEmail | No | Whether the email is pre-verified | |
| phone | No | User's phone number in E.164 format | |
| verifiedPhone | No | Whether the phone is pre-verified | |
| displayName | No | User's display name | |
| givenName | No | User's given/first name | |
| middleName | No | User's middle name | |
| familyName | No | User's family/last name | |
| picture | No | URL to user's profile picture | |
| roles | No | Global role names to assign to the user | |
| userTenants | No | Tenant associations with specific roles | |
| ssoAppIds | No | SSO application IDs to associate | |
| customAttributes | No | Custom attributes for the user | |
| inviteUrl | No | Custom URL for the invitation link | |
| sendMail | No | Send invite via email (default follows project settings) | |
| sendSMS | No | Send invite via SMS (default follows project settings) | |
| templateId | No | Custom template ID for the invitation | |
| templateOptions | No | Options for customizing the invitation template |
Implementation Reference
- src/descope.ts:291-344 (handler)Handler function that processes input parameters, constructs invite options, calls descope.management.user.invite(), and returns success or error message.async ({ loginId, inviteUrl, sendMail, sendSMS, templateId, templateOptions, ...userOptions }) => { try { // Define the type for invite options const inviteOptions: { inviteUrl?: string; sendMail?: boolean; sendSMS?: boolean; templateId?: string; templateOptions?: { appUrl?: string; redirectUrl?: string; customClaims?: string; }; } & typeof userOptions = { ...userOptions, inviteUrl, sendMail, sendSMS, templateId, }; // Only add templateOptions if they exist and ensure customClaims is handled properly if (templateOptions) { inviteOptions.templateOptions = { appUrl: templateOptions.appUrl, redirectUrl: templateOptions.redirectUrl, }; // Only add customClaims if it's provided if (templateOptions.customClaims) { inviteOptions.templateOptions.customClaims = templateOptions.customClaims; } } const user = await descope.management.user.invite(loginId, inviteOptions); return { content: [ { type: "text", text: `Successfully invited user:\n\n${JSON.stringify(user.data, null, 2)}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error inviting user: ${error}`, }, ], }; } },
- src/descope.ts:237-290 (schema)Zod schema defining all input parameters for the invite-user tool, including user details and invite-specific options.{ // Basic user info loginId: z.string() .describe("Primary login identifier for the user"), additionalLoginIds: z.array(z.string()).optional() .describe("Additional login identifiers"), email: z.string().email().optional() .describe("User's email address"), verifiedEmail: z.boolean().optional() .describe("Whether the email is pre-verified"), phone: z.string().optional() .describe("User's phone number in E.164 format"), verifiedPhone: z.boolean().optional() .describe("Whether the phone is pre-verified"), displayName: z.string().optional() .describe("User's display name"), givenName: z.string().optional() .describe("User's given/first name"), middleName: z.string().optional() .describe("User's middle name"), familyName: z.string().optional() .describe("User's family/last name"), picture: z.string().url().optional() .describe("URL to user's profile picture"), roles: z.array(z.string()).optional() .describe("Global role names to assign to the user"), userTenants: z.array(z.object({ tenantId: z.string(), roleNames: z.array(z.string()), })).optional() .describe("Tenant associations with specific roles"), ssoAppIds: z.array(z.string()).optional() .describe("SSO application IDs to associate"), customAttributes: z.record(z.any()).optional() .describe("Custom attributes for the user"), // Invite specific options inviteUrl: z.string().url().optional() .describe("Custom URL for the invitation link"), sendMail: z.boolean().optional() .describe("Send invite via email (default follows project settings)"), sendSMS: z.boolean().optional() .describe("Send invite via SMS (default follows project settings)"), templateId: z.string().optional() .describe("Custom template ID for the invitation"), templateOptions: z.object({ appUrl: z.string().url().optional() .describe("Application URL to use in the template"), redirectUrl: z.string().url().optional() .describe("URL to redirect after authentication"), customClaims: z.string().optional() .describe("Custom claims to include in the template (as JSON string)"), }).optional() .describe("Options for customizing the invitation template"), },
- src/descope.ts:233-345 (registration)Registration of the invite-user tool on the MCP server with name, description, input schema, and handler function.// Add invite-user tool server.tool( "invite-user", "Create and invite a new user to the Descope project", { // Basic user info loginId: z.string() .describe("Primary login identifier for the user"), additionalLoginIds: z.array(z.string()).optional() .describe("Additional login identifiers"), email: z.string().email().optional() .describe("User's email address"), verifiedEmail: z.boolean().optional() .describe("Whether the email is pre-verified"), phone: z.string().optional() .describe("User's phone number in E.164 format"), verifiedPhone: z.boolean().optional() .describe("Whether the phone is pre-verified"), displayName: z.string().optional() .describe("User's display name"), givenName: z.string().optional() .describe("User's given/first name"), middleName: z.string().optional() .describe("User's middle name"), familyName: z.string().optional() .describe("User's family/last name"), picture: z.string().url().optional() .describe("URL to user's profile picture"), roles: z.array(z.string()).optional() .describe("Global role names to assign to the user"), userTenants: z.array(z.object({ tenantId: z.string(), roleNames: z.array(z.string()), })).optional() .describe("Tenant associations with specific roles"), ssoAppIds: z.array(z.string()).optional() .describe("SSO application IDs to associate"), customAttributes: z.record(z.any()).optional() .describe("Custom attributes for the user"), // Invite specific options inviteUrl: z.string().url().optional() .describe("Custom URL for the invitation link"), sendMail: z.boolean().optional() .describe("Send invite via email (default follows project settings)"), sendSMS: z.boolean().optional() .describe("Send invite via SMS (default follows project settings)"), templateId: z.string().optional() .describe("Custom template ID for the invitation"), templateOptions: z.object({ appUrl: z.string().url().optional() .describe("Application URL to use in the template"), redirectUrl: z.string().url().optional() .describe("URL to redirect after authentication"), customClaims: z.string().optional() .describe("Custom claims to include in the template (as JSON string)"), }).optional() .describe("Options for customizing the invitation template"), }, async ({ loginId, inviteUrl, sendMail, sendSMS, templateId, templateOptions, ...userOptions }) => { try { // Define the type for invite options const inviteOptions: { inviteUrl?: string; sendMail?: boolean; sendSMS?: boolean; templateId?: string; templateOptions?: { appUrl?: string; redirectUrl?: string; customClaims?: string; }; } & typeof userOptions = { ...userOptions, inviteUrl, sendMail, sendSMS, templateId, }; // Only add templateOptions if they exist and ensure customClaims is handled properly if (templateOptions) { inviteOptions.templateOptions = { appUrl: templateOptions.appUrl, redirectUrl: templateOptions.redirectUrl, }; // Only add customClaims if it's provided if (templateOptions.customClaims) { inviteOptions.templateOptions.customClaims = templateOptions.customClaims; } } const user = await descope.management.user.invite(loginId, inviteOptions); return { content: [ { type: "text", text: `Successfully invited user:\n\n${JSON.stringify(user.data, null, 2)}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error inviting user: ${error}`, }, ], }; } }, );