@utaba/ucm-mcp-server
Version:
Universal Context Manager MCP Server - AI Productivity Platform
108 lines • 5.36 kB
JavaScript
/**
* 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