UNPKG

mcp-baidu-curl

Version:

一个MCP服务,提供获取百度网站HTML内容的功能,支持Cursor、Claude Desktop、Cherry Studio等主流MCP客户端

165 lines (162 loc) 6.63 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 axios from 'axios'; /** * MCP服务演示 - 百度网站Curl功能 * 这个服务提供一个工具来获取百度网站的HTML内容 */ class BaiduCurlMCPServer { server; constructor() { this.server = new Server({ name: 'baidu-curl-demo', version: '1.0.0', }, { capabilities: { tools: {}, }, }); this.setupToolHandlers(); this.setupErrorHandling(); } setupToolHandlers() { // 注册工具列表处理器 this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'curl_baidu', description: '获取百度网站(www.baidu.com)的HTML内容', inputSchema: { type: 'object', properties: { timeout: { type: 'number', description: '请求超时时间(毫秒),默认为5000ms', default: 5000, }, userAgent: { type: 'string', description: '自定义User-Agent,默认使用标准浏览器UA', default: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', }, }, additionalProperties: false, }, }, ], }; }); // 注册工具调用处理器 this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (name === 'curl_baidu') { try { return await this.handleCurlBaidu(args || {}); } catch (error) { const errorMessage = error instanceof Error ? error.message : '未知错误'; return { content: [ { type: 'text', text: `❌ 请求失败: ${errorMessage}`, }, ], isError: true, }; } } throw new Error(`未知的工具: ${name}`); }); } async handleCurlBaidu(args) { const timeout = args?.timeout || 5000; const userAgent = args?.userAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'; console.error(`🌐 正在请求百度网站... (超时: ${timeout}ms)`); try { const response = await axios.get('https://www.baidu.com', { timeout, headers: { 'User-Agent': userAgent, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', }, maxRedirects: 5, }); const htmlContent = response.data; const statusCode = response.status; const headers = response.headers; console.error(`✅ 请求成功! 状态码: ${statusCode}, 内容长度: ${htmlContent.length} 字符`); // 限制HTML内容长度以避免JSON解析问题 const truncatedHtml = htmlContent.length > 2000 ? htmlContent.substring(0, 2000) + '\n... (内容已截断,完整内容长度: ' + htmlContent.length + ' 字符)' : htmlContent; return { content: [ { type: 'text', text: `🎉 百度网站请求成功! 📊 **响应信息:** - 状态码: ${statusCode} - 内容长度: ${htmlContent.length} 字符 - 内容类型: ${headers['content-type'] || '未知'} - 服务器: ${headers['server'] || '未知'} 📄 **HTML内容预览:** \`\`\`html ${truncatedHtml} \`\`\` 🔍 **主要响应头信息:** - content-type: ${headers['content-type'] || '未知'} - server: ${headers['server'] || '未知'} - content-length: ${headers['content-length'] || '未知'} - date: ${headers['date'] || '未知'}`, }, ], }; } catch (error) { if (axios.isAxiosError(error)) { const statusCode = error.response?.status; const statusText = error.response?.statusText; const errorMessage = error.message; throw new Error(`HTTP请求失败 - 状态码: ${statusCode || '无'}, 状态文本: ${statusText || '无'}, 错误: ${errorMessage}`); } throw error; } } setupErrorHandling() { this.server.onerror = (error) => { console.error('❌ MCP服务器错误:', error); }; process.on('SIGINT', async () => { console.error('🛑 收到SIGINT信号,正在关闭服务器...'); await this.server.close(); process.exit(0); }); process.on('SIGTERM', async () => { console.error('🛑 收到SIGTERM信号,正在关闭服务器...'); await this.server.close(); process.exit(0); }); } async run() { const transport = new StdioServerTransport(); console.error('🚀 百度Curl MCP服务器启动中...'); console.error('📡 监听stdio传输...'); await this.server.connect(transport); console.error('✅ MCP服务器已就绪!'); } } // 启动服务器 const server = new BaiduCurlMCPServer(); server.run().catch((error) => { console.error('💥 服务器启动失败:', error); process.exit(1); }); //# sourceMappingURL=index.js.map