search_tools
Find AI developer tools by category, popularity, or keyword to identify suitable options for your projects.
Instructions
Search and filter AI developer tools by category, popularity, or keyword
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Filter by tool category | |
| min_downloads | No | Minimum monthly downloads (e.g., 1000000 for 1M+) | |
| keyword | No | Search for keyword in tool name or description | |
| sort_by | No | How to sort results | downloads |
Implementation Reference
- src/tools/search.js:55-110 (handler)The 'execute' method of the searchTool object, which handles tool invocation: destructures args, calls searchData helper for filtering, applies sorting, formats a detailed markdown output with results and statistics.async execute(args) { const { category, min_downloads, keyword, sort_by = 'downloads' } = args; // Perform search let results = searchData({ category, min_downloads, keyword }); // Apply sorting if (sort_by === 'downloads') { results.sort((a, b) => b.npm_downloads_monthly - a.npm_downloads_monthly); } else if (sort_by === 'stars') { results.sort((a, b) => b.github_stars - a.github_stars); } else if (sort_by === 'name') { results.sort((a, b) => a.name.localeCompare(b.name)); } // Build output let output = `🔍 AI Developer Tools Search Results\n\n`; // Show active filters const activeFilters = []; if (category) activeFilters.push(`Category: ${category}`); if (min_downloads) activeFilters.push(`Min Downloads: ${formatNumber(min_downloads)}`); if (keyword) activeFilters.push(`Keyword: "${keyword}"`); if (activeFilters.length > 0) { output += `**Filters:** ${activeFilters.join(' | ')}\n`; output += `**Sort:** ${sort_by}\n\n`; } // Results if (results.length === 0) { output += `No tools found matching your criteria.`; return output; } output += `**Found ${results.length} tool${results.length === 1 ? '' : 's'}:**\n\n`; results.forEach((tool, index) => { output += `${index + 1}. **${tool.name}** (\`${tool.package}\`)\n`; output += ` - ${tool.description}\n`; output += ` - Category: ${tool.category}\n`; output += ` - Monthly Downloads: ${formatNumber(tool.npm_downloads_monthly)}\n`; output += ` - GitHub Stars: ${formatNumber(tool.github_stars)}\n`; output += ` - Community: ${tool.stackoverflow_questions_30d} SO questions, ${tool.reddit_mentions_30d} Reddit mentions (30d)\n\n`; }); // Summary stats const totalDownloads = results.reduce((sum, t) => sum + t.npm_downloads_monthly, 0); const avgDownloads = totalDownloads / results.length; output += `**Summary Statistics**\n`; output += `• Total Monthly Downloads: ${formatNumber(totalDownloads)}\n`; output += `• Average per Tool: ${formatNumber(Math.round(avgDownloads))}\n`; return output; }
- src/tools/search.js:27-52 (schema)JSON Schema defining the input parameters for the 'search_tools' tool: optional filters for category, minimum downloads, keyword, and sort order.inputSchema: { type: 'object', properties: { category: { type: 'string', enum: ['llm-api', 'editor', 'assistant', 'framework'], description: 'Filter by tool category' }, min_downloads: { type: 'integer', minimum: 0, description: 'Minimum monthly downloads (e.g., 1000000 for 1M+)' }, keyword: { type: 'string', description: 'Search for keyword in tool name or description' }, sort_by: { type: 'string', enum: ['downloads', 'stars', 'name'], default: 'downloads', description: 'How to sort results' } }, // No required parameters - all filters are optional additionalProperties: false
- src/index.js:66-70 (registration)Registration of the 'search_tools' tool (imported as searchTool) in the central tools array used by the MCP server's listTools and callTool request handlers.compareTool, trendingTool, historyTool, searchTool ];
- src/data/mock-data.js:177-203 (helper)Helper function 'searchTools' that performs the actual data filtering by category, min_downloads, and keyword, combining TOOLS and CURRENT_METRICS data; imported and aliased as searchData in the handler.export function searchTools(query = {}) { const { category, min_downloads, keyword } = query; let results = Object.entries(TOOLS).map(([id, tool]) => ({ id, ...tool, ...CURRENT_METRICS[id] })); if (category) { results = results.filter(t => t.category === category); } if (min_downloads) { results = results.filter(t => t.npm_downloads_monthly >= min_downloads); } if (keyword) { const lowerKeyword = keyword.toLowerCase(); results = results.filter(t => t.name.toLowerCase().includes(lowerKeyword) || t.description.toLowerCase().includes(lowerKeyword) ); } return results; }