8.6 KiB
name, description, compatibility
| name | description | compatibility |
|---|---|---|
| doc-translator | Translates external documentation websites to specified language(s) and publishes to Outline wiki. Use when: (1) Translating SaaS/product documentation into German or Czech, (2) Publishing translated docs to Outline wiki, (3) Re-hosting external images to Outline. Triggers: 'translate docs', 'translate documentation', 'translate to German', 'translate to Czech', 'publish to wiki', 'doc translation', 'TEEM translation'. | opencode |
Doc Translator
Translate external documentation websites to German (DE) and/or Czech (CZ), then publish to the company Outline wiki at https://wiki.az-gruppe.com. All images are re-hosted on Outline. UI terms use TEEM format.
Core Workflow
1. Validate Input & Clarify
Before starting, confirm:
- URL accessibility - Check with
curl -sI <URL>for HTTP 200 - Target language(s) - Always ask explicitly using the
questiontool:
question: "Which language(s) should I translate to?"
options: ["German (DE)", "Czech (CZ)", "Both (DE + CZ)"]
- Scope - If URL is an index page with multiple sub-pages, ask:
question: "This page links to multiple sub-pages. What should I translate?"
options: ["This page only", "This page + all linked sub-pages", "Let me pick specific pages"]
- Target collection - Use
Outline_list_collectionsto show available collections, then ask which one to publish to
CRITICAL: NEVER auto-select collection. Always present collection list to user and wait for explicit selection before proceeding with document creation.
If URL fetch fails, use question to ask for an alternative URL or manual content paste.
2. Fetch & Parse Content
Use the webfetch tool to retrieve page content:
webfetch(url="<URL>", format="markdown")
From the result:
- Extract main content body (ignore navigation, footers, sidebars, cookie banners)
- Preserve document structure (headings, lists, tables, code blocks)
- Collect all image URLs into a list for Step 3
- Note any embedded videos or interactive elements (these cannot be translated)
For multi-page docs, repeat for each page.
3. Download Images
Download all images to a temporary directory:
mkdir -p /tmp/doc-images
# For each image URL:
curl -sL "IMAGE_URL" -o "/tmp/doc-images/$(basename IMAGE_URL)"
Track a mapping of: original_url -> local_filename -> outline_attachment_url
If an image download fails, log it and continue. Use a placeholder in the final document:
> **[Image unavailable]** Original: IMAGE_URL
4. Upload Images to Outline
MCP-outline does not support attachment creation. Use the bundled script for image uploads:
# Upload with optional document association
bash scripts/upload_image_to_outline.sh "/tmp/doc-images/screenshot.png" "$DOCUMENT_ID"
# Upload without document (attach later)
bash scripts/upload_image_to_outline.sh "/tmp/doc-images/screenshot.png"
The script handles API key loading from /run/agenix/outline-key, content-type detection, the two-step presigned POST flow, and retries. Output is JSON: {"success": true, "attachment_url": "https://..."}.
Replace image references in the translated markdown with the returned attachment_url:

For all other Outline operations (documents, collections, search), use MCP tools (Outline_*).
5. Translate with TEEM Format
Translate the entire document into each target language. Apply TEEM format to UI elements.
Address Form (CRITICAL)
Always use the informal "you" form in ALL target languages:
- German: Use "Du" (informal), NEVER "Sie" (formal)
- Czech: Use "ty" (informal), NEVER "vy" (formal)
- This applies to all translations — documentation should feel approachable and direct
Infobox / Callout Formatting
Source documentation often uses admonitions, callouts, or info boxes (e.g., GitHub-style > [!NOTE], Docusaurus :::note, or custom HTML boxes). Convert ALL such elements to Outline's callout syntax:
:::tip
Tip or best practice content here.
:::
:::info
Informational content here.
:::
:::warning
Warning or caution content here.
:::
:::success
Success message or positive outcome here.
:::
Mapping rules (source → Outline):
| Source pattern | Outline syntax |
|---|---|
| Note, Info, Information | :::info |
| Tip, Hint, Best Practice | :::tip |
| Warning, Caution, Danger, Important | :::warning |
| Success, Done, Check | :::success |
CRITICAL formatting: The closing ::: MUST be on its own line with an empty line before it. Content goes directly after the opening line.
TEEM Rules
Format: **English UI Term** (Translation)
Apply TEEM to:
- Button labels
- Menu items and navigation tabs
- Form field labels
- Dialog/modal titles
- Toolbar icons with text
- Status messages from the app
- Headings containing UI terms (example: "## [Adding a new To-do]" becomes "## [Ein neues To-do (Aufgabe) hinzufügen]")
Translate normally (no TEEM):
- Your own explanatory text
- Document headings you create (that don't contain UI terms)
- General descriptions and conceptual explanations
- Code blocks and technical identifiers
German Examples
Click **Settings** (Einstellungen) to open preferences.
Navigate to **Dashboard** (Übersicht) > **Reports** (Berichte).
Press the **Submit** (Absenden) button.
In the **File** (Datei) menu, select **Export** (Exportieren).
# Heading with UI term: Create a new **To-do** (Aufgabe)
## [Adding a new **To-do** (Aufgabe)]
Czech Examples
Click **Settings** (Nastavení) to open preferences.
Navigate to **Dashboard** (Přehled) > **Reports** (Sestavy).
Press the **Submit** (Odeslat) button.
In the **File** (Soubor) menu, select **Export** (Exportovat).
# Heading with UI term: Create a new **To-do** (Úkol)
## [Adding a new **To-do** (Úkol)]
Ambiguous UI Terms
If a UI term has multiple valid translations depending on context, use the question tool:
question: "The term 'Board' appears in the UI. Which translation fits this context?"
options: ["Pinnwand (pinboard/bulletin)", "Tafel (whiteboard)", "Gremium (committee)"]
6. Publish to Outline
Use mcp-outline tools to publish:
-
Find or create collection:
Outline_list_collectionsto find target collectionOutline_create_collectionif needed
-
Create document:
Outline_create_documentwith translated markdown content- Set
publish: truefor immediate visibility - Use
parent_document_idif nesting under an existing doc
-
For multi-language: Create one document per language, clearly titled:
[Product Name] - Dokumentation (DE)[Product Name] - Dokumentace (CZ)
Error Handling
| Issue | Action |
|---|---|
| URL fetch fails | Use question to ask for alternative URL or manual paste |
| Image download fails | Continue with placeholder, note in completion report |
| Outline API error (attachments) | Script retries 3x with backoff; on final failure save markdown to /tmp/doc-translator-backup-TIMESTAMP.md, report error |
| Outline API error (document) | Save markdown to /tmp/doc-translator-backup-TIMESTAMP.md, report error |
| Ambiguous UI term | Use question to ask user for correct translation |
| Large document (>5000 words) | Ask user if splitting into multiple docs is preferred |
| Multi-page docs | Ask user about scope before proceeding |
| Rate limiting | Wait and retry with exponential backoff |
If Outline publish fails, always save the translated markdown locally as backup before reporting the error.
Completion Report
After each translation, output:
Translation Complete
Documents Created:
- DE: [Document Title] - ID: [xxx] - URL: https://wiki.az-gruppe.com/doc/[slug]
- CZ: [Document Title] - ID: [xxx] - URL: https://wiki.az-gruppe.com/doc/[slug]
Images Processed: X of Y successfully uploaded
Items Needing Review:
- [Any sections with complex screenshots]
- [Any failed image uploads with original URLs]
- [Any unclear UI terms that were best-guessed]
Language Codes
| Code | Language | Native Name |
|---|---|---|
| DE | German | Deutsch |
| CZ | Czech | Čeština |
Environment Variables
| Variable | Purpose | Source |
|---|---|---|
OUTLINE_API_KEY |
Bearer token for wiki.az-gruppe.com API | Auto-loaded from /run/agenix/outline-key by upload script |
Integration with Other Skills
| Need | Skill | When |
|---|---|---|
| Wiki document management | outline | Managing existing translated docs |
| Browser-based content extraction | playwright / dev-browser | When webfetch cannot access content (login-required pages) |