AI translations
You can drive the full Messagevisor export and import loop through an agentic coding tool like Claude Code, Cursor, Cline, or any custom agent that can read files and run shell commands. The agent handles the CSV export, fills in the translations, and runs the import back into the project.
This guide shows how to set that up. It assumes you have a Messagevisor project already in place. If not, start with the Quick start.
This workflow uses an LLM to produce the translations. Like any machine translation, the output should be reviewed before shipping. The benefit over a vanilla GOOGLETRANSLATE flow is that an LLM understands ICU syntax, can keep {name} placeholders intact, can be told about brand and tone, and can be asked to flag rows it is unsure about.
Why use an agent#
A well-prompted agent can do the boring parts of the round trip on its own:
- run the right
messagevisor exportcommand for the locales and targets you ask about - translate the CSV cells while preserving ICU and interpolation placeholders
- write the translated file back to disk
- preview the import, summarize the diff, and apply it on your confirmation
- run lint, tests, and the catalog after applying
You stay in the loop for review, but you do not have to remember every CLI flag or open a spreadsheet.
Install the Messagevisor skills#
The Messagevisor repository ships with a set of skills for AI assistants. Each skill is a self-contained directory with a SKILL.md describing when to trigger and what to do.
Install them into your project with:
$ npx skills add messagevisor/messagevisorOr install just the ones relevant to this workflow:
$ npx skills add messagevisor/messagevisor$ npx skills add messagevisor/messagevisor-csv$ npx skills add messagevisor/messagevisor-cli$ npx skills add messagevisor/messagevisor-icuThe most important skill for this workflow is messagevisor-csv, which documents the export and import surface in agent-friendly form. The messagevisor entry-point skill and messagevisor-cli skill give the agent the broader project context. The messagevisor-icu skill helps the agent preserve plurals, selects, and named formats when translating.
Once installed, your agent picks the skills up automatically when you mention Messagevisor in a prompt.
How the workflow runs#
The pattern is the same as the CSV round trip, with the agent doing the work between the export and import steps:
export CSV ─► agent fills target locale columns ─► import CSV ─► lint + test + catalogStep 1: Ask the agent to export#
A prompt like this is usually enough:
Export an untranslated CSV for the "web" target with English as the sourceand German as the target. Save it to exports/de-web.csv.The agent runs:
$ npx messagevisor export \ --locale=en \ --locale=de \ --target=web \ --onlyUntranslated \ --output=exports/de-web.csvIf you do not specify the source or target, the agent will ask. Be explicit in the prompt to skip the back and forth.
Step 2: Ask the agent to translate#
Once the CSV exists, ask the agent to fill in the target locale column:
Translate every row in exports/de-web.csv from the `en` column into the `de`column. Keep ICU placeholders like {name} and {count, plural, ...} exactlyas they appear in the source. Flag any row you are not confident about byleaving its cell empty and adding a comment in your reply.The agent reads the CSV, generates translations, and writes the file back. Because the agent understands ICU syntax (with the messagevisor-icu skill loaded), placeholders survive intact in a way they often do not with off-the-shelf machine translation.
Useful additions to the prompt:
- the product name and a short tone description ("formal, B2B, never use emojis")
- glossary terms that must not be translated ("keep 'Workspace', 'Pro plan', and 'Pipeline' in English")
- which rows to skip ("leave any row whose
messageKeystarts withlegal.empty; those need a lawyer")
The agent can also work column by column for multiple locales in one CSV by repeating the same prompt with different target columns.
Step 3: Ask the agent to preview the import#
Preview a Messagevisor import of exports/de-web.csv for the `de` locale andsummarize what would change.The agent runs:
$ npx messagevisor import exports/de-web.csv --locale=deAnd reports back the changed messages, changed overrides, skipped rows, and any warnings the CLI emitted. Ask follow-up questions (for example, "why was auth.signin skipped?") before applying.
Step 4: Ask the agent to apply and validate#
When the preview looks right:
Apply the import for `de`, then run lint and tests. Open the catalog for me.The agent runs:
$ npx messagevisor import exports/de-web.csv --locale=de --apply$ npx messagevisor lint$ npx messagevisor test$ npx messagevisor catalogThe catalog is the fastest way to spot wrong-tone copy and ICU bugs. Skim the new de translations for a few minutes before opening a pull request.
Step 5: Commit and review#
Ask the agent to stage and commit the touched messages/ files, with a commit message that mentions which locale was imported and which target the export covered. Then open a pull request the same way you would for any other translations as code change.
End-to-end prompt#
If you trust the agent to run the whole loop in one go, a single prompt works too:
For the `web` target, do this:1. Export an untranslated CSV with English as the source locale and German as the target locale. Save to exports/de-web.csv.2. Fill in the `de` column by translating each `en` value. Preserve ICU and interpolation placeholders verbatim. Match the tone of the existing German strings under `messages/`. Keep brand names ("Acme", "Workspace", "Pro plan") untranslated.3. Preview a Messagevisor import of the file for the `de` locale and summarize the diff. Stop and ask me to confirm before applying.4. After I confirm, apply the import, run lint and tests, and open the catalog.The agent will pause between steps 3 and 4 for your review. Adjust the prompt to add or remove confirmation gates as you trust the loop more.
Translating multiple locales in one pass#
To seed several locales at once, export with multiple target locale columns and ask the agent to fill all of them:
Export untranslated rows for `web` with English as the source andde, fr, nl-NL, and es as the target locales. Save to exports/multi-web.csv.Then translate each target column and preview the import.The agent runs an export like:
$ npx messagevisor export \ --locale=en \ --locale=de \ --locale=fr \ --locale=nl-NL \ --locale=es \ --target=web \ --onlyUntranslated \ --output=exports/multi-web.csvThen it fills de, fr, nl-NL, and es cells, previews:
$ npx messagevisor import exports/multi-web.csvAnd after your confirmation, applies all of them in one go:
$ npx messagevisor import exports/multi-web.csv --applyTranslating regional locales#
For regional locales like en-GB, pt-BR, or nl-BE that inherit from a parent, ask the agent to use --onlyDirectlyUntranslated on export and --prune on import:
Export an en-GB CSV for `web` that includes only rows without a directen-GB translation, even if inheritance is filling them in. Then translateeach row, but if your translation matches the parent en value exactly,leave the cell as the inherited value so we can prune it on import.The agent runs:
$ npx messagevisor export \ --locale=en \ --locale=en-GB \ --target=web \ --onlyDirectlyUntranslated \ --output=exports/en-GB-web.csv$ npx messagevisor import exports/en-GB-web.csv --locale=en-GB --prune$ npx messagevisor import exports/en-GB-web.csv --locale=en-GB --prune --applySee Inheritance and the export and import reference for how --prune works.
Working in a sets project#
For projects with sets: true, the same prompts work, but the agent has to pass --set to both the export and import commands. The messagevisor-sets skill teaches the agent the conventions:
$ npx messagevisor export --set=staging --locale=en --locale=de --target=web --output=exports/staging-de-web.csv$ npx messagevisor import exports/staging-de-web.csv --set=staging --locale=de --applyIf your CSV has a set column from a multi-set export, the agent can update multiple sets in a single import without passing --set.
Guardrails worth keeping#
Even with a competent agent, keep these guardrails in place:
- Always preview before
--apply. The agent should runimportwithout--applyfirst and report the diff. - Lint and test after every import. The agent should run
npx messagevisor lintandnpx messagevisor testbefore declaring success. - Open a pull request, do not push to
main. The pull request review is where a human catches the things the agent and the LLM did not. - Skim the catalog. A few minutes in
messagevisor catalogcatches wrong-tone copy and ICU placeholder damage faster than reading a CSV diff. - Do not let the agent run
--createMissingunprompted. This flag creates new messages from unknown CSV rows. It is the fastest way to pollute the project. Always preview first, and only ask the agent to use--createMissingwhen you know the CSV is meant to add new entries. - Keep sensitive copy out of the loop. Legal disclaimers, financial copy, and regulated content should go through a human translator, not an LLM. Filter those messages out of the export with
--excludeMessagesor by editing the CSV before translation.
Compared to translating in Google Sheets#
The Google Sheets workflow and this one solve the same problem two different ways:
| Concern | Google Sheets | AI agent |
|---|---|---|
| Where translation runs | Inside the spreadsheet, via GOOGLETRANSLATE | Inside the agent, via an LLM |
| ICU placeholder safety | Often broken, needs manual checks | Usually preserved when the agent is prompted to do so |
| Brand and tone control | None | Controlled through the prompt and project context |
| Cost shape | Free | LLM tokens |
| Best for | Quick bootstrap of a new locale | Larger batches, ICU-heavy content, repeated runs |
Both produce a first draft. Neither replaces a human reviewer for production copy.

