Skip to main content
Glama
A7OM-AI

atom-mcp-server

by A7OM-AI

Compare Prices Across Vendors

compare_prices
Read-onlyIdempotent

Compare AI model prices across vendors to find the lowest inference costs. Search specific models or families and sort by price for cost optimization and vendor selection.

Instructions

Cross-vendor price comparison for a specific model or model family.

Shows the same model (or family) priced across different vendors, sorted cheapest first. Essential for cost optimization and vendor selection.

Examples:

  • "Compare Llama 3.1 70B pricing across vendors" → model_name="Llama 3.1 70B"

  • "Cheapest GPT-4 family output pricing" → model_family="GPT-4", direction="Output"

  • "Claude pricing comparison" → model_family="Claude"

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
model_nameNoModel name to compare prices for, e.g. 'GPT-4o', 'Llama 3.1 70B'
model_familyNoModel family to compare, e.g. 'GPT-4o', 'Claude 3.5'
directionNoFilter by pricing direction
modalityNoFilter by modality: Text, Image, Audio, etc.
limitNoMaximum results (default 50)
_atom_api_keyNoYour ATOM API key for full access. Omit for free tier (redacted data).

Implementation Reference

  • Main handler function that executes the compare_prices tool logic. Takes parameters and tier, validates required fields (model_name or model_family), queries the sku_index table from Supabase, filters by model_family if needed, handles free vs paid tier result gating, and returns price comparison results with stats like cheapest/most expensive and spread ratio.
    export async function handleComparePrices(
      params: z.infer<z.ZodObject<typeof comparePricesSchema>>,
      tier: Tier
    ) {
      if (!params.model_name && !params.model_family) {
        return {
          content: [
            {
              type: "text" as const,
              text: JSON.stringify({
                tool: "compare_prices",
                error: "Please provide either model_name or model_family to compare.",
              }),
            },
          ],
        };
      }
    
      const filters: string[] = [];
      if (params.model_name) filters.push(`model_name=ilike.*${params.model_name}*`);
      if (params.direction) filters.push(`direction=eq.${params.direction}`);
      if (params.modality) filters.push(`modality=ilike.*${params.modality}*`);
      filters.push("normalized_price=gt.0");
    
      let skus = await queryTable<SkuIndex>("sku_index", filters, {
        select: "sku_id,vendor_name,model_name,modality,direction,normalized_price,normalized_price_unit,billing_method",
        order: "normalized_price.asc",
        limit: params.limit,
      });
    
      // If model_family was provided, filter by model registry
      if (params.model_family && !params.model_name) {
        const models = await queryTable<{ model_id: string }>("model_registry", [
          `model_family=ilike.*${params.model_family}*`,
        ], {
          select: "model_id",
        });
        const modelIds = new Set(models.map((m) => m.model_id));
    
        // Re-query SKUs without model_name filter
        const familyFilters: string[] = [];
        if (params.direction) familyFilters.push(`direction=eq.${params.direction}`);
        if (params.modality) familyFilters.push(`modality=ilike.*${params.modality}*`);
        familyFilters.push("normalized_price=gt.0");
    
        const allSkus = await queryTable<SkuIndex>("sku_index", familyFilters, {
          select: "sku_id,model_id,vendor_name,model_name,modality,direction,normalized_price,normalized_price_unit,billing_method",
          order: "normalized_price.asc",
          limit: 200,
        });
    
        skus = allSkus.filter((s) => modelIds.has(s.model_id)).slice(0, params.limit);
      }
    
      if (skus.length === 0) {
        return {
          content: [
            {
              type: "text" as const,
              text: JSON.stringify({
                tool: "compare_prices",
                error: `No pricing data found for '${params.model_name || params.model_family}'.`,
              }),
            },
          ],
        };
      }
    
      const prices = skus
        .map((s) => s.normalized_price)
        .filter((p): p is number => p !== null && p > 0);
    
      let results: unknown;
    
      if (tier === "paid") {
        results = {
          comparisons: skus,
          stats: {
            total: skus.length,
            vendors: [...new Set(skus.map((s) => s.vendor_name))].length,
            cheapest: prices.length > 0 ? prices[0] : null,
            most_expensive: prices.length > 0 ? prices[prices.length - 1] : null,
            spread_ratio:
              prices.length >= 2
                ? +(prices[prices.length - 1] / prices[0]).toFixed(2)
                : null,
          },
        };
      } else {
        results = {
          summary: {
            total_vendors: [...new Set(skus.map((s) => s.vendor_name))].length,
            total_skus: skus.length,
            price_range: {
              min: prices.length > 0 ? prices[0] : null,
              max: prices.length > 0 ? prices[prices.length - 1] : null,
            },
            spread_ratio:
              prices.length >= 2
                ? +(prices[prices.length - 1] / prices[0]).toFixed(2)
                : null,
            directions: [...new Set(skus.map((s) => s.direction))],
          },
          sample: gateResults(
            skus.slice(0, 3) as unknown as Record<string, unknown>[],
            "free"
          ),
          upgrade_message:
            "Full vendor-by-vendor comparison requires ATOM MCP Pro ($49/mo). Visit https://a7om.com/mcp",
        };
      }
    
      const content: { type: "text"; text: string }[] = [
        {
          type: "text" as const,
          text: JSON.stringify(
            {
              tool: "compare_prices",
              tier,
              query: {
                model_name: params.model_name,
                model_family: params.model_family,
                direction: params.direction,
                modality: params.modality,
              },
              results,
            },
            null,
            2
          ),
        },
      ];
    
      if (tier === "free") {
        content.push(freeTierNote("Full vendor-by-vendor price comparison"));
      }
    
      return { content };
    }
  • Zod schema definition for the compare_prices tool inputs. Defines optional fields for model_name, model_family, direction (enum), modality, and limit (default 50). Used for input validation and type inference.
    export const comparePricesSchema = {
      model_name: z
        .string()
        .optional()
        .describe("Model name to compare prices for, e.g. 'GPT-4o', 'Llama 3.1 70B'"),
      model_family: z
        .string()
        .optional()
        .describe("Model family to compare, e.g. 'GPT-4o', 'Claude 3.5'"),
      direction: z
        .enum(["Input", "Output", "Cached Input"])
        .optional()
        .describe("Filter by pricing direction"),
      modality: z
        .string()
        .optional()
        .describe("Filter by modality: Text, Image, Audio, etc."),
      limit: z
        .coerce.number()
        .int()
        .min(1)
        .max(100)
        .default(50)
        .describe("Maximum results (default 50)"),
    };
  • src/server.ts:96-123 (registration)
    Tool registration in the MCP server. Registers 'compare_prices' with title, description, input schema (merged with apiKeyField), annotations, and handler callback that resolves tier and calls handleComparePrices.
      // ----------------------------------------------------------
      // 3. compare_prices
      // ----------------------------------------------------------
      server.registerTool(
        "compare_prices",
        {
          title: "Compare Prices Across Vendors",
          description: `Cross-vendor price comparison for a specific model or model family.
    
    Shows the same model (or family) priced across different vendors, sorted cheapest first. Essential for cost optimization and vendor selection.
    
    Examples:
      - "Compare Llama 3.1 70B pricing across vendors" → model_name="Llama 3.1 70B"
      - "Cheapest GPT-4 family output pricing" → model_family="GPT-4", direction="Output"
      - "Claude pricing comparison" → model_family="Claude"`,
          inputSchema: { ...comparePricesSchema, ...apiKeyField },
          annotations: {
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: false,
          },
        },
        async (params) => {
          const tier = await resolveTier(params._atom_api_key);
          return handleComparePrices(params, tier);
        }
      );
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds crucial behavioral detail not present in annotations: results are 'sorted cheapest first.' Annotations already establish read-only/idempotent safety (readOnlyHint=true, destructiveHint=false), so description appropriately focuses on business logic behavior rather than safety. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Perfectly structured with one-line purpose, behavioral constraint (sorting), use case context (cost optimization), and three targeted examples. Every sentence serves a distinct function; no redundancy or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 6 parameters with complete schema coverage and safety annotations, the description provides excellent context through examples. Minor gap: no output schema exists, and description could briefly characterize the return value (e.g., 'returns list of vendor offers') to complete the picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 100% schema coverage, the examples section adds substantial semantic value by demonstrating the relationship between model_name and model_family parameters, and showing how to map user intent (e.g., 'Cheapest GPT-4 family') to specific parameter values including the direction enum.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with specific verb 'Cross-vendor price comparison' and identifies the resource (prices for specific models/families). Distinct from siblings like get_vendor_catalog (which likely lists vendors without price comparison) and get_model_detail (which provides specifications rather than pricing).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides three concrete examples mapping natural language queries to exact parameter combinations, giving clear context for how to use model_name vs model_family and direction parameters. Lacks explicit 'when not to use' or named sibling alternatives, but examples provide strong implicit guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/A7OM-AI/atom-mcp-server'

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