mcp-baidu-curl
Version:
一个MCP服务,提供获取百度网站HTML内容的功能,支持Cursor、Claude Desktop、Cherry Studio等主流MCP客户端
165 lines (162 loc) • 6.63 kB
JavaScript
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