@z_ai/mcp-server 0.1.0 → 0.1.1-beta.1

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.
@@ -0,0 +1,78 @@
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 { GENERAL_IMAGE_ANALYSIS_PROMPT } from '../prompts/index.js';
7
+ /**
8
+ * General Image Analysis service - Fallback for any image analysis
9
+ */
10
+ class GeneralImageAnalysisService extends BaseImageAnalysisService {
11
+ /**
12
+ * Analyze image with general purpose prompt
13
+ * @param imageSource Image file path or URL
14
+ * @param userPrompt User's analysis request
15
+ * @returns Analysis result
16
+ */
17
+ async analyzeImage(imageSource, userPrompt) {
18
+ console.info('Starting general image analysis', {
19
+ imageSource,
20
+ prompt: userPrompt
21
+ });
22
+ // Validate prompt
23
+ this.validatePrompt(userPrompt, 'analyze-image');
24
+ // Process image
25
+ const imageContent = await this.processImageSource(imageSource);
26
+ // Execute analysis
27
+ return await this.executeVisionAnalysis(GENERAL_IMAGE_ANALYSIS_PROMPT, userPrompt, [imageContent], 'analyze-image');
28
+ }
29
+ }
30
+ /**
31
+ * Register General Image Analysis tool with MCP server
32
+ * @param server MCP server instance
33
+ */
34
+ export function registerGeneralImageAnalysisTool(server) {
35
+ const service = new GeneralImageAnalysisService();
36
+ const retryableAnalyze = withRetry(service.analyzeImage.bind(service), 2, 1000);
37
+ server.tool('analyze_image', `General-purpose image analysis for scenarios not covered by specialized tools.
38
+
39
+ Use this tool as a FALLBACK when none of the other specialized tools (ui_to_artifact, extract_text_from_screenshot,
40
+ diagnose_error_screenshot, understand_technical_diagram, analyze_data_visualization, ui_diff_check) fit the user's need.
41
+
42
+ This tool provides flexible image understanding for any visual content.`, {
43
+ image_source: z.string().describe('Local file path or remote URL to the image'),
44
+ prompt: z.string().describe('Detailed description of what you want to analyze, extract, or understand from the image. Be specific about your requirements.')
45
+ }, async (params) => {
46
+ try {
47
+ const validationSchema = new ToolSchemaBuilder()
48
+ .required('image_source', CommonSchemas.nonEmptyString)
49
+ .required('prompt', CommonSchemas.nonEmptyString)
50
+ .build();
51
+ validationSchema.parse(params);
52
+ const result = await retryableAnalyze(params.image_source, params.prompt);
53
+ return formatMcpResponse(createSuccessResponse(result));
54
+ }
55
+ catch (error) {
56
+ console.error('General image analysis tool execution failed', {
57
+ error: error instanceof Error ? error.message : String(error),
58
+ params
59
+ });
60
+ let errorResponse;
61
+ if (error instanceof z.ZodError) {
62
+ const validationErrors = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
63
+ errorResponse = createErrorResponse(`Validation failed: ${validationErrors}`);
64
+ }
65
+ else if (error instanceof FileNotFoundError) {
66
+ errorResponse = createErrorResponse(`Image file not found: ${error.message}`);
67
+ }
68
+ else if (error instanceof ApiError) {
69
+ errorResponse = createErrorResponse(`API error: ${error.message}`);
70
+ }
71
+ else {
72
+ errorResponse = createErrorResponse(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
73
+ }
74
+ return formatMcpResponse(errorResponse);
75
+ }
76
+ });
77
+ console.info('General Image Analysis tool registered successfully');
78
+ }
@@ -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 { 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
+
46
+ Use this tool ONLY when the user has a screenshot containing text and wants to extract it.
47
+ This tool specializes in OCR for code, terminal output, documentation, and general text extraction.
48
+
49
+ Do NOT use for: UI design conversion, error diagnosis, or diagram understanding.`, {
50
+ image_source: z.string().describe('Local file path or remote URL to the image'),
51
+ prompt: z.string().describe('Instructions for text extraction. Specify what type of text to extract and any formatting requirements.'),
52
+ 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.')
53
+ }, async (params) => {
54
+ try {
55
+ const validationSchema = new ToolSchemaBuilder()
56
+ .required('image_source', CommonSchemas.nonEmptyString)
57
+ .required('prompt', CommonSchemas.nonEmptyString)
58
+ .optional('programming_language', z.string())
59
+ .build();
60
+ validationSchema.parse(params);
61
+ const result = await retryableExtract(params.image_source, params.prompt, params.programming_language);
62
+ return formatMcpResponse(createSuccessResponse(result));
63
+ }
64
+ catch (error) {
65
+ console.error('Text extraction 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('Text Extraction tool registered successfully');
87
+ }
@@ -0,0 +1,92 @@
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
+
51
+ Use this tool ONLY when the user wants to compare an expected/reference UI with an actual implementation.
52
+ This tool is specialized for UI quality assurance and design-to-implementation verification.
53
+
54
+ Do NOT use for: general image comparison, error diagnosis, or analyzing single UIs.`, {
55
+ expected_image_source: z.string().describe('Local file path or remote URL to the image'),
56
+ actual_image_source: z.string().describe('Local file path or remote URL to the image'),
57
+ prompt: z.string().describe('Instructions for the comparison. Specify what aspects to focus on or what level of detail is needed.')
58
+ }, async (params) => {
59
+ try {
60
+ const validationSchema = new ToolSchemaBuilder()
61
+ .required('expected_image_source', CommonSchemas.nonEmptyString)
62
+ .required('actual_image_source', CommonSchemas.nonEmptyString)
63
+ .required('prompt', CommonSchemas.nonEmptyString)
64
+ .build();
65
+ validationSchema.parse(params);
66
+ const result = await retryableCompare(params.expected_image_source, params.actual_image_source, params.prompt);
67
+ return formatMcpResponse(createSuccessResponse(result));
68
+ }
69
+ catch (error) {
70
+ console.error('UI diff check tool execution failed', {
71
+ error: error instanceof Error ? error.message : String(error),
72
+ params
73
+ });
74
+ let errorResponse;
75
+ if (error instanceof z.ZodError) {
76
+ const validationErrors = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
77
+ errorResponse = createErrorResponse(`Validation failed: ${validationErrors}`);
78
+ }
79
+ else if (error instanceof FileNotFoundError) {
80
+ errorResponse = createErrorResponse(`Image file not found: ${error.message}`);
81
+ }
82
+ else if (error instanceof ApiError) {
83
+ errorResponse = createErrorResponse(`API error: ${error.message}`);
84
+ }
85
+ else {
86
+ errorResponse = createErrorResponse(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
87
+ }
88
+ return formatMcpResponse(errorResponse);
89
+ }
90
+ });
91
+ console.info('UI Diff Check tool registered successfully');
92
+ }
@@ -0,0 +1,91 @@
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
+
47
+ Use this tool ONLY when the user wants to:
48
+ - Generate frontend code from UI design (output_type='code')
49
+ - Create AI prompts for UI generation (output_type='prompt')
50
+ - Extract design specifications (output_type='spec')
51
+ - Get natural language description of the UI (output_type='description')
52
+
53
+ Do NOT use for: screenshots containing text/code to extract, error messages, diagrams, or data visualizations.`, {
54
+ image_source: z.string().describe('Local file path or remote URL to the image'),
55
+ 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)."),
56
+ prompt: z.string().describe('Detailed instructions describing what to generate from this UI image. Should clearly state the desired output and any specific requirements.')
57
+ }, async (params) => {
58
+ try {
59
+ const validationSchema = new ToolSchemaBuilder()
60
+ .required('image_source', CommonSchemas.nonEmptyString)
61
+ .required('output_type', z.enum(['code', 'prompt', 'spec', 'description']))
62
+ .required('prompt', CommonSchemas.nonEmptyString)
63
+ .build();
64
+ validationSchema.parse(params);
65
+ const result = await retryableConvert(params.image_source, params.output_type, params.prompt);
66
+ return formatMcpResponse(createSuccessResponse(result));
67
+ }
68
+ catch (error) {
69
+ console.error('UI to artifact tool execution failed', {
70
+ error: error instanceof Error ? error.message : String(error),
71
+ params
72
+ });
73
+ let errorResponse;
74
+ if (error instanceof z.ZodError) {
75
+ const validationErrors = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
76
+ errorResponse = createErrorResponse(`Validation failed: ${validationErrors}`);
77
+ }
78
+ else if (error instanceof FileNotFoundError) {
79
+ errorResponse = createErrorResponse(`Image file not found: ${error.message}`);
80
+ }
81
+ else if (error instanceof ApiError) {
82
+ errorResponse = createErrorResponse(`API error: ${error.message}`);
83
+ }
84
+ else {
85
+ errorResponse = createErrorResponse(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
86
+ }
87
+ return formatMcpResponse(errorResponse);
88
+ }
89
+ });
90
+ console.info('UI to Artifact tool registered successfully');
91
+ }
@@ -78,7 +78,16 @@ export function registerVideoAnalysisTool(server) {
78
78
  const retryableAnalyze = withRetry(analysisService.analyzeVideo.bind(analysisService), 2, // Maximum 2 retries
79
79
  1000 // 1 second delay
80
80
  );
81
- server.tool('analyze_video', 'Analyze a video using advanced AI vision models with comprehensive understanding capabilities. Supports both local files and remote URL. Maximum local file size: 8MB', {
81
+ server.tool('analyze_video', `Analyze video content using advanced AI vision models.
82
+
83
+ Use this tool when the user wants to:
84
+ - Understand what happens in a video
85
+ - Extract key moments or actions from video
86
+ - Analyze video content, scenes, or sequences
87
+ - Get descriptions of video footage
88
+ - Identify objects, people, or activities in video
89
+
90
+ Supports both local files and remote URL. Maximum file size: 8MB. Supports MP4, MOV, M4V formats.`, {
82
91
  video_source: z.string().describe('Local file path or remote URL to the video (supports MP4, MOV, M4V)'),
83
92
  prompt: z.string().describe('Detailed text prompt describing what to analyze, extract, or understand from the video')
84
93
  }, async (params) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@z_ai/mcp-server",
3
- "version": "0.1.0",
3
+ "version": "0.1.1-beta.1",
4
4
  "description": "MCP Server for Z.AI - A Model Context Protocol server that provides AI capabilities",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
@@ -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
- }