@z_ai/mcp-server 0.1.0 → 0.1.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -0
- package/README.zh-CN.md +53 -6
- package/build/core/base-image-service.js +91 -0
- package/build/core/chat-service.js +15 -1
- package/build/index.js +16 -3
- package/build/prompts/data-viz.js +97 -0
- package/build/prompts/diagram-analysis.js +101 -0
- package/build/prompts/error-diagnosis.js +68 -0
- package/build/prompts/general-image.js +44 -0
- package/build/prompts/index.js +11 -0
- package/build/prompts/text-extraction.js +44 -0
- package/build/prompts/ui-diff.js +189 -0
- package/build/prompts/ui-to-artifact.js +88 -0
- package/build/tools/data-viz.js +82 -0
- package/build/tools/diagram-analysis.js +82 -0
- package/build/tools/error-diagnosis.js +82 -0
- package/build/tools/general-image.js +73 -0
- package/build/tools/text-extraction.js +82 -0
- package/build/tools/ui-diff.js +87 -0
- package/build/tools/ui-to-artifact.js +83 -0
- package/package.json +1 -1
- package/build/tools/image-analysis.js +0 -125
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { FileNotFoundError, ApiError } from '../types/index.js';
|
|
3
|
+
import { CommonSchemas, ToolSchemaBuilder } from '../utils/validation.js';
|
|
4
|
+
import { formatMcpResponse, createSuccessResponse, createErrorResponse, withRetry } from '../core/api-common.js';
|
|
5
|
+
import { BaseImageAnalysisService } from '../core/base-image-service.js';
|
|
6
|
+
import { TEXT_EXTRACTION_PROMPT } from '../prompts/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Text Extraction service - OCR and text extraction from screenshots
|
|
9
|
+
*/
|
|
10
|
+
class TextExtractionService extends BaseImageAnalysisService {
|
|
11
|
+
/**
|
|
12
|
+
* Extract text from screenshot
|
|
13
|
+
* @param imageSource Image file path or URL
|
|
14
|
+
* @param userPrompt User's extraction requirements
|
|
15
|
+
* @param programmingLanguage Optional programming language hint
|
|
16
|
+
* @returns Extracted text
|
|
17
|
+
*/
|
|
18
|
+
async extractText(imageSource, userPrompt, programmingLanguage) {
|
|
19
|
+
console.info('Starting text extraction', {
|
|
20
|
+
imageSource,
|
|
21
|
+
prompt: userPrompt,
|
|
22
|
+
language: programmingLanguage
|
|
23
|
+
});
|
|
24
|
+
// Validate prompt
|
|
25
|
+
this.validatePrompt(userPrompt, 'text-extraction');
|
|
26
|
+
// Enhance prompt with language hint if provided
|
|
27
|
+
let enhancedPrompt = userPrompt;
|
|
28
|
+
if (programmingLanguage && programmingLanguage.trim()) {
|
|
29
|
+
enhancedPrompt = `${userPrompt}\n\n<language_hint>The code is in ${programmingLanguage}.</language_hint>`;
|
|
30
|
+
}
|
|
31
|
+
// Process image
|
|
32
|
+
const imageContent = await this.processImageSource(imageSource);
|
|
33
|
+
// Execute analysis
|
|
34
|
+
return await this.executeVisionAnalysis(TEXT_EXTRACTION_PROMPT, enhancedPrompt, [imageContent], 'text-extraction');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Register Text Extraction tool with MCP server
|
|
39
|
+
* @param server MCP server instance
|
|
40
|
+
*/
|
|
41
|
+
export function registerTextExtractionTool(server) {
|
|
42
|
+
const service = new TextExtractionService();
|
|
43
|
+
const retryableExtract = withRetry(service.extractText.bind(service), 2, 1000);
|
|
44
|
+
server.tool('extract_text_from_screenshot', 'Extract and recognize text from screenshots using advanced OCR capabilities.', {
|
|
45
|
+
image_source: z.string().describe('Local file path or remote URL to the image'),
|
|
46
|
+
prompt: z.string().describe('Instructions for text extraction. Specify what type of text to extract and any formatting requirements.'),
|
|
47
|
+
programming_language: z.string().optional().describe('Optional: specify the programming language if the screenshot contains code (e.g., \'python\', \'javascript\', \'java\'). Leave empty for auto-detection or non-code text.')
|
|
48
|
+
}, async (params) => {
|
|
49
|
+
try {
|
|
50
|
+
const validationSchema = new ToolSchemaBuilder()
|
|
51
|
+
.required('image_source', CommonSchemas.nonEmptyString)
|
|
52
|
+
.required('prompt', CommonSchemas.nonEmptyString)
|
|
53
|
+
.optional('programming_language', z.string())
|
|
54
|
+
.build();
|
|
55
|
+
validationSchema.parse(params);
|
|
56
|
+
const result = await retryableExtract(params.image_source, params.prompt, params.programming_language);
|
|
57
|
+
return formatMcpResponse(createSuccessResponse(result));
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('Text extraction tool execution failed', {
|
|
61
|
+
error: error instanceof Error ? error.message : String(error),
|
|
62
|
+
params
|
|
63
|
+
});
|
|
64
|
+
let errorResponse;
|
|
65
|
+
if (error instanceof z.ZodError) {
|
|
66
|
+
const validationErrors = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
67
|
+
errorResponse = createErrorResponse(`Validation failed: ${validationErrors}`);
|
|
68
|
+
}
|
|
69
|
+
else if (error instanceof FileNotFoundError) {
|
|
70
|
+
errorResponse = createErrorResponse(`Image file not found: ${error.message}`);
|
|
71
|
+
}
|
|
72
|
+
else if (error instanceof ApiError) {
|
|
73
|
+
errorResponse = createErrorResponse(`API error: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
errorResponse = createErrorResponse(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
77
|
+
}
|
|
78
|
+
return formatMcpResponse(errorResponse);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
console.info('Text Extraction tool registered successfully');
|
|
82
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { FileNotFoundError, ApiError } from '../types/index.js';
|
|
3
|
+
import { CommonSchemas, ToolSchemaBuilder } from '../utils/validation.js';
|
|
4
|
+
import { formatMcpResponse, createSuccessResponse, createErrorResponse, withRetry } from '../core/api-common.js';
|
|
5
|
+
import { BaseImageAnalysisService } from '../core/base-image-service.js';
|
|
6
|
+
import { UI_DIFF_CHECK_PROMPT } from '../prompts/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* UI Diff Check service - Compare two UI screenshots
|
|
9
|
+
*/
|
|
10
|
+
class UiDiffCheckService extends BaseImageAnalysisService {
|
|
11
|
+
/**
|
|
12
|
+
* Compare two UI screenshots
|
|
13
|
+
* @param expectedImageSource Expected/reference design image
|
|
14
|
+
* @param actualImageSource Actual implementation image
|
|
15
|
+
* @param userPrompt User's comparison requirements
|
|
16
|
+
* @returns Comparison analysis with differences
|
|
17
|
+
*/
|
|
18
|
+
async compareUiScreenshots(expectedImageSource, actualImageSource, userPrompt) {
|
|
19
|
+
console.info('Starting UI diff comparison', {
|
|
20
|
+
expectedImage: expectedImageSource,
|
|
21
|
+
actualImage: actualImageSource,
|
|
22
|
+
prompt: userPrompt
|
|
23
|
+
});
|
|
24
|
+
// Validate prompt
|
|
25
|
+
this.validatePrompt(userPrompt, 'ui-diff-check');
|
|
26
|
+
// Enhance prompt to clarify which image is which
|
|
27
|
+
const enhancedPrompt = `<images>
|
|
28
|
+
The first image is the EXPECTED/REFERENCE design (the target).
|
|
29
|
+
The second image is the ACTUAL/CURRENT implementation (what needs to be checked).
|
|
30
|
+
</images>
|
|
31
|
+
|
|
32
|
+
${userPrompt}`;
|
|
33
|
+
// Process both images
|
|
34
|
+
const imageContents = await this.processMultipleImageSources([
|
|
35
|
+
expectedImageSource,
|
|
36
|
+
actualImageSource
|
|
37
|
+
]);
|
|
38
|
+
// Execute analysis
|
|
39
|
+
return await this.executeVisionAnalysis(UI_DIFF_CHECK_PROMPT, enhancedPrompt, imageContents, 'ui-diff-check');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Register UI Diff Check tool with MCP server
|
|
44
|
+
* @param server MCP server instance
|
|
45
|
+
*/
|
|
46
|
+
export function registerUiDiffCheckTool(server) {
|
|
47
|
+
const service = new UiDiffCheckService();
|
|
48
|
+
const retryableCompare = withRetry(service.compareUiScreenshots.bind(service), 2, 1000);
|
|
49
|
+
server.tool('ui_diff_check', 'Compare two UI screenshots to identify visual differences and implementation discrepancies.', {
|
|
50
|
+
expected_image_source: z.string().describe('Local file path or remote URL to the image'),
|
|
51
|
+
actual_image_source: z.string().describe('Local file path or remote URL to the image'),
|
|
52
|
+
prompt: z.string().describe('Instructions for the comparison. Specify what aspects to focus on or what level of detail is needed.')
|
|
53
|
+
}, async (params) => {
|
|
54
|
+
try {
|
|
55
|
+
const validationSchema = new ToolSchemaBuilder()
|
|
56
|
+
.required('expected_image_source', CommonSchemas.nonEmptyString)
|
|
57
|
+
.required('actual_image_source', CommonSchemas.nonEmptyString)
|
|
58
|
+
.required('prompt', CommonSchemas.nonEmptyString)
|
|
59
|
+
.build();
|
|
60
|
+
validationSchema.parse(params);
|
|
61
|
+
const result = await retryableCompare(params.expected_image_source, params.actual_image_source, params.prompt);
|
|
62
|
+
return formatMcpResponse(createSuccessResponse(result));
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error('UI diff check tool execution failed', {
|
|
66
|
+
error: error instanceof Error ? error.message : String(error),
|
|
67
|
+
params
|
|
68
|
+
});
|
|
69
|
+
let errorResponse;
|
|
70
|
+
if (error instanceof z.ZodError) {
|
|
71
|
+
const validationErrors = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
72
|
+
errorResponse = createErrorResponse(`Validation failed: ${validationErrors}`);
|
|
73
|
+
}
|
|
74
|
+
else if (error instanceof FileNotFoundError) {
|
|
75
|
+
errorResponse = createErrorResponse(`Image file not found: ${error.message}`);
|
|
76
|
+
}
|
|
77
|
+
else if (error instanceof ApiError) {
|
|
78
|
+
errorResponse = createErrorResponse(`API error: ${error.message}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
errorResponse = createErrorResponse(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
82
|
+
}
|
|
83
|
+
return formatMcpResponse(errorResponse);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
console.info('UI Diff Check tool registered successfully');
|
|
87
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { FileNotFoundError, ApiError } from '../types/index.js';
|
|
3
|
+
import { CommonSchemas, ToolSchemaBuilder } from '../utils/validation.js';
|
|
4
|
+
import { formatMcpResponse, createSuccessResponse, createErrorResponse, withRetry } from '../core/api-common.js';
|
|
5
|
+
import { BaseImageAnalysisService } from '../core/base-image-service.js';
|
|
6
|
+
import { UI_TO_ARTIFACT_PROMPTS } from '../prompts/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* UI to Artifact service - Convert UI screenshots to code/prompts/specs/descriptions
|
|
9
|
+
*/
|
|
10
|
+
class UiToArtifactService extends BaseImageAnalysisService {
|
|
11
|
+
/**
|
|
12
|
+
* Convert UI screenshot to specified artifact type
|
|
13
|
+
* @param imageSource Image file path or URL
|
|
14
|
+
* @param outputType Type of output (code, prompt, spec, description)
|
|
15
|
+
* @param userPrompt User's specific requirements
|
|
16
|
+
* @returns Generated artifact
|
|
17
|
+
*/
|
|
18
|
+
async convertUiToArtifact(imageSource, outputType, userPrompt) {
|
|
19
|
+
console.info('Starting UI to artifact conversion', {
|
|
20
|
+
imageSource,
|
|
21
|
+
outputType,
|
|
22
|
+
prompt: userPrompt
|
|
23
|
+
});
|
|
24
|
+
// Validate output type
|
|
25
|
+
const normalizedType = outputType.toLowerCase();
|
|
26
|
+
const systemPrompt = UI_TO_ARTIFACT_PROMPTS[normalizedType];
|
|
27
|
+
if (!systemPrompt) {
|
|
28
|
+
throw new Error(`Invalid output_type '${outputType}'. Must be one of: code, prompt, spec, description`);
|
|
29
|
+
}
|
|
30
|
+
// Validate prompt
|
|
31
|
+
this.validatePrompt(userPrompt, 'ui-to-artifact');
|
|
32
|
+
// Process image
|
|
33
|
+
const imageContent = await this.processImageSource(imageSource);
|
|
34
|
+
// Execute analysis
|
|
35
|
+
return await this.executeVisionAnalysis(systemPrompt, userPrompt, [imageContent], 'ui-to-artifact');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Register UI to Artifact tool with MCP server
|
|
40
|
+
* @param server MCP server instance
|
|
41
|
+
*/
|
|
42
|
+
export function registerUiToArtifactTool(server) {
|
|
43
|
+
const service = new UiToArtifactService();
|
|
44
|
+
const retryableConvert = withRetry(service.convertUiToArtifact.bind(service), 2, 1000);
|
|
45
|
+
server.tool('ui_to_artifact', 'Convert UI screenshots into various artifacts: code, prompts, design specifications, or descriptions.', {
|
|
46
|
+
image_source: z.string().describe('Local file path or remote URL to the image'),
|
|
47
|
+
output_type: z.enum(['code', 'prompt', 'spec', 'description']).describe("Type of output to generate. Options: 'code' (generate frontend code), 'prompt' (generate AI prompt for recreating this UI), 'spec' (generate design specification document), 'description' (natural language description of the UI)."),
|
|
48
|
+
prompt: z.string().describe('Detailed instructions describing what to generate from this UI image. Should clearly state the desired output and any specific requirements.')
|
|
49
|
+
}, async (params) => {
|
|
50
|
+
try {
|
|
51
|
+
const validationSchema = new ToolSchemaBuilder()
|
|
52
|
+
.required('image_source', CommonSchemas.nonEmptyString)
|
|
53
|
+
.required('output_type', z.enum(['code', 'prompt', 'spec', 'description']))
|
|
54
|
+
.required('prompt', CommonSchemas.nonEmptyString)
|
|
55
|
+
.build();
|
|
56
|
+
validationSchema.parse(params);
|
|
57
|
+
const result = await retryableConvert(params.image_source, params.output_type, params.prompt);
|
|
58
|
+
return formatMcpResponse(createSuccessResponse(result));
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error('UI to artifact tool execution failed', {
|
|
62
|
+
error: error instanceof Error ? error.message : String(error),
|
|
63
|
+
params
|
|
64
|
+
});
|
|
65
|
+
let errorResponse;
|
|
66
|
+
if (error instanceof z.ZodError) {
|
|
67
|
+
const validationErrors = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
68
|
+
errorResponse = createErrorResponse(`Validation failed: ${validationErrors}`);
|
|
69
|
+
}
|
|
70
|
+
else if (error instanceof FileNotFoundError) {
|
|
71
|
+
errorResponse = createErrorResponse(`Image file not found: ${error.message}`);
|
|
72
|
+
}
|
|
73
|
+
else if (error instanceof ApiError) {
|
|
74
|
+
errorResponse = createErrorResponse(`API error: ${error.message}`);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
errorResponse = createErrorResponse(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
78
|
+
}
|
|
79
|
+
return formatMcpResponse(errorResponse);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
console.info('UI to Artifact tool registered successfully');
|
|
83
|
+
}
|
package/package.json
CHANGED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { FileNotFoundError, ApiError } from '../types/index.js';
|
|
3
|
-
import { ToolExecutionError } from '../core/error-handler.js';
|
|
4
|
-
import { CommonSchemas, ToolSchemaBuilder } from '../utils/validation.js';
|
|
5
|
-
import { createMultiModalMessage, createImageContent, formatMcpResponse, createSuccessResponse, createErrorResponse, withRetry } from '../core/api-common.js';
|
|
6
|
-
import { fileService } from '../core/file-service.js';
|
|
7
|
-
import { chatService } from '../core/chat-service.js';
|
|
8
|
-
/**
|
|
9
|
-
* Image analysis service class
|
|
10
|
-
*/
|
|
11
|
-
export class ImageAnalysisService {
|
|
12
|
-
chatService = chatService;
|
|
13
|
-
fileService = fileService;
|
|
14
|
-
MAX_IMAGE_SIZE_MB = 5;
|
|
15
|
-
/**
|
|
16
|
-
* Execute image analysis
|
|
17
|
-
* @param request Image analysis request
|
|
18
|
-
* @returns Analysis result
|
|
19
|
-
*/
|
|
20
|
-
async analyzeImage(request) {
|
|
21
|
-
console.info('Starting image analysis', {
|
|
22
|
-
imageSource: request.imageSource,
|
|
23
|
-
prompt: request.prompt
|
|
24
|
-
});
|
|
25
|
-
try {
|
|
26
|
-
// Validate image source (file or URL) and size
|
|
27
|
-
await this.fileService.validateImageSource(request.imageSource, this.MAX_IMAGE_SIZE_MB);
|
|
28
|
-
// Validate prompt
|
|
29
|
-
if (!request.prompt || request.prompt.trim().length === 0) {
|
|
30
|
-
throw new ToolExecutionError('Prompt is required for image analysis', 'image-analysis', 'VALIDATION_ERROR', {
|
|
31
|
-
toolName: 'image-analysis',
|
|
32
|
-
operation: 'analyzeImage',
|
|
33
|
-
metadata: { imageSource: request.imageSource }
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
// Handle image source (URL or local file)
|
|
37
|
-
let imageContent;
|
|
38
|
-
if (this.fileService.isUrl(request.imageSource)) {
|
|
39
|
-
// For URLs, pass directly without base64 encoding
|
|
40
|
-
imageContent = createImageContent(request.imageSource);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
// For local files, encode to base64
|
|
44
|
-
const imageData = await this.fileService.encodeImageToBase64(request.imageSource);
|
|
45
|
-
imageContent = createImageContent(imageData);
|
|
46
|
-
}
|
|
47
|
-
// Create multimodal message
|
|
48
|
-
const messages = createMultiModalMessage([imageContent], request.prompt);
|
|
49
|
-
const result = await this.chatService.visionCompletions(messages);
|
|
50
|
-
console.info('Image analysis completed', {
|
|
51
|
-
imageSource: request.imageSource
|
|
52
|
-
});
|
|
53
|
-
return result;
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
console.error('Image analysis failed', {
|
|
57
|
-
error: error instanceof Error ? error.message : String(error),
|
|
58
|
-
imageSource: request.imageSource
|
|
59
|
-
});
|
|
60
|
-
if (error instanceof ToolExecutionError) {
|
|
61
|
-
throw error;
|
|
62
|
-
}
|
|
63
|
-
// Wrap unknown errors
|
|
64
|
-
throw new ToolExecutionError(`Image analysis failed: ${error.message}`, 'image-analysis', 'EXECUTION_ERROR', {
|
|
65
|
-
toolName: 'image-analysis',
|
|
66
|
-
operation: 'analyzeImage',
|
|
67
|
-
metadata: { imageSource: request.imageSource, originalError: error }
|
|
68
|
-
}, error);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Register image analysis tool with MCP server
|
|
74
|
-
* @param server MCP server instance
|
|
75
|
-
*/
|
|
76
|
-
export function registerImageAnalysisTool(server) {
|
|
77
|
-
const analysisService = new ImageAnalysisService();
|
|
78
|
-
const retryableAnalyze = withRetry(analysisService.analyzeImage.bind(analysisService), 2, // Maximum 2 retries
|
|
79
|
-
1000 // 1 second delay
|
|
80
|
-
);
|
|
81
|
-
server.tool('analyze_image', 'Analyze an image using advanced AI vision models with comprehensive understanding capabilities. Supports both local files and remote URL. Maximum file size: 5MB', {
|
|
82
|
-
image_source: z.string().describe('Local file path or remote URL to the image (supports PNG, JPG, JPEG)'),
|
|
83
|
-
prompt: z.string().describe('Detailed text prompt. If the task is **front-end code replication**, the prompt you provide must be: "Describe in detail the layout structure, color style, main components, and interactive elements of the website in this image to facilitate subsequent code generation by the model." + your additional requirements. \ For **other tasks**, the prompt you provide must clearly describe what to analyze, extract, or understand from the image.')
|
|
84
|
-
}, async (params) => {
|
|
85
|
-
try {
|
|
86
|
-
// Validate parameters
|
|
87
|
-
const validationSchema = new ToolSchemaBuilder()
|
|
88
|
-
.required('image_source', CommonSchemas.nonEmptyString)
|
|
89
|
-
.required('prompt', CommonSchemas.nonEmptyString)
|
|
90
|
-
.build();
|
|
91
|
-
validationSchema.parse(params);
|
|
92
|
-
// Build request object
|
|
93
|
-
const request = {
|
|
94
|
-
imageSource: params.image_source,
|
|
95
|
-
prompt: params.prompt
|
|
96
|
-
};
|
|
97
|
-
// Execute analysis
|
|
98
|
-
const result = await retryableAnalyze(request);
|
|
99
|
-
const response = createSuccessResponse(result);
|
|
100
|
-
return formatMcpResponse(response);
|
|
101
|
-
}
|
|
102
|
-
catch (error) {
|
|
103
|
-
console.error('Tool execution failed', {
|
|
104
|
-
error: error instanceof Error ? error.message : String(error),
|
|
105
|
-
params
|
|
106
|
-
});
|
|
107
|
-
let errorResponse;
|
|
108
|
-
if (error instanceof z.ZodError) {
|
|
109
|
-
const validationErrors = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
110
|
-
errorResponse = createErrorResponse(`Validation failed: ${validationErrors}`);
|
|
111
|
-
}
|
|
112
|
-
else if (error instanceof FileNotFoundError) {
|
|
113
|
-
errorResponse = createErrorResponse(`Image file not found: ${error.message}`);
|
|
114
|
-
}
|
|
115
|
-
else if (error instanceof ApiError) {
|
|
116
|
-
errorResponse = createErrorResponse(`API error: ${error.message}`);
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
errorResponse = createErrorResponse(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
120
|
-
}
|
|
121
|
-
return formatMcpResponse(errorResponse);
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
console.info('Image analysis tool registered successfully');
|
|
125
|
-
}
|