UNPKG

noodle-perplexity-mcp

Version:

A Perplexity API Model Context Protocol (MCP) server that unlocks Perplexity's search-augmented AI capabilities for LLM agents. Features robust error handling, secure input validation, and transparent reasoning with the showThinking parameter. Built with

101 lines (100 loc) 3.66 kB
import { logger } from '../index.js'; // --- Pricing Data Structures --- // Rates are typically per million tokens or per 1000 requests/searches const PER_MILLION = 1000000; const PER_THOUSAND = 1000; // --- Current Perplexity Model Pricing --- // Based on documentation from 2025-07-05 const modelPricingSheet = { 'sonar': { tokenPricing: { input: 1.00, output: 1.00 }, actionPricing: { requestFeesByTier: { low: 5, medium: 8, high: 12 } } }, 'sonar-pro': { tokenPricing: { input: 3.00, output: 15.00 }, actionPricing: { requestFeesByTier: { low: 6, medium: 10, high: 14 } } }, 'sonar-reasoning': { tokenPricing: { input: 1.00, output: 5.00 }, actionPricing: { requestFeesByTier: { low: 5, medium: 8, high: 12 } } }, 'sonar-reasoning-pro': { tokenPricing: { input: 2.00, output: 8.00 }, actionPricing: { requestFeesByTier: { low: 6, medium: 10, high: 14 } } }, 'sonar-deep-research': { tokenPricing: { input: 2.00, output: 8.00, citation: 2.00, reasoning: 3.00, }, actionPricing: { searchQueryFee: 5.00 } } }; // --- Cost Calculation Logic --- /** * Calculates the estimated cost of a Perplexity API call. * * @param model - The name of the Perplexity model used. * @param usage - The token and action usage data from the API response. * @param apiTier - The API tier used ('low', 'medium', 'high'), which may affect request fees. * @param context - The request context for logging. * @returns The estimated cost in USD, or null if pricing info is unavailable. */ export function calculatePerplexityCost(model, usage, apiTier, context) { const operation = 'calculatePerplexityCost'; const pricing = modelPricingSheet[model]; if (!pricing) { logger.error(`Pricing information not found for model: ${model}`, { ...context, operation, model }); return null; } let cost = 0; // 1. Calculate Token Costs const { tokenPricing } = pricing; cost += (usage.prompt_tokens / PER_MILLION) * tokenPricing.input; cost += (usage.completion_tokens / PER_MILLION) * tokenPricing.output; if (tokenPricing.reasoning && usage.reasoning_tokens) { cost += (usage.reasoning_tokens / PER_MILLION) * tokenPricing.reasoning; } if (tokenPricing.citation && usage.citation_tokens) { cost += (usage.citation_tokens / PER_MILLION) * tokenPricing.citation; } // 2. Calculate Action Costs const { actionPricing } = pricing; if (actionPricing.requestFeesByTier && apiTier) { const requestFeePerThousand = actionPricing.requestFeesByTier[apiTier]; if (requestFeePerThousand !== undefined) { cost += requestFeePerThousand / PER_THOUSAND; // Cost for a single request } else { logger.warning(`API tier '${apiTier}' not found for model ${model}. Request fee not applied.`, { ...context, operation, model }); } } if (actionPricing.searchQueryFee && usage.search_queries) { cost += (usage.search_queries / PER_THOUSAND) * actionPricing.searchQueryFee; } logger.debug(`Calculated cost for model ${model}`, { ...context, operation, model, usage, apiTier: apiTier ?? 'N/A', estimatedCost: cost, }); // Return cost rounded to a reasonable number of decimal places (e.g., 6) return parseFloat(cost.toFixed(6)); } export const costTracker = { calculatePerplexityCost, };