UNPKG

@utaba/ucm-mcp-server

Version:

Universal Context Manager MCP Server - AI Productivity Platform

114 lines 5.32 kB
/** * SharePointSignOutTool * Revoke user's OnBehalfOf authorization for a SharePoint connection */ import { BaseToolController } from '../base/BaseToolController.js'; import { McpError, McpErrorCode } from '../../utils/McpErrorHandler.js'; export class SharePointSignOutTool extends BaseToolController { constructor(ucmClient, logger, publishingAuthorId) { super(ucmClient, logger, publishingAuthorId); } get name() { return 'ucm_sharepoint_signout'; } get description() { return 'This signs the user out only for connections with user-delegated permissions.'; } get inputSchema() { return { type: 'object', properties: { connectionId: { type: 'string', description: 'SharePoint connection ID to revoke authorization for (get this from list_connections)', minLength: 36, maxLength: 36 } }, required: ['connectionId'] }; } validateParams(params) { super.validateParams(params); // Validate connectionId if (!params.connectionId || typeof params.connectionId !== 'string') { throw new McpError(McpErrorCode.InvalidParams, 'connectionId is required and must be a string'); } if (params.connectionId.length !== 36) { throw new McpError(McpErrorCode.InvalidParams, 'connectionId must be a valid UUID (36 characters)'); } } async handleExecute(params) { this.logger.info('SharePointSignOutTool', `Revoking SharePoint authorization for connection ${params.connectionId}`); try { // Call API to revoke authorization const result = await this.ucmClient.sharePointSignOut(params.connectionId); this.logger.info('SharePointSignOutTool', 'Authorization revoked successfully', '', { connectionId: params.connectionId, success: result.success }); // Return structured markdown response const markdown = this.formatSignOutResponse(result); return markdown; } catch (error) { // Sanitize error for logging to avoid circular reference issues const sanitizedError = { message: error?.message, status: error?.response?.status, data: error?.response?.data }; this.logger.error('SharePointSignOutTool', 'Failed to revoke authorization', '', sanitizedError); if (error instanceof McpError) { throw error; } // Handle API errors if (error.response) { const status = error.response.status; const errorData = error.response.data; if (status === 401 || status === 403) { throw new McpError(McpErrorCode.InvalidRequest, `Access denied: ${errorData?.message || 'Not authorized to revoke SharePoint authorization'}`); } if (status === 404) { throw new McpError(McpErrorCode.InvalidRequest, `Connection not found: ${errorData?.message || 'SharePoint connection does not exist'}`); } if (status === 400 && errorData?.error === 'INVALID_AUTH_TYPE') { throw new McpError(McpErrorCode.InvalidRequest, `Invalid operation: Only OnBehalfOf (user-delegated) connections support user authorization. This connection uses ServicePrincipal authentication.`); } throw new McpError(McpErrorCode.InternalError, `API error: ${errorData?.message || error.message}`); } throw new McpError(McpErrorCode.InternalError, `Failed to revoke SharePoint authorization: ${error.message}`); } } /** * Format sign out response as markdown */ formatSignOutResponse(result) { const lines = []; lines.push('# SharePoint Authorization Revoked\n'); if (result.success) { lines.push('✅ **Status**: Authorization successfully revoked\n'); lines.push(`**Connection ID**: ${result.connectionId}\n`); if (result.revokedAt) { lines.push(`**Revoked At**: ${new Date(result.revokedAt).toLocaleString()}\n`); } lines.push('\n## What This Means\n'); lines.push('- Your access tokens have been deleted from the system'); lines.push('- You are now signed out of this SharePoint connection'); lines.push('- To access SharePoint files again, you must re-authorize\n'); if (result._links?.authorize) { lines.push('\n## Re-authorize Access\n'); lines.push(`To grant access again, visit: ${result._links.authorize.href}\n`); } } else { lines.push('⚠️ **Status**: Revocation failed or not needed\n'); lines.push(`**Message**: ${result.message}\n`); if (result.details?.reason) { lines.push(`**Reason**: ${result.details.reason}\n`); } } return lines.join('\n'); } } //# sourceMappingURL=SharePointSignOutTool.js.map