Skip to main content
Glama

estimate_conversion_cost

Read-onlyIdempotent

Estimate credit cost for a document conversion before executing. Returns word count, page estimate, and credit breakdown to prevent insufficient balance errors.

Instructions

Estimate credit cost for a conversion BEFORE running it. Returns word count, page calculation (300 words/page), and a credit breakdown by format and template type. Use this when the user asks 'how much will this cost?' or when you suspect a conversion might exceed their balance — convert_document refuses to run if credits are insufficient, so estimating first is friendlier.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
contentYesMarkdown content to estimate credit cost for
templateNameYesTemplate ID or name (UUID for custom templates, name for system templates)
outputFormatYesOutput format(s): docx (DOCX only), pdf (DOCX+PDF), html (DOCX+HTML), all/all-formats (DOCX+PDF+HTML)
pageSizeNoPage size for the document
orientationNoPage orientation

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
wordCountNoWord count of the markdown content
pageCountNoEstimated page count (300 words/page)
totalCreditsYesTotal credits required for this conversion
breakdownNoHuman-readable breakdown of how credits are calculated

Implementation Reference

  • Core handler function that estimates credit cost for a document conversion. Takes content, templateName, outputFormat (and optional pageSize/orientation), calculates credits via CreditCalculator, fetches current balance, and returns a formatted string with word count, page calculation, credit breakdown, and balance comparison.
    export async function handleEstimateConversionCost(
      creditCalculator: CreditCalculator,
      args: {
        content: string;
        templateName: string;
        outputFormat: string;
        pageSize?: string;
        orientation?: string;
      }
    ): Promise<string> {
      try {
        console.error('[EstimateConversionCost] Calculating credit estimate...');
        
        const { content, templateName, outputFormat } = args;
        
        // Determine output formats based on request
        let outputFormats: string[];
        if (outputFormat === 'docx') {
          outputFormats = ['docx']; // DOCX only
        } else if (outputFormat === 'all' || outputFormat === 'all-formats') {
          outputFormats = ['docx', 'pdf', 'html']; // ALL THREE FORMATS
        } else {
          outputFormats = ['docx', outputFormat]; // DOCX + one other format
        }
    
        // Calculate credits
        const calculation = await creditCalculator.calculateCredits(content, templateName, outputFormats);
        
        // Get current balance for comparison
        const balance = await creditCalculator.getCreditBalance();
        
        // Format output description
        const formatDescription = outputFormats.length === 1 
          ? 'DOCX only'
          : outputFormats.length === 2
            ? `DOCX + ${outputFormats[1].toUpperCase()}`
            : 'DOCX + PDF + HTML (all formats)';
    
        // Determine template type
        const templateType = templateName.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
          ? 'Custom Template'
          : 'System Template';
    
        const response = [
          `💳 **Credit Cost Estimate**`,
          ``,
          `**Content Analysis:**`,
          `- Word Count: ${calculation.wordCount} words`,
          `- Pages: ${calculation.pages} (${calculation.wordsPerPage} words per page)`,
          `- Template: ${templateType}`,
          `- Output: ${formatDescription}`,
          ``,
          `**Credit Breakdown:**`,
          `- ${calculation.breakdown}`,
          ``,
          `**Your Balance:**`,
          `- Current Credits: ${balance.total_credits}`,
          `- After Conversion: ${balance.total_credits - calculation.totalCredits} credits`,
          ``,
          balance.total_credits >= calculation.totalCredits
            ? `✅ **You have sufficient credits!** Would you like to proceed with the conversion?`
            : `❌ **Insufficient credits!** You need ${calculation.totalCredits - balance.total_credits} more credits to perform this conversion.`
        ].join('\n');
    
        console.error(`[EstimateConversionCost] ✅ Estimated ${calculation.totalCredits} credits for conversion`);
        return response;
    
      } catch (error) {
        console.error('[EstimateConversionCost] ❌ Error estimating conversion cost:', error);
        const mcpError = handleApiError(error);
        return `❌ Error estimating conversion cost: ${mcpError.message}`;
      }
    }
  • Alternative handler in creditTools.ts that wraps the same logic with Zod schema validation (estimateConversionCostSchema). Returns a CallToolResult with structured content. This is the handler actually referenced in the unified tool registration (src/tools/index.ts).
    export async function handleEstimateConversionCost(
      creditCalculator: CreditCalculator,
      args: any
    ): Promise<CallToolResult> {
      try {
        console.error('[estimate_conversion_cost] Estimating conversion cost...');
        const input = estimateConversionCostSchema.parse(args);
        
        const { content, templateName, outputFormat } = input;
        
        // Determine output formats based on request
        let outputFormats: string[];
        if (outputFormat === 'docx') {
          outputFormats = ['docx']; // DOCX only
        } else if (outputFormat === 'all' || outputFormat === 'all-formats') {
          outputFormats = ['docx', 'pdf', 'html']; // ALL THREE FORMATS
        } else {
          outputFormats = ['docx', outputFormat]; // DOCX + one other format
        }
    
        // Calculate credits
        const calculation = await creditCalculator.calculateCredits(content, templateName, outputFormats);
        
        // Get current balance for comparison
        const balance = await creditCalculator.getCreditBalance();
        
        // Format output description
        const formatDescription = outputFormats.length === 1 
          ? 'DOCX only'
          : outputFormats.length === 2
            ? `DOCX + ${outputFormats[1].toUpperCase()}`
            : 'DOCX + PDF + HTML (all formats)';
    
        // Determine template type
        const templateType = templateName.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
          ? 'Custom Template'
          : 'System Template';
        
        return {
          content: [
            {
              type: 'text',
              text: `💳 **Credit Cost Estimate**
    
    **Content Analysis:**
    - Word Count: ${calculation.wordCount} words
    - Template: ${templateType}
    - Output: ${formatDescription}
    
    **Credit Breakdown:**
    - ${calculation.breakdown}
    
    **Your Balance:**
    - Current Credits: ${balance.total_credits}
    - After Conversion: ${balance.total_credits - calculation.totalCredits} credits
    
    ${balance.total_credits >= calculation.totalCredits
      ? `✅ **You have sufficient credits!** Would you like to proceed with the conversion?`
      : `❌ **Insufficient credits!** You need ${calculation.totalCredits - balance.total_credits} more credits to perform this conversion.`}
    
    💡 This is an estimate. Actual cost may vary slightly based on document complexity.`
            }
          ]
        };
      } catch (error: any) {
        console.error('[estimate_conversion_cost] Error:', error);
        
        if (error.name === 'ZodError') {
          const issues = error.issues.map((issue: any) => `- ${issue.path.join('.')}: ${issue.message}`).join('\n');
          return {
            content: [
              {
                type: 'text',
                text: `❌ Invalid parameters:
    
    ${issues}
    
    💡 Please check your input and try again.`
              }
            ],
            isError: true
          };
        }
        
        throw error; // Let unified handler deal with it
      }
    }
  • Zod schema for runtime input validation: validates content (string), templateName (string), outputFormat (enum docx/pdf/html/all/all-formats), pageSize (enum A3/A4/Executive/US_Legal/US_Letter, default A4), orientation (enum Portrait/Landscape, default Portrait).
    export const estimateConversionCostSchema = z.object({
      content: z.string().describe("Markdown content to estimate credit cost for"),
      templateName: z.string().describe("Template ID or name (UUID for custom templates, name for system templates)"),
      outputFormat: z.enum(['docx', 'pdf', 'html', 'all', 'all-formats']).describe("Output format(s): docx (DOCX only), pdf (DOCX+PDF), html (DOCX+HTML), all/all-formats (DOCX+PDF+HTML)"),
      pageSize: z.enum(['A3', 'A4', 'Executive', 'US_Legal', 'US_Letter']).default('A4').describe("Page size for the document"),
      orientation: z.enum(['Portrait', 'Landscape']).default('Portrait').describe("Page orientation")
    });
  • Tool definition object with name 'estimate_conversion_cost', description, and inputSchema (JSON Schema) defining the same parameters as the Zod schema. Also serves as a standalone tool definition in its own file.
    export const estimateConversionCost: Tool = {
      name: 'estimate_conversion_cost',
      description: 'Estimate credit cost for a conversion without performing it. Shows word count, page calculation, and detailed credit breakdown.',
      inputSchema: {
        type: 'object',
        properties: {
          content: {
            type: 'string',
            description: 'Markdown content to estimate credit cost for'
          },
          templateName: {
            type: 'string',
            description: 'Template ID or name (UUID for custom templates, name for system templates)'
          },
          outputFormat: {
            type: 'string',
            enum: ['docx', 'pdf', 'html', 'all', 'all-formats'],
            description: 'Output format(s): docx (DOCX only), pdf (DOCX+PDF), html (DOCX+HTML), all/all-formats (DOCX+PDF+HTML)'
          },
          pageSize: {
            type: 'string',
            enum: ['A3', 'A4', 'Executive', 'US_Legal', 'US_Letter'],
            description: 'Page size for the document',
            default: 'A4'
          },
          orientation: {
            type: 'string',
            enum: ['Portrait', 'Landscape'],
            description: 'Page orientation',
            default: 'Portrait'
          }
        },
        required: ['content', 'templateName', 'outputFormat']
      }
    };
  • Unified handler registration: routes 'estimate_conversion_cost' tool requests to handleEstimateConversionCost(creditCalculator, args) from creditTools.ts.
            case 'estimate_conversion_cost':
              return await handleEstimateConversionCost(creditCalculator, request.params.arguments);
    
            case 'validate_markdown':
              return await handleValidateMarkdown(apiClient, request.params.arguments);
    
            case 'get_template_details':
              return await handleGetTemplateDetails(apiClient, request.params.arguments);
    
            case 'recommend_template':
              return await handleRecommendTemplate(apiClient, request.params.arguments);
    
            default:
              throw new Error(`Unknown tool: ${toolName}`);
          }
        } catch (error: any) {
          console.error(`[MCP] Error handling ${toolName}:`, error);
          return {
            content: [
              {
                type: "text",
                text: `❌ Error: ${error.message}`
              }
            ],
            isError: true
          };
        }
      });
    
      console.error('✅ All MCP tools registered successfully with unified handler');
      console.error('📋 Available tools: convert_document, list_all_templates, list_builtin_templates, list_custom_templates, show_default_settings, check_credit_balance, estimate_conversion_cost, validate_markdown, get_template_details, recommend_template');
    }
Behavior5/5

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

Annotations already declare readOnly=true, destructive=false, idempotent=true. Description adds context that convert_document refuses if insufficient credits, explaining the behavioral context of the estimate. No contradictions.

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?

Three sentences, each valuable: first states purpose, second lists return values, third gives when-to-use guidance. No fluff.

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

Completeness5/5

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

Given 5 parameters with full schema descriptions and an output schema (present), the description effectively covers usage context, behavioral traits, and relationship to sibling tool convert_document. Complete for an estimation tool.

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

Parameters4/5

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

Schema has 100% coverage with descriptions for all 5 parameters. The description adds value by explaining that the estimate includes credit breakdown by format and template type, and mentions the 300 words/page calculation, which provides additional insight into how parameters affect the result.

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?

The description clearly states it estimates credit cost before conversion, specifies return values (word count, page calculation, credit breakdown), and distinguishes itself from convert_document by mentioning it is friendly to use before running the actual conversion.

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

Usage Guidelines5/5

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

Explicitly tells when to use: when user asks 'how much will this cost?' or when suspecting insufficient balance. Also contrasts with convert_document that refuses if credits are insufficient, making the estimation alternative clear.

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/MDMagic-MCP/mdmagic-mcp-server'

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