Skip to main content
Glama

Evaluate Translation Quality

xcomet_evaluate
Read-onlyIdempotent

Evaluate translation quality by analyzing source and translated text, returning a score (0-1), detected errors with severity, and a summary.

Instructions

Evaluate the quality of a translation using xCOMET model.

This tool analyzes a source text and its translation, providing:

  • A quality score between 0 and 1 (higher is better)

  • Detected error spans with severity levels (minor/major/critical)

  • A human-readable quality summary

Args:

  • source (string): Original source text to translate from

  • translation (string): Translated text to evaluate

  • reference (string, optional): Reference translation for comparison

  • source_lang (string, optional): Source language code (ISO 639-1)

  • target_lang (string, optional): Target language code (ISO 639-1)

  • response_format ('json' | 'markdown'): Output format (default: 'json')

  • use_gpu (boolean, optional): Use GPU for inference if available (default: false)

Returns: For JSON format: { "score": number, // Quality score 0-1 "errors": [ // Detected errors { "text": string, "start": number, "end": number, "severity": "minor" | "major" | "critical" } ], "summary": string // Human-readable summary }

Examples:

  • Evaluate EN→JA translation quality

  • Check if MT output needs post-editing

  • Compare translation against reference

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sourceYesOriginal source text
translationYesTranslated text to evaluate
referenceNoOptional reference translation for comparison
source_langNoSource language code (ISO 639-1, e.g., 'en', 'ja')
target_langNoTarget language code (ISO 639-1, e.g., 'en', 'ja')
response_formatNoOutput format: 'json' for structured data or 'markdown' for human-readablejson
use_gpuNoUse GPU for inference (faster if available). Default: false (CPU only)

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
scoreYesQuality score between 0 and 1
errorsYesDetected error spans
summaryYesHuman-readable quality summary

Implementation Reference

  • Registration and handler for the xcomet_evaluate MCP tool. The handler calls xCometService.evaluate() with source, translation, reference, and use_gpu params, then formats the result as JSON or markdown.
    // Tool: xcomet_evaluate
    server.registerTool(
      "xcomet_evaluate",
      {
        title: "Evaluate Translation Quality",
        description: TOOL_DESCRIPTIONS.evaluate,
        inputSchema: {
          source: EvaluateInputSchema.shape.source,
          translation: EvaluateInputSchema.shape.translation,
          reference: EvaluateInputSchema.shape.reference,
          source_lang: EvaluateInputSchema.shape.source_lang,
          target_lang: EvaluateInputSchema.shape.target_lang,
          response_format: EvaluateInputSchema.shape.response_format,
          use_gpu: EvaluateInputSchema.shape.use_gpu,
        },
        outputSchema: {
          score: EvaluateOutputSchema.shape.score,
          errors: EvaluateOutputSchema.shape.errors,
          summary: EvaluateOutputSchema.shape.summary,
        },
        annotations: READ_ONLY_ANNOTATIONS,
      },
      async (params: EvaluateInput) => {
        try {
          const result = await xCometService.evaluate(
            params.source,
            params.translation,
            params.reference,
            params.use_gpu
          );
          return createToolResponse(result, params.response_format, "Translation Quality Evaluation");
        } catch (error) {
          return createErrorResponse(error, "evaluating translation");
        }
      }
    );
  • EvaluateInputSchema defines the input parameters for xcomet_evaluate: source (required), translation (required), reference (optional), source_lang (optional ISO code), target_lang (optional ISO code), response_format (json/markdown, default json), use_gpu (boolean, default false).
    export const EvaluateInputSchema = z.object({
      source: z
        .string()
        .min(1, "Source text is required")
        .max(MAX_TEXT_LENGTH, `Source text must not exceed ${MAX_TEXT_LENGTH} characters`)
        .describe("Original source text"),
      translation: z
        .string()
        .min(1, "Translation text is required")
        .max(MAX_TEXT_LENGTH, `Translation text must not exceed ${MAX_TEXT_LENGTH} characters`)
        .describe("Translated text to evaluate"),
      reference: z
        .string()
        .max(MAX_TEXT_LENGTH)
        .optional()
        .describe("Optional reference translation for comparison"),
      source_lang: z
        .string()
        .length(2)
        .optional()
        .describe("Source language code (ISO 639-1, e.g., 'en', 'ja')"),
      target_lang: z
        .string()
        .length(2)
        .optional()
        .describe("Target language code (ISO 639-1, e.g., 'en', 'ja')"),
      response_format: ResponseFormat.default("json").describe(
        "Output format: 'json' for structured data or 'markdown' for human-readable"
      ),
      use_gpu: UseGpuSchema,
    });
    export type EvaluateInput = z.infer<typeof EvaluateInputSchema>;
  • EvaluateOutputSchema defines the return type: score (0-1), errors array with text/start/end/severity, and a human-readable summary string.
    export const EvaluateOutputSchema = z.object({
      score: z.number().min(0).max(1).describe("Quality score between 0 and 1"),
      errors: z
        .array(
          z.object({
            text: z.string().describe("Error span text"),
            start: z.number().describe("Start position in translation"),
            end: z.number().describe("End position in translation"),
            severity: ErrorSeverity.describe("Error severity level"),
          })
        )
        .describe("Detected error spans"),
      summary: z.string().describe("Human-readable quality summary"),
    });
    export type EvaluateOutput = z.infer<typeof EvaluateOutputSchema>;
  • The XCometService.evaluate() method that performs the actual evaluation logic. It validates reference requirements, sends a 'evaluate' RPC request to the Python server via stdio JSON-RPC protocol, and returns the EvaluateOutput.
    async evaluate(
      source: string,
      translation: string,
      reference?: string,
      useGpu: boolean = false
    ): Promise<EvaluateOutput> {
      // Validate reference requirement
      if (!reference && modelRequiresReference(this.config.model)) {
        throw new Error(XCometServiceErrors.referenceRequired(this.config.model));
      }
    
      const result = await this.serverManager.request<EvaluateOutput>(
        "evaluate",
        {
          source,
          translation,
          reference,
          use_gpu: useGpu,
        },
        this.config.timeout
      );
    
      return result;
    }
  • formatAsMarkdown helper used by createToolResponse to render evaluation results as a human-readable markdown string with star ratings, quality score percentage, and error tables.
    function formatAsMarkdown(data: Record<string, unknown>, title: string): string {
      let md = `## ${title}\n\n`;
    
      if ("score" in data && typeof data.score === "number") {
        const score = data.score;
        const stars = score >= 0.9 ? "⭐⭐⭐⭐⭐" : score >= 0.7 ? "⭐⭐⭐⭐" : score >= 0.5 ? "⭐⭐⭐" : score >= 0.3 ? "⭐⭐" : "⭐";
        md += `**Quality Score:** ${(score * 100).toFixed(1)}% ${stars}\n\n`;
      }
    
      if ("summary" in data && typeof data.summary === "string") {
        md += `**Summary:** ${data.summary}\n\n`;
      }
    
      if ("errors" in data && Array.isArray(data.errors) && data.errors.length > 0) {
        md += `### Detected Errors\n\n`;
        md += `| Severity | Text | Position |\n`;
        md += `|----------|------|----------|\n`;
        for (const error of data.errors) {
          const e = error as { severity: string; text: string; start: number; end: number };
          const severityEmoji = e.severity === "critical" ? "🔴" : e.severity === "major" ? "🟠" : "🟡";
          md += `| ${severityEmoji} ${e.severity} | ${e.text} | ${e.start}-${e.end} |\n`;
        }
        md += "\n";
      }
    
      if ("results" in data && Array.isArray(data.results)) {
        md += `### Batch Results\n\n`;
        md += `| # | Score | Errors | Critical |\n`;
        md += `|---|-------|--------|----------|\n`;
        for (const r of data.results) {
          const result = r as { index: number; score: number; error_count: number; has_critical_errors: boolean };
          md += `| ${result.index + 1} | ${(result.score * 100).toFixed(1)}% | ${result.error_count} | ${result.has_critical_errors ? "⚠️ Yes" : "✓ No"} |\n`;
        }
        md += "\n";
      }
    
      return md;
    }
Behavior5/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds that it uses xCOMET model, returns quality scores, error spans (with severity), and a summary. No contradictions; behavior is fully disclosed with no hidden side effects.

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

Conciseness4/5

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

The description is well-structured with a lead sentence, bullet points for outputs, labeled Args list, Returns section with JSON format, and usage examples. It is slightly verbose but each sentence serves a purpose, making it efficient.

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 7 parameters (2 required), 100% schema coverage, presence of output schema, and sibling tools, the description is complete: describes all parameters, return structure, usage examples, and model name. No gaps for agent decision-making.

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 description coverage is 100%, so baseline is 3. The description adds value by providing more context for each parameter (e.g., 'source: Original source text to translate from') and showing the return format with example output. This goes beyond schema terseness.

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 the tool evaluates translation quality using xCOMET model. It lists specific outputs (score, errors, summary) and examples. It distinguishes from siblings (xcomet_batch_evaluate for batch, xcomet_detect_errors for error-only) by focusing on single pair evaluation with full output.

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?

The description provides usage examples (evaluate EN→JA, check post-editing need, compare against reference) which imply when to use. It does not explicitly state when not to use or mention alternatives, but sibling tools are known. Still, clear context for single evaluation.

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/shuji-bonji/xcomet-mcp-server'

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