Skip to main content
Glama
resources.ts23.6 kB
import { Client } from '@microsoft/microsoft-graph-client'; import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js'; /** * MCP Resources for Microsoft 365 * These resources provide LLMs and users with quick access to commonly needed M365 data */ export interface ResourceHandler { uri: string; name: string; description: string; mimeType: string; handler: (graphClient: Client, params?: URLSearchParams) => Promise<any>; } export const m365Resources: ResourceHandler[] = [ // ===== SECURITY RESOURCES ===== { uri: 'm365://security/alerts', name: 'Security Alerts', description: 'Current security alerts from Microsoft Defender and security products', mimeType: 'application/json', handler: async (graphClient) => { const alerts = await graphClient .api('/security/alerts_v2') .top(50) .orderby('createdDateTime desc') .get(); return alerts; } }, { uri: 'm365://security/incidents', name: 'Security Incidents', description: 'Active security incidents requiring attention', mimeType: 'application/json', handler: async (graphClient) => { const incidents = await graphClient .api('/security/incidents') .top(50) .orderby('createdDateTime desc') .get(); return incidents; } }, { uri: 'm365://security/conditional-access', name: 'Conditional Access Policies', description: 'Conditional access policies and their configuration', mimeType: 'application/json', handler: async (graphClient) => { const policies = await graphClient .api('/identity/conditionalAccess/policies') .get(); return policies; } }, { uri: 'm365://security/identity-protection', name: 'Identity Protection', description: 'Identity protection risk detections and risky users', mimeType: 'application/json', handler: async (graphClient) => { const [riskDetections, riskyUsers] = await Promise.all([ graphClient.api('/identityProtection/riskDetections').top(50).get(), graphClient.api('/identityProtection/riskyUsers').top(50).get() ]); return { riskDetections, riskyUsers }; } }, { uri: 'm365://security/threat-assessment', name: 'Threat Assessment', description: 'Threat assessment summary and recommendations', mimeType: 'application/json', handler: async (graphClient) => { const secureScore = await graphClient .api('/security/secureScores') .top(1) .get(); return secureScore; } }, // ===== COMPLIANCE RESOURCES ===== { uri: 'm365://compliance/policies', name: 'Compliance Policies', description: 'DLP policies, retention policies, and compliance configurations', mimeType: 'application/json', handler: async (graphClient) => { // Note: DLP policies require specific endpoints const retentionPolicies = await graphClient .api('/compliance/retentionPolicies') .get() .catch(() => ({ value: [] })); return { retentionPolicies }; } }, { uri: 'm365://compliance/audit-summary', name: 'Audit Log Summary', description: 'Recent audit log activity summary', mimeType: 'application/json', handler: async (graphClient) => { const auditLogs = await graphClient .api('/auditLogs/directoryAudits') .top(100) .orderby('activityDateTime desc') .get(); return auditLogs; } }, { uri: 'm365://compliance/sensitivity-labels', name: 'Sensitivity Labels', description: 'Information protection sensitivity labels and policies', mimeType: 'application/json', handler: async (graphClient) => { const labels = await graphClient .api('/informationProtection/policy/labels') .get() .catch(() => ({ value: [] })); return labels; } }, // ===== DEVICE MANAGEMENT RESOURCES ===== { uri: 'm365://devices/overview', name: 'Device Overview', description: 'Overview of all managed devices across platforms', mimeType: 'application/json', handler: async (graphClient) => { const devices = await graphClient .api('/deviceManagement/managedDevices') .top(100) .get(); return devices; } }, { uri: 'm365://devices/compliance', name: 'Device Compliance Status', description: 'Compliance status of managed devices', mimeType: 'application/json', handler: async (graphClient) => { const [compliance, policies] = await Promise.all([ graphClient.api('/deviceManagement/managedDevices') .select('id,deviceName,complianceState,operatingSystem,lastSyncDateTime') .get(), graphClient.api('/deviceManagement/deviceCompliancePolicies').get() ]); return { devices: compliance, policies }; } }, { uri: 'm365://devices/intune-policies', name: 'Intune Policies', description: 'Device configuration and compliance policies', mimeType: 'application/json', handler: async (graphClient) => { const [configPolicies, compliancePolicies] = await Promise.all([ graphClient.api('/deviceManagement/deviceConfigurations').get(), graphClient.api('/deviceManagement/deviceCompliancePolicies').get() ]); return { configPolicies, compliancePolicies }; } }, { uri: 'm365://devices/apps', name: 'Managed Applications', description: 'Applications managed through Intune', mimeType: 'application/json', handler: async (graphClient) => { const apps = await graphClient .api('/deviceManagement/mobileApps') .top(100) .get(); return apps; } }, // ===== USER & IDENTITY RESOURCES ===== { uri: 'm365://users/directory', name: 'User Directory', description: 'All users in the organization with key attributes', mimeType: 'application/json', handler: async (graphClient, params) => { const top = params?.get('top') || '100'; const users = await graphClient .api('/users') .select('id,displayName,userPrincipalName,mail,jobTitle,department,accountEnabled') .top(parseInt(top)) .get(); return users; } }, { uri: 'm365://users/licenses', name: 'License Assignment', description: 'User license assignments and available licenses', mimeType: 'application/json', handler: async (graphClient) => { const [subscribedSkus, users] = await Promise.all([ graphClient.api('/subscribedSkus').get(), graphClient.api('/users') .select('id,displayName,assignedLicenses') .filter('assignedLicenses/$count ne 0') .top(100) .get() ]); return { subscribedSkus, licensedUsers: users }; } }, { uri: 'm365://users/privileged', name: 'Privileged Users', description: 'Users with administrative roles', mimeType: 'application/json', handler: async (graphClient) => { const roleAssignments = await graphClient .api('/roleManagement/directory/roleAssignments') .expand('principal') .get(); return roleAssignments; } }, // ===== GROUP RESOURCES ===== { uri: 'm365://groups/all', name: 'All Groups', description: 'Security groups, M365 groups, and distribution lists', mimeType: 'application/json', handler: async (graphClient, params) => { const top = params?.get('top') || '100'; const groups = await graphClient .api('/groups') .select('id,displayName,groupTypes,mailEnabled,securityEnabled,mail,description') .top(parseInt(top)) .get(); return groups; } }, { uri: 'm365://groups/teams', name: 'Microsoft Teams', description: 'All Microsoft Teams in the organization', mimeType: 'application/json', handler: async (graphClient) => { const teams = await graphClient .api('/groups') .filter('resourceProvisioningOptions/Any(x:x eq \'Team\')') .select('id,displayName,description,mail,visibility') .get(); return teams; } }, // ===== SHAREPOINT RESOURCES ===== { uri: 'm365://sharepoint/sites', name: 'SharePoint Sites', description: 'SharePoint sites in the tenant', mimeType: 'application/json', handler: async (graphClient, params) => { const top = params?.get('top') || '50'; const sites = await graphClient .api('/sites') .select('id,displayName,webUrl,description,createdDateTime') .top(parseInt(top)) .get(); return sites; } }, { uri: 'm365://sharepoint/permissions', name: 'SharePoint Permissions', description: 'External sharing and permission summary', mimeType: 'application/json', handler: async (graphClient) => { const sites = await graphClient .api('/sites') .select('id,displayName') .top(20) .get(); // Get sharing links for each site const sharingData = await Promise.all( sites.value.map(async (site: any) => { try { const permissions = await graphClient .api(`/sites/${site.id}/permissions`) .get(); return { site: site.displayName, permissions: permissions.value }; } catch { return { site: site.displayName, permissions: [] }; } }) ); return sharingData; } }, // ===== EXCHANGE RESOURCES ===== { uri: 'm365://exchange/mailboxes', name: 'Exchange Mailboxes', description: 'Mailbox configurations and settings', mimeType: 'application/json', handler: async (graphClient) => { const users = await graphClient .api('/users') .select('id,displayName,mail,mailboxSettings') .filter('mail ne null') .top(100) .get(); return users; } }, { uri: 'm365://exchange/transport-rules', name: 'Exchange Transport Rules', description: 'Mail flow rules and configurations', mimeType: 'application/json', handler: async (graphClient) => { // Note: Transport rules require Exchange Online PowerShell or specific Graph endpoints return { message: 'Transport rules require specific Exchange Online access', recommendation: 'Use manage_exchange_settings tool for detailed configuration' }; } }, // ===== COLLABORATION RESOURCES ===== { uri: 'm365://collaboration/teams-activity', name: 'Teams Activity', description: 'Microsoft Teams usage and activity statistics', mimeType: 'application/json', handler: async (graphClient) => { const reports = await graphClient .api('/reports/getTeamsUserActivityUserDetail(period=\'D7\')') .get() .catch(() => ({ value: 'Reports require additional permissions' })); return reports; } }, { uri: 'm365://collaboration/onedrive-usage', name: 'OneDrive Usage', description: 'OneDrive storage and usage statistics', mimeType: 'application/json', handler: async (graphClient) => { const reports = await graphClient .api('/reports/getOneDriveUsageAccountDetail(period=\'D7\')') .get() .catch(() => ({ value: 'Reports require additional permissions' })); return reports; } }, // ===== APPLICATION RESOURCES ===== { uri: 'm365://applications/registrations', name: 'Application Registrations', description: 'Azure AD application registrations', mimeType: 'application/json', handler: async (graphClient) => { const apps = await graphClient .api('/applications') .select('id,appId,displayName,signInAudience,createdDateTime') .top(100) .get(); return apps; } }, { uri: 'm365://applications/service-principals', name: 'Service Principals', description: 'Enterprise applications and service principals', mimeType: 'application/json', handler: async (graphClient) => { const sps = await graphClient .api('/servicePrincipals') .select('id,appId,displayName,servicePrincipalType,accountEnabled') .top(100) .get(); return sps; } }, { uri: 'm365://applications/consent', name: 'Application Consent', description: 'OAuth2 permissions and consent grants', mimeType: 'application/json', handler: async (graphClient) => { const grants = await graphClient .api('/oauth2PermissionGrants') .top(100) .get(); return grants; } }, // ===== GOVERNANCE RESOURCES ===== { uri: 'm365://governance/access-reviews', name: 'Access Reviews', description: 'Access review campaigns and status', mimeType: 'application/json', handler: async (graphClient) => { const reviews = await graphClient .api('/identityGovernance/accessReviews/definitions') .get() .catch(() => ({ value: [] })); return reviews; } }, { uri: 'm365://governance/entitlement', name: 'Entitlement Management', description: 'Access packages and entitlement policies', mimeType: 'application/json', handler: async (graphClient) => { const packages = await graphClient .api('/identityGovernance/entitlementManagement/accessPackages') .get() .catch(() => ({ value: [] })); return packages; } }, // ===== TENANT INFORMATION ===== { uri: 'm365://tenant/organization', name: 'Organization Information', description: 'Tenant configuration and organization details', mimeType: 'application/json', handler: async (graphClient) => { const org = await graphClient .api('/organization') .get(); return org; } }, { uri: 'm365://tenant/domains', name: 'Verified Domains', description: 'Verified domains in the tenant', mimeType: 'application/json', handler: async (graphClient) => { const domains = await graphClient .api('/domains') .get(); return domains; } }, { uri: 'm365://tenant/subscriptions', name: 'Subscriptions', description: 'Active subscriptions and SKUs', mimeType: 'application/json', handler: async (graphClient) => { const skus = await graphClient .api('/subscribedSkus') .get(); return skus; } }, // ===== DOCUMENT GENERATION RESOURCES ===== { uri: 'm365://documents/presentations', name: 'PowerPoint Presentations', description: 'List of PowerPoint presentations in user\'s OneDrive', mimeType: 'application/json', handler: async (graphClient) => { const presentations = await graphClient .api('/me/drive/root/search(q=\'.pptx\')') .top(50) .select('id,name,createdDateTime,lastModifiedDateTime,size,webUrl') .get(); return presentations; } }, { uri: 'm365://documents/word-documents', name: 'Word Documents', description: 'List of Word documents in user\'s OneDrive', mimeType: 'application/json', handler: async (graphClient) => { const documents = await graphClient .api('/me/drive/root/search(q=\'.docx\')') .top(50) .select('id,name,createdDateTime,lastModifiedDateTime,size,webUrl') .get(); return documents; } }, { uri: 'm365://documents/reports', name: 'Generated Reports', description: 'List of generated reports and analysis documents', mimeType: 'application/json', handler: async (graphClient) => { const reports = await graphClient .api('/me/drive/root/children') .filter('startsWith(name,\'Report_\') or startsWith(name,\'Analysis_\')') .select('id,name,createdDateTime,lastModifiedDateTime,size,webUrl') .get() .catch(() => ({ value: [] })); return reports; } }, { uri: 'm365://documents/templates', name: 'Document Templates', description: 'Available document templates for report generation', mimeType: 'application/json', handler: async (graphClient) => { // Return metadata about available templates return { powerpoint: { professional: { id: 'professional', name: 'Professional Business', slides: ['title', 'agenda', 'content', 'conclusion'] }, security: { id: 'security', name: 'Security Assessment', slides: ['cover', 'executive_summary', 'findings', 'recommendations', 'roadmap'] }, compliance: { id: 'compliance', name: 'Compliance Report', slides: ['title', 'overview', 'status', 'gaps', 'remediation'] } }, word: { professional: { id: 'professional', name: 'Professional Report', sections: ['cover', 'toc', 'executive_summary', 'analysis', 'recommendations', 'appendix'] }, technical: { id: 'technical', name: 'Technical Documentation', sections: ['title', 'overview', 'architecture', 'configuration', 'troubleshooting'] }, audit: { id: 'audit', name: 'Audit Report', sections: ['cover', 'scope', 'methodology', 'findings', 'conclusions', 'action_plan'] } }, html: { dashboard: { id: 'dashboard', name: 'Interactive Dashboard', theme: 'modern', features: ['charts', 'filters', 'export'] }, report: { id: 'report', name: 'Web Report', theme: 'professional', features: ['toc', 'sections', 'print_view'] } } }; } }, // ===== POLICY MANAGEMENT RESOURCES ===== { uri: 'm365://policies/conditional-access', name: 'Conditional Access Policies', description: 'All conditional access policies and their current state', mimeType: 'application/json', handler: async (graphClient) => { const policies = await graphClient .api('/identity/conditionalAccess/policies') .select('id,displayName,state,conditions,grantControls,sessionControls') .get(); return policies; } }, { uri: 'm365://policies/retention', name: 'Retention Policies', description: 'Retention policies across Microsoft 365 workloads', mimeType: 'application/json', handler: async (graphClient) => { const policies = await graphClient .api('/security/informationProtection/retentionLabels') .get() .catch(() => ({ value: [] })); return policies; } }, { uri: 'm365://policies/information-protection', name: 'Information Protection Policies', description: 'Azure Information Protection and sensitivity label policies', mimeType: 'application/json', handler: async (graphClient) => { const [labels, labelPolicies] = await Promise.all([ graphClient.api('/security/informationProtection/sensitivityLabels').get().catch(() => ({ value: [] })), graphClient.api('/security/informationProtection/labelPolicies').get().catch(() => ({ value: [] })) ]); return { labels, labelPolicies }; } }, { uri: 'm365://policies/defender', name: 'Defender Policies', description: 'Microsoft Defender for Office 365 security policies', mimeType: 'application/json', handler: async (graphClient) => { // Defender policies are managed through Security & Compliance Center const threatPolicies = await graphClient .api('/security/threatSubmission/emailThreats') .top(50) .get() .catch(() => ({ value: [] })); return threatPolicies; } }, { uri: 'm365://policies/teams', name: 'Teams Policies', description: 'Microsoft Teams messaging, meeting, and calling policies', mimeType: 'application/json', handler: async (graphClient) => { const teams = await graphClient .api('/teams') .top(50) .select('id,displayName,description') .get() .catch(() => ({ value: [] })); return { teams, note: 'Teams policies are managed through Teams admin center APIs' }; } }, { uri: 'm365://policies/exchange', name: 'Exchange Policies', description: 'Exchange Online mail flow, retention, and mobile device policies', mimeType: 'application/json', handler: async (graphClient) => { // Exchange policies information return { note: 'Exchange policies are managed through Exchange Online PowerShell', categories: [ 'Mail flow rules (Transport rules)', 'Mobile device policies', 'Retention policies', 'Sharing policies', 'Address book policies' ] }; } }, { uri: 'm365://policies/sharepoint-governance', name: 'SharePoint Governance Policies', description: 'SharePoint sharing, access control, and lifecycle policies', mimeType: 'application/json', handler: async (graphClient) => { const adminSettings = await graphClient .api('/admin/sharepoint/settings') .get() .catch(() => null); const sites = await graphClient .api('/sites?search=*') .top(10) .select('id,displayName,webUrl,sharingCapabilities') .get() .catch(() => ({ value: [] })); return { adminSettings, recentSites: sites }; } }, { uri: 'm365://policies/security-alerts', name: 'Security Alert Policies', description: 'Security alert policies and notification configurations', mimeType: 'application/json', handler: async (graphClient) => { const alertPolicies = await graphClient .api('/security/alerts_v2') .filter('status eq \'new\' or status eq \'inProgress\'') .top(50) .select('id,title,category,severity,status,createdDateTime') .orderby('createdDateTime desc') .get(); return alertPolicies; } }, { uri: 'm365://policies/overview', name: 'Policy Overview', description: 'Summary of all policies across Microsoft 365', mimeType: 'application/json', handler: async (graphClient) => { // Gather overview of policies across different areas const [conditionalAccess, dlpPolicies, alerts] = await Promise.all([ graphClient.api('/identity/conditionalAccess/policies').select('id,displayName,state').get().catch(() => ({ value: [] })), graphClient.api('/security/informationProtection/sensitivityLabels').get().catch(() => ({ value: [] })), graphClient.api('/security/alerts_v2').top(10).get().catch(() => ({ value: [] })) ]); return { summary: { conditionalAccessPolicies: conditionalAccess.value?.length || 0, sensitivityLabels: dlpPolicies.value?.length || 0, activeAlerts: alerts.value?.length || 0 }, lastUpdated: new Date().toISOString() }; } } ]; /** * Get resource by URI or URI pattern */ export function getResourceByUri(uri: string): ResourceHandler | undefined { // Direct match const direct = m365Resources.find(r => r.uri === uri); if (direct) return direct; // Pattern match (e.g., m365://users/directory?top=50) const uriWithoutParams = uri.split('?')[0]; return m365Resources.find(r => r.uri === uriWithoutParams); } /** * List all available resources with descriptions */ export function listResources(): Array<{ uri: string; name: string; description: string; mimeType: string }> { return m365Resources.map(r => ({ uri: r.uri, name: r.name, description: r.description, mimeType: r.mimeType })); }

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