MCP server
easyi18n mcp runs an MCP server over standard input and output. The client
launches it; you do not run it in a terminal yourself. It exposes tools, two
prompts (setup and translate) and server instructions that tell the agent
the safety rules and the translation loop.
Configuration
The server reads its settings from the environment the client gives it.
| Variable | Meaning |
|---|---|
EASYI18N_TOKEN | The project API key. Use an agent key. A tool that needs the key and finds none returns no_credential. |
EASYI18N_PROJECT_DIR | The project directory, when the client does not start the server in it. |
EASYI18N_MCP_MAX_CREDITS | The most one authorization may ask for, in credits. Default 50; 0 disables real pushes and syncs. |
EASYI18N_BASE_URL | An API origin to trust besides the easyi18n API, for a staging backend. |
Every tool accepts project_dir, an absolute path. The server resolves the
project from project_dir, then EASYI18N_PROJECT_DIR, then its working
directory, and reads easyi18n.yaml there.
The key never travels as a tool argument: tool schemas reject unknown
arguments, so a token argument is refused. The server also refuses to send
the key to a baseUrl from easyi18n.yaml unless it is the easyi18n API over
HTTPS, a loopback host, or the exact origin in EASYI18N_BASE_URL. A
repository you open cannot redirect your key to another host.
Tools
The list is fixed and ordered: core tools first, then each adapter's tools.
Clients show them with their own prefix, for example
mcp__easyi18n__push.
Core tools
| Tool | What it does | Main inputs | Key scope |
|---|---|---|---|
init | Detects the stack and writes easyi18n.yaml, the adapter's setup and the AGENTS.md block. Safe to repeat. | workspace, project or project_id, stack (flutter, xcode, web, auto; default auto), mode, format, output, catalog, force, write_agents, dry_run | none |
doctor | Checks config, credential, AGENTS.md, published state and the adapter's wiring. Read-only and free. | source_dir | read, optional |
status | Compares the published version with your last pull, and lists languages, the family and the stack. | none | read |
authorize | Asks the server for an operation and returns its approval_url. With operation_id, it only reads the operation's state. | action (translate, publish, rollback), max_credits, operation_id, plus the scope of the action | the action's |
fill_status | One poll: is the translation complete? Reconciles requests left unresolved by a lost response or a restart. | langs, tracking_tokens | translate |
publish | Freezes and serves a new version. Needs an approved publish operation. Refuses an incomplete project unless require_complete is false. | operation_id, approved_only, require_complete (default true), incomplete_mode, skip_if_identical | publish |
rollback | Restores an earlier version as a new version. Needs an approved rollback operation. | operation_id, version (default previous) | publish |
pull | Writes the published files or catalog and returns their paths, never their contents. It never writes the base-language file of a web project. | version, lang, dry_run, require_complete, key_policy | read |
add_language | Adds a language to the project, or changes its fill mode. | code, fill_mode (ai, manual) | write |
Code-first tools: Dart and Flutter
| Tool | What it does | Main inputs | Key scope |
|---|---|---|---|
extract | Scans tr() calls against easyi18n.lock, offline and free. Paginated. | source_dir, limit, offset | none |
push_preview | Estimates the credits a push would spend. Free. | langs, source_dir | translate |
push | Registers the strings, writes easyi18n.lock and queues the translation. Spends credits. | operation_id, langs, source_dir, prune | translate |
apply | Rewrites tr() literals corrected in source review. Previews unless write is true. | write, source_dir | read |
File-first tools: Xcode String Catalogs and web JSON catalogs
| Tool | What it does | Main inputs | Key scope |
|---|---|---|---|
sync_preview | Uploads the catalog, or the base-language file of a web project, as a dry run: keys created and updated, conflicts, diagnostics and estimated credits. Free. | on_conflict (server, file) | translate |
sync | Uploads the same file and queues the translation. Spends credits. | operation_id, on_conflict | translate |
An adapter tool called on a project of the other family returns
wrong_family with the name of the tool to use instead. status tells the
agent the family before it starts.
Spending and publishing
push, sync, publish and rollback need the operation_id of an operation
a person approved in the dashboard. A push or sync whose preview costs 0
credits runs without one. Operations and approvals
describes the same flow as HTTP requests.
For a translation, authorize computes the maximum as the estimate plus 20 %,
rounded up and capped at EASYI18N_MCP_MAX_CREDITS. If that cap is below the
estimate, it returns ceiling_below_estimate before creating anything, and only
the person who configured the client can raise it. The approved maximum is
enforced by the easyi18n server: the translation stops before it would charge
more.
push and sync write each request to .easyi18n/operations/ before sending
it. If a response is lost or the client restarts, fill_status asks the server
what happened to that request instead of sending it again.
In Claude Code 2.1.199 or later, push, sync, publish and rollback also
ask for your permission on every call. Other clients use their own tool
approval settings. The dashboard approval applies in every client.
Errors
A failure comes back as a tool result with isError and an error object
with message, code, statusCode and retryable. The message says what to
do next.
| Code | Meaning |
|---|---|
no_credential | EASYI18N_TOKEN is missing from the server's environment. Fix the client configuration; do not paste the key into the chat. |
wrong_family | The tool belongs to the other family. The result names the tool to use. |
unsupported_stack | init with stack: auto found no stack it can set up in the directory. The error also carries supported and roadmap, each a list of stack names. Call it again with project_dir on the root of the app, or stop. |
catalog_scope_unknown | The web input declaration is missing, invalid, or cannot be inspected. Declare sourceRoot and sourceLayout as described in Web input layouts. After inspecting the input it carries fields, the settings to fix, and files: the JSON files under the declared root, or the ones beside source: when sourceRoot is missing. Nothing was uploaded. |
several_files_per_locale | A web project keeps its base language in more than one file, as i18next namespaces and Transloco scopes do. The error carries source and files, the paths it found. Nothing was uploaded. |
edited_targets | A locale file changed since the pull that wrote it, and the call would replace it. edited lists each one as {file}. Nothing was uploaded or written. Tell the human: the change belongs in the dashboard, and easyi18n pull --force discards it. No tool overwrites the file. |
authorization_required | The call needs an approved operation. Run authorize. |
scope_changed | The work no longer matches what was approved, for example after the source changed. Authorize again. |
ceiling_below_estimate, above_ceiling | The estimate or the operation exceeds EASYI18N_MCP_MAX_CREDITS. |
ingests_disabled | EASYI18N_MCP_MAX_CREDITS is 0. |
nothing_to_authorize | The preview costs nothing; push or sync without an operation. |
request_unresolved | An earlier request has no known outcome. Run fill_status before sending more. |
fill_incomplete | publish found untranslated or refused cells in the version it would freeze. |
invalid_project_dir, source_dir_outside_project | A path argument is not absolute, or points outside the project. |
output_too_large | The result exceeds the 32 KiB output budget even after truncating its lists. |
List fields in results are truncated to fit 32 KiB, with truncated: true and
the total count. Tool results contain text written by your project's users,
such as keys, source strings and error messages; the server instructions tell
the agent to treat it as data.
Prompts
setup takes a repository from nothing to ready to translate: it detects the
stack, asks you for the project and the key, runs init and doctor, and shows
what would be translated without spending anything. translate runs the loop,
including both approvals, the fill_status polling and the final pull.
Clients that support MCP prompts list them; the Claude Code plugin ships them
as skills.