DeepL Shipped a v3 Customization Hub. We Covered It in One YAML File.
In late May, DeepL turned on the Customization Hub — 13 new REST endpoints across style rules, multilingual glossaries, translation memory, the redesigned /v3/languages resource, and an opt-in tag_handling v2 algorithm. On the morning we merged our DADL for it, the official deepl-mcp-server still exposed nine tools — all of them v2 — and the community alternative mcp-deepl was in the same shape, last released 2026-05-09. Not because anyone is slow. The unit of work for adding API coverage is fundamentally different on either side of that line, and the new release surfaces the gap clearly. This post is the build log.
What the new release added
Section titled “What the new release added”The Customization Hub is the marketing name for an honest API expansion. DeepL now lets API consumers manage per-language style profiles (think “Brand voice — DE”), multilingual glossaries (one glossary, many source → target dictionaries), and translation memories (segment-level reuse with a configurable match threshold). /v2/translate accepts three new parameters — style_id, custom_instructions, translation_memory_id — any of which silently bumps the model to quality_optimized. The new /v3/languages endpoint replaces the old /v2/languages and exposes per-resource feature flags (formality support, glossary support, style-rules support, voice). Finally, tag_handling_version: v2 ships a much improved HTML/XML structure preservation algorithm — position-independent translation, better-preserved nesting.
That is a meaningful expansion. None of it is in the official MCP server today.
The numbers
Section titled “The numbers”DADL (deepl.dadl) | deepl-mcp-server (official) | |
|---|---|---|
| Tools | 27 | 9 |
| Coverage | text translation, document translation, multilingual v3 glossaries, style rules CRUD, custom instructions CRUD, TM listing, Write/rephrase, /v3/languages, usage | translate-text, rephrase-text, translate-document, list-glossaries, get-glossary-info, get-glossary-dictionary-entries, get-source-languages, get-target-languages, get-writing-styles |
| Distribution | 38 KB YAML | Node.js server (TypeScript SDK, build step, runtime to host) |
| Adding a new endpoint | ~30 lines of YAML | Tool definition + request handler + tests + release |
| v3 Customization Hub coverage | full | none today |
The local validation, run from the registry checkout:
> cd dadl-registry && npm run validate✅ deepl.dadl — 27 toolsSource on GitHub: dadl-registry/deepl.dadl. Merged in PR #34. The DADL spec itself: dadl.ai/spec.
A worked example: style rules end-to-end
Section titled “A worked example: style rules end-to-end”The interesting thing about style rules is that they actually take effect — custom_instructions carry through into the model output. Here is the round trip:
const style = await toolmesh.deepl_create_style_rule({ name: "Brand voice — DE", language: "de", custom_instructions: [ { label: "Greeting", prompt: "Begin every translation with 'Sehr geehrte Damen und Herren'." }, { label: "Product term", prompt: "Render 'ToolMesh' verbatim, never translate." } ]});
const r = await toolmesh.deepl_translate({ text: ["The deployment of ToolMesh was successful."], source_lang: "EN", target_lang: "DE", style_id: style.style_id});// → "Sehr geehrte Damen und Herren, die Bereitstellung von ToolMesh war erfolgreich."Two calls. No glue code. The first hits POST /v3/style_rules; the second references the result by style_id in POST /v2/translate. The DADL transparently handles:
- the unusual
DeepL-Auth-KeyAuthorization scheme (custom prefix, server-side credential injection — the model never sees the key); - the language-code casing trap (UPPERCASE for
translate, lowercase for style rules — both correctly typed); - the silent model switch — passing
style_id,custom_instructions, ortranslation_memory_idflipsmodel_typetoquality_optimized; - retries on
429/529withRetry-After, and terminal classification for400/401/403/456(the Free-plan quota-exceeded code is456, not429— a footgun in hand-coded clients).
Same call from Claude or any other agent. No DeepL-specific code on the client side.
Maintenance asymmetry
Section titled “Maintenance asymmetry”This is the part that does not show up in the tool count but shapes how quickly an integration tracks an upstream API.
Adding the v3 endpoints to the DADL:
- Open
deepl.dadl. - Add the new tool blocks (~30 lines of YAML per endpoint).
npm run validate— output is✅ deepl.dadl — 27 tools.- Open a PR. Review the YAML diff. Merge.
- ToolMesh picks the new tools up on next reload. Users see them.
Adding the same endpoints to a hand-coded MCP server:
- Update the TypeScript SDK to model the new request and response shapes.
- Add tool definitions and request handlers (one per endpoint).
- Write or extend tests.
- Cut a release. Tag. Publish to npm.
- Tell users to upgrade. Wait for them.
- Repeat for the Python SDK if you maintain one. Repeat for any downstream forks.
DADL collapses steps 1, 2, 4, 5, and 6 into “edit one YAML file.” The PR diff is a reviewable change set, not a software release. We made the general version of this argument in an earlier post; the DeepL release is the concrete case study.
The flip side worth naming: if you need behavior the runtime does not support, the YAML file does not save you. DADL is declarative — there is no escape hatch for custom orchestration. For DeepL specifically, the document-translation flow (upload_document → check_document_status → download_document) is purely sequential REST and fits cleanly. A protocol-level deviation — say, the WebSocket Voice API — would not.
The context-window argument
Section titled “The context-window argument”The other reason the tool count matters less than it looks: Code Mode. Instead of injecting every backend’s full tool list into the model’s context window, ToolMesh exposes two meta-tools (list_tools and execute_code). The model discovers what is available on demand and calls flat tool names from inside a sandboxed JavaScript runtime — toolmesh.deepl_translate, toolmesh.deepl_create_style_rule, not toolmesh.deepl.translate.
The token cost is roughly constant: ~1 k tokens of meta-tool description, regardless of whether the registry has one backend with 9 tools or twenty backends with 985. Tool-count-driven bloat goes away. Adding the v3 Customization Hub took the DADL from 14 to 27 tools and added zero tokens to every Claude conversation that does not actively touch DeepL.
In Code Mode, the JavaScript in the worked example above is not an illustration — it is literally what the model writes to call the tools. That is why it reads like JavaScript rather than like JSON tool-call payloads.
Honest caveats
Section titled “Honest caveats”The DADL is not a full coverage replacement. Real limits:
- Voice translation is WebSocket-based. DeepL’s real-time voice translation is a bidirectional streaming protocol. DADL describes REST APIs declaratively; it does not describe streaming protocols. That endpoint is not in our 27-tool count and will not be — it is custom-server territory.
- The Admin API is out of scope on purpose. DeepL exposes admin endpoints (org analytics, developer-key management). We deliberately scoped this DADL to user-facing translation surfaces. Admin endpoints have a different threat model and belong in a separate, more privileged backend — not bundled with the everyday
translatetool that any team member might use. - Translation memory mutation is web-UI only.
/v3/translation_memoriesis read-only via the API as of May 2026 — TMs are created and edited in the DeepL web UI. We exposelist_translation_memories; we cannot expose endpoints that do not exist. - Stateful MCP clients are a legitimate use case. If you drive Claude Desktop, Cursor, or Continue directly and want a local MCP server with no governance layer in between, the official
deepl-mcp-serveris the right shape for that. The DADL-via-ToolMesh approach assumes a runtime that centralizes credentials, authorization, and audit — and that someone is willing to host it. For an individual developer with no governance requirements, that is overhead, not value. - Latency-sensitive pipelines. Every call hops through ToolMesh. For interactive translation at human latencies, this is invisible; for high-throughput batched pipelines, calling the DeepL client library directly is probably faster.
DADL is good at one specific thing — making REST API surface available to agents quickly, with a real control layer underneath. It is not a silver bullet, and it does not try to replace every kind of MCP server.
What is actually different
Section titled “What is actually different”The substantive question is not “DADL vs MCP server” — that framing is wrong; ToolMesh runs both, and they coexist in the same registry. The substantive question is: what does it cost to track an upstream API release?
For a hand-coded server, it costs an engineering cycle: SDK changes, tool definitions, handlers, tests, a release, an npm publish, user upgrades. That is why community MCP servers tend to lag fast-moving APIs — not for lack of effort, but because the work is linear in software releases, not in lines of YAML.
For a DADL, it costs one PR with a YAML diff. DeepL shipped 13 new endpoints in mid-May. We shipped the updated DADL on May 21 — 14 old tools plus the 13 new ones, validated, merged, live. The work for the new endpoints was a couple of hours, most of it spent reading DeepL’s API reference and verifying behavior against a Free key. The runtime did the rest.
That is the asymmetry. Not “everyone should ditch MCP servers.” Not “DADL is universally better.” Just: when the unit of work to add API coverage is a YAML diff rather than a software release, the integration tracks the upstream faster. That matters when the upstream is shipping a Customization Hub.
→ Für die deutsche Geschäfts-Perspektive: dunkel.cloud/de/blog/deepl-customization-hub-via-dadl