intelligent_research
Perform intelligent searches across web, news, academic, and social sources with smart ranking, deduplication, and in-depth analysis to refine results efficiently.
Instructions
Intelligent search across multiple sources with smart ranking and deduplication
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| includeAnalysis | No | Include intelligent analysis of results | |
| maxResults | No | Maximum results per source (1-20) | |
| query | Yes | Search query to execute across multiple sources | |
| sources | No | Sources to search: web, news, academic, social, tech |
Implementation Reference
- Core handler logic for intelligent_research tool. Aggregates parallel searches from multiple sources (web/Google, news/NewsAPI, academic/arXiv, social/Reddit, tech/GitHub), processes results with extraction helpers, ranks by relevance to query, deduplicates, generates analysis and metadata.execute: async (args: any) => { try { const startTime = Date.now(); const sources = args.sources || ['web', 'news', 'academic', 'social']; const maxResults = args.maxResults || 5; const results: any = { query: args.query, sources_searched: [], results_by_source: {}, aggregated_results: [], analysis: {}, metadata: { search_time: 0, total_results: 0, sources_count: 0 } }; // 并行搜索多个源 const searchPromises = []; // Web搜索 (Google) if (sources.includes('web')) { const webTool = registry.getTool('google_web_search'); if (webTool) { searchPromises.push( webTool.execute({ query: args.query, limit: maxResults }) .then(result => ({ source: 'web', data: result })) .catch(error => ({ source: 'web', error: error.message })) ); } } // 新闻搜索 (NewsAPI) if (sources.includes('news')) { const newsTool = registry.getTool('newsapi_search'); if (newsTool) { searchPromises.push( newsTool.execute({ query: args.query, maxResults }) .then(result => ({ source: 'news', data: result })) .catch(error => ({ source: 'news', error: error.message })) ); } } // 学术搜索 (arXiv) if (sources.includes('academic')) { const academicTool = registry.getTool('search_arxiv'); if (academicTool) { searchPromises.push( academicTool.execute({ query: args.query, max_results: maxResults }) .then(result => ({ source: 'academic', data: result })) .catch(error => ({ source: 'academic', error: error.message })) ); } } // 社交媒体搜索 (Reddit) if (sources.includes('social')) { const socialTool = registry.getTool('reddit_post_search'); if (socialTool) { searchPromises.push( socialTool.execute({ query: args.query, maxResults }) .then(result => ({ source: 'social', data: result })) .catch(error => ({ source: 'social', error: error.message })) ); } } // 技术搜索 (GitHub) if (sources.includes('tech')) { const techTool = registry.getTool('github_repository_search'); if (techTool) { searchPromises.push( techTool.execute({ query: args.query, maxResults }) .then(result => ({ source: 'tech', data: result })) .catch(error => ({ source: 'tech', error: error.message })) ); } } // 等待所有搜索完成 const searchResults = await Promise.all(searchPromises); // 处理搜索结果 let totalResults = 0; const allResults: any[] = []; for (const searchResult of searchResults) { if ('error' in searchResult) { results.results_by_source[searchResult.source] = { status: 'error', error: searchResult.error }; continue; } const sourceData = searchResult.data; if (sourceData.success && sourceData.data) { const sourceResults = extractResults(sourceData.data, searchResult.source); results.results_by_source[searchResult.source] = { status: 'success', count: sourceResults.length, results: sourceResults }; results.sources_searched.push(searchResult.source); totalResults += sourceResults.length; allResults.push(...sourceResults.map((r: any) => ({ ...r, source: searchResult.source }))); } else { results.results_by_source[searchResult.source] = { status: 'no_results', error: sourceData.error || 'No results found' }; } } // 智能排序和去重 const rankedResults = rankAndDeduplicateResults(allResults, args.query); results.aggregated_results = rankedResults.slice(0, maxResults * 2); // 返回更多聚合结果 // 生成分析 if (args.includeAnalysis) { results.analysis = { query_analysis: `Search for "${args.query}" across ${results.sources_searched.length} sources`, source_performance: results.sources_searched.map((source: string) => ({ source, status: results.results_by_source[source].status, result_count: results.results_by_source[source].count || 0 })), recommendations: ['Consider searching more sources for comprehensive results'] }; } // 设置元数据 results.metadata = { search_time: Date.now() - startTime, total_results: totalResults, sources_count: results.sources_searched.length, aggregated_count: results.aggregated_results.length }; return { success: true, data: results }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Smart search failed' }; } }
- Input schema defining parameters for the intelligent_research tool: query (required), sources array (default: web,news,academic,social), maxResults (1-20), includeAnalysis boolean.inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query to execute across multiple sources' }, sources: { type: 'array', items: { type: 'string' }, description: 'Sources to search: web, news, academic, social, tech', default: ['web', 'news', 'academic', 'social'] }, maxResults: { type: 'number', description: 'Maximum results per source (1-20)', default: 5, minimum: 1, maximum: 20 }, includeAnalysis: { type: 'boolean', description: 'Include intelligent analysis of results', default: true } }, required: ['query'] },
- src/tools/aggregation/smart-search-tools.ts:61-247 (registration)Tool registration within registerSmartSearchTools function, defining name, description, category, source, inputSchema, and execute handler.registry.registerTool({ name: 'intelligent_research', description: 'Intelligent search across multiple sources with smart ranking and deduplication', category: 'aggregation', source: 'multiple', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query to execute across multiple sources' }, sources: { type: 'array', items: { type: 'string' }, description: 'Sources to search: web, news, academic, social, tech', default: ['web', 'news', 'academic', 'social'] }, maxResults: { type: 'number', description: 'Maximum results per source (1-20)', default: 5, minimum: 1, maximum: 20 }, includeAnalysis: { type: 'boolean', description: 'Include intelligent analysis of results', default: true } }, required: ['query'] }, execute: async (args: any) => { try { const startTime = Date.now(); const sources = args.sources || ['web', 'news', 'academic', 'social']; const maxResults = args.maxResults || 5; const results: any = { query: args.query, sources_searched: [], results_by_source: {}, aggregated_results: [], analysis: {}, metadata: { search_time: 0, total_results: 0, sources_count: 0 } }; // 并行搜索多个源 const searchPromises = []; // Web搜索 (Google) if (sources.includes('web')) { const webTool = registry.getTool('google_web_search'); if (webTool) { searchPromises.push( webTool.execute({ query: args.query, limit: maxResults }) .then(result => ({ source: 'web', data: result })) .catch(error => ({ source: 'web', error: error.message })) ); } } // 新闻搜索 (NewsAPI) if (sources.includes('news')) { const newsTool = registry.getTool('newsapi_search'); if (newsTool) { searchPromises.push( newsTool.execute({ query: args.query, maxResults }) .then(result => ({ source: 'news', data: result })) .catch(error => ({ source: 'news', error: error.message })) ); } } // 学术搜索 (arXiv) if (sources.includes('academic')) { const academicTool = registry.getTool('search_arxiv'); if (academicTool) { searchPromises.push( academicTool.execute({ query: args.query, max_results: maxResults }) .then(result => ({ source: 'academic', data: result })) .catch(error => ({ source: 'academic', error: error.message })) ); } } // 社交媒体搜索 (Reddit) if (sources.includes('social')) { const socialTool = registry.getTool('reddit_post_search'); if (socialTool) { searchPromises.push( socialTool.execute({ query: args.query, maxResults }) .then(result => ({ source: 'social', data: result })) .catch(error => ({ source: 'social', error: error.message })) ); } } // 技术搜索 (GitHub) if (sources.includes('tech')) { const techTool = registry.getTool('github_repository_search'); if (techTool) { searchPromises.push( techTool.execute({ query: args.query, maxResults }) .then(result => ({ source: 'tech', data: result })) .catch(error => ({ source: 'tech', error: error.message })) ); } } // 等待所有搜索完成 const searchResults = await Promise.all(searchPromises); // 处理搜索结果 let totalResults = 0; const allResults: any[] = []; for (const searchResult of searchResults) { if ('error' in searchResult) { results.results_by_source[searchResult.source] = { status: 'error', error: searchResult.error }; continue; } const sourceData = searchResult.data; if (sourceData.success && sourceData.data) { const sourceResults = extractResults(sourceData.data, searchResult.source); results.results_by_source[searchResult.source] = { status: 'success', count: sourceResults.length, results: sourceResults }; results.sources_searched.push(searchResult.source); totalResults += sourceResults.length; allResults.push(...sourceResults.map((r: any) => ({ ...r, source: searchResult.source }))); } else { results.results_by_source[searchResult.source] = { status: 'no_results', error: sourceData.error || 'No results found' }; } } // 智能排序和去重 const rankedResults = rankAndDeduplicateResults(allResults, args.query); results.aggregated_results = rankedResults.slice(0, maxResults * 2); // 返回更多聚合结果 // 生成分析 if (args.includeAnalysis) { results.analysis = { query_analysis: `Search for "${args.query}" across ${results.sources_searched.length} sources`, source_performance: results.sources_searched.map((source: string) => ({ source, status: results.results_by_source[source].status, result_count: results.results_by_source[source].count || 0 })), recommendations: ['Consider searching more sources for comprehensive results'] }; } // 设置元数据 results.metadata = { search_time: Date.now() - startTime, total_results: totalResults, sources_count: results.sources_searched.length, aggregated_count: results.aggregated_results.length }; return { success: true, data: results }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Smart search failed' }; } } });
- src/index.ts:254-254 (registration)Top-level call to registerSmartSearchTools in OpenSearchMCPServer.registerAllTools(), which registers the intelligent_research tool among others.registerSmartSearchTools(this.toolRegistry); // 2 tools: intelligent_research, market_intelligence_aggregator
- Helper function used by the handler to deduplicate results by title/url and sort by relevance score to the query.function rankAndDeduplicateResults(results: any[], query: string): any[] { const seen = new Set(); const unique = results.filter(result => { const key = result.title || result.name || result.url; if (seen.has(key)) return false; seen.add(key); return true; }); return unique.sort((a, b) => { const aRelevance = calculateRelevance(a, query); const bRelevance = calculateRelevance(b, query); return bRelevance - aRelevance; }); }