Skip to main content
Glama
fabkho
by fabkho

Translate Missing

translate_missing
Idempotent

Find missing i18n keys across target locales and translate them. In provider mode it writes results; otherwise it returns fallback contexts for agent-side translation.

Instructions

Find the keys missing in the target locales and translate them. Without a translation backend nothing is written: the result carries per-locale fallback contexts to translate by hand instead. Two modes: in provider mode (the server env-configured with I18N_PROVIDER, I18N_MODEL and an API key) it calls the LLM provider directly and writes the results; in agent mode it returns those fallbackContexts — translate them inline and persist via write_translations. Check the discover output for the active mode. Uses the project config (glossary, translation prompt, locale notes, examples) where there is one. Translates all locales concurrently, so pass every target locale at once.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keysNoDot-path keys to translate (e.g., ["auth.login.title", "common.save"]). If omitted, translates every missing key in the layer.
layerNoLayer to translate (e.g., "root", "app-admin"). Omit to translate every locale-backed layer in one call — the recommended default for layered projects, which returns a result per layer plus an aggregated summary.
dryRunNoReturn which keys would be translated without calling the provider or writing files. Default: false.
compactNoReturn a compact summary (totalTranslated, totalFailed, byLocale) instead of full per-locale results. Default: false.
batchSizeNoMaximum number of keys per provider request. Default: 50. A lower value reduces per-batch risk and increases round trips.
projectDirNoAbsolute path to the project root. Defaults to I18N_PROJECT_DIR, then server cwd. Example: "/home/user/my-app".
targetLocalesNoLocale codes to translate into (e.g., ["de", "fr", "sv"]). Defaults to all locales except the reference.
overwriteStaleNoAlso re-translate keys whose target value was written from source text that has changed since. Needs the translation memory, which is on unless translationMemory is false in the project config — without it nothing is known to be stale and this changes nothing. Default: false, which reports those keys under "stale" and leaves their values alone.
referenceLocaleNoLocale code used as the translation source (e.g., "en", "en-US"). Defaults to the project default locale.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changedv1.0.6
    • changedInput schema / properties / batchSize / description
      Previous value: -"Max keys per provider request (provider mode only). Default: 50. Lower values reduce per-batch risk but increase round trips."New value: +"Maximum number of keys per provider request. Default: 50. A lower value reduces per-batch risk and increases round trips."
    • addedInput schema / properties / batchSize / maximum
      Added value: +9007199254740991
    • addedInput schema / properties / batchSize / minimum
      Added value: +1
    • changedInput schema / properties / batchSize / type
      Previous value: -"number"New value: +"integer"
    • changedInput schema / properties / compact / description
      Previous value: -"When true, returns a compact summary (totalTranslated, totalFailed, byLocale) instead of full per-locale results. Default: false."New value: +"Return a compact summary (totalTranslated, totalFailed, byLocale) instead of full per-locale results. Default: false."
    • changedInput schema / properties / dryRun / description
      Previous value: -"When true, returns which keys would be translated without calling the LLM or writing files. Default: false."New value: +"Return which keys would be translated without calling the provider or writing files. Default: false."
    • changedInput schema / properties / keys / description
      Previous value: -"Specific dot-path keys to translate (e.g., [\"auth.login.title\", \"common.save\"]). If omitted, translates all missing keys in the layer."New value: +"Dot-path keys to translate (e.g., [\"auth.login.title\", \"common.save\"]). If omitted, translates every missing key in the layer."
    • changedInput schema / properties / layer / description
      Previous value: -"Layer name from discover to translate (e.g., \"root\", \"app-admin\"). Omit to translate every locale-backed layer in one call — the recommended default for layered projects, which returns a result per layer plus an aggregated summary."New value: +"Layer to translate (e.g., \"root\", \"app-admin\"). Omit to translate every locale-backed layer in one call — the recommended default for layered projects, which returns a result per layer plus an aggregated summary."
    • addedInput schema / properties / overwriteStale
      Added value: +{
      +  "description": "Also re-translate keys whose target value was written from source text that has changed since. Needs the translation memory, which is on unless translationMemory is false in the project config — without it nothing is known to be stale and this changes nothing. Default: false, which reports those keys under \"stale\" and leaves their values alone.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / projectDir / description
      Previous value: -"Absolute path to the Nuxt project root. Defaults to I18N_PROJECT_DIR, then server cwd. Example: \"/home/user/my-app\"."New value: +"Absolute path to the project root. Defaults to I18N_PROJECT_DIR, then server cwd. Example: \"/home/user/my-app\"."
    • changedInput schema / properties / referenceLocale / description
      Previous value: -"Locale code used as translation source (e.g., \"en\", \"en-US\"). Defaults to the project default locale."New value: +"Locale code used as the translation source (e.g., \"en\", \"en-US\"). Defaults to the project default locale."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "https://json-schema.org/draft/2020-12/schema",
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "fallbackContexts": {
      +          "additionalProperties": {
      +            "additionalProperties": {
      +              "description": "The value of that field, as the prompt builder produced it."
      +            },
      +            "propertyNames": {
      +              "description": "Context field, e.g. \"keysToTranslate\", \"glossary\", \"instructions\".",
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "description": "Per-locale context to translate inline and persist with write_translations. Present only in agent mode.",
      +          "propertyNames": {
      +            "description": "Target locale code.",
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "results": {
      +          "additionalProperties": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "batches": {
      +                "description": "Provider requests this locale took. Absent outside provider mode.",
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              "failed": {
      +                "description": "Keys the run attempted and lost. They are still missing; a re-run retries them.",
      +                "items": {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "key": {
      +                      "description": "The key that could not be translated.",
      +                      "type": "string"
      +                    },
      +                    "reason": {
      +                      "description": "Why the key could not be translated. A closed set — branch on the value.",
      +                      "enum": [
      +                        "provider-error",
      +                        "omitted-by-model",
      +                        "placeholder-mismatch",
      +                        "plural-mismatch",
      +                        "write-error",
      +                        "truncated"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "key",
      +                    "reason"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "missing": {
      +                "description": "Keys missing for this locale. Always equals translated + wouldTranslate + failed + skipped.",
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              "mode": {
      +                "description": "How the run was executed: \"provider\" called the configured LLM, \"agent\" returned contexts to translate by hand, \"dry-run\" wrote nothing.",
      +                "enum": [
      +                  "provider",
      +                  "agent",
      +                  "dry-run"
      +                ],
      +                "type": "string"
      +              },
      +              "model": {
      +                "description": "Model that produced the translations. Absent outside provider mode.",
      +                "type": "string"
      +              },
      +              "placeholderValidation": {
      +                "additionalProperties": false,
      +                "description": "Placeholder comparison of the new values against their source. Absent when nothing was translated.",
      +                "properties": {
      +                  "errors": {
      +                    "description": "One entry per translation that did not match. Empty when ok is true.",
      +                    "items": {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "extra": {
      +                          "description": "Placeholders the translation invented and the source does not have.",
      +                          "items": {
      +                            "type": "string"
      +                          },
      +                          "type": "array"
      +                        },
      +                        "key": {
      +                          "description": "Dot-path key of the mismatching translation.",
      +                          "type": "string"
      +                        },
      +                        "kind": {
      +                          "description": "What failed: a placeholder set mismatch (the default) or a vue-i18n plural variant-count mismatch.",
      +                          "enum": [
      +                            "placeholder",
      +                            "plural-count"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "locale": {
      +                          "description": "Locale code the mismatch was found in.",
      +                          "type": "string"
      +                        },
      +                        "missing": {
      +                          "description": "Placeholders the source has and the translation dropped.",
      +                          "items": {
      +                            "type": "string"
      +                          },
      +                          "type": "array"
      +                        },
      +                        "sourceVariants": {
      +                          "description": "Plural variants in the source value. Present only for kind \"plural-count\".",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        },
      +                        "targetVariants": {
      +                          "description": "Plural variants in the translated value. Present only for kind \"plural-count\".",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        }
      +                      },
      +                      "required": [
      +                        "locale",
      +                        "key",
      +                        "missing",
      +                        "extra"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "ok": {
      +                    "description": "True when every checked translation carries the same placeholders as its source.",
      +                    "type": "boolean"
      +                  },
      +                  "placeholders": {
      +                    "description": "Placeholder names found in the source values, e.g. [\"{name}\"].",
      +                    "items": {
      +                      "type": "string"
      +                    },
      +                    "type": "array"
      +                  }
      +                },
      +                "required": [
      +                  "ok",
      +                  "placeholders",
      +                  "errors"
      +                ],
      +                "type": "object"
      +              },
      +              "skipped": {
      +                "description": "Keys deliberately not attempted.",
      +                "items": {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "key": {
      +                      "description": "The key that was not attempted.",
      +                      "type": "string"
      +                    },
      +                    "reason": {
      +                      "description": "Why the key or locale was deliberately not attempted. A closed set — branch on the value.",
      +                      "enum": [
      +                        "no-provider",
      +                        "already-translated",
      +                        "protected-locale"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "key",
      +                    "reason"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "stale": {
      +                "description": "Keys whose target was written from source text that has changed since, left untouched by this run. Translation memory only, and outside the missing invariant — these keys are translated, just outdated.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "translated": {
      +                "description": "Keys translated and written.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "wouldTranslate": {
      +                "description": "Keys a dry run would translate. Present only on a dry run.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "writeError": {
      +                "description": "Present when translations were produced but writing the locale file failed.",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "mode",
      +              "missing",
      +              "translated",
      +              "failed",
      +              "skipped"
      +            ],
      +            "type": "object"
      +          },
      +          "description": "Full per-locale results. Absent in compact mode, which returns summary.byLocale instead.",
      +          "propertyNames": {
      +            "description": "Target locale code.",
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "summary": {
      +          "additionalProperties": false,
      +          "description": "What the run did across every locale of the layer.",
      +          "properties": {
      +            "byLocale": {
      +              "description": "A per-locale digest in place of full results. Present only in compact mode.",
      +              "items": {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "batches": {
      +                    "description": "Provider requests this locale took. Absent outside provider mode.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "failed": {
      +                    "description": "Of those, the ones attempted and lost.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "locale": {
      +                    "description": "Locale code this digest is about.",
      +                    "type": "string"
      +                  },
      +                  "missing": {
      +                    "description": "Keys missing for this locale.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "mode": {
      +                    "description": "How the run was executed: \"provider\" called the configured LLM, \"agent\" returned contexts to translate by hand, \"dry-run\" wrote nothing.",
      +                    "enum": [
      +                      "provider",
      +                      "agent",
      +                      "dry-run"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "model": {
      +                    "description": "Model that produced the translations. Absent outside provider mode.",
      +                    "type": "string"
      +                  },
      +                  "skipped": {
      +                    "description": "Of those, the ones deliberately not attempted.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "stale": {
      +                    "description": "Keys left untouched as outdated. Translation memory only.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "translated": {
      +                    "description": "Of those, the ones translated and written.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "wouldTranslate": {
      +                    "description": "Keys a dry run would translate. Present only on a dry run.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "writeError": {
      +                    "description": "Present when writing the locale file failed.",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "locale",
      +                  "mode",
      +                  "missing",
      +                  "translated",
      +                  "failed",
      +                  "skipped"
      +                ],
      +                "type": "object"
      +              },
      +              "type": "array"
      +            },
      +            "dryRun": {
      +              "description": "True when nothing was written because a preview was asked for.",
      +              "type": "boolean"
      +            },
      +            "layer": {
      +              "description": "The layer that was translated.",
      +              "type": "string"
      +            },
      +            "message": {
      +              "description": "What to do next: how to persist the fallback contexts in agent mode, or which locales lost keys after a partial failure. Absent when a run needs nothing from you.",
      +              "type": "string"
      +            },
      +            "mode": {
      +              "description": "How the run was executed: \"provider\" called the configured LLM, \"agent\" returned contexts to translate by hand, \"dry-run\" wrote nothing.",
      +              "enum": [
      +                "provider",
      +                "agent",
      +                "dry-run"
      +              ],
      +              "type": "string"
      +            },
      +            "referenceLocale": {
      +              "anyOf": [
      +                {
      +                  "description": "Locale code, e.g. \"de\".",
      +                  "type": "string"
      +                },
      +                {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "code": {
      +                      "description": "Canonical locale code, e.g. \"en-US\". This is the spelling to pass back to another call.",
      +                      "type": "string"
      +                    },
      +                    "file": {
      +                      "description": "Locale file name, e.g. \"en-US.json\". Absent for directory-per-locale layouts such as Laravel.",
      +                      "type": "string"
      +                    },
      +                    "language": {
      +                      "description": "BCP-47 language tag, e.g. \"en-GB\". Absent when the framework config carries none.",
      +                      "type": "string"
      +                    },
      +                    "name": {
      +                      "description": "Human-readable language name, e.g. \"Deutsch\". Absent unless the framework config names one.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "code"
      +                  ],
      +                  "type": "object"
      +                }
      +              ],
      +              "description": "The locale the translations were made from."
      +            },
      +            "staleCount": {
      +              "description": "Stale keys left untouched across every locale. Translation memory only.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "targetLocales": {
      +              "description": "The locales that were translated into.",
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "description": "Locale code, e.g. \"de\".",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "code": {
      +                        "description": "Canonical locale code, e.g. \"en-US\". This is the spelling to pass back to another call.",
      +                        "type": "string"
      +                      },
      +                      "file": {
      +                        "description": "Locale file name, e.g. \"en-US.json\". Absent for directory-per-locale layouts such as Laravel.",
      +                        "type": "string"
      +                      },
      +                      "language": {
      +                        "description": "BCP-47 language tag, e.g. \"en-GB\". Absent when the framework config carries none.",
      +                        "type": "string"
      +                      },
      +                      "name": {
      +                        "description": "Human-readable language name, e.g. \"Deutsch\". Absent unless the framework config names one.",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "code"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ],
      +                "description": "The locale, either as a bare code or resolved to its code, language tag and file."
      +              },
      +              "type": "array"
      +            },
      +            "totalFailed": {
      +              "description": "Keys attempted and lost across every locale. The counter the translate gate reads.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "totalSkipped": {
      +              "description": "Keys deliberately not attempted across every locale.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "totalTranslated": {
      +              "description": "Keys translated and written across every locale.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "totalWouldTranslate": {
      +              "description": "Keys a dry run would translate. Present only on a dry run.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "mode",
      +            "totalTranslated",
      +            "totalFailed",
      +            "totalSkipped",
      +            "layer",
      +            "referenceLocale",
      +            "targetLocales",
      +            "dryRun"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "summary"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "layers": {
      +          "additionalProperties": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "fallbackContexts": {
      +                "additionalProperties": {
      +                  "additionalProperties": {
      +                    "description": "The value of that field, as the prompt builder produced it."
      +                  },
      +                  "propertyNames": {
      +                    "description": "Context field, e.g. \"keysToTranslate\", \"glossary\", \"instructions\".",
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "description": "Per-locale context to translate inline and persist with write_translations. Present only in agent mode.",
      +                "propertyNames": {
      +                  "description": "Target locale code.",
      +                  "type": "string"
      +                },
      +                "type": "object"
      +              },
      +              "results": {
      +                "additionalProperties": {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "batches": {
      +                      "description": "Provider requests this locale took. Absent outside provider mode.",
      +                      "maximum": 9007199254740991,
      +                      "minimum": -9007199254740991,
      +                      "type": "integer"
      +                    },
      +                    "failed": {
      +                      "description": "Keys the run attempted and lost. They are still missing; a re-run retries them.",
      +                      "items": {
      +                        "additionalProperties": false,
      +                        "properties": {
      +                          "key": {
      +                            "description": "The key that could not be translated.",
      +                            "type": "string"
      +                          },
      +                          "reason": {
      +                            "description": "Why the key could not be translated. A closed set — branch on the value.",
      +                            "enum": [
      +                              "provider-error",
      +                              "omitted-by-model",
      +                              "placeholder-mismatch",
      +                              "plural-mismatch",
      +                              "write-error",
      +                              "truncated"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "key",
      +                          "reason"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "missing": {
      +                      "description": "Keys missing for this locale. Always equals translated + wouldTranslate + failed + skipped.",
      +                      "maximum": 9007199254740991,
      +                      "minimum": -9007199254740991,
      +                      "type": "integer"
      +                    },
      +                    "mode": {
      +                      "description": "How the run was executed: \"provider\" called the configured LLM, \"agent\" returned contexts to translate by hand, \"dry-run\" wrote nothing.",
      +                      "enum": [
      +                        "provider",
      +                        "agent",
      +                        "dry-run"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "model": {
      +                      "description": "Model that produced the translations. Absent outside provider mode.",
      +                      "type": "string"
      +                    },
      +                    "placeholderValidation": {
      +                      "additionalProperties": false,
      +                      "description": "Placeholder comparison of the new values against their source. Absent when nothing was translated.",
      +                      "properties": {
      +                        "errors": {
      +                          "description": "One entry per translation that did not match. Empty when ok is true.",
      +                          "items": {
      +                            "additionalProperties": false,
      +                            "properties": {
      +                              "extra": {
      +                                "description": "Placeholders the translation invented and the source does not have.",
      +                                "items": {
      +                                  "type": "string"
      +                                },
      +                                "type": "array"
      +                              },
      +                              "key": {
      +                                "description": "Dot-path key of the mismatching translation.",
      +                                "type": "string"
      +                              },
      +                              "kind": {
      +                                "description": "What failed: a placeholder set mismatch (the default) or a vue-i18n plural variant-count mismatch.",
      +                                "enum": [
      +                                  "placeholder",
      +                                  "plural-count"
      +                                ],
      +                                "type": "string"
      +                              },
      +                              "locale": {
      +                                "description": "Locale code the mismatch was found in.",
      +                                "type": "string"
      +                              },
      +                              "missing": {
      +                                "description": "Placeholders the source has and the translation dropped.",
      +                                "items": {
      +                                  "type": "string"
      +                                },
      +                                "type": "array"
      +                              },
      +                              "sourceVariants": {
      +                                "description": "Plural variants in the source value. Present only for kind \"plural-count\".",
      +                                "maximum": 9007199254740991,
      +                                "minimum": -9007199254740991,
      +                                "type": "integer"
      +                              },
      +                              "targetVariants": {
      +                                "description": "Plural variants in the translated value. Present only for kind \"plural-count\".",
      +                                "maximum": 9007199254740991,
      +                                "minimum": -9007199254740991,
      +                                "type": "integer"
      +                              }
      +                            },
      +                            "required": [
      +                              "locale",
      +                              "key",
      +                              "missing",
      +                              "extra"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "type": "array"
      +                        },
      +                        "ok": {
      +                          "description": "True when every checked translation carries the same placeholders as its source.",
      +                          "type": "boolean"
      +                        },
      +                        "placeholders": {
      +                          "description": "Placeholder names found in the source values, e.g. [\"{name}\"].",
      +                          "items": {
      +                            "type": "string"
      +                          },
      +                          "type": "array"
      +                        }
      +                      },
      +                      "required": [
      +                        "ok",
      +                        "placeholders",
      +                        "errors"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "skipped": {
      +                      "description": "Keys deliberately not attempted.",
      +                      "items": {
      +                        "additionalProperties": false,
      +                        "properties": {
      +                          "key": {
      +                            "description": "The key that was not attempted.",
      +                            "type": "string"
      +                          },
      +                          "reason": {
      +                            "description": "Why the key or locale was deliberately not attempted. A closed set — branch on the value.",
      +                            "enum": [
      +                              "no-provider",
      +                              "already-translated",
      +                              "protected-locale"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "key",
      +                          "reason"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "stale": {
      +                      "description": "Keys whose target was written from source text that has changed since, left untouched by this run. Translation memory only, and outside the missing invariant — these keys are translated, just outdated.",
      +                      "items": {
      +                        "type": "string"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "translated": {
      +                      "description": "Keys translated and written.",
      +                      "items": {
      +                        "type": "string"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "wouldTranslate": {
      +                      "description": "Keys a dry run would translate. Present only on a dry run.",
      +                      "items": {
      +                        "type": "string"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "writeError": {
      +                      "description": "Present when translations were produced but writing the locale file failed.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "mode",
      +                    "missing",
      +                    "translated",
      +                    "failed",
      +                    "skipped"
      +                  ],
      +                  "type": "object"
      +                },
      +                "description": "Full per-locale results. Absent in compact mode, which returns summary.byLocale instead.",
      +                "propertyNames": {
      +                  "description": "Target locale code.",
      +                  "type": "string"
      +                },
      +                "type": "object"
      +              },
      +              "summary": {
      +                "additionalProperties": false,
      +                "description": "What the run did across every locale of the layer.",
      +                "properties": {
      +                  "byLocale": {
      +                    "description": "A per-locale digest in place of full results. Present only in compact mode.",
      +                    "items": {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "batches": {
      +                          "description": "Provider requests this locale took. Absent outside provider mode.",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        },
      +                        "failed": {
      +                          "description": "Of those, the ones attempted and lost.",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        },
      +                        "locale": {
      +                          "description": "Locale code this digest is about.",
      +                          "type": "string"
      +                        },
      +                        "missing": {
      +                          "description": "Keys missing for this locale.",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        },
      +                        "mode": {
      +                          "description": "How the run was executed: \"provider\" called the configured LLM, \"agent\" returned contexts to translate by hand, \"dry-run\" wrote nothing.",
      +                          "enum": [
      +                            "provider",
      +                            "agent",
      +                            "dry-run"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "model": {
      +                          "description": "Model that produced the translations. Absent outside provider mode.",
      +                          "type": "string"
      +                        },
      +                        "skipped": {
      +                          "description": "Of those, the ones deliberately not attempted.",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        },
      +                        "stale": {
      +                          "description": "Keys left untouched as outdated. Translation memory only.",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        },
      +                        "translated": {
      +                          "description": "Of those, the ones translated and written.",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        },
      +                        "wouldTranslate": {
      +                          "description": "Keys a dry run would translate. Present only on a dry run.",
      +                          "maximum": 9007199254740991,
      +                          "minimum": -9007199254740991,
      +                          "type": "integer"
      +                        },
      +                        "writeError": {
      +                          "description": "Present when writing the locale file failed.",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "locale",
      +                        "mode",
      +                        "missing",
      +                        "translated",
      +                        "failed",
      +                        "skipped"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "dryRun": {
      +                    "description": "True when nothing was written because a preview was asked for.",
      +                    "type": "boolean"
      +                  },
      +                  "layer": {
      +                    "description": "The layer that was translated.",
      +                    "type": "string"
      +                  },
      +                  "message": {
      +                    "description": "What to do next: how to persist the fallback contexts in agent mode, or which locales lost keys after a partial failure. Absent when a run needs nothing from you.",
      +                    "type": "string"
      +                  },
      +                  "mode": {
      +                    "description": "How the run was executed: \"provider\" called the configured LLM, \"agent\" returned contexts to translate by hand, \"dry-run\" wrote nothing.",
      +                    "enum": [
      +                      "provider",
      +                      "agent",
      +                      "dry-run"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "referenceLocale": {
      +                    "anyOf": [
      +                      {
      +                        "description": "Locale code, e.g. \"de\".",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "additionalProperties": false,
      +                        "properties": {
      +                          "code": {
      +                            "description": "Canonical locale code, e.g. \"en-US\". This is the spelling to pass back to another call.",
      +                            "type": "string"
      +                          },
      +                          "file": {
      +                            "description": "Locale file name, e.g. \"en-US.json\". Absent for directory-per-locale layouts such as Laravel.",
      +                            "type": "string"
      +                          },
      +                          "language": {
      +                            "description": "BCP-47 language tag, e.g. \"en-GB\". Absent when the framework config carries none.",
      +                            "type": "string"
      +                          },
      +                          "name": {
      +                            "description": "Human-readable language name, e.g. \"Deutsch\". Absent unless the framework config names one.",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "code"
      +                        ],
      +                        "type": "object"
      +                      }
      +                    ],
      +                    "description": "The locale the translations were made from."
      +                  },
      +                  "staleCount": {
      +                    "description": "Stale keys left untouched across every locale. Translation memory only.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "targetLocales": {
      +                    "description": "The locales that were translated into.",
      +                    "items": {
      +                      "anyOf": [
      +                        {
      +                          "description": "Locale code, e.g. \"de\".",
      +                          "type": "string"
      +                        },
      +                        {
      +                          "additionalProperties": false,
      +                          "properties": {
      +                            "code": {
      +                              "description": "Canonical locale code, e.g. \"en-US\". This is the spelling to pass back to another call.",
      +                              "type": "string"
      +                            },
      +                            "file": {
      +                              "description": "Locale file name, e.g. \"en-US.json\". Absent for directory-per-locale layouts such as Laravel.",
      +                              "type": "string"
      +                            },
      +                            "language": {
      +                              "description": "BCP-47 language tag, e.g. \"en-GB\". Absent when the framework config carries none.",
      +                              "type": "string"
      +                            },
      +                            "name": {
      +                              "description": "Human-readable language name, e.g. \"Deutsch\". Absent unless the framework config names one.",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "code"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      ],
      +                      "description": "The locale, either as a bare code or resolved to its code, language tag and file."
      +                    },
      +                    "type": "array"
      +                  },
      +                  "totalFailed": {
      +                    "description": "Keys attempted and lost across every locale. The counter the translate gate reads.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "totalSkipped": {
      +                    "description": "Keys deliberately not attempted across every locale.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "totalTranslated": {
      +                    "description": "Keys translated and written across every locale.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "totalWouldTranslate": {
      +                    "description": "Keys a dry run would translate. Present only on a dry run.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  }
      +                },
      +                "required": [
      +                  "mode",
      +                  "totalTranslated",
      +                  "totalFailed",
      +                  "totalSkipped",
      +                  "layer",
      +                  "referenceLocale",
      +                  "targetLocales",
      +                  "dryRun"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "summary"
      +            ],
      +            "type": "object"
      +          },
      +          "description": "One full result per locale-backed layer.",
      +          "propertyNames": {
      +            "description": "Layer name.",
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "summary": {
      +          "additionalProperties": false,
      +          "description": "What the run did across every layer and locale, with the per-layer split under byLayer.",
      +          "properties": {
      +            "byLayer": {
      +              "description": "The same totals split per layer.",
      +              "items": {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "layer": {
      +                    "description": "Layer these totals are for.",
      +                    "type": "string"
      +                  },
      +                  "totalFailed": {
      +                    "description": "Keys attempted and lost in that layer.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "totalSkipped": {
      +                    "description": "Keys deliberately not attempted in that layer.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "totalTranslated": {
      +                    "description": "Keys translated and written in that layer.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  },
      +                  "totalWouldTranslate": {
      +                    "description": "Keys a dry run would translate. 0 outside a dry run.",
      +                    "maximum": 9007199254740991,
      +                    "minimum": -9007199254740991,
      +                    "type": "integer"
      +                  }
      +                },
      +                "required": [
      +                  "layer",
      +                  "totalTranslated",
      +                  "totalFailed",
      +                  "totalSkipped",
      +                  "totalWouldTranslate"
      +                ],
      +                "type": "object"
      +              },
      +              "type": "array"
      +            },
      +            "dryRun": {
      +              "description": "True when nothing was written because a preview was asked for.",
      +              "type": "boolean"
      +            },
      +            "layers": {
      +              "description": "Layer names that were translated.",
      +              "items": {
      +                "type": "string"
      +              },
      +              "type": "array"
      +            },
      +            "message": {
      +              "description": "What to do next: how to persist the fallback contexts in agent mode, or which locales lost keys after a partial failure. Absent when a run needs nothing from you.",
      +              "type": "string"
      +            },
      +            "mode": {
      +              "description": "How the run was executed: \"provider\" called the configured LLM, \"agent\" returned contexts to translate by hand, \"dry-run\" wrote nothing.",
      +              "enum": [
      +                "provider",
      +                "agent",
      +                "dry-run"
      +              ],
      +              "type": "string"
      +            },
      +            "referenceLocale": {
      +              "anyOf": [
      +                {
      +                  "description": "Locale code, e.g. \"de\".",
      +                  "type": "string"
      +                },
      +                {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "code": {
      +                      "description": "Canonical locale code, e.g. \"en-US\". This is the spelling to pass back to another call.",
      +                      "type": "string"
      +                    },
      +                    "file": {
      +                      "description": "Locale file name, e.g. \"en-US.json\". Absent for directory-per-locale layouts such as Laravel.",
      +                      "type": "string"
      +                    },
      +                    "language": {
      +                      "description": "BCP-47 language tag, e.g. \"en-GB\". Absent when the framework config carries none.",
      +                      "type": "string"
      +                    },
      +                    "name": {
      +                      "description": "Human-readable language name, e.g. \"Deutsch\". Absent unless the framework config names one.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "code"
      +                  ],
      +                  "type": "object"
      +                }
      +              ],
      +              "description": "The locale the translations were made from."
      +            },
      +            "staleCount": {
      +              "description": "Stale keys left untouched across every layer and locale. Translation memory only.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "targetLocales": {
      +              "description": "The locales that were translated into.",
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "description": "Locale code, e.g. \"de\".",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "code": {
      +                        "description": "Canonical locale code, e.g. \"en-US\". This is the spelling to pass back to another call.",
      +                        "type": "string"
      +                      },
      +                      "file": {
      +                        "description": "Locale file name, e.g. \"en-US.json\". Absent for directory-per-locale layouts such as Laravel.",
      +                        "type": "string"
      +                      },
      +                      "language": {
      +                        "description": "BCP-47 language tag, e.g. \"en-GB\". Absent when the framework config carries none.",
      +                        "type": "string"
      +                      },
      +                      "name": {
      +                        "description": "Human-readable language name, e.g. \"Deutsch\". Absent unless the framework config names one.",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "code"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ],
      +                "description": "The locale, either as a bare code or resolved to its code, language tag and file."
      +              },
      +              "type": "array"
      +            },
      +            "totalFailed": {
      +              "description": "Keys attempted and lost across every layer and locale. The counter the translate gate reads.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "totalSkipped": {
      +              "description": "Keys deliberately not attempted across every layer and locale.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "totalTranslated": {
      +              "description": "Keys translated and written across every layer and locale.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            },
      +            "totalWouldTranslate": {
      +              "description": "Keys a dry run would translate. Present only on a dry run.",
      +              "maximum": 9007199254740991,
      +              "minimum": -9007199254740991,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "mode",
      +            "totalTranslated",
      +            "totalFailed",
      +            "totalSkipped",
      +            "layers",
      +            "byLayer",
      +            "dryRun"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "layers",
      +        "summary"
      +      ],
      +      "type": "object"
      +    }
      +  ],
      +  "type": "object"
      +}
  2. Changed5 schema fields changedv1.0.3
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • changedInput schema / properties / batchSize / description
      Previous value: -"Max keys per LLM sampling request. Default: 50. Lower values reduce per-batch risk but increase round trips."New value: +"Max keys per provider request (provider mode only). Default: 50. Lower values reduce per-batch risk but increase round trips."
    • changedInput schema / properties / layer / description
      Previous value: -"Layer name from discover to translate (e.g., \"root\", \"app-admin\"). Call discover to discover available layers."New value: +"Layer name from discover to translate (e.g., \"root\", \"app-admin\"). Omit to translate every locale-backed layer in one call — the recommended default for layered projects, which returns a result per layer plus an aggregated summary."
    • changedInput schema / properties / projectDir / description
      Previous value: -"Absolute path to the Nuxt project root. Defaults to server cwd. Example: \"/home/user/my-app\"."New value: +"Absolute path to the Nuxt project root. Defaults to I18N_PROJECT_DIR, then server cwd. Example: \"/home/user/my-app\"."
    • removedInput schema / required
      Removed value: -[
      -  "layer"
      -]
  3. First observedv1.0.0

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses substantial behavior beyond annotations: the provider vs. agent mode distinction, the fact that without a backend nothing is written, concurrency across all locales, and use of project config resources. This goes well past the safety profile covered by annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and the critical no-backend caveat, then explains modes. A few sentences are slightly dense but every piece earns its place – no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the presence of an output schema, and the 100% schema coverage, the description covers all the behavioral and routing information an agent needs: modes, concurrency, config usage, and the next tool to call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 9 parameters thoroughly. The description adds no parameter-specific syntax or default information beyond what the schema provides; the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Find the keys missing in the target locales and translate them.' It clearly distinguishes itself from siblings like get_missing_translations (find only) and translate_key (single key), and the two-mode behavior further clarifies scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes when it writes vs. when it returns fallback contexts for manual translation, names the alternative tool (write_translations) for agent mode, tells the user to 'check the discover output for the active mode', and advises passing all target locales concurrently. This is rich, actionable guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.