metrx_run_cost_leak_scan
Scan your agent fleet to identify cost inefficiencies like idle agents and model overprovisioning, then receive a scored report with fix recommendations and estimated monthly savings.
Instructions
Run a comprehensive cost leak audit across your entire agent fleet. Identifies 7 types of cost inefficiencies: idle agents, model overprovisioning, missing caching, high error rates, context bloat, missing budgets, and cross-provider arbitrage opportunities (covers anthropic, cohere, google, mistral, openai). Returns a scored report with fix recommendations and estimated monthly savings. Supports output_format="json" for machine-readable output in CI/CD pipelines. Do NOT use as a continuous monitoring loop — use configure_alert_threshold for ongoing monitoring. Do NOT use for fixing leaks — use apply_optimization for one-click fixes.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | No | Scan a specific agent instead of the entire fleet | |
| include_low_severity | No | Include low-severity findings in the report | |
| output_format | No | Output format: "text" (default) returns a human-readable markdown report; "json" returns raw machine-readable JSON suitable for CI/CD pipelines and programmatic processing. | text |
Implementation Reference
- src/tools/cost-leak-detector.ts:47-166 (handler)The complete tool registration and handler implementation. The registerCostLeakDetectorTools function registers the tool as 'run_cost_leak_scan' (which gets prefixed to 'metrx_run_cost_leak_scan' by the server factory). The handler (lines 87-165) fetches cost leak data from the API, processes it, and returns either JSON or formatted text reports.
export function registerCostLeakDetectorTools(server: McpServer, client: MetrxApiClient): void { server.registerTool( 'run_cost_leak_scan', { title: 'Run Cost Leak Scan', description: 'Run a comprehensive cost leak audit across your entire agent fleet. ' + 'Identifies 7 types of cost inefficiencies: idle agents, model overprovisioning, ' + 'missing caching, high error rates, context bloat, missing budgets, and ' + `cross-provider arbitrage opportunities (covers ${getCoveredProviders().join(', ')}). ` + 'Returns a scored report with fix recommendations and estimated monthly savings. ' + 'Supports output_format="json" for machine-readable output in CI/CD pipelines. ' + 'Do NOT use as a continuous monitoring loop — use configure_alert_threshold for ongoing monitoring. ' + 'Do NOT use for fixing leaks — use apply_optimization for one-click fixes.', inputSchema: { agent_id: z .string() .uuid() .optional() .describe('Scan a specific agent instead of the entire fleet'), include_low_severity: z .boolean() .default(false) .describe('Include low-severity findings in the report'), output_format: z .enum(['text', 'json']) .default('text') .optional() .describe( 'Output format: "text" (default) returns a human-readable markdown report; ' + '"json" returns raw machine-readable JSON suitable for CI/CD pipelines and programmatic processing.' ), }, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }, async ({ agent_id, include_low_severity, output_format }) => { const fmt = output_format ?? 'text'; // Fetch fleet data from the API const params: Record<string, string> = { include_optimization: 'true', include_cost_leak_scan: 'true', }; if (agent_id) params.agent_id = agent_id; const result = await client.get<{ cost_leak_report?: CostLeakReport; }>('/dashboard', params); if (result.error) { if (fmt === 'json') { return { content: [ { type: 'text', text: JSON.stringify({ error: result.error }, null, 2), }, ], isError: true, }; } return { content: [{ type: 'text', text: `Error running cost leak scan: ${result.error}` }], isError: true, }; } const report = result.data?.cost_leak_report; if (!report) { // If the API doesn't support cost leak scanning yet, // return a helpful message if (fmt === 'json') { return { content: [ { type: 'text', text: JSON.stringify( { status: 'computing', message: 'Cost leak scanning is being computed. Please check back in a few minutes, ' + 'or use get_optimization_recommendations for individual agent analysis.', }, null, 2 ), }, ], }; } return { content: [ { type: 'text', text: 'Cost leak scanning is being computed. Please check back in a few minutes, ' + 'or use get_optimization_recommendations for individual agent analysis.', }, ], }; } if (fmt === 'json') { return { content: [{ type: 'text', text: JSON.stringify(report, null, 2) }], }; } const text = formatCostLeakReport(report, include_low_severity ?? false); return { content: [{ type: 'text', text }], }; } ); - Input schema definition using Zod for the tool parameters: agent_id (optional UUID), include_low_severity (boolean, default false), and output_format (enum 'text'|'json', default 'text').
agent_id: z .string() .uuid() .optional() .describe('Scan a specific agent instead of the entire fleet'), include_low_severity: z .boolean() .default(false) .describe('Include low-severity findings in the report'), output_format: z .enum(['text', 'json']) .default('text') .optional() .describe( 'Output format: "text" (default) returns a human-readable markdown report; ' + '"json" returns raw machine-readable JSON suitable for CI/CD pipelines and programmatic processing.' ), }, - TypeScript interfaces defining the data structures: LeakFinding (check, severity, agent info, description, waste estimate, fix, auto_fixable) and CostLeakReport (scan metadata, totals, findings array, health score).
interface LeakFinding { check: string; severity: 'critical' | 'high' | 'medium' | 'low'; agent_id?: string; agent_name?: string; description: string; estimated_waste_monthly_cents: number; fix: string; auto_fixable: boolean; } interface CostLeakReport { scan_timestamp: string; total_agents_scanned: number; total_leaks_found: number; total_estimated_waste_monthly_cents: number; findings: LeakFinding[]; health_score: number; // 0-100 } - src/server-factory.ts:42-68 (registration)Server factory code that adds the 'metrx_' prefix to all tool registrations and wraps handlers with rate limiting middleware. This transforms 'run_cost_leak_scan' to 'metrx_run_cost_leak_scan'.
// Add rate limiting middleware + metrx_ namespace prefix const METRX_PREFIX = 'metrx_'; const originalRegisterTool = server.registerTool.bind(server); (server as any).registerTool = function ( name: string, config: any, handler: (...handlerArgs: any[]) => Promise<any> ) { const wrappedHandler = async (...handlerArgs: any[]) => { if (!rateLimiter.isAllowed(name)) { return { content: [ { type: 'text' as const, text: `Rate limit exceeded for tool '${name}'. Maximum 60 requests per minute allowed.`, }, ], isError: true, }; } return handler(...handlerArgs); }; // Register with metrx_ prefix (primary name only — no deprecated aliases) const prefixedName = name.startsWith(METRX_PREFIX) ? name : `${METRX_PREFIX}${name}`; originalRegisterTool(prefixedName, config, wrappedHandler); }; - src/server-factory.ts:76-76 (registration)The call to registerCostLeakDetectorTools which activates the metrx_run_cost_leak_scan tool in the MCP server.
registerCostLeakDetectorTools(server, apiClient);