Skip to main content
Glama
kapilduraphe

Okta MCP Server

assign_users_to_groups

Assign users to specific groups in the Okta MCP Server using attribute-based mapping, streamlining group management and organization.

Instructions

Assign multiple users to groups based on attributes

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
attributeMappingYesMapping of user attributes to group IDs (e.g., {"department": {"Engineering": "group1Id", "Sales": "group2Id"}})
userIdsYesList of user IDs to assign

Implementation Reference

  • The main handler function for the 'assign_users_to_groups' tool. It parses input, fetches user profiles from Okta, matches attributes to group mappings, assigns users to corresponding groups using Okta API, and returns a detailed summary of successes and failures.
      assign_users_to_groups: async (request: { parameters: unknown }) => {
        const { userIds, attributeMapping } = 
          onboardingSchemas.assignUsersToGroups.parse(request.parameters);
        
        try {
          const oktaClient = getOktaClient();
          
          const results = {
            success: [] as any[],
            failed: [] as any[]
          };
          
          // Process each user
          for (const userId of userIds) {
            try {
              // Get user details to access attributes
              const user = await oktaClient.userApi.getUser({ userId });
              
              if (!user || !user.profile) {
                results.failed.push({
                  userId: userId,
                  reason: 'User not found or profile unavailable'
                });
                continue;
              }
              
              // Determine which groups to assign based on user attributes
              const groupsToAssign = new Set<string>();
              
              // Process attribute mapping
              for (const [attribute, valueMapping] of Object.entries(attributeMapping)) {
                const userAttributeValue = user.profile[attribute as keyof typeof user.profile];
                if (userAttributeValue && valueMapping[userAttributeValue as string]) {
                  groupsToAssign.add(valueMapping[userAttributeValue as string]);
                }
              }
              
              // Skip if no groups matched
              if (groupsToAssign.size === 0) {
                results.success.push({
                  id: userId,
                  email: user.profile.email,
                  assignedGroups: [],
                  message: 'No group mappings matched user attributes'
                });
                continue;
              }
              
              // Assign user to each mapped group
              const assignedGroups = [];
              for (const groupId of groupsToAssign) {
                await oktaClient.groupApi.assignUserToGroup({
                  groupId,
                  userId
                });
                assignedGroups.push(groupId);
              }
              
              results.success.push({
                userId: userId,
                email: user.profile.email,
                assignedGroups
              });
            } catch (error) {
              results.failed.push({
                id: userId,
                reason: error instanceof Error ? error.message : String(error)
              });
            }
          }
          
          // Format response
          const summary = `Processed group assignments for ${userIds.length} users:
    - Successful assignments: ${results.success.length}
    - Failed assignments: ${results.failed.length}
    
    ${results.success.length > 0 ? `• Successfully assigned users:
    ${results.success.map((user, i) => {
      const groupsInfo = user.assignedGroups.length > 0 
        ? `assigned to ${user.assignedGroups.length} groups`
        : user.message || 'no matching groups';
      return `${i+1}. ${user.email || user.userId} (${groupsInfo})`;
    }).join('\n')}` : ''}
    
    ${results.failed.length > 0 ? `• Failed assignments:
    ${results.failed.map((user, i) => `${i+1}. User ID: ${user.userId} - ${user.reason}`).join('\n')}` : ''}`;
          
          return {
            content: [{ type: 'text', text: summary }],
            data: results
          };
        } catch (error) {
          console.error("Error during group assignment:", error);
          return {
            content: [
              {
                type: "text",
                text: `Failed to assign users to groups: ${error instanceof Error ? error.message : String(error)}`,
              },
            ],
            isError: true,
          };
        }
      },
  • Zod schema used for internal input validation within the handler of the 'assign_users_to_groups' tool.
    assignUsersToGroups: z.object({
      userIds: z.array(z.string().min(1, "User ID is required")),
      attributeMapping: z.record(z.record(z.string())).describe(
        "Mapping of user attributes to group IDs (e.g., {\"department\": {\"Engineering\": \"group1Id\"}})"
      ),
    }),
  • Tool registration object defining the name, description, and input schema for the 'assign_users_to_groups' tool, included in the onboardingTools export which is aggregated into the main TOOLS array.
      name: "assign_users_to_groups",
      description: "Assign multiple users to groups based on attributes",
      inputSchema: {
        type: "object",
        properties: {
          userIds: {
            type: "array",
            items: { type: "string" },
            description: "List of user IDs to assign"
          },
          attributeMapping: {
            type: "object",
            description: "Mapping of user attributes to group IDs (e.g., {\"department\": {\"Engineering\": \"group1Id\", \"Sales\": \"group2Id\"}})"
          }
        },
        required: ["userIds", "attributeMapping"]
      },
    },
  • src/tools/index.ts:6-6 (registration)
    Aggregation of all tools including onboardingTools (which contains 'assign_users_to_groups') into the main TOOLS export used by the MCP server.
    export const TOOLS = [...userTools, ...groupTools, ...onboardingTools];
  • src/tools/index.ts:9-9 (registration)
    Aggregation of all handlers including onboardingHandlers (which contains the handler for 'assign_users_to_groups') into the main HANDLERS export used by the MCP server.
    export const HANDLERS = {
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the action ('Assign') but doesn't cover critical traits like required permissions, whether assignments are additive or replace existing ones, error handling for invalid inputs, or side effects. This is a significant gap for a mutation tool with zero annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste—it directly states the tool's purpose without redundancy. It's appropriately sized and front-loaded, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (mutation with nested objects, no output schema, and no annotations), the description is inadequate. It lacks details on behavioral traits, output expectations, error cases, and how it differs from siblings. For a tool that modifies user-group relationships in bulk, more context is needed to ensure safe and correct usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters thoroughly. The description adds minimal value by hinting at the attribute-based logic ('based on attributes'), but doesn't provide additional syntax, format details, or examples beyond what the schema's descriptions offer. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Assign') and resources ('multiple users to groups'), specifying it's based on attributes. It distinguishes from 'assign_user_to_group' by indicating bulk assignment with attribute-based logic, though it doesn't explicitly name that sibling. The purpose is specific but could be more precise about the attribute-driven mechanism.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'assign_user_to_group' (for single assignments) or 'bulk_user_import' (for broader operations). It mentions 'based on attributes' but doesn't clarify prerequisites, exclusions, or ideal scenarios, leaving usage context implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kapilduraphe/okta-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server