#!/usr/bin/env node const path = require('path'); const { Client } = require('@modelcontextprotocol/sdk/client/index.js'); const { StdioClientTransport } = require('@modelcontextprotocol/sdk/client/stdio.js'); async function main() { const serverPath = path.resolve(__dirname, '..', 'mcp', 'src', 'server.js'); const client = new Client({ name: 'tihao-smoke-client', version: '0.1.0' }); const transport = new StdioClientTransport({ command: process.execPath, args: [serverPath] }); await client.connect(transport); try { const tools = await client.listTools(); const names = tools.tools.map(tool => tool.name).sort(); for (const required of ['fmode_image_analysis', 'tihao_brief_sourcing_run', 'tihao_preference_update', 'tihao_token_check']) { if (!names.includes(required)) throw new Error(`Missing MCP tool: ${required}`); } const tokenCheck = await client.callTool({ name: 'tihao_token_check', arguments: {} }); if (!tokenCheck.structuredContent || !['ok', 'needs_token'].includes(tokenCheck.structuredContent.status)) { throw new Error('token check returned unexpected structured content'); } const imageNoToken = await client.callTool({ name: 'fmode_image_analysis', arguments: { images: ['data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII='], prompt: '识别这张测试图片', allowEnvToken: false } }); if (!imageNoToken.structuredContent || imageNoToken.structuredContent.status !== 'needs_token') { throw new Error('image analysis no-token path returned unexpected structured content'); } if (Array.isArray(imageNoToken.structuredContent.errors) && imageNoToken.structuredContent.errors.length !== 0) { throw new Error('image analysis no-token path should keep errors empty'); } const sample = await client.callTool({ name: 'tihao_brief_sourcing_run', arguments: { collectionMode: 'sample', briefText: '客户名称:花漾肌研\n小红书 2人\n粉丝量范围:2万-30万\n预算范围:¥3000-¥18000\n偏好真实体验和敏感肌修护', output: path.join(process.env.TEMP || process.cwd(), `tihao-mcp-smoke-${Date.now()}`) } }); if (sample.structuredContent?.status !== 'ok') throw new Error('sample MCP tool did not return ok'); if (!sample.structuredContent.assistantMessage.includes('商务可用名单')) { throw new Error('sample MCP tool did not return business-ready report body'); } } finally { await client.close(); } console.log('tihao mcp protocol smoke ok'); } main().catch(error => { console.error(error && error.stack ? error.stack : String(error)); process.exit(1); });