Skip to main content
Glama
mwhesse

Dataverse MCP Server

by mwhesse

Create Dataverse Team

create_dataverse_team

Create new teams in Dataverse to organize users and manage permissions. Establish owner teams for record ownership or access teams for sharing records, grouping users with similar access requirements.

Instructions

Creates a new team in Dataverse for organizing users and managing permissions. Teams can be owner teams (for record ownership) or access teams (for sharing records). Use this to establish groups of users who work together and need similar access levels.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
administratorIdYesUser ID of the team administrator
azureActiveDirectoryObjectIdNoAzure AD Object ID for the team
businessUnitIdNoBusiness unit ID to associate the team with (defaults to root business unit)
delegatedAuthorizationIdNoDelegated authorization context for the team
descriptionNoDescription of the team
emailAddressNoEmail address for the team
membershipTypeNoMembership type: 0=Members and guests, 1=Members, 2=Owners, 3=Guests0
nameYesName of the team
queueIdNoDefault queue ID for the team
teamTemplateIdNoTeam template ID to associate with the team
teamTypeNoTeam type: 0=Owner, 1=Access, 2=Security Group, 3=Office Group0
transactionCurrencyIdNoCurrency ID associated with the team
yomiNameNoPronunciation of the team name in phonetic characters

Implementation Reference

  • The core handler function that executes the tool logic: constructs team creation payload with OData bindings for relationships, fetches root business unit if needed, posts to /teams endpoint, and returns success/error response.
    async (params) => {
      try {
        const teamData: any = {
          name: params.name,
          description: params.description,
          teamtype: parseInt(params.teamType),
          membershiptype: parseInt(params.membershipType),
          emailaddress: params.emailAddress,
          yominame: params.yomiName,
          azureactivedirectoryobjectid: params.azureActiveDirectoryObjectId
        };
    
        // Set administrator
        teamData['administratorid@odata.bind'] = `/systemusers(${params.administratorId})`;
    
        // Set business unit (default to root if not provided)
        if (params.businessUnitId) {
          teamData['businessunitid@odata.bind'] = `/businessunits(${params.businessUnitId})`;
        } else {
          // Get the root business unit
          const businessUnits = await client.get('businessunits?$filter=parentbusinessunitid eq null&$select=businessunitid');
          
          if (businessUnits.value && businessUnits.value.length > 0) {
            teamData['businessunitid@odata.bind'] = `/businessunits(${businessUnits.value[0].businessunitid})`;
          }
        }
    
        // Set optional relationships
        if (params.queueId) {
          teamData['queueid@odata.bind'] = `/queues(${params.queueId})`;
        }
        if (params.teamTemplateId) {
          teamData['teamtemplateid@odata.bind'] = `/teamtemplates(${params.teamTemplateId})`;
        }
        if (params.delegatedAuthorizationId) {
          teamData['delegatedauthorizationid@odata.bind'] = `/delegatedauthorizations(${params.delegatedAuthorizationId})`;
        }
        if (params.transactionCurrencyId) {
          teamData['transactioncurrencyid@odata.bind'] = `/transactioncurrencies(${params.transactionCurrencyId})`;
        }
    
        const response = await client.post('teams', teamData);
        
        return {
          content: [
            {
              type: "text",
              text: `Successfully created team '${params.name}'.\n\nTeam created successfully.\n\nResponse: ${JSON.stringify(response, null, 2)}`
            }
          ]
        };
      } catch (error) {
        return {
          content: [
            {
              type: "text",
              text: `Error creating team: ${error instanceof Error ? error.message : 'Unknown error'}`
            }
          ],
          isError: true
        };
      }
    }
  • Tool metadata (title, description) and Zod-based inputSchema defining all parameters for creating a Dataverse team, including required name/administratorId and optional fields with constraints.
    {
      title: "Create Dataverse Team",
      description: "Creates a new team in Dataverse for organizing users and managing permissions. Teams can be owner teams (for record ownership) or access teams (for sharing records). Use this to establish groups of users who work together and need similar access levels.",
      inputSchema: {
        name: z.string().max(160).describe("Name of the team"),
        description: z.string().max(2000).optional().describe("Description of the team"),
        businessUnitId: z.string().optional().describe("Business unit ID to associate the team with (defaults to root business unit)"),
        administratorId: z.string().describe("User ID of the team administrator"),
        teamType: z.enum(['0', '1', '2', '3']).default('0').describe("Team type: 0=Owner, 1=Access, 2=Security Group, 3=Office Group"),
        membershipType: z.enum(['0', '1', '2', '3']).default('0').describe("Membership type: 0=Members and guests, 1=Members, 2=Owners, 3=Guests"),
        emailAddress: z.string().max(100).optional().describe("Email address for the team"),
        yomiName: z.string().max(160).optional().describe("Pronunciation of the team name in phonetic characters"),
        azureActiveDirectoryObjectId: z.string().optional().describe("Azure AD Object ID for the team"),
        queueId: z.string().optional().describe("Default queue ID for the team"),
        teamTemplateId: z.string().optional().describe("Team template ID to associate with the team"),
        delegatedAuthorizationId: z.string().optional().describe("Delegated authorization context for the team"),
        transactionCurrencyId: z.string().optional().describe("Currency ID associated with the team")
      }
    },
  • The exported createTeamTool function that performs the server.registerTool call to register the 'create_dataverse_team' tool with its schema and handler.
    export function createTeamTool(server: McpServer, client: DataverseClient) {
      server.registerTool(
        "create_dataverse_team",
        {
          title: "Create Dataverse Team",
          description: "Creates a new team in Dataverse for organizing users and managing permissions. Teams can be owner teams (for record ownership) or access teams (for sharing records). Use this to establish groups of users who work together and need similar access levels.",
          inputSchema: {
            name: z.string().max(160).describe("Name of the team"),
            description: z.string().max(2000).optional().describe("Description of the team"),
            businessUnitId: z.string().optional().describe("Business unit ID to associate the team with (defaults to root business unit)"),
            administratorId: z.string().describe("User ID of the team administrator"),
            teamType: z.enum(['0', '1', '2', '3']).default('0').describe("Team type: 0=Owner, 1=Access, 2=Security Group, 3=Office Group"),
            membershipType: z.enum(['0', '1', '2', '3']).default('0').describe("Membership type: 0=Members and guests, 1=Members, 2=Owners, 3=Guests"),
            emailAddress: z.string().max(100).optional().describe("Email address for the team"),
            yomiName: z.string().max(160).optional().describe("Pronunciation of the team name in phonetic characters"),
            azureActiveDirectoryObjectId: z.string().optional().describe("Azure AD Object ID for the team"),
            queueId: z.string().optional().describe("Default queue ID for the team"),
            teamTemplateId: z.string().optional().describe("Team template ID to associate with the team"),
            delegatedAuthorizationId: z.string().optional().describe("Delegated authorization context for the team"),
            transactionCurrencyId: z.string().optional().describe("Currency ID associated with the team")
          }
        },
        async (params) => {
          try {
            const teamData: any = {
              name: params.name,
              description: params.description,
              teamtype: parseInt(params.teamType),
              membershiptype: parseInt(params.membershipType),
              emailaddress: params.emailAddress,
              yominame: params.yomiName,
              azureactivedirectoryobjectid: params.azureActiveDirectoryObjectId
            };
    
            // Set administrator
            teamData['administratorid@odata.bind'] = `/systemusers(${params.administratorId})`;
    
            // Set business unit (default to root if not provided)
            if (params.businessUnitId) {
              teamData['businessunitid@odata.bind'] = `/businessunits(${params.businessUnitId})`;
            } else {
              // Get the root business unit
              const businessUnits = await client.get('businessunits?$filter=parentbusinessunitid eq null&$select=businessunitid');
              
              if (businessUnits.value && businessUnits.value.length > 0) {
                teamData['businessunitid@odata.bind'] = `/businessunits(${businessUnits.value[0].businessunitid})`;
              }
            }
    
            // Set optional relationships
            if (params.queueId) {
              teamData['queueid@odata.bind'] = `/queues(${params.queueId})`;
            }
            if (params.teamTemplateId) {
              teamData['teamtemplateid@odata.bind'] = `/teamtemplates(${params.teamTemplateId})`;
            }
            if (params.delegatedAuthorizationId) {
              teamData['delegatedauthorizationid@odata.bind'] = `/delegatedauthorizations(${params.delegatedAuthorizationId})`;
            }
            if (params.transactionCurrencyId) {
              teamData['transactioncurrencyid@odata.bind'] = `/transactioncurrencies(${params.transactionCurrencyId})`;
            }
    
            const response = await client.post('teams', teamData);
            
            return {
              content: [
                {
                  type: "text",
                  text: `Successfully created team '${params.name}'.\n\nTeam created successfully.\n\nResponse: ${JSON.stringify(response, null, 2)}`
                }
              ]
            };
          } catch (error) {
            return {
              content: [
                {
                  type: "text",
                  text: `Error creating team: ${error instanceof Error ? error.message : 'Unknown error'}`
                }
              ],
              isError: true
            };
          }
        }
      );
    }
  • src/index.ts:199-199 (registration)
    Invocation of createTeamTool in the main index.ts to register the tool during server initialization.
    createTeamTool(server, dataverseClient);
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. While it mentions the tool creates teams and describes team types, it doesn't address critical behavioral aspects like required permissions, whether the operation is idempotent, what happens on failure, or what the response contains. For a creation tool with 13 parameters, this leaves significant gaps.

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 efficiently structured in two sentences: the first states the core purpose and team types, the second provides usage context. Every word earns its place with no redundancy or fluff. It's appropriately sized for the tool's complexity.

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

Completeness3/5

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

Given the tool's complexity (13 parameters, creation operation) and absence of both annotations and output schema, the description is adequate but incomplete. It covers the 'what' and 'why' well but lacks information about behavioral characteristics, error handling, and response format. For a creation tool with many parameters, more context would be beneficial.

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 all 13 parameters thoroughly. The description adds minimal parameter semantics beyond the schema - it mentions team types (owner vs. access) which relates to the 'teamType' parameter, but doesn't provide additional context about parameter interactions or usage patterns. This meets the baseline for high schema coverage.

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

Purpose5/5

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

The description clearly states the verb 'creates' and resource 'new team in Dataverse', specifies the purpose ('organizing users and managing permissions'), and distinguishes between team types (owner vs. access teams). It differentiates from siblings like 'update_dataverse_team' or 'delete_dataverse_team' by focusing on creation.

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool ('to establish groups of users who work together and need similar access levels'), but doesn't explicitly mention when NOT to use it or name specific alternatives among the many sibling tools. The guidance is helpful but not exhaustive.

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

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/mwhesse/mcp-dataverse'

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