Skip to main content
Glama
purview-compliance-handler.ts14.7 kB
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js'; import { Client } from '@microsoft/microsoft-graph-client'; import { DLPPolicyArgs, RetentionPolicyArgs, SensitivityLabelArgs, InformationProtectionPolicyArgs } from '../types/policy-types.js'; // DLP Policy Management Handler export async function handleDLPPolicies( graphClient: Client, args: DLPPolicyArgs ): Promise<{ content: { type: string; text: string }[] }> { let apiPath = ''; let result: any; switch (args.action) { case 'list': // List all DLP policies apiPath = '/security/informationProtection/dataLossPreventionPolicies'; result = await graphClient.api(apiPath).get(); break; case 'get': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for get action'); } apiPath = `/security/informationProtection/dataLossPreventionPolicies/${args.policyId}`; result = await graphClient.api(apiPath).get(); break; case 'create': if (!args.displayName) { throw new McpError(ErrorCode.InvalidParams, 'displayName is required for create action'); } const dlpPolicyPayload = { displayName: args.displayName, description: args.description || '', mode: args.mode || 'Test', priority: args.priority || 0, locations: args.locations || {}, rules: args.rules || [] }; apiPath = '/security/informationProtection/dataLossPreventionPolicies'; result = await graphClient.api(apiPath).post(dlpPolicyPayload); break; case 'update': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for update action'); } const updatePayload: any = {}; if (args.displayName) updatePayload.displayName = args.displayName; if (args.description) updatePayload.description = args.description; if (args.mode) updatePayload.mode = args.mode; if (args.priority !== undefined) updatePayload.priority = args.priority; if (args.locations) updatePayload.locations = args.locations; if (args.rules) updatePayload.rules = args.rules; apiPath = `/security/informationProtection/dataLossPreventionPolicies/${args.policyId}`; result = await graphClient.api(apiPath).patch(updatePayload); break; case 'delete': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for delete action'); } apiPath = `/security/informationProtection/dataLossPreventionPolicies/${args.policyId}`; await graphClient.api(apiPath).delete(); result = { message: `DLP policy ${args.policyId} deleted successfully` }; break; case 'enable': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for enable action'); } apiPath = `/security/informationProtection/dataLossPreventionPolicies/${args.policyId}`; result = await graphClient.api(apiPath).patch({ mode: 'Enforce' }); break; case 'disable': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for disable action'); } apiPath = `/security/informationProtection/dataLossPreventionPolicies/${args.policyId}`; result = await graphClient.api(apiPath).patch({ mode: 'Test' }); break; default: throw new McpError(ErrorCode.InvalidParams, `Unknown action: ${args.action}`); } return { content: [{ type: 'text', text: `DLP Policy ${args.action} operation completed:\n\n${JSON.stringify(result, null, 2)}` }] }; } // Retention Policy Management Handler export async function handleRetentionPolicies( graphClient: Client, args: RetentionPolicyArgs ): Promise<{ content: { type: string; text: string }[] }> { let apiPath = ''; let result: any; switch (args.action) { case 'list': // List all retention policies apiPath = '/security/informationProtection/retentionPolicies'; result = await graphClient.api(apiPath).get(); break; case 'get': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for get action'); } apiPath = `/security/informationProtection/retentionPolicies/${args.policyId}`; result = await graphClient.api(apiPath).get(); break; case 'create': if (!args.displayName || !args.retentionSettings) { throw new McpError(ErrorCode.InvalidParams, 'displayName and retentionSettings are required for create action'); } const retentionPolicyPayload = { displayName: args.displayName, description: args.description || '', isEnabled: args.isEnabled !== undefined ? args.isEnabled : true, retentionSettings: args.retentionSettings, locations: args.locations || {} }; apiPath = '/security/informationProtection/retentionPolicies'; result = await graphClient.api(apiPath).post(retentionPolicyPayload); break; case 'update': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for update action'); } const updatePayload: any = {}; if (args.displayName) updatePayload.displayName = args.displayName; if (args.description) updatePayload.description = args.description; if (args.isEnabled !== undefined) updatePayload.isEnabled = args.isEnabled; if (args.retentionSettings) updatePayload.retentionSettings = args.retentionSettings; if (args.locations) updatePayload.locations = args.locations; apiPath = `/security/informationProtection/retentionPolicies/${args.policyId}`; result = await graphClient.api(apiPath).patch(updatePayload); break; case 'delete': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for delete action'); } apiPath = `/security/informationProtection/retentionPolicies/${args.policyId}`; await graphClient.api(apiPath).delete(); result = { message: `Retention policy ${args.policyId} deleted successfully` }; break; default: throw new McpError(ErrorCode.InvalidParams, `Unknown action: ${args.action}`); } return { content: [{ type: 'text', text: `Retention Policy ${args.action} operation completed:\n\n${JSON.stringify(result, null, 2)}` }] }; } // Sensitivity Label Management Handler export async function handleSensitivityLabels( graphClient: Client, args: SensitivityLabelArgs ): Promise<{ content: { type: string; text: string }[] }> { let apiPath = ''; let result: any; switch (args.action) { case 'list': // List all sensitivity labels apiPath = '/security/informationProtection/sensitivityLabels'; result = await graphClient.api(apiPath).get(); break; case 'get': if (!args.labelId) { throw new McpError(ErrorCode.InvalidParams, 'labelId is required for get action'); } apiPath = `/security/informationProtection/sensitivityLabels/${args.labelId}`; result = await graphClient.api(apiPath).get(); break; case 'create': if (!args.displayName) { throw new McpError(ErrorCode.InvalidParams, 'displayName is required for create action'); } const sensitivityLabelPayload: any = { displayName: args.displayName, description: args.description || '', tooltip: args.tooltip || args.description || '', priority: args.priority || 0, isEnabled: args.isEnabled !== undefined ? args.isEnabled : true, labelActions: [], applicableTo: 'EmailMessage,File' }; // Add settings if provided if (args.settings) { if (args.settings.contentMarking) { sensitivityLabelPayload.labelActions.push({ '@odata.type': 'microsoft.graph.contentMarkingLabelAction', ...args.settings.contentMarking }); } if (args.settings.encryption && args.settings.encryption.enabled) { sensitivityLabelPayload.labelActions.push({ '@odata.type': 'microsoft.graph.encryptionLabelAction', ...args.settings.encryption }); } if (args.settings.accessControl) { sensitivityLabelPayload.labelActions.push({ '@odata.type': 'microsoft.graph.accessControlLabelAction', ...args.settings.accessControl }); } if (args.settings.autoLabeling && args.settings.autoLabeling.enabled) { sensitivityLabelPayload.labelActions.push({ '@odata.type': 'microsoft.graph.autoLabelingLabelAction', ...args.settings.autoLabeling }); } } apiPath = '/security/informationProtection/sensitivityLabels'; result = await graphClient.api(apiPath).post(sensitivityLabelPayload); break; case 'update': if (!args.labelId) { throw new McpError(ErrorCode.InvalidParams, 'labelId is required for update action'); } const updatePayload: any = {}; if (args.displayName) updatePayload.displayName = args.displayName; if (args.description) updatePayload.description = args.description; if (args.tooltip) updatePayload.tooltip = args.tooltip; if (args.priority !== undefined) updatePayload.priority = args.priority; if (args.isEnabled !== undefined) updatePayload.isEnabled = args.isEnabled; // Handle settings updates if (args.settings) { updatePayload.labelActions = []; if (args.settings.contentMarking) { updatePayload.labelActions.push({ '@odata.type': 'microsoft.graph.contentMarkingLabelAction', ...args.settings.contentMarking }); } if (args.settings.encryption && args.settings.encryption.enabled) { updatePayload.labelActions.push({ '@odata.type': 'microsoft.graph.encryptionLabelAction', ...args.settings.encryption }); } if (args.settings.accessControl) { updatePayload.labelActions.push({ '@odata.type': 'microsoft.graph.accessControlLabelAction', ...args.settings.accessControl }); } if (args.settings.autoLabeling && args.settings.autoLabeling.enabled) { updatePayload.labelActions.push({ '@odata.type': 'microsoft.graph.autoLabelingLabelAction', ...args.settings.autoLabeling }); } } apiPath = `/security/informationProtection/sensitivityLabels/${args.labelId}`; result = await graphClient.api(apiPath).patch(updatePayload); break; case 'delete': if (!args.labelId) { throw new McpError(ErrorCode.InvalidParams, 'labelId is required for delete action'); } apiPath = `/security/informationProtection/sensitivityLabels/${args.labelId}`; await graphClient.api(apiPath).delete(); result = { message: `Sensitivity label ${args.labelId} deleted successfully` }; break; case 'publish': if (!args.labelId) { throw new McpError(ErrorCode.InvalidParams, 'labelId is required for publish action'); } // Create a label policy to publish the label const publishPayload = { displayName: `${args.displayName || 'Label'} Policy`, description: `Policy for publishing sensitivity label`, labels: [args.labelId], settings: { mandatory: false, requireJustification: false } }; apiPath = '/security/informationProtection/labelPolicies'; result = await graphClient.api(apiPath).post(publishPayload); break; default: throw new McpError(ErrorCode.InvalidParams, `Unknown action: ${args.action}`); } return { content: [{ type: 'text', text: `Sensitivity Label ${args.action} operation completed:\n\n${JSON.stringify(result, null, 2)}` }] }; } // Information Protection Policy Management Handler export async function handleInformationProtectionPolicies( graphClient: Client, args: InformationProtectionPolicyArgs ): Promise<{ content: { type: string; text: string }[] }> { let apiPath = ''; let result: any; switch (args.action) { case 'list': // List all information protection policies apiPath = '/security/informationProtection/labelPolicies'; result = await graphClient.api(apiPath).get(); break; case 'get': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for get action'); } apiPath = `/security/informationProtection/labelPolicies/${args.policyId}`; result = await graphClient.api(apiPath).get(); break; case 'create': if (!args.displayName) { throw new McpError(ErrorCode.InvalidParams, 'displayName is required for create action'); } const infoPolicyPayload = { displayName: args.displayName, description: args.description || '', settings: args.settings || {} }; apiPath = '/security/informationProtection/labelPolicies'; result = await graphClient.api(apiPath).post(infoPolicyPayload); break; case 'update': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for update action'); } const updatePayload: any = {}; if (args.displayName) updatePayload.displayName = args.displayName; if (args.description) updatePayload.description = args.description; if (args.settings) updatePayload.settings = args.settings; apiPath = `/security/informationProtection/labelPolicies/${args.policyId}`; result = await graphClient.api(apiPath).patch(updatePayload); break; case 'delete': if (!args.policyId) { throw new McpError(ErrorCode.InvalidParams, 'policyId is required for delete action'); } apiPath = `/security/informationProtection/labelPolicies/${args.policyId}`; await graphClient.api(apiPath).delete(); result = { message: `Information protection policy ${args.policyId} deleted successfully` }; break; default: throw new McpError(ErrorCode.InvalidParams, `Unknown action: ${args.action}`); } return { content: [{ type: 'text', text: `Information Protection Policy ${args.action} operation completed:\n\n${JSON.stringify(result, null, 2)}` }] }; }

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/DynamicEndpoints/m365-core-mcp'

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