Guide · Amazon Translate · Custom Terminology
MCP Server AWS Translate Custom Terminology — ImportTerminologyCommand, directionality
Amazon Translate custom terminologies let you enforce exact translations for domain-specific words — product names, technical terms, brand vocabulary — that the neural translation model would otherwise paraphrase. You import a terminology file (CSV or TMX format) with ImportTerminologyCommand, then reference it by name in TranslateTextCommand via TerminologyNames. When a source term from the file appears in the input, Translate substitutes your pre-approved translation verbatim rather than generating one. The two directionality modes are UNI (one-way: source language → one target language) and MULTI (source language → any supported target language using per-language target columns in the CSV). Get the directionality wrong and either Translate silently ignores the terminology or raises a ValidationException at import time.
TL;DR
Create a CSV file with columns en, es, fr (etc.) — first column is source language, remaining columns are target languages. Import with ImportTerminologyCommand({ Name, MergeStrategy: 'OVERWRITE', TerminologyData: { File: csvBuffer, Format: 'CSV', Directionality: 'MULTI' } }). Apply by passing TerminologyNames: ['my-terminology'] to TranslateTextCommand. Check response.AppliedTerminologies to confirm terms were matched and substituted. Up to 100 terminologies per account; each file up to 10MB; up to 256 entries in the file for MULTI directionality.
Terminology file format: CSV vs TMX
Amazon Translate accepts two file formats: CSV (comma-separated values, easiest to maintain in a spreadsheet) and TMX (Translation Memory eXchange, the standard used by professional translation tools). For MCP server use cases, CSV is simpler to generate programmatically from a configuration object or database query.
A MULTI-directionality CSV has a header row listing language codes, followed by one row per term. The first column is the source language. Each subsequent column is a target language. Leave a cell blank if you have no approved translation for that language yet.
# terminology-multi.csv — MULTI directionality (source → many targets)
en,es,fr,de,ja
MCP server,servidor MCP,serveur MCP,MCP-Server,MCPサーバー
uptime monitoring,monitoreo de tiempo de actividad,surveillance de disponibilité,Verfügbarkeitsüberwachung,稼働時間監視
health check,verificación de estado,vérification de l'état,Integritätsprüfung,ヘルスチェック
AliveMCP,AliveMCP,AliveMCP,AliveMCP,AliveMCP
A UNI-directionality CSV has exactly two columns: source term and target term. It maps one source language to exactly one target language — the target language must match the TargetLanguageCode at translation time.
# terminology-uni.csv — UNI directionality (source → single target only)
en,es
MCP server,servidor MCP
uptime monitoring,monitoreo de tiempo de actividad
health check,verificación de estado
Case sensitivity: matches are case-sensitive by default. The term MCP server will match in source text that contains exactly MCP server but not mcp server or MCP Server. Import a separate entry for each casing variant you want to protect, or use the AppliedTerminologies response field to verify at runtime which terms were actually matched.
Importing a terminology with ImportTerminologyCommand
Terminologies are account-and-region-scoped — a terminology imported in us-east-1 is not visible in eu-west-1. Import once and reference by name. MergeStrategy: 'OVERWRITE' replaces the existing terminology if a file with the same name already exists.
import {
TranslateClient,
ImportTerminologyCommand,
type ImportTerminologyCommandInput,
} from '@aws-sdk/client-translate';
import { readFileSync } from 'fs';
const translate = new TranslateClient({ region: process.env.AWS_REGION ?? 'us-east-1' });
export async function importTerminology(
name: string,
csvPath: string,
directionality: 'UNI' | 'MULTI' = 'MULTI',
): Promise<void> {
const csvBuffer = readFileSync(csvPath); // Buffer / Uint8Array
const input: ImportTerminologyCommandInput = {
Name: name, // unique identifier within the account+region
MergeStrategy: 'OVERWRITE', // 'OVERWRITE' (replace) | 'FAIL_ON_CONFLICT' (error if exists)
TerminologyData: {
File: csvBuffer, // raw bytes of the CSV or TMX file
Format: 'CSV', // 'CSV' | 'TMX'
Directionality: directionality, // 'UNI' | 'MULTI'
},
Description: 'MCP server domain terminology — MCP-specific vocabulary',
};
const response = await translate.send(new ImportTerminologyCommand(input));
console.log('Terminology imported:', {
name: response.TerminologyProperties?.Name,
sourceLanguage: response.TerminologyProperties?.SourceLanguageCode,
targetLanguages: response.TerminologyProperties?.TargetLanguageCodes,
termCount: response.TerminologyProperties?.TermCount,
createdAt: response.TerminologyProperties?.CreatedAt,
});
}
The TerminologyProperties in the response includes TermCount — the number of entries Translate parsed from your file. If TermCount is lower than expected, the file has formatting errors (extra commas, missing language header, BOM at the start of the file). UTF-8 without BOM is required for CSV files.
Applying a terminology in TranslateTextCommand
Pass the terminology name in the TerminologyNames array when calling TranslateTextCommand. Up to 1 custom terminology can be applied per call. The applied terminology must match the SourceLanguageCode and TargetLanguageCode of the translation request — mismatches cause a ResourceNotFoundException at call time (not at import time).
import { TranslateClient, TranslateTextCommand } from '@aws-sdk/client-translate';
const translate = new TranslateClient({ region: process.env.AWS_REGION ?? 'us-east-1' });
export async function translateWithTerminology(
text: string,
targetLang: string,
terminologyName: string,
): Promise<{ translated: string; appliedTerms: string[] }> {
const response = await translate.send(new TranslateTextCommand({
Text: text,
SourceLanguageCode: 'en',
TargetLanguageCode: targetLang,
TerminologyNames: [terminologyName], // array; currently max 1 custom terminology per call
}));
// AppliedTerminologies lists terms from the file that were actually found and substituted
const appliedTerms = (response.AppliedTerminologies ?? []).flatMap(t =>
(t.Terms ?? []).map(term => `${term.SourceText} → ${term.TargetText}`)
);
return {
translated: response.TranslatedText ?? '',
appliedTerms,
};
}
// Usage:
// const result = await translateWithTerminology(
// 'The MCP server health check endpoint returned a timeout.',
// 'es',
// 'mcp-domain-terms',
// );
// result.appliedTerms → ['MCP server → servidor MCP', 'health check → verificación de estado']
AppliedTerminologies[].Terms is a list of { SourceText, TargetText } pairs that were matched. If this array is empty when you expected matches, the most common causes are: (1) case mismatch in the source text vs the terminology entry, (2) the terminology was imported with UNI directionality but the target language in the call is different from the one configured at import, or (3) the term appears inside a larger compound word or phrase that the tokenizer treats as a single unit.
Listing and retrieving terminologies
Use ListTerminologiesCommand to enumerate all terminologies in the account+region, and GetTerminologyCommand to retrieve a terminology's metadata and download its contents as a presigned S3 URL.
import {
TranslateClient,
ListTerminologiesCommand,
GetTerminologyCommand,
} from '@aws-sdk/client-translate';
const translate = new TranslateClient({ region: process.env.AWS_REGION ?? 'us-east-1' });
// List all terminologies
export async function listTerminologies(): Promise<string[]> {
const response = await translate.send(new ListTerminologiesCommand({}));
return (response.TerminologyPropertiesList ?? []).map(t => t.Name ?? '');
}
// Get metadata + download URL for a specific terminology
export async function getTerminology(name: string) {
const response = await translate.send(new GetTerminologyCommand({
Name: name,
TerminologyDataFormat: 'CSV', // 'CSV' | 'TMX' — format for the download URL
}));
return {
name: response.TerminologyProperties?.Name,
termCount: response.TerminologyProperties?.TermCount,
sourceLanguage: response.TerminologyProperties?.SourceLanguageCode,
targetLanguages: response.TerminologyProperties?.TargetLanguageCodes,
directionality: response.TerminologyProperties?.Directionality,
downloadUrl: response.TerminologyDataLocation?.Location, // presigned S3 URL, 300s expiry
createdAt: response.TerminologyProperties?.CreatedAt,
lastUpdatedAt: response.TerminologyProperties?.LastUpdatedAt,
};
}
The TerminologyDataLocation.Location is a presigned S3 URL valid for 300 seconds. Download it promptly if you need to inspect or edit the file — after expiry you must call GetTerminologyCommand again to get a fresh URL.
UNI vs MULTI directionality decision table
| Use case | Directionality | CSV structure | Constraint |
|---|---|---|---|
| Single target language (e.g. English → Spanish only) | UNI | 2 columns: source, target | Target language fixed at import — cannot reuse for other targets |
| Multiple target languages from one source | MULTI | N+1 columns: source + one per target language | Max 10 target language columns; max 256 terms per file |
| Bidirectional (en↔es, es↔en) | MULTI | Both en and es as columns — Translate infers direction at call time | MULTI with both source and target as columns enables both directions |
| Large term list (>256 entries) | UNI | Split into multiple UNI files | MULTI cap is 256; UNI has no published limit beyond 10MB file size |
The 10MB file size limit applies to the raw bytes sent to ImportTerminologyCommand. For large domain vocabularies exceeding 256 MULTI entries, split into multiple UNI files and apply the right one at call time based on the target language. Each TranslateTextCommand call can reference only one terminology.
Error handling reference
| Error | Cause | Fix |
|---|---|---|
| ValidationException at import | Wrong directionality for the CSV structure, missing language code header, or BOM in UTF-8 file | Ensure CSV header matches Directionality; save as UTF-8 without BOM |
| ResourceNotFoundException at translate | Terminology name not found in this region, or target language not in the terminology's TargetLanguageCodes | Verify name with ListTerminologiesCommand; check that MULTI file includes the target language column |
| LimitExceededException | More than 100 terminologies per account+region, or file exceeds 10MB | Delete unused terminologies; split large files |
| AccessDeniedException | Missing translate:ImportTerminology or translate:GetTerminology IAM action | Add translate:ImportTerminology, translate:GetTerminology, translate:ListTerminologies to the role |
| AppliedTerminologies is empty (no error) | Terms not matched — case mismatch, tokenization boundary, or wrong directionality | Log the exact source text; check for leading/trailing spaces; verify casing in the CSV |