UNPKG

qiuxinmcp-sms

Version:

MCP 协议手机验证码服务,支持发送验证码并返回标准格式。

324 lines (276 loc) 8.86 kB
#!/usr/bin/env node /** * MCP 手机验证码服务器 * 基于 Model Context Protocol (MCP) 协议的手机验证码服务 * 提供获取验证码的工具,可与 Claude、VSCode 等 MCP 客户端集成 */ 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 fetch from 'node-fetch'; /** * MCP 手机验证码服务器类 */ class MCPSmsServer { constructor() { console.error('[Setup] 初始化 MCP 手机验证码服务器...'); // 创建 MCP 服务器实例 this.server = new Server( { name: 'qiuxinmcp-sms', version: '1.0.2', }, { capabilities: { tools: {}, }, } ); // 配置工具处理器 this.setupToolHandlers(); // 错误处理 this.server.onerror = (error) => console.error('[错误]', error); // 优雅退出处理 process.on('SIGINT', async () => { await this.server.close(); process.exit(0); }); } /** * 设置工具处理器 * 定义 MCP 客户端可以调用的工具 */ setupToolHandlers() { // 注册可用工具列表 this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'get_verification_code', description: '获取手机验证码 - 输入手机号码获取验证码信息', inputSchema: { type: 'object', properties: { mobile: { type: 'string', description: '手机号码(11位数字,如:13800138000)', pattern: '^1[3-9]\\d{9}$' }, }, required: ['mobile'], }, }, ], })); // 处理工具调用请求 this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { // 验证工具名称 if (request.params.name !== 'get_verification_code') { throw new McpError( ErrorCode.MethodNotFound, `未知工具: ${request.params.name}` ); } // 获取请求参数 const args = request.params.arguments; // 验证必需参数 if (!args || !args.mobile) { throw new McpError( ErrorCode.InvalidParams, '缺少必需参数: mobile' ); } const mobile = args.mobile; // 验证手机号格式 const mobileRegex = /^1[3-9]\d{9}$/; if (!mobileRegex.test(mobile)) { throw new McpError( ErrorCode.InvalidParams, '手机号格式不正确,请输入有效的11位手机号码' ); } console.error(`[API] 正在为手机号 ${mobile} 获取验证码...`); // 调用验证码 API return await this.getVerificationCode(mobile); } catch (error) { console.error('[错误] 工具调用失败:', error); if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `获取验证码失败: ${error.message}` ); } }); } /** * 调用验证码 API * @param {string} mobile - 手机号码 * @returns {Promise<Object>} - MCP 工具调用结果 */ async getVerificationCode(mobile) { try { console.error(`[API] 正在调用验证码接口...`); // 构建请求 URL const url = new URL('https://xydapi.qiuxin.tech/v1_mcp/check'); url.searchParams.append('mobile', mobile); // 发送 HTTP 请求 const response = await fetch(url.toString(), { method: 'GET', headers: { 'Accept': 'application/json', 'User-Agent': 'MCP-SMS-Server/1.0.0' }, timeout: 10000 // 10秒超时 }); // 检查 HTTP 响应状态 if (!response.ok) { throw new Error(`HTTP 错误: ${response.status} ${response.statusText}`); } // 解析 JSON 响应 const data = await response.json(); console.error(`[API] 接口响应:`, JSON.stringify(data, null, 2)); // 检查业务状态码 if (data.code !== 200) { throw new Error(`API 错误: ${data.msg || '未知错误'}`); } // 提取验证码相关数据 const contractData = data.data?.contract_data; if (!contractData) { throw new Error('API 响应中缺少验证码数据'); } // 构建成功响应 const result = { success: true, mobile: mobile, contract_data: contractData, message: data.msg || '操作成功', timestamp: new Date().toISOString() }; console.error(`[API] 验证码获取成功`); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { console.error(`[API] 验证码获取失败:`, error.message); // 构建错误响应 const errorResult = { success: false, mobile: mobile, error: error.message, timestamp: new Date().toISOString() }; return { content: [ { type: 'text', text: JSON.stringify(errorResult, null, 2), }, ], isError: true, }; } } /** * 启动 MCP 服务器 */ async run() { try { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('MCP 手机验证码服务器已启动,使用 stdio 传输'); } catch (error) { console.error('服务器启动失败:', error); process.exit(1); } } } /** * 生成请求 ID * @returns {string} - 唯一请求标识符 */ function generateRequestId() { return Date.now().toString(36) + Math.random().toString(36).substr(2); } /** * 主入口函数 * 检测是否作为 MCP 服务器运行或命令行工具运行 */ async function main() { const args = process.argv.slice(2); // 如果没有参数或者第一个参数不是命令,则作为 MCP 服务器运行 if (args.length === 0 || !['send', '--help', '-h'].includes(args[0])) { console.error('[启动] 作为 MCP 服务器启动...'); const server = new MCPSmsServer(); await server.run(); return; } // 命令行模式的帮助信息 const helpText = ` MCP-SMS - 手机验证码工具 用法: mcp-sms 作为 MCP 服务器运行 mcp-sms send <手机号> 发送验证码到指定手机号 mcp-sms --help 显示帮助信息 示例: mcp-sms send 13800138000 mcp-sms --help MCP 服务器模式: 当不提供参数或参数不是有效命令时,程序将以 MCP 服务器模式运行, 可与 Claude Desktop、VSCode 等 MCP 客户端集成使用。 `; // 处理帮助命令 if (args[0] === '--help' || args[0] === '-h') { console.log(helpText); return; } // 处理发送验证码命令 if (args[0] === 'send' && args[1]) { const mobile = args[1]; // 验证手机号格式 const mobileRegex = /^1[3-9]\d{9}$/; if (!mobileRegex.test(mobile)) { console.error('错误: 手机号格式不正确'); process.exit(1); } console.log(`正在为手机号 ${mobile} 获取验证码...`); try { // 创建临时服务器实例进行 API 调用 const server = new MCPSmsServer(); const result = await server.getVerificationCode(mobile); // 解析结果 const resultData = JSON.parse(result.content[0].text); if (resultData.success) { console.log(`获取成功:`); console.log(`验证码信息: ${resultData.contract_data}`); console.log(`时间: ${resultData.timestamp}`); } else { console.error(`获取失败: ${resultData.error}`); process.exit(1); } } catch (error) { console.error(`获取失败: ${error.message}`); process.exit(1); } } else { console.log('参数错误,请查看帮助信息:'); console.log(helpText); process.exit(1); } } // 程序入口 main().catch(error => { console.error('程序运行出错:', error); process.exit(1); });