UNPKG

@utaba/ucm-mcp-server

Version:

Universal Context Manager MCP Server - AI Productivity Platform

108 lines 5.36 kB
/** * SharePointReadRelatedFileTool * Retrieve related file (image/embedded file) extracted from a SharePoint document */ import { BaseToolController } from '../base/BaseToolController.js'; import { McpError, McpErrorCode } from '../../utils/McpErrorHandler.js'; export class SharePointReadRelatedFileTool extends BaseToolController { constructor(ucmClient, logger, publishingAuthorId) { super(ucmClient, logger, publishingAuthorId); } get name() { return 'ucm_sharepoint_read_relatedfile'; } get description() { return 'Retrieve a related file (image or embedded file) that was extracted from a SharePoint document. Pass the full URI from markdown. Returns complete file. Large images (>500KB original size) may fail with size limit error.'; } get inputSchema() { return { type: 'object', properties: { uri: { type: 'string', description: 'Full URI from markdown (e.g., "file1.jpg?connectionId=...&fileId=...&eTag=..." or without protocol prefix)', minLength: 1, maxLength: 2000 } }, required: ['uri'], additionalProperties: false }; } validateParams(params) { super.validateParams(params); // Validate URI is provided and is a non-empty string if (!params.uri || typeof params.uri !== 'string' || params.uri.trim() === '') { throw new McpError(McpErrorCode.InvalidParams, 'URI is required and must be a non-empty string'); } // Don't validate format - let server handle parsing and auto-correction } async handleExecute(params) { this.logger.info('SharePointReadRelatedFileTool', `Reading related file from URI: ${params.uri}`); try { // Call the API to read the related file (no pagination - always complete file) const result = await this.ucmClient.sharePointReadRelatedFile(params.uri); this.logger.info('SharePointReadRelatedFileTool', `Related file retrieved: ${result.fileName}, size: ${result.size} bytes, content length: ${result.content.length} chars`); // Check if base64 content exceeds safe MCP token limit (~15,000 characters) // This prevents MCP response errors for large images if (result.content.length > 15000) { throw new McpError(McpErrorCode.InternalError, 'Image file too large for MCP response. Please resize the image in SharePoint or use the web UI to download.'); } // Check if this is an image file - return as image resource for visual analysis if (result.mimeType && result.mimeType.startsWith('image/')) { return { content: [ { type: 'image', data: result.content, // base64 encoded image data mimeType: result.mimeType }, { type: 'text', text: `Image: ${result.fileName}\nSize: ${result.size} bytes\nType: ${result.mimeType}` } ] }; } // For non-image files, return file information as JSON const response = { success: true, fileName: result.fileName, mimeType: result.mimeType, size: result.size, contentLength: result.content.length, content: result.content, // base64 encoded binary data encoding: 'base64' }; return { content: [ { type: 'text', text: JSON.stringify(response, null, 2) } ] }; } 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('SharePointReadRelatedFileTool', 'Read related file operation failed', '', sanitizedError); // Format error response if (error?.response?.status === 404) { throw new McpError(McpErrorCode.InvalidParams, 'Related file not found. File may no longer be available. Re-read the parent document to access related files.'); } if (error?.response?.status === 401 || error?.response?.status === 403) { throw new McpError(McpErrorCode.InvalidParams, 'Not authorized to access this SharePoint connection or file'); } if (error?.response?.status === 400) { throw new McpError(McpErrorCode.InvalidParams, error?.response?.data?.message || 'Invalid request parameters'); } throw new McpError(McpErrorCode.InternalError, `SharePoint read related file failed: ${error?.message || 'Unknown error'}`, { originalError: error?.message }); } } } //# sourceMappingURL=SharePointReadRelatedFileTool.js.map