Skip to main content
Glama

web_search

Perform web or news searches using Bing to find information, tutorials, or current events with time-based filtering options.

Instructions

Perform web or news search using Bing search engine. Supports both general web search and news search modes.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query, e.g., Node.js tutorial, tech news, political updates, etc.
searchTypeYesSearch type: web (general web search), news (news search) - required
maxResultsNoMaximum number of results
timeFilterNoTime filter (only valid for news search): past 1 hour, 24 hours, 7 days, 30 dayspast_24_hours

Implementation Reference

  • Main MCP tool handler for web_search. Validates input parameters and delegates to searchService for Bing web or news search.
    async function handleWebSearch(args) { const { query, searchType, maxResults = 10, timeFilter = 'past_24_hours' } = args; if (!query || typeof query !== 'string') { throw new Error('Query parameter is required and must be a string'); } if (!searchType || !['web', 'news'].includes(searchType)) { throw new Error('searchType is required and must be either "web" or "news"'); } if (maxResults < 1 || maxResults > 20) { throw new Error('maxResults must be between 1 and 20'); } if (searchType === 'news' && !['past_hour', 'past_24_hours', 'past_7_days', 'past_30_days'].includes(timeFilter)) { throw new Error('timeFilter must be a valid time filter option'); } const searchService = (await import('../services/searchService.js')).default; let results; if (searchType === 'news') { results = await searchService.searchBingNews(query, maxResults, timeFilter); } else { results = await searchService.searchBing(query, maxResults); } return { tool: 'web_search', searchType, query, maxResults, timeFilter: searchType === 'news' ? timeFilter : undefined, results: results.results, totalResults: results.totalResults, timestamp: results.timestamp }; }
  • Input schema definition for the web_search tool, including parameters query, searchType, maxResults, and timeFilter.
    name: 'web_search', description: 'Perform web or news search using Bing search engine. Supports both general web search and news search modes.', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query, e.g., Node.js tutorial, tech news, political updates, etc.' }, searchType: { type: 'string', enum: ['web', 'news'], description: 'Search type: web (general web search), news (news search) - required' }, maxResults: { type: 'number', description: 'Maximum number of results', default: 10, minimum: 1, maximum: 20 }, timeFilter: { type: 'string', enum: ['past_hour', 'past_24_hours', 'past_7_days', 'past_30_days'], description: 'Time filter (only valid for news search): past 1 hour, 24 hours, 7 days, 30 days', default: 'past_24_hours' } }, required: ['query', 'searchType'] }
  • Switch case registration that maps tool call 'web_search' to the handleWebSearch function.
    case 'web_search': result = await handleWebSearch(args);
  • Core implementation of Bing web search using Puppeteer browser automation to scrape search results.
    async searchBing(query, maxResults = 10) { try { const browser = await this.initBrowser(); const page = await browser.newPage(); await page.setUserAgent(this.getRandomUserAgent()); await page.setViewport({ width: 1920, height: 1080 }); const searchUrl = `https://www.bing.com/search?q=${encodeURIComponent(query)}&count=${maxResults}`; await page.goto(searchUrl, { waitUntil: 'networkidle2' }); await page.waitForSelector('#b_results', { timeout: 10000 }); const rawResults = await page.evaluate(() => { const searchResults = []; const resultElements = document.querySelectorAll('#b_results .b_algo'); resultElements.forEach((element, index) => { if (index >= 10) return; const titleElement = element.querySelector('h2 a'); const snippetElement = element.querySelector('.b_caption p'); if (titleElement) { searchResults.push({ title: titleElement.textContent.trim(), url: titleElement.href, snippet: snippetElement ? snippetElement.textContent.trim() : '', rank: index + 1 }); } }); return searchResults; }); // Clean URLs in Node.js const results = rawResults.map(item => ({ ...item, url: this.cleanUrl(item.url) })); await page.close(); logger.info(`Bing search completed for query: "${query}", found ${results.length} results`); return { engine: 'Bing', query, results, totalResults: results.length, timestamp: new Date().toISOString() }; } catch (error) { logger.error('Bing search error:', error); throw new Error(`Bing search failed: ${error.message}`); } }
  • Core implementation of Bing news search with time filtering using Puppeteer to handle dynamic news results.
    async searchBingNews(query, maxResults = 10, timeFilter = 'past_24_hours') { try { const browser = await this.initBrowser(); const page = await browser.newPage(); await page.setUserAgent(this.getRandomUserAgent()); await page.setViewport({ width: 1920, height: 1080 }); // Build news search URL let searchUrl = `https://www.bing.com/news/search?q=${encodeURIComponent(query)}`; // Add time filter const timeParams = { 'past_hour': '&qft=interval%3d"1"', 'past_24_hours': '&qft=interval%3d"24"', 'past_7_days': '&qft=interval%3d"7"', 'past_30_days': '&qft=interval%3d"30"' }; if (timeParams[timeFilter]) { searchUrl += timeParams[timeFilter]; } logger.info(`Navigating to Bing News: ${searchUrl}`); await page.goto(searchUrl, { waitUntil: 'networkidle2', timeout: 15000 }); // Wait for news results to load await new Promise(resolve => setTimeout(resolve, 3000)); // Try to wait for page content try { await page.waitForSelector('body', { timeout: 5000 }); } catch (error) { logger.warn('Timeout waiting for page load, continuing'); } const rawResults = await page.evaluate((maxResults) => { const newsResults = []; // Try multiple selectors for news items const selectors = [ '.news-card', '.news-item', '.news-card-container', '[data-news-card]', '.news-content', '.news-title', '.news-item-container', '.news-list-item' ]; let newsElements = []; for (const selector of selectors) { newsElements = document.querySelectorAll(selector); if (newsElements.length > 0) { break; } } // Fallback: try links containing /news/ if (newsElements.length === 0) { const allLinks = document.querySelectorAll('a[href*="/news/"]'); newsElements = Array.from(allLinks).map(link => { const container = link.closest('div') || link.parentElement; return container || link; }); } // Fallback: just take some links if (newsElements.length === 0) { const allLinks = document.querySelectorAll('a[href]'); newsElements = Array.from(allLinks).slice(0, 20); } // Extract news info newsElements.forEach((element, index) => { if (index >= maxResults) return; let title = ''; let url = ''; let source = ''; let time = ''; // Title const titleSelectors = ['h2', 'h3', '.news-title', '.title', 'a']; for (const selector of titleSelectors) { const el = element.querySelector(selector); if (el && el.textContent.trim()) { title = el.textContent.trim(); if (el.href) { url = el.href; } break; } } // Link if (!url) { const linkEl = element.querySelector('a[href]'); if (linkEl && linkEl.href) { url = linkEl.href; } } // Source const sourceSelectors = ['.news-source', '.source', '.publisher', '.author']; for (const selector of sourceSelectors) { const el = element.querySelector(selector); if (el && el.textContent.trim()) { source = el.textContent.trim(); break; } } // Time const timeSelectors = ['.news-time', '.time', '.date', '.timestamp']; for (const selector of timeSelectors) { const el = element.querySelector(selector); if (el && el.textContent.trim()) { time = el.textContent.trim(); break; } } // Validate if (title && url) { const isValidNewsUrl = url.includes('/news/') || url.includes('news') || url.includes('bing.com') || url.includes('msn.com') || url.includes('baidu.com') || url.includes('baike.baidu.com'); if (isValidNewsUrl) { newsResults.push({ title, url, source, time, rank: index + 1 }); } } }); return newsResults; }, maxResults); // Clean URLs in Node.js const results = rawResults.map(item => ({ ...item, url: this.cleanUrl(item.url) })); await page.close(); logger.info(`Bing News search completed for query: "${query}", found ${results.length} results`); return { engine: 'Bing News', query, results, totalResults: results.length, timeFilter, timestamp: new Date().toISOString() }; } catch (error) { logger.error('Bing News search error:', error); throw new Error(`Bing News search failed: ${error.message}`); } }

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/Bosegluon2/spider-mcp'

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