manage_m365_groups
Create, update, delete, and manage Microsoft 365 groups for team collaboration with shared resources like mailboxes, calendars, and files.
Instructions
Manage Microsoft 365 groups for team collaboration with shared resources like mailbox, calendar, and files.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform on M365 group | |
| groupId | No | M365 group ID for existing group operations | |
| displayName | No | Display name for the M365 group | |
| description | No | Description of the M365 group | |
| owners | No | List of owner email addresses | |
| members | No | List of member email addresses | |
| settings | No | M365 group settings |
Implementation Reference
- src/handlers.ts:1209-1307 (handler)The core handler function that implements the manage_m365_groups tool. Handles actions: get, create, update, delete, add_members, remove_members using Microsoft Graph API to manage M365 groups and membership.export async function handleM365Groups( graphClient: Client, args: M365GroupArgs ): Promise<{ content: { type: string; text: string }[] }> { let apiPath = ''; let result: any; switch (args.action) { case 'get': if (!args.groupId) { throw new McpError(ErrorCode.InvalidParams, 'groupId is required for get action'); } apiPath = `/groups/${args.groupId}`; result = await graphClient.api(apiPath).get(); break; case 'create': if (!args.displayName) { throw new McpError(ErrorCode.InvalidParams, 'displayName is required for create action'); } apiPath = '/groups'; const createPayload = { displayName: args.displayName, description: args.description || '', mailNickname: args.displayName.replace(/\s+/g, '').toLowerCase(), mailEnabled: true, securityEnabled: false, groupTypes: ['Unified'], // M365 groups are unified groups visibility: args.settings?.visibility || 'Private' }; result = await graphClient.api(apiPath).post(createPayload); // Add owners if provided if (args.owners?.length && result.id) { for (const owner of args.owners) { await graphClient .api(`/groups/${result.id}/owners/$ref`) .post({ '@odata.id': `https://graph.microsoft.com/v1.0/users/${owner}` }); } } break; case 'update': if (!args.groupId) { throw new McpError(ErrorCode.InvalidParams, 'groupId is required for update action'); } apiPath = `/groups/${args.groupId}`; const updatePayload: any = {}; if (args.displayName) updatePayload.displayName = args.displayName; if (args.description) updatePayload.description = args.description; if (args.settings?.visibility) updatePayload.visibility = args.settings.visibility; result = await graphClient.api(apiPath).patch(updatePayload); break; case 'delete': if (!args.groupId) { throw new McpError(ErrorCode.InvalidParams, 'groupId is required for delete action'); } apiPath = `/groups/${args.groupId}`; await graphClient.api(apiPath).delete(); result = { message: 'M365 group deleted successfully' }; break; case 'add_members': if (!args.groupId || !args.members?.length) { throw new McpError(ErrorCode.InvalidParams, 'groupId and members are required for add_members action'); } for (const member of args.members) { await graphClient .api(`/groups/${args.groupId}/members/$ref`) .post({ '@odata.id': `https://graph.microsoft.com/v1.0/users/${member}` }); } result = { message: `Added ${args.members.length} members to M365 group` }; break; case 'remove_members': if (!args.groupId || !args.members?.length) { throw new McpError(ErrorCode.InvalidParams, 'groupId and members are required for remove_members action'); } for (const member of args.members) { await graphClient .api(`/groups/${args.groupId}/members/${member}/$ref`) .delete(); } result = { message: `Removed ${args.members.length} members from M365 group` }; break; default: throw new McpError(ErrorCode.InvalidParams, `Invalid action: ${args.action}`); } return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; }
- src/server.ts:395-414 (registration)MCP tool registration for 'manage_m365_groups' in the main server class, linking to the handler function and input schema.this.server.tool( "manage_m365_groups", "Manage Microsoft 365 groups for team collaboration with shared resources like mailbox, calendar, and files.", m365GroupSchema.shape, {"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false}, wrapToolHandler(async (args: M365GroupArgs) => { // Validate credentials only when tool is executed (lazy loading) this.validateCredentials(); try { return await handleM365Groups(this.getGraphClient(), args); } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Error executing tool: ${error instanceof Error ? error.message : 'Unknown error'}` ); } }) ); // Exchange Settings - Lazy loading enabled for tool discovery
- src/tool-definitions.ts:66-79 (schema)Zod input schema validation for manage_m365_groups tool parameters.// Microsoft 365 Group Management export const m365GroupSchema = z.object({ action: z.enum(['get', 'create', 'update', 'delete', 'add_members', 'remove_members']).describe('Action to perform on M365 group'), groupId: z.string().optional().describe('M365 group ID for existing group operations'), displayName: z.string().optional().describe('Display name for the M365 group'), description: z.string().optional().describe('Description of the M365 group'), owners: z.array(z.string()).optional().describe('List of owner email addresses'), members: z.array(z.string()).optional().describe('List of member email addresses'), settings: z.object({ visibility: z.enum(['Private', 'Public']).optional().describe('Group visibility setting'), allowExternalSenders: z.boolean().optional().describe('Allow external senders'), autoSubscribeNewMembers: z.boolean().optional().describe('Auto-subscribe new members'), }).optional().describe('M365 group settings'), });
- src/types.ts:49-62 (schema)TypeScript interface defining the arguments structure for the M365 groups handler.// M365 Group Types export interface M365GroupArgs { action: 'get' | 'create' | 'update' | 'delete' | 'add_members' | 'remove_members'; groupId?: string; displayName?: string; description?: string; owners?: string[]; members?: string[]; settings?: { visibility?: 'Private' | 'Public'; allowExternalSenders?: boolean; autoSubscribeNewMembers?: boolean; }; }
- src/tool-metadata.ts:31-34 (helper)Tool metadata including description, title, and annotations used for MCP client discovery and UI hints.manage_m365_groups: { description: "Manage Microsoft 365 groups for team collaboration with shared resources like mailbox, calendar, and files.", title: "M365 Group Manager", annotations: { title: "M365 Group Manager", readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }