Skip to main content
Glama
reviewwebsite.tool.ts20.9 kB
/** * @file reviewwebsite.tool.ts * @description Tool definitions for the ReviewWeb.site API */ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { Logger } from '../utils/logger.util.js'; import { formatErrorForMcpTool } from '../utils/error.util.js'; import reviewWebsiteController from '../controllers/reviewwebsite.controller.js'; import { ConvertToMarkdownToolArgs, ConvertToMarkdownToolArgsType, ConvertMultipleToMarkdownToolArgs, ConvertMultipleToMarkdownToolArgsType, ExtractDataToolArgs, ExtractDataToolArgsType, ExtractDataMultipleToolArgs, ExtractDataMultipleToolArgsType, ScrapeUrlToolArgs, ScrapeUrlToolArgsType, ExtractLinksToolArgs, ExtractLinksToolArgsType, SummarizeUrlToolArgs, SummarizeUrlToolArgsType, SummarizeWebsiteToolArgs, SummarizeWebsiteToolArgsType, SummarizeMultipleUrlsToolArgs, SummarizeMultipleUrlsToolArgsType, UrlIsAliveToolArgs, UrlIsAliveToolArgsType, UrlGetUrlAfterRedirectsToolArgs, UrlGetUrlAfterRedirectsToolArgsType, SeoKeywordIdeasToolArgs, SeoKeywordIdeasToolArgsType, SeoKeywordDifficultyToolArgs, SeoKeywordDifficultyToolArgsType, SeoTrafficToolArgs, SeoTrafficToolArgsType, SeoBacklinksToolArgs, SeoBacklinksToolArgsType, } from './reviewwebsite.types.js'; /** * @function handleConvertToMarkdown * @description MCP Tool handler to convert a URL to Markdown using AI * @param {ConvertToMarkdownToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleConvertToMarkdown(args: ConvertToMarkdownToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleConvertToMarkdown', ); methodLogger.debug(`Converting URL to Markdown with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.convertToMarkdown( args.url, { model: args.model, delayAfterLoad: args.delayAfterLoad, debug: args.debug, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error converting URL to Markdown`, error); return formatErrorForMcpTool(error); } } /** * @function handleConvertMultipleToMarkdown * @description MCP Tool handler to convert multiple URLs to Markdown using AI * @param {ConvertMultipleToMarkdownToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleConvertMultipleToMarkdown( args: ConvertMultipleToMarkdownToolArgsType, ) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleConvertMultipleToMarkdown', ); methodLogger.debug(`Converting multiple URLs to Markdown with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.convertMultipleToMarkdown( args.urls, { model: args.model, delayAfterLoad: args.delayAfterLoad, debug: args.debug, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error converting multiple URLs to Markdown`, error); return formatErrorForMcpTool(error); } } /** * @function handleExtractData * @description MCP Tool handler to extract structured data from a URL using AI * @param {ExtractDataToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleExtractData(args: ExtractDataToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleExtractData', ); methodLogger.debug(`Extracting data from URL with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.extractData( args.url, { instructions: args.instructions, systemPrompt: args.systemPrompt, jsonTemplate: args.jsonTemplate, model: args.model, delayAfterLoad: args.delayAfterLoad, recursive: args.recursive, debug: args.debug, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error extracting data from URL`, error); return formatErrorForMcpTool(error); } } /** * @function handleExtractDataMultiple * @description MCP Tool handler to extract structured data from multiple URLs using AI * @param {ExtractDataMultipleToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleExtractDataMultiple( args: ExtractDataMultipleToolArgsType, ) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleExtractDataMultiple', ); methodLogger.debug(`Extracting data from multiple URLs with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.extractDataMultiple( args.urls, { instructions: args.instructions, systemPrompt: args.systemPrompt, jsonTemplate: args.jsonTemplate, model: args.model, delayAfterLoad: args.delayAfterLoad, debug: args.debug, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error extracting data from multiple URLs`, error); return formatErrorForMcpTool(error); } } /** * @function handleScrapeUrl * @description MCP Tool handler to scrape a URL * @param {ScrapeUrlToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleScrapeUrl(args: ScrapeUrlToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleScrapeUrl', ); methodLogger.debug(`Scraping URL with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.scrapeUrl( args.url, args.delayAfterLoad, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error scraping URL`, error); return formatErrorForMcpTool(error); } } /** * @function handleExtractLinks * @description MCP Tool handler to extract links from a URL * @param {ExtractLinksToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleExtractLinks(args: ExtractLinksToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleExtractLinks', ); methodLogger.debug(`Extracting links from URL with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.extractLinks( args.url, { type: args.type, maxLinks: args.maxLinks, delayAfterLoad: args.delayAfterLoad, getStatusCode: args.getStatusCode, autoScrapeInternalLinks: args.autoScrapeInternalLinks, debug: args.debug, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error extracting links from URL`, error); return formatErrorForMcpTool(error); } } /** * @function handleSummarizeUrl * @description MCP Tool handler to summarize a URL using AI * @param {SummarizeUrlToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleSummarizeUrl(args: SummarizeUrlToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleSummarizeUrl', ); methodLogger.debug(`Summarizing URL with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.summarizeUrl( args.url, { instructions: args.instructions, systemPrompt: args.systemPrompt, model: args.model, delayAfterLoad: args.delayAfterLoad, maxLength: args.maxLength, format: args.format, debug: args.debug, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error summarizing URL`, error); return formatErrorForMcpTool(error); } } /** * @function handleSummarizeWebsite * @description MCP Tool handler to summarize a website (multiple pages) using AI * @param {SummarizeWebsiteToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleSummarizeWebsite(args: SummarizeWebsiteToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleSummarizeWebsite', ); methodLogger.debug(`Summarizing website with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.summarizeWebsite( args.url, { instructions: args.instructions, systemPrompt: args.systemPrompt, model: args.model, delayAfterLoad: args.delayAfterLoad, maxLinks: args.maxLinks, maxLength: args.maxLength, format: args.format, debug: args.debug, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error summarizing website`, error); return formatErrorForMcpTool(error); } } /** * @function handleSummarizeMultipleUrls * @description MCP Tool handler to summarize multiple URLs using AI * @param {SummarizeMultipleUrlsToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleSummarizeMultipleUrls( args: SummarizeMultipleUrlsToolArgsType, ) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleSummarizeMultipleUrls', ); methodLogger.debug(`Summarizing multiple URLs with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.summarizeMultipleUrls( args.urls, { instructions: args.instructions, systemPrompt: args.systemPrompt, model: args.model, delayAfterLoad: args.delayAfterLoad, maxLinks: args.maxLinks, maxLength: args.maxLength, format: args.format, debug: args.debug, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error summarizing multiple URLs`, error); return formatErrorForMcpTool(error); } } /** * @function handleIsUrlAlive * @description MCP Tool handler to check if a URL is alive * @param {UrlIsAliveToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleIsUrlAlive(args: UrlIsAliveToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleIsUrlAlive', ); methodLogger.debug(`Checking if URL is alive with options:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.isUrlAlive( args.url, { timeout: args.timeout, proxyUrl: args.proxyUrl, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error checking if URL is alive`, error); return formatErrorForMcpTool(error); } } /** * @function handleGetUrlAfterRedirects * @description MCP Tool handler to get URL after redirects * @param {UrlGetUrlAfterRedirectsToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleGetUrlAfterRedirects( args: UrlGetUrlAfterRedirectsToolArgsType, ) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleGetUrlAfterRedirects', ); methodLogger.debug(`Getting URL after redirects:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.getUrlAfterRedirects( args.url, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error getting URL after redirects`, error); return formatErrorForMcpTool(error); } } /** * @function handleGetKeywordIdeas * @description MCP Tool handler to get keyword ideas for a keyword * @param {SeoKeywordIdeasToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleGetKeywordIdeas(args: SeoKeywordIdeasToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleGetKeywordIdeas', ); methodLogger.debug(`Getting keyword ideas:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.getKeywordIdeas( args.keyword, { country: args.country, searchEngine: args.searchEngine, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error getting keyword ideas`, error); return formatErrorForMcpTool(error); } } /** * @function handleGetKeywordDifficulty * @description MCP Tool handler to get keyword difficulty for a keyword * @param {SeoKeywordDifficultyToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleGetKeywordDifficulty( args: SeoKeywordDifficultyToolArgsType, ) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleGetKeywordDifficulty', ); methodLogger.debug(`Getting keyword difficulty:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.getKeywordDifficulty( args.keyword, { country: args.country, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error getting keyword difficulty`, error); return formatErrorForMcpTool(error); } } /** * @function handleGetTraffic * @description MCP Tool handler to check traffic for a domain or URL * @param {SeoTrafficToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleGetTraffic(args: SeoTrafficToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleGetTraffic', ); methodLogger.debug(`Checking traffic:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.getTraffic( args.domainOrUrl, { mode: args.mode, country: args.country, }, { api_key: args.api_key, }, ); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error checking traffic`, error); return formatErrorForMcpTool(error); } } /** * @function handleGetBacklinks * @description MCP Tool handler to get backlinks for a domain * @param {SeoBacklinksToolArgsType} args - Arguments provided to the tool * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP */ async function handleGetBacklinks(args: SeoBacklinksToolArgsType) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'handleGetBacklinks', ); methodLogger.debug(`Getting backlinks:`, { ...args, api_key: args.api_key ? '[REDACTED]' : undefined, }); try { const result = await reviewWebsiteController.getBacklinks(args.domain, { api_key: args.api_key, }); return { content: [ { type: 'text' as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error getting backlinks`, error); return formatErrorForMcpTool(error); } } /** * @function register * @description Registers the ReviewWeb.site tools with the MCP server * @param {McpServer} server - The MCP server instance */ function register(server: McpServer) { const methodLogger = Logger.forContext( 'tools/reviewwebsite.tool.ts', 'register', ); methodLogger.debug(`Registering ReviewWeb.site tools...`); // Register convert to markdown tools server.tool( 'convert_to_markdown', `Convert a URL to Markdown using AI via ReviewWeb.site API. Turn a web page into LLM-friendly content.`, ConvertToMarkdownToolArgs.shape, handleConvertToMarkdown, ); server.tool( 'convert_multiple_to_markdown', `Convert multiple URLs to Markdown using AI via ReviewWeb.site API. Turn multiple web pages into LLM-friendly content.`, ConvertMultipleToMarkdownToolArgs.shape, handleConvertMultipleToMarkdown, ); // Register extract data tools server.tool( 'extract_data', `Extract structured data (JSON) from a web page URL using AI via ReviewWeb.site API.`, ExtractDataToolArgs.shape, handleExtractData, ); server.tool( 'extract_data_multiple', `Extract structured data (JSON) from multiple web page URLs using AI via ReviewWeb.site API.`, ExtractDataMultipleToolArgs.shape, handleExtractDataMultiple, ); // Register scrape tools server.tool( 'scrape_url', `Scrape a URL and return HTML content using ReviewWeb.site API.`, ScrapeUrlToolArgs.shape, handleScrapeUrl, ); server.tool( 'extract_links', `Extract all links from a HTML content of web page URL using ReviewWeb.site API.`, ExtractLinksToolArgs.shape, handleExtractLinks, ); // Register summarize tools server.tool( 'summarize_url', `Summarize a web page URL using AI via ReviewWeb.site API.`, SummarizeUrlToolArgs.shape, handleSummarizeUrl, ); server.tool( 'summarize_website', `Summarize a website (and its internal links) using AI via ReviewWeb.site API.`, SummarizeWebsiteToolArgs.shape, handleSummarizeWebsite, ); server.tool( 'summarize_multiple_urls', `Summarize multiple web page URLs using AI via ReviewWeb.site API.`, SummarizeMultipleUrlsToolArgs.shape, handleSummarizeMultipleUrls, ); // Register URL tools server.tool( 'url_is_alive', `Check if a URL is alive using ReviewWeb.site API.`, UrlIsAliveToolArgs.shape, handleIsUrlAlive, ); server.tool( 'url_get_after_redirects', `Get URL after redirects using ReviewWeb.site API.`, UrlGetUrlAfterRedirectsToolArgs.shape, handleGetUrlAfterRedirects, ); // Register SEO insights tools server.tool( 'seo_keyword_ideas', `Get keyword ideas for a keyword using ReviewWeb.site API.`, SeoKeywordIdeasToolArgs.shape, handleGetKeywordIdeas, ); server.tool( 'seo_keyword_difficulty', `Get keyword difficulty for a keyword using ReviewWeb.site API.`, SeoKeywordDifficultyToolArgs.shape, handleGetKeywordDifficulty, ); server.tool( 'seo_traffic', `Check traffic for a domain or URL using ReviewWeb.site API.`, SeoTrafficToolArgs.shape, handleGetTraffic, ); server.tool( 'seo_backlinks', `Get backlinks for a domain using ReviewWeb.site API.`, SeoBacklinksToolArgs.shape, handleGetBacklinks, ); methodLogger.debug('Successfully registered ReviewWeb.site tools.'); } export default { register };

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/mrgoonie/reviewwebsite-mcp-server'

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