deepl-i18n

deepl-i18n

MCP server for translating JSON localization files via DeepL API or local LLMs, enabling agents to estimate, check, and run translations.

Category
访问服务器

README

deepl-i18n

CI

Translate your JSON localization files with the DeepL API. DeepL-first, config-driven, and free — no telemetry, no account required beyond a DeepL API key (the free tier gives 500,000 characters/month).

Unofficial project. Not affiliated with, sponsored by, or endorsed by DeepL SE. "DeepL" is a trademark of DeepL SE; used here only to describe API compatibility.

Point it at a source-language JSON file, list your target languages, and it fills in only the missing keys — existing translations are preserved, obsolete keys are removed, and placeholders are protected from corruption.

Optionally translate via a local LLM (LM Studio) instead of DeepL — see Local model.

Features

  • Incremental — only missing/empty keys are translated; existing values stay untouched.
  • Placeholder-safe — variables like {{ name }} are shielded from translation and verified afterwards, catching both changed tokens and corruption where a placeholder gets glued to a word (e.g. d{{value1}}ových). The placeholder format is configurable ({{ }}, %s, {0}, …).
  • Multiple formats — JSON and YAML (nested), Java .properties and iOS .strings (flat); auto-detected by extension or forced with --file-format. Nested objects are recursed; non-string values (numbers, booleans, null) are copied verbatim.
  • Formality, context & model — set DeepL formality, a context prompt, and the model_type (quality- vs. latency-optimized) to steer tone, terminology and speed.
  • Cost transparency — every run reports the characters DeepL actually billed.
  • Dry run — see how many keys and characters would be translated, and whether it fits the DeepL free tier, without spending any quota.
  • Quota display — real-time DeepL character usage.

Requirements

  • Python 3.13+
  • A DeepL API key
  • deepl (the only third-party dependency)

Setup

# create & activate a virtual environment
python -m venv venv
./venv/Scripts/activate        # Windows
# source venv/bin/activate     # macOS/Linux

# install the CLI (and its only dependency, deepl) from source
pip install -e .

This installs a deepl-i18n command. config.json and .env are resolved from the current working directory, so run the command from your project folder (or pass --config path/to/config.json).

API key

Provide your DeepL API key in one of these ways (checked in this order):

  1. DEEPL_API_KEY environment variable (recommended, especially for CI)
  2. a .env file in the project root containing DEEPL_API_KEY=your-key (copy .env.example to .env)

.env and config.json are git-ignored so your key and local paths never get committed.

Configuration

Copy the example config and adjust it:

cp config.example.json config.json
{
  "source_lang": "EN",
  "output_languages": ["DE", "FR", "ES", "IT", "PT-PT"],
  "filename_overrides": {},
  "formality": "default",
  "placeholder_pattern": "{{\\s*\\w+\\s*}}",
  "context": "Optional: describe your app so DeepL picks the right terminology and tone.",
  "targets": {
    "app": {
      "input_path": "./locales/en.json",
      "output_dir": "./locales"
    }
  }
}
Key Meaning
source_lang DeepL source language code of your master file (e.g. EN, DE).
output_languages Target language codes (e.g. DE, FR, PT-PT, EN-US).
filename_overrides Map a language code to a custom output filename, e.g. {"EN-US": "en"}en.json.
formality less, more, prefer_less, prefer_more, or default (omit). Applied only to languages that support it.
placeholder_pattern Regex matching your placeholders. Default {{ … }}. Use e.g. %\\d*\\$?[sd@] (printf) or \\{\\d+\\} (MessageFormat).
context Optional prompt passed to DeepL to disambiguate terminology and tone.
glossary Optional path to a glossary file (see Glossary), or null.
file_format Force a format (json/yaml/properties/strings), or null to auto-detect by extension.
model_type DeepL model: quality_optimized (default), latency_optimized, prefer_quality_optimized, or null.
targets Named input/output path pairs. Each needs input_path (the source file) and output_dir.

Output filenames use the lowercase language code (e.g. de.json, pt-pt.json) unless overridden.

Usage

All commands take a <target> — a key under targets in your config.json.

# translate the missing keys of a target
deepl-i18n translate app

# only one language
deepl-i18n translate app --lang FR

# dry run — no API calls, no files written; shows keys, characters and free-tier fit
deepl-i18n translate app --dry-run
deepl-i18n translate app --dry-run --lang FR

# re-translate existing keys, and keep a .bak of each file before overwriting
deepl-i18n translate app --override --backup

# use a config elsewhere
deepl-i18n translate app --config ./locales/config.json

Watch

Re-translate automatically whenever the source file changes:

deepl-i18n watch app                 # polls the source file (default every 2s)
deepl-i18n watch app --interval 5 --backup

Check (CI gate)

Validate existing translations without translating anything: reports missing/empty keys and placeholder corruption, and exits non-zero if any problem is found — ready to drop into CI.

deepl-i18n check app
deepl-i18n check app --lang FR

DeepL quota

deepl-i18n usage

Also printed automatically at the end of every translate run and dry run.

File formats

The format is detected from the source file's extension; output files use the same extension. Force it with --file-format (or file_format in the config) when the extension is ambiguous or missing.

Format Extensions Structure Notes
JSON .json nested i18next-style; non-string values preserved
YAML .yaml, .yml nested needs pip install deepl-i18n[yaml]; comments not preserved
Java properties .properties flat #/! comments, =/: separators, line continuations
iOS strings .strings flat /* */ and // comments
Flutter ARB .arb flat @@locale and @key metadata are preserved, never translated
Android XML .xml flat <string> elements; respects translatable="false"
CSV .csv flat key,value columns; optional header row
deepl-i18n translate app --file-format yaml

More formats (gettext .po, ARB template regeneration, Android <string-array>/<plurals>) are on the roadmap.

Glossary

Keep terminology consistent across languages. Point glossary in your config (or pass --glossary path) at a JSON file with two optional sections:

{
  "doNotTranslate": ["BeerpongMe", "Rerack", "Bracket"],
  "terms": {
    "Turnier": { "FR": "tournoi", "ES": "torneo" }
  }
}
  • doNotTranslate — terms kept verbatim in every target language.
  • terms — per-term, per-language forced translations (language codes match your output_languages; a base code like EN also matches EN-US).

For DeepL, an ephemeral glossary is created for each target language, used for that run, and deleted afterwards (glossary create/delete cost no characters). Language pairs DeepL doesn't support for glossaries are skipped with a note. For the local model, the same glossary is injected into the prompt.

# validate a glossary file and preview entries per language (no API calls)
deepl-i18n glossary check app --glossary glossary.json

# manage glossaries stored on DeepL
deepl-i18n glossary list
deepl-i18n glossary delete <id>
deepl-i18n glossary delete --all

Local model (LM Studio)

Instead of DeepL you can translate with a local LLM through LM Studio's OpenAI-compatible server (default http://localhost:1234, default model openai/gpt-oss-20b). Same key-selection logic (missing keys only), same output files. Batch mode groups several keys per request; keys the batch returns broken (e.g. corrupted placeholders) are retried individually.

deepl-i18n local app                 # translate target "app" (batch mode)
deepl-i18n local app --lang CS
deepl-i18n local app --dry-run
deepl-i18n local app --model "openai/gpt-oss-20b"
deepl-i18n local app --single        # key-by-key instead of batch
deepl-i18n local app --chunk-size 20 # keys per batch request (default 30)

Compare a local model against existing (DeepL) translations without writing anything:

deepl-i18n compare app --lang CS

LMSTUDIO_MODEL and LMSTUDIO_URL can be set via environment variables.

MCP server

Expose the tool to MCP clients (Claude Desktop, Claude Code, …) so an agent can estimate, check and run translations for you.

pip install deepl-i18n[mcp]

Tools:

Tool What it does
dry_run_estimate missing keys/characters per language, free-tier fit — no API calls
check_integrity completeness + placeholder check; returns {ok, issues}
deepl_usage current DeepL quota
translate_missing translate missing keys and write the files (uses quota)

Each tool takes a target (a key under targets), an optional lang, and an optional config path. Register the server with your client (set cwd to the folder that holds your config.json and API key):

{
  "mcpServers": {
    "deepl-i18n": {
      "command": "deepl-i18n-mcp",
      "cwd": "/path/to/your/i18n/project"
    }
  }
}

Development

pip install -e .[dev]   # installs pytest + pyyaml
pytest -q               # runs the offline test suite (no DeepL calls)

CI runs the suite on Python 3.10–3.13 via GitHub Actions (.github/workflows/ci.yml).

Roadmap

This project is being generalized from an internal tool into a public, DeepL-first i18n CLI. See ROADMAP.md for planned work (unified CLI, pip install, glossary support, more providers, an MCP server, more file formats, and more).

License

MIT © 2026 Lorenz Schubert — free to use, modify and distribute, including commercially, as long as the copyright notice is kept.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选