compare_tools
Compare two software products side-by-side to view pricing, features, ratings, and key differences.
Instructions
Side-by-side structured comparison of two software products. Returns pricing, features, ratings, and key differences.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tool1 | Yes | Slug of the first tool to compare | |
| tool2 | Yes | Slug of the second tool to compare |
Implementation Reference
- index.js:92-103 (schema)Schema definition for compare_tools tool: defines name, description, and inputSchema with required tool1/tool2 slug strings.
{ name: 'compare_tools', description: 'Side-by-side structured comparison of two software products. Returns pricing, features, ratings, and key differences.', inputSchema: { type: 'object', properties: { tool1: { type: 'string', description: 'Slug of the first tool to compare' }, tool2: { type: 'string', description: 'Slug of the second tool to compare' }, }, required: ['tool1', 'tool2'], }, }, - index.js:292-332 (handler)Handler function for compare_tools. Fetches all tools, finds both by slug, and returns a side-by-side formatted comparison including category, rating, free plan, starting price, plans, and URLs.
async function compareTools(args) { const { tool1, tool2 } = args; const allTools = await getAllTools(); const t1 = allTools.find(x => x.slug === tool1); const t2 = allTools.find(x => x.slug === tool2); if (!t1) return `Tool "${tool1}" not found. Use search_tools to find the correct slug.`; if (!t2) return `Tool "${tool2}" not found. Use search_tools to find the correct slug.`; const lines = [ `Comparison: ${t1.name} vs ${t2.name}`, '', fmtRow('Field', t1.name.slice(0, 20), t2.name.slice(0, 20)), '-'.repeat(70), fmtRow('Category', t1.categoryName || t1.category, t2.categoryName || t2.category), fmtRow('Rating', t1.rating ? `${t1.rating}/5` : 'N/A', t2.rating ? `${t2.rating}/5` : 'N/A'), fmtRow('Free plan', t1.freePlan ? 'Yes' : 'No', t2.freePlan ? 'Yes' : 'No'), fmtRow('Starting price', formatPrice(t1.startingPrice), formatPrice(t2.startingPrice)), fmtRow('Verified at', t1.verifiedAt || 'N/A', t2.verifiedAt || 'N/A'), ]; // Plans for t1 const p1 = t1.plans; if (p1 && p1.length > 0) { lines.push(`\n${t1.name} plans:`); p1.forEach(p => lines.push(` - ${p.name}: ${formatPrice(p.price)}`)); } // Plans for t2 const p2 = t2.plans; if (p2 && p2.length > 0) { lines.push(`\n${t2.name} plans:`); p2.forEach(p => lines.push(` - ${p.name}: ${formatPrice(p.price)}`)); } lines.push(`\n${t1.name} URL: ${toolURL(tool1)}`); lines.push(`${t2.name} URL: ${toolURL(tool2)}`); lines.push(`Full comparison: ${SITE_BASE}/compare/${tool1}-vs-${tool2}`); return lines.join('\n'); } - index.js:448-460 (registration)Dispatch registration in callTool() switch statement routing the name 'compare_tools' to the compareTools handler function.
async function callTool(name, args) { switch (name) { case 'search_tools': return searchTools(args); case 'get_tool': return getTool(args); case 'compare_tools': return compareTools(args); case 'list_category': return listCategory(args); case 'get_alternatives':return getAlternatives(args); case 'get_pricing': return getPricing(args); case 'get_leaderboard': return getLeaderboard(args); case 'list_categories': return listCategoriesFn(); default: throw new Error(`Unknown tool: ${name}`); } } - index.js:199-201 (helper)fmtRow helper used by compareTools to format a padded two-column row for the comparison output.
function fmtRow(label, v1, v2) { return `${label.padEnd(22)} ${String(v1 ?? 'N/A').slice(0, 22).padEnd(22)} ${String(v2 ?? 'N/A').slice(0, 22)}`; }