@chenlei28188/image-processor-mcp
Version:
MCP Server for intelligent image processing and analysis
377 lines • 18.8 kB
JavaScript
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
// 导入功能模块
import { ImageAnalyzer } from './services/ImageAnalyzer.js'; // 图片分析服务
import { ImageCompressor } from './services/ImageCompressor.js'; // 图片压缩服务
import { FormatConverter } from './services/FormatConverter.js'; // 格式转换服务
import { ColorExtractor } from './services/ColorExtractor.js'; // 颜色提取服务
import { BatchProcessor } from './services/BatchProcessor.js'; // 批量处理服务
// 导入工具类
import { OutputFormatter } from './utils/OutputFormatter.js'; // 输出格式化工具
import { Logger } from './utils/Logger.js'; // 简易日志工具
/**
* @class ImageProcessorMCPServer
* @description 这是整个图片处理工具的入口点。
* 它遵循模型上下文协议(MCP),将复杂的图片处理功能封装成一系列可供AI调用的标准化工具。
* 主要职责包括:
* 1. 初始化并启动一个MCP服务器。
* 2. 实例化并管理项目的所有核心模块(分析、压缩、转换、颜色提取、批量处理)。
* 3. 定义AI可以使用的工具集(如`analyze_image`, `compress_image`等),并提供清晰的描述和输入规范。
* 4. 接收并解析AI的工具调用请求,将其路由到相应的内部处理逻辑。
* 5. 协调各个模块,完成从图片加载、处理、格式化到返回结果的完整工作流。
*/
class ImageProcessorMCPServer {
server; // MCP服务器实例
// 各种图片处理服务实例
imageAnalyzer; // 图片分析服务
imageCompressor; // 图片压缩服务
formatConverter; // 格式转换服务(JPG/PNG/WebP等互转)
colorExtractor; // 颜色提取服务
batchProcessor; // 批量处理服务(并发控制、进度跟踪)
// 工具类实例
outputFormatter; // 输出格式化工具(JSON/Markdown/HTML/CSS)
logger; // 日志记录工具
/**
* 构造函数:初始化MCP服务器和所有依赖组件
*/
constructor() {
// 1.创建MCP服务器实例,配置服务器基本信息
this.server = new Server({
name: 'image-processor-mcp', // 服务器名称,用于MCP协议识别
version: '1.0.0', // 版本号
capabilities: {
tools: {}, // 声明支持工具调用功能
},
});
// 2.实例化核心模块
//初始化日志工具(所有服务都需要日志记录)
this.logger = new Logger();
// 初始化各个图片处理服务,都注入logger实例用于统一日志管理
this.imageAnalyzer = new ImageAnalyzer(this.logger);
this.imageCompressor = new ImageCompressor(this.logger);
this.formatConverter = new FormatConverter(this.logger);
this.colorExtractor = new ColorExtractor(this.logger);
this.batchProcessor = new BatchProcessor(this.logger);
// 初始化输出格式化工具(不需要logger)
this.outputFormatter = new OutputFormatter();
// 设置MCP协议的请求处理器
this.setupToolHandlers();
}
/**
* 设置MCP协议的请求处理器
* 这是MCP服务器的核心,定义了AI模型可以调用的所有工具
*/
setupToolHandlers() {
// 设置工具列表请求处理器
// 当AI模型询问"有哪些工具可用"时,会调用这个处理器
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
// 工具1:智能图片分析
{
name: 'analyze_image',
description: '智能分析图片:获取尺寸、格式、颜色分析、OCR文字识别等详细信息',
inputSchema: {
type: 'object',
properties: {
source: {
type: 'string',
description: '图片来源:URL链接或base64数据或本地文件路径'
},
options: {
type: 'object',
properties: {
includeOCR: { type: 'boolean', description: '是否进行OCR文字识别', default: true },
includeColors: { type: 'boolean', description: '是否分析颜色信息', default: true },
ocrLanguage: { type: 'string', description: 'OCR识别语言', default: 'chi_sim+eng' },
outputFormat: { type: 'string', enum: ['json', 'markdown', 'html'], default: 'json' }
}
}
},
required: ['source'] // 必需参数:图片来源
}
},
//工具2:图片压缩优化
{
name: 'compress_image',
description: '图片压缩优化:支持多种压缩算法和质量选项',
inputSchema: {
type: 'object',
properties: {
source: {
type: 'string',
description: '图片来源:URL链接或base64数据或本地文件路径'
},
options: {
type: 'object',
properties: {
quality: { type: 'number', minimum: 1, maximum: 100, description: '压缩质量(1-100)', default: 80 },
algorithm: { type: 'string', enum: ['mozjpeg', 'webp', 'avif'], description: '压缩算法', default: 'mozjpeg' },
maxWidth: { type: 'number', description: '最大宽度限制' },
maxHeight: { type: 'number', description: '最大高度限制' },
outputFormat: { type: 'string', enum: ['base64', 'buffer', 'file'], default: 'base64' },
outputPath: { type: 'string', description: '指定保存的完整文件路径(仅当outputFormat为file时有效)' },
outputDir: { type: 'string', description: '指定保存目录(如果不指定outputPath)', default: './output' }
}
}
},
required: ['source']
}
},
//工具3:格式转换
{
name: 'convert_format',
description: '格式转换:支持JPG/PNG/WebP/AVIF等格式互转',
inputSchema: {
type: 'object',
properties: {
source: {
type: 'string',
description: '图片来源:URL链接或base64数据或本地文件路径'
},
targetFormat: {
type: 'string',
enum: ['jpg', 'jpeg', 'png', 'webp', 'avif', 'gif', 'bmp'],
description: '目标格式'
},
options: {
type: 'object',
properties: {
quality: { type: 'number', minimum: 1, maximum: 100, description: '输出质量', default: 90 },
progressive: { type: 'boolean', description: '是否使用渐进式编码', default: false },
outputFormat: { type: 'string', enum: ['base64', 'buffer', 'file'], default: 'base64' },
outputPath: { type: 'string', description: '指定保存的完整文件路径(仅当outputFormat为file时有效)' },
outputDir: { type: 'string', description: '指定保存目录(如果不指定outputPath)', default: './output' }
}
}
},
required: ['source', 'targetFormat']
}
},
//工具4:颜色提取
{
name: 'extract_colors',
description: '提取图片主色调和配色方案',
inputSchema: {
type: 'object',
properties: {
source: {
type: 'string',
description: '图片来源:URL链接或base64数据或本地文件路径'
},
options: {
type: 'object',
properties: {
colorCount: { type: 'number', minimum: 1, maximum: 20, description: '提取颜色数量', default: 5 },
algorithm: { type: 'string', enum: ['vibrant', 'thief'], description: '颜色提取算法', default: 'vibrant' },
includeHex: { type: 'boolean', description: '包含HEX颜色值', default: true },
includeRgb: { type: 'boolean', description: '包含RGB颜色值', default: true },
includeHsl: { type: 'boolean', description: '包含HSL颜色值', default: false },
outputFormat: { type: 'string', enum: ['json', 'css', 'html'], default: 'json' }
}
}
},
required: ['source']
}
},
//工具5:批量处理
{
name: 'batch_process',
description: '批量图片处理:支持多张图片的批量操作',
inputSchema: {
type: 'object',
properties: {
sources: {
type: 'array',
items: { type: 'string' },
description: '图片来源列表:URL链接或base64数据或本地文件路径'
},
operation: {
type: 'string',
enum: ['analyze', 'compress', 'convert', 'extract_colors'],
description: '批量操作类型'
},
options: {
type: 'object',
description: '操作选项,根据operation类型而定'
},
concurrency: {
type: 'number',
minimum: 1,
maximum: 10,
description: '并发处理数量',
default: 3
}
},
required: ['sources', 'operation']
}
}
]
}));
// 注册 "CallTool" 请求的处理器。当AI决定调用上述某个工具时,请求会进入这里。
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
// 从请求中提取工具名称和参数
const { name, arguments: args } = request.params;
try {
// 使用 switch 语句将请求分发到对应的处理方法
switch (name) {
case 'analyze_image':
return await this.handleAnalyzeImage(args);
case 'compress_image':
return await this.handleCompressImage(args);
case 'convert_format':
return await this.handleConvertFormat(args);
case 'extract_colors':
return await this.handleExtractColors(args);
case 'batch_process':
return await this.handleBatchProcess(args);
default:
throw new McpError(ErrorCode.MethodNotFound, `未知或不支持的工具: ${name}`);
}
}
catch (error) {
// 捕获所有处理过程中可能发生的错误,并以标准的错误格式返回给AI
this.logger.error(`处理工具 [${name}] 时发生错误:`, error);
throw new McpError(ErrorCode.InternalError, `工具执行失败: ${error instanceof Error ? error.message : String(error)}`);
}
});
}
/**
* @private
* @method handleAnalyzeImage
* @description 处理图片分析请求的完整业务逻辑。
* 包括OCR文字识别、颜色分析、元数据提取等功能。
* @param args - 工具调用时传入的参数
*/
async handleAnalyzeImage(args) {
const { source, options = {} } = args;
// 1. 执行图片分析(调用ImageAnalyzer服务)
const result = await this.imageAnalyzer.analyze(source, options);
// 2. 根据用户指定的格式进行输出格式化
const outputFormat = options.outputFormat || 'json';
const formattedResult = this.outputFormatter.format(result, outputFormat);
// 3. 返回符合MCP协议的响应格式
return {
content: [
{
type: 'text',
text: formattedResult
}
]
};
}
/**
* @private
* @method handleCompressImage
* @description 处理图片压缩请求的完整业务逻辑。
* 支持多种压缩算法和质量控制。
* @param args - 工具调用时传入的参数
*/
async handleCompressImage(args) {
const { source, options = {} } = args;
// 1. 执行图片压缩(调用ImageCompressor服务)
const result = await this.imageCompressor.compress(source, options);
// 2. 返回压缩结果(包含原始大小、压缩后大小、压缩比等信息)
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
}
/**
* @private
* @method handleConvertFormat
* @description 处理图片格式转换请求的完整业务逻辑。
* 支持主流图片格式之间的互转。
* @param args - 工具调用时传入的参数
*/
async handleConvertFormat(args) {
const { source, targetFormat, options = {} } = args;
// 1. 执行格式转换(调用FormatConverter服务)
const result = await this.formatConverter.convert(source, targetFormat, options);
// 2. 返回转换结果
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
}
/**
* @private
* @method handleExtractColors
* @description 处理颜色提取请求的完整业务逻辑。
* 可提取主色调、调色板等颜色信息。
* @param args - 工具调用时传入的参数
*/
async handleExtractColors(args) {
const { source, options = {} } = args;
// 1. 执行颜色提取(调用ColorExtractor服务)
const result = await this.colorExtractor.extract(source, options);
// 2. 根据用户指定的格式进行输出格式化
const outputFormat = options.outputFormat || 'json';
const formattedResult = this.outputFormatter.format(result, outputFormat);
// 3. 返回格式化后的颜色信息
return {
content: [
{
type: 'text',
text: formattedResult
}
]
};
}
/**
* @private
* @method handleBatchProcess
* @description 处理批量处理请求,使用高效的异步并发模式处理多张图片。
* 支持所有单个操作的批量版本。
* @param args - 工具调用时传入的参数
*/
async handleBatchProcess(args) {
const { sources, operation, options = {}, concurrency = 3 } = args;
// 1. 执行批量处理(内部会使用Promise.allSettled进行并发控制)
const result = await this.batchProcessor.process(sources, operation, options, concurrency);
// 2. 返回批量处理结果(包含成功/失败统计和详细结果)
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
}
/**
* @public
* @method run
* @description 启动MCP服务器,开始监听来自AI的请求。
* 使用标准输入/输出作为通信通道。
*/
async run() {
// 使用标准输入/输出作为通信通道,这是MCP协议的标准传输方式
const transport = new StdioServerTransport();
// 连接服务器到传输层,开始监听请求
await this.server.connect(transport);
// 在标准错误流中打印日志,避免污染标准输出流的数据通道
this.logger.info('图片处理 MCP 服务器已成功启动并准备就绪');
}
}
// ==================== 服务器启动入口 ====================
/**
* 创建并启动图片处理MCP服务器实例
* 这是整个应用程序的入口点
*/
const server = new ImageProcessorMCPServer();
// 启动服务器,如果启动失败则退出进程
server.run().catch((error) => {
console.error('服务器启动失败:', error);
process.exit(1); // 以错误状态码退出
});
//# sourceMappingURL=index.js.map