UNPKG

@mcpcn/image-understanding-mcp

Version:

智谱GLM-4V-Plus-0111 图片内容理解MCP工具

178 lines 6.83 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { ImageUnderstandingTool } from './tools/image-recognition.js'; import { DEFAULT_VISION_MODEL, SUPPORTED_VISION_MODELS } from './config.js'; // 从环境变量获取API密钥 const API_KEY = process.env.ZHIPU_API_KEY; if (!API_KEY) { console.error('错误:未找到API密钥。请设置环境变量 GLM_API_KEY 或 ZHIPU_API_KEY'); process.exit(1); } // 创建图片理解工具实例 const imageUnderstanding = new ImageUnderstandingTool(API_KEY); // 创建MCP服务器 const server = new Server({ name: 'image-understanding-mcp', version: '1.0.0', }, { capabilities: { tools: {}, }, }); // 注册工具列表处理器 server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'analyze_image', description: `使用智谱视觉模型(默认:${DEFAULT_VISION_MODEL})分析图片内容,支持通过URL上传图片`, inputSchema: { type: 'object', properties: { imageUrl: { type: 'string', description: '图片的URL地址(支持HTTP/HTTPS链接和base64编码)', }, prompt: { type: 'string', description: '对图片分析的具体要求或问题(可选,默认为通用描述)', default: '请详细描述这张图片的内容', }, model: { type: 'string', enum: SUPPORTED_VISION_MODELS, description: `使用的模型版本(默认:${DEFAULT_VISION_MODEL},可通过环境变量GLM_VISION_MODEL覆盖)`, default: DEFAULT_VISION_MODEL, }, temperature: { type: 'number', minimum: 0, maximum: 1, description: '生成文本的随机性控制(0-1,可选,默认0.7)', default: 0.7, }, maxTokens: { type: 'number', minimum: 1, maximum: 4096, description: '最大输出token数量(可选,默认1024)', default: 1024, }, }, required: ['imageUrl'], }, }, ], }; }); // 注册工具调用处理器 server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case 'analyze_image': { // 校验并收窄参数类型 const params = (args ?? {}); if (!('imageUrl' in (args ?? {}))) { throw new Error('imageUrl参数是必需的'); } if (!params.imageUrl) { throw new Error('imageUrl参数是必需的'); } const result = await imageUnderstanding.analyzeImage(params); if (result.success) { return { content: [ { type: 'text', text: JSON.stringify({ success: true, analysis: result.analysis, model: result.model, tokenUsage: result.tokenUsage, }, null, 2), }, ], }; } else { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: result.error, model: result.model, }, null, 2), }, ], isError: true, }; } } default: throw new Error(`未知的工具: ${name}`); } } catch (error) { const errorMessage = error instanceof Error ? error.message : '未知错误'; return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: errorMessage, }, null, 2), }, ], isError: true, }; } }); // 启动服务器 async function main() { console.error(`智谱图片内容理解MCP服务器启动中(默认模型:${DEFAULT_VISION_MODEL})...`); // 验证API密钥 try { const isValid = await imageUnderstanding.validateApiKey(); if (!isValid) { console.error('警告:API密钥验证失败,请检查您的GLM_API_KEY或ZHIPU_API_KEY环境变量'); } else { console.error('API密钥验证成功'); } } catch (error) { console.error('API密钥验证时出现错误,但服务器将继续启动'); } const transport = new StdioServerTransport(); await server.connect(transport); console.error('服务器已启动,等待连接...'); } // 处理未捕获的异常 process.on('uncaughtException', (error) => { console.error('未捕获的异常:', error); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', reason); process.exit(1); }); // 优雅关闭 process.on('SIGINT', () => { console.error('接收到SIGINT信号,正在关闭服务器...'); process.exit(0); }); process.on('SIGTERM', () => { console.error('接收到SIGTERM信号,正在关闭服务器...'); process.exit(0); }); main().catch((error) => { console.error('服务器启动失败:', error); process.exit(1); }); //# sourceMappingURL=index.js.map