Skip to main content
Glama

llm_web_search

Perform web searches using LLM optimization for architectural decision research, extracting relevant content to support technical documentation.

Instructions

LLM-managed web search using Firecrawl for cross-platform support

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesThe search query to execute
maxResultsNoMaximum results to return
includeContentNoInclude full content in results
llmInstructionsNoLLM instructions for search optimization
projectPathNoPath to project directory.
adrDirectoryNoDirectory containing ADR filesdocs/adrs

Implementation Reference

  • The core handler function `llmWebSearch` that executes the tool logic: validates input, initializes ResearchOrchestrator with Firecrawl, performs web search, limits results, generates LLM analysis, and formats markdown output with progress reporting.
    export async function llmWebSearch( args: { query: string; maxResults?: number; includeContent?: boolean; llmInstructions?: string; projectPath?: string; adrDirectory?: string; }, context?: ToolContext ): Promise<any> { const { query, maxResults = 5, includeContent = true, llmInstructions, projectPath, adrDirectory, } = args; if (!query || query.trim().length === 0) { throw new McpAdrError('Query parameter is required and cannot be empty', 'INVALID_QUERY'); } try { context?.info(`🌐 Initializing web search for: ${query}`); context?.report_progress(0, 100); // Initialize research orchestrator with Firecrawl const orchestrator = new ResearchOrchestrator(projectPath, adrDirectory); // Enhance query with LLM instructions if provided context?.info('🤖 Optimizing search query with LLM guidance...'); context?.report_progress(25, 100); let enhancedQuery = query; if (llmInstructions) { enhancedQuery = `${query}\n\nLLM Instructions: ${llmInstructions}`; } // Perform web search using research orchestrator context?.info('🔍 Executing web search with Firecrawl...'); context?.report_progress(50, 100); const researchResult = await orchestrator.answerResearchQuestion(enhancedQuery); // Extract web search results const webSearchSource = researchResult.sources.find(source => source.type === 'web_search'); const webResults = webSearchSource?.data?.results || []; // Limit results const limitedResults = webResults.slice(0, maxResults); // Generate LLM analysis of results context?.info('📊 Analyzing search results with LLM...'); context?.report_progress(75, 100); const llmAnalysis = await generateLLMAnalysis(query, limitedResults, llmInstructions); context?.info('✅ Web search complete!'); context?.report_progress(100, 100); return { content: [ { type: 'text', text: `# LLM-Managed Web Search Results ## Query ${query} ${llmInstructions ? `## LLM Instructions\n${llmInstructions}\n` : ''} ## Search Results (${limitedResults.length} found) ${limitedResults .map( (result: any, index: number) => ` ### ${index + 1}. ${result.title} - **URL**: ${result.url} - **Relevance**: ${(result.relevance * 100).toFixed(1)}% - **Content**: ${includeContent ? result.content?.substring(0, 500) + '...' : 'Content available'} --- ` ) .join('\n')} ## LLM Analysis ${llmAnalysis} ## Search Metadata - **Provider**: Firecrawl - **Total Results**: ${webResults.length} - **Returned Results**: ${limitedResults.length} - **Confidence**: ${(researchResult.confidence * 100).toFixed(1)}% - **Timestamp**: ${new Date().toISOString()} `, }, ], }; } catch (error) { throw new McpAdrError( `Web search failed: ${error instanceof Error ? error.message : String(error)}`, 'WEB_SEARCH_ERROR' ); } }
  • Tool registration in the central TOOL_CATALOG with metadata, JSON input schema, category 'research', and related tools.
    TOOL_CATALOG.set('llm_web_search', { name: 'llm_web_search', shortDescription: 'Web search via LLM', fullDescription: 'Performs web searches with LLM-enhanced result analysis.', category: 'research', complexity: 'moderate', tokenCost: { min: 2000, max: 5000 }, hasCEMCPDirective: true, // Phase 4.3: Moderate tool - LLM web search relatedTools: ['perform_research', 'llm_cloud_management'], keywords: ['search', 'web', 'llm', 'internet'], requiresAI: true, inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query' }, maxResults: { type: 'number', default: 10 }, }, required: ['query'], }, });
  • Supporting helper function for generating LLM analysis of search results (currently stubbed).
    async function generateLLMAnalysis( _query: string, _results: unknown[], _instructions?: string ): Promise<string> { // TODO: Implement LLM analysis when AI executor is available // const { loadAIConfig, getAIExecutor } = await import('../config/ai-config.js'); // const aiConfig = loadAIConfig(); // const executor = getAIExecutor(); // const prompt = ` // Analyze these web search results for the query: "${query}" // // ${instructions ? `Additional Instructions: ${instructions}` : ''} // // Search Results: // ${results.map((result, index) => ` // ${index + 1}. ${result.title} // URL: ${result.url} // Relevance: ${(result.relevance * 100).toFixed(1)}% // Content Preview: ${result.content?.substring(0, 300)}... // `).join('\n')} // // Provide analysis covering: // 1. Overall quality and relevance of results // 2. Key insights and findings // 3. Gaps or missing information // 4. Recommendations for further research // 5. Summary of most valuable sources // // Keep analysis concise but comprehensive. // `; // const result = await executor.executeStructuredPrompt(prompt, { // type: 'object', // properties: { // analysis: { type: 'string' } // } // }); // return result.data.analysis || 'Analysis unavailable'; return 'LLM analysis is not yet available. Results are available but require manual review.'; }
  • The tool dispatcher that generates the MCP tool list using the TOOL_CATALOG, including llm_web_search schema via toMCPTool.
    export function getToolListForMCP(options: { mode?: 'full' | 'lightweight' | 'summary' }): { tools: Tool[]; } { const { mode = 'lightweight' } = options; if (mode === 'summary') { // Return only the search_tools meta-tool return { tools: [getSearchToolsDefinition()], }; } if (mode === 'lightweight') { // Return lightweight list with search_tools const lightList = getLightweightToolList(); const tools: Tool[] = [ getSearchToolsDefinition(), ...lightList.map(item => ({ name: item.name, description: `[${item.category}] ${item.description}${item.hasCEMCPDirective ? ' (CE-MCP)' : ''}`, inputSchema: { type: 'object' as const, properties: {}, description: `Use search_tools with query:"${item.name}" to get full schema`, }, })), ]; return { tools }; } // Full mode - return all tools with schemas from catalog const tools: Tool[] = [getSearchToolsDefinition()]; for (const [, metadata] of TOOL_CATALOG) { tools.push(toMCPTool(metadata)); } return { tools }; }

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/tosin2013/mcp-adr-analysis-server'

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