test-client.js•6.59 kB
#!/usr/bin/env node
/**
* MCP 抽签工具测试客户端
* 这个文件演示了如何与 MCP 服务器进行交互
*/
import { spawn } from 'child_process';
import { createInterface } from 'readline';
// 启动 MCP 服务器进程
const serverProcess = spawn('node', ['src/server.js'], {
stdio: ['pipe', 'pipe', 'inherit']
});
// 创建读写接口
const rl = createInterface({
input: process.stdin,
output: process.stdout
});
// 发送 MCP 请求的辅助函数
function sendRequest(request) {
return new Promise((resolve, reject) => {
let responseData = '';
const timeout = setTimeout(() => {
reject(new Error('请求超时'));
}, 5000);
serverProcess.stdout.once('data', (data) => {
clearTimeout(timeout);
responseData += data.toString();
try {
const response = JSON.parse(responseData);
resolve(response);
} catch (error) {
reject(new Error('解析响应失败: ' + error.message));
}
});
serverProcess.stdin.write(JSON.stringify(request) + '\n');
});
}
// 测试用例
async function runTests() {
console.log('🧪 开始测试 MCP 抽签工具...\n');
try {
// 测试1: 列出可用工具
console.log('📋 测试1: 列出可用工具');
const toolsResponse = await sendRequest({
jsonrpc: '2.0',
id: 1,
method: 'tools/list'
});
console.log('可用工具:', toolsResponse.result.tools.map(t => t.name).join(', '));
console.log('✅ 测试1 通过\n');
// 测试2: 简单抽签
console.log('🎲 测试2: 简单抽签');
const lotteryResponse = await sendRequest({
jsonrpc: '2.0',
id: 2,
method: 'tools/call',
params: {
name: 'draw_lottery',
arguments: {
options: ['苹果', '香蕉', '橙子', '葡萄', '草莓']
}
}
});
console.log('抽签结果:', lotteryResponse.result.content[0].text);
console.log('✅ 测试2 通过\n');
// 测试3: 多选抽签
console.log('🎯 测试3: 多选抽签');
const multiLotteryResponse = await sendRequest({
jsonrpc: '2.0',
id: 3,
method: 'tools/call',
params: {
name: 'draw_lottery',
arguments: {
options: ['一等奖', '二等奖', '三等奖', '四等奖', '五等奖'],
count: 3,
allow_duplicate: false
}
}
});
console.log('多选结果:', multiLotteryResponse.result.content[0].text);
console.log('✅ 测试3 通过\n');
// 测试4: 投骰子
console.log('🎲 测试4: 投骰子');
const diceResponse = await sendRequest({
jsonrpc: '2.0',
id: 4,
method: 'tools/call',
params: {
name: 'roll_dice',
arguments: {
sides: 20,
count: 3
}
}
});
console.log('骰子结果:', diceResponse.result.content[0].text);
console.log('✅ 测试4 通过\n');
// 测试5: 抛硬币
console.log('🪙 测试5: 抛硬币');
const coinResponse = await sendRequest({
jsonrpc: '2.0',
id: 5,
method: 'tools/call',
params: {
name: 'flip_coin',
arguments: {
count: 5
}
}
});
console.log('硬币结果:', coinResponse.result.content[0].text);
console.log('✅ 测试5 通过\n');
// 测试6: 错误处理
console.log('❌ 测试6: 错误处理');
const errorResponse = await sendRequest({
jsonrpc: '2.0',
id: 6,
method: 'tools/call',
params: {
name: 'draw_lottery',
arguments: {
options: []
}
}
});
console.log('错误处理:', errorResponse.result.content[0].text);
console.log('✅ 测试6 通过\n');
console.log('🎉 所有测试通过!');
} catch (error) {
console.error('❌ 测试失败:', error.message);
} finally {
serverProcess.kill();
rl.close();
}
}
// 交互式测试模式
async function interactiveMode() {
console.log('🎮 进入交互式测试模式');
console.log('输入 "test" 运行自动测试,输入 "quit" 退出\n');
rl.on('line', async (input) => {
const command = input.trim();
if (command === 'quit') {
console.log('👋 再见!');
serverProcess.kill();
rl.close();
return;
}
if (command === 'test') {
await runTests();
return;
}
if (command.startsWith('lottery ')) {
const options = command.substring(8).split(',').map(s => s.trim());
try {
const response = await sendRequest({
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: {
name: 'draw_lottery',
arguments: { options }
}
});
console.log('结果:', response.result.content[0].text);
} catch (error) {
console.error('错误:', error.message);
}
return;
}
if (command.startsWith('dice ')) {
const [sides, count] = command.substring(5).split(' ').map(Number);
try {
const response = await sendRequest({
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: {
name: 'roll_dice',
arguments: { sides: sides || 6, count: count || 1 }
}
});
console.log('结果:', response.result.content[0].text);
} catch (error) {
console.error('错误:', error.message);
}
return;
}
if (command.startsWith('coin ')) {
const count = parseInt(command.substring(5)) || 1;
try {
const response = await sendRequest({
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: {
name: 'flip_coin',
arguments: { count }
}
});
console.log('结果:', response.result.content[0].text);
} catch (error) {
console.error('错误:', error.message);
}
return;
}
console.log('可用命令:');
console.log(' test - 运行自动测试');
console.log(' lottery 选项1,选项2,选项3 - 抽签');
console.log(' dice 面数 数量 - 投骰子');
console.log(' coin 次数 - 抛硬币');
console.log(' quit - 退出');
});
}
// 主程序
async function main() {
const args = process.argv.slice(2);
if (args.includes('--test')) {
await runTests();
} else {
await interactiveMode();
}
}
main().catch(console.error);