Skip to main content
Glama
web-service.ts3.51 kB
import axios from 'axios'; import * as cheerio from 'cheerio'; export interface WebPage { url: string; title: string; content: string; text: string; links: string[]; } export class WebService { private allowedHosts: string[]; private userAgent: string; constructor() { this.allowedHosts = (process.env.WEB_ALLOWED_HOSTS || 'example.com,developer.mozilla.org') .split(',') .map(host => host.trim()); this.userAgent = 'AI-Ops-Hub/1.0 (MCP Server)'; } async fetchPage(url: string): Promise<WebPage> { try { console.log(`🌐 Получение страницы: ${url}`); // Проверяем разрешенные хосты this.validateUrl(url); // Получаем страницу const response = await axios.get(url, { headers: { 'User-Agent': this.userAgent, }, timeout: 10000, // 10 секунд таймаут }); // Парсим HTML const $ = cheerio.load(response.data); // Извлекаем основную информацию const title = $('title').first().text().trim() || 'Без заголовка'; // Убираем скрипты, стили и другие ненужные элементы $('script, style, noscript, iframe, img, svg').remove(); // Получаем чистый текст const text = $('body').text() .replace(/\s+/g, ' ') .trim(); // Получаем ссылки const links = $('a[href]') .map((_, el) => $(el).attr('href')) .get() .filter(href => href && href.startsWith('http')) .slice(0, 20); // Ограничиваем количество ссылок const page: WebPage = { url, title, content: response.data, text: text.substring(0, 5000), // Ограничиваем размер текста links, }; console.log(`✅ Страница получена: ${title} (${text.length} символов, ${links.length} ссылок)`); return page; } catch (error) { console.error('Ошибка получения страницы:', error); throw new Error(`Ошибка получения страницы: ${error}`); } } private validateUrl(url: string): void { try { const urlObj = new URL(url); const host = urlObj.hostname.toLowerCase(); // Проверяем, что хост разрешен const isAllowed = this.allowedHosts.some(allowedHost => host === allowedHost || host.endsWith('.' + allowedHost) ); if (!isAllowed) { throw new Error(`Хост ${host} не разрешен. Разрешенные хосты: ${this.allowedHosts.join(', ')}`); } // Проверяем протокол if (urlObj.protocol !== 'http:' && urlObj.protocol !== 'https:') { throw new Error('Поддерживаются только HTTP и HTTPS протоколы'); } } catch (error) { if (error instanceof Error) { throw error; } throw new Error('Некорректный URL'); } } async isUrlAllowed(url: string): Promise<boolean> { try { this.validateUrl(url); return true; } catch { return false; } } getAllowedHosts(): string[] { return [...this.allowedHosts]; } }

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Galiusbro/MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server