Industry Benchmark Comparison
competitor_benchmarkCompare your ad performance against industry benchmarks for specific verticals. Identify performance gaps and receive recommendations to improve CTR, CPC, CPM, conversion rate, CPA, and ROAS.
Instructions
Compare your ad performance against industry averages for a chosen vertical. Input: industry (e.g. "ecommerce", "saas", "finance", "healthcare", "education", "travel", "real_estate", "legal"), optional platform filter. Returns {industry, your_metrics, benchmarks (CTR, CPC, CPM, conversion_rate, CPA, ROAS industry averages), comparison (percent above/below benchmark per metric), recommendations[]}. Benchmarks are curated static tables — not live market data.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| industry | Yes | Industry for benchmarking (e.g., "ecommerce", "saas", "finance") | |
| platform | No |
Implementation Reference
- src/services/analytics.ts:253-331 (handler)Contains the INDUSTRY_BENCHMARKS data (static benchmark tables for 9 verticals + default) and the generateBenchmark() function which calculates the actual benchmark comparison. This is the core handler logic.
// ── Competitor Benchmark ──────────────────────────────────────────── const INDUSTRY_BENCHMARKS: Record<string, { ctr: number; cpc: number; cpm: number; conversion_rate: number; cpa: number; roas: number }> = { ecommerce: { ctr: 2.69, cpc: 1.16, cpm: 11.20, conversion_rate: 2.81, cpa: 45.27, roas: 4.0 }, saas: { ctr: 2.44, cpc: 3.80, cpm: 25.00, conversion_rate: 3.04, cpa: 133.00, roas: 3.5 }, finance: { ctr: 2.91, cpc: 3.44, cpm: 20.00, conversion_rate: 5.01, cpa: 78.09, roas: 5.0 }, healthcare: { ctr: 3.27, cpc: 2.62, cpm: 17.80, conversion_rate: 3.36, cpa: 78.09, roas: 3.2 }, education: { ctr: 3.78, cpc: 2.40, cpm: 15.00, conversion_rate: 3.39, cpa: 72.70, roas: 3.8 }, real_estate: { ctr: 3.71, cpc: 2.37, cpm: 14.00, conversion_rate: 2.47, cpa: 116.61, roas: 2.8 }, travel: { ctr: 4.68, cpc: 1.53, cpm: 10.50, conversion_rate: 3.55, cpa: 44.73, roas: 5.2 }, retail: { ctr: 2.67, cpc: 1.15, cpm: 10.00, conversion_rate: 2.81, cpa: 42.52, roas: 4.5 }, technology: { ctr: 2.09, cpc: 3.80, cpm: 24.00, conversion_rate: 2.92, cpa: 133.52, roas: 3.0 }, default: { ctr: 2.83, cpc: 2.14, cpm: 15.00, conversion_rate: 3.17, cpa: 75.00, roas: 3.5 }, }; /** Compare campaign performance against industry averages for 9 verticals. Returns metric-by-metric comparison with ratings and recommendations. */ export async function generateBenchmark( industry: string, platformFilter?: Platform, store?: Storage, ): Promise<CompetitorBenchmark> { const s = store ?? defaultStorage; const benchmarks = INDUSTRY_BENCHMARKS[industry.toLowerCase()] ?? INDUSTRY_BENCHMARKS.default; const metrics = await s.getAllMetrics(); const filtered = platformFilter ? metrics.filter((m) => m.platform === platformFilter) : metrics; const totalSpend = filtered.reduce((s, m) => s + m.spend, 0); const totalClicks = filtered.reduce((s, m) => s + m.clicks, 0); const totalImpressions = filtered.reduce((s, m) => s + m.impressions, 0); const totalConversions = filtered.reduce((s, m) => s + m.conversions, 0); const totalRevenue = filtered.reduce((s, m) => s + m.conversion_value, 0); const yourPerf = { ctr: calculateCTR(totalClicks, totalImpressions), cpc: calculateCPC(totalSpend, totalClicks), cpm: calculateCPM(totalSpend, totalImpressions), conversion_rate: calculateConversionRate(totalConversions, totalClicks), cpa: calculateCPA(totalSpend, totalConversions), roas: calculateROAS(totalRevenue, totalSpend), }; const metricsToCompare = [ { metric: 'CTR (%)', your_value: yourPerf.ctr, industry_avg: benchmarks.ctr }, { metric: 'CPC ($)', your_value: yourPerf.cpc, industry_avg: benchmarks.cpc }, { metric: 'CPM ($)', your_value: yourPerf.cpm, industry_avg: benchmarks.cpm }, { metric: 'Conversion Rate (%)', your_value: yourPerf.conversion_rate, industry_avg: benchmarks.conversion_rate }, { metric: 'CPA ($)', your_value: yourPerf.cpa, industry_avg: benchmarks.cpa }, { metric: 'ROAS', your_value: yourPerf.roas, industry_avg: benchmarks.roas }, ]; const comparison = metricsToCompare.map((m) => { const diff = m.industry_avg > 0 ? ((m.your_value - m.industry_avg) / m.industry_avg) * 100 : 0; const isLowerBetter = ['CPC ($)', 'CPM ($)', 'CPA ($)'].includes(m.metric); const rating = isLowerBetter ? diff < -10 ? 'above_average' as const : diff > 10 ? 'below_average' as const : 'average' as const : diff > 10 ? 'above_average' as const : diff < -10 ? 'below_average' as const : 'average' as const; return { ...m, difference_percent: round(diff), rating }; }); const recommendations: string[] = []; for (const c of comparison) { if (c.rating === 'below_average') { if (c.metric.includes('CTR')) recommendations.push('Your CTR is below average. Test new ad copy and creative to improve engagement.'); if (c.metric.includes('CPC')) recommendations.push('Your CPC is higher than average. Review keyword bidding strategy and quality scores.'); if (c.metric.includes('CPA')) recommendations.push('Your CPA is above average. Optimize conversion funnel and targeting.'); if (c.metric.includes('ROAS')) recommendations.push('Your ROAS is below average. Focus budget on highest-performing campaigns.'); } } if (recommendations.length === 0) recommendations.push('Your performance is at or above industry averages. Keep optimizing!'); return { industry: industry.toLowerCase(), benchmarks: { avg_ctr: benchmarks.ctr, avg_cpc: benchmarks.cpc, avg_cpm: benchmarks.cpm, avg_conversion_rate: benchmarks.conversion_rate, avg_cpa: benchmarks.cpa, avg_roas: benchmarks.roas }, your_performance: yourPerf, comparison, recommendations, }; } - src/index.ts:568-586 (handler)Registration of the 'competitor_benchmark' tool on the MCP server. Wires up the handler that calls generateBenchmark() and returns JSON response.
// ── Tool 13: competitor_benchmark ─────────────────────────────────── server.registerTool( 'competitor_benchmark', { title: 'Industry Benchmark Comparison', description: 'Compare your ad performance against industry averages for a chosen vertical. Input: industry (e.g. "ecommerce", "saas", "finance", "healthcare", "education", "travel", "real_estate", "legal"), optional platform filter. Returns {industry, your_metrics, benchmarks (CTR, CPC, CPM, conversion_rate, CPA, ROAS industry averages), comparison (percent above/below benchmark per metric), recommendations[]}. Benchmarks are curated static tables — not live market data.', inputSchema: CompetitorBenchmarkInputSchema, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, }, async ({ industry, platform }) => { try { const reject = await ensureProOrReject(LICENSE_CONFIG, 'competitor_benchmark'); if (reject) return reject; const benchmark = await generateBenchmark(industry, platform); return { content: [{ type: 'text' as const, text: JSON.stringify(benchmark, null, 2) }] }; } catch (e) { return handleToolError(e); } }, ); - src/models/adops.ts:347-373 (schema)CompetitorBenchmarkSchema - defines the output shape of the benchmark result (industry, benchmarks, your_performance, comparison array, recommendations).
export const CompetitorBenchmarkSchema = z.object({ industry: z.string(), benchmarks: z.object({ avg_ctr: z.number(), avg_cpc: z.number(), avg_cpm: z.number(), avg_conversion_rate: z.number(), avg_cpa: z.number(), avg_roas: z.number(), }), your_performance: z.object({ ctr: z.number(), cpc: z.number(), cpm: z.number(), conversion_rate: z.number(), cpa: z.number(), roas: z.number(), }), comparison: z.array(z.object({ metric: z.string(), your_value: z.number(), industry_avg: z.number(), difference_percent: z.number(), rating: z.enum(['above_average', 'average', 'below_average']), })), recommendations: z.array(z.string()), }); - src/models/adops.ts:480-483 (schema)CompetitorBenchmarkInputSchema - input validation schema (industry string + optional platform filter).
export const CompetitorBenchmarkInputSchema = z.object({ industry: z.string().describe('Industry for benchmarking (e.g., "ecommerce", "saas", "finance")'), platform: PlatformSchema.optional(), }); - src/services/analytics.ts:424-426 (helper)round() helper function used to round numbers to 2 decimal places in the benchmark calculations.
function round(n: number): number { return Math.round(n * 100) / 100; }