# KAERIS i18n (pypi · kaeris-mcp)

Translate app language files into 46 languages and check placeholders, plurals and missing keys.

- Trust score: 54/100 (low)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- pypi · `kaeris-mcp`: 54/100 (this document), [markdown](https://verifymcp.io/servers/kaeris-io-kaeris-mcp/kaeris-mcp.md), [page](https://verifymcp.io/servers/kaeris-io-kaeris-mcp/kaeris-mcp)

## Channel facts

- Registry: `pypi`
- Package: `kaeris-mcp`
- Version: `0.2.18`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs setuptools.build_meta at install time, a recognised build step with no custom scripting around it.
  - 1 of 29 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 48/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 3 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 59/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 3718 tokens (~531/item across 7 items; 7 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 67/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 7 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 7 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the KAERIS i18n MCP server?

KAERIS i18n runs locally as a PyPI package, launched with uvx kaeris-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add kaeris-io-kaeris-mcp -- uvx kaeris-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "kaeris-io-kaeris-mcp": {
      "command": "uvx",
      "args": [
        "kaeris-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "kaeris-io-kaeris-mcp": {
      "command": "uvx",
      "args": [
        "kaeris-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add kaeris-io-kaeris-mcp -- uvx kaeris-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "kaeris-io-kaeris-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "kaeris-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add kaeris-io-kaeris-mcp --command uvx --arg kaeris-mcp
```

### Hermes

```yaml
mcp_servers:
  kaeris-io-kaeris-mcp:
    command: "uvx"
    args: ["kaeris-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "kaeris-io-kaeris-mcp": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "kaeris-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add kaeris-io-kaeris-mcp -t stdio -c uvx -a kaeris-mcp
```

### Other

```json
{
  "mcpServers": {
    "kaeris-io-kaeris-mcp": {
      "command": "uvx",
      "args": [
        "kaeris-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-05 (score 54, −15)

- [security regression] Malware scan: pass → unverified

### 2026-11-04 (score 69, +1)

No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-02 (score 68, +1)

No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-01 (score 67, 0)

- [security regression] Tool safety: pass → unverified
- [security regression] Stability: 0.10 → unverified
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional] First check of Schema quality: unverified
- [functional] Package version: 0.2.16 → 0.2.18

### 2026-10-30 (score 67, +17)

- [security improvement] Malware scan: unverified → pass
- [functional improvement] Security disclosure: fail → pass

### 2026-10-29 (score 50, −15)

- [security regression] Malware scan: pass → unverified

### 2026-10-28 (score 65)

First indexed and scored.

## MCP tools (7)

### `kaeris_list_languages` (~56 tokens)

List every target language KAERIS can translate into.

Returns a mapping of language code → English name (e.g. {"es": "Spanish", ...}).
Use the codes with kaeris_translate / kaeris_translate_file.

### `kaeris_scan_repo` (~415 tokens)

Discover a repo's i18n setup: which locale files exist, what the base
(source) language and target languages are, and which framework/convention
is in use. Purely local — reads the filesystem, makes no API call.

Use this FIRST when asked to "look at/audit/fix this repo's i18n" and you
don't already know the source file — it tells you where to point
kaeris_status / kaeris_list_missing_keys / kaeris_add_language.

Supports i18next/react-i18next (locales/<lang>/*.json), next-intl
(messages/<lang>.json), vue-i18n (src/locales/<lang>.json), Flutter ARB
(lib/l10n/*.arb), Android (res/values[-<lang>]/strings.xml), iOS
(<lang>.lproj/Localizable.strings), gettext (locale/<lang>/LC_MESSAGES/*.po),
Xcode String Catalogs (Localizable.xcstrings — one file holding every language,
read out of the catalog itself), XLIFF (.xliff/.xlf), Java/Spring .properties,
.NET RESX, Mozilla Fluent (.ftl), Markdown/MDX, plus plain
\<lang>.json/.yaml/.csv files anywhere else. Skips node_modules,
.git, build/dist output and other noise; bounded so it's safe on large repos.

Args:
    path: directory to scan (default: current directory).

Returns:
    { "root": "<abs path scanned>",
      "locale_files": ["locales/en.json", "locales/de.json", ...],
      "base_lang": "en",            # best guess, or null if none found/ambiguous
      "target_langs": ["de", "fr"], # languages present other than base_lang
      "framework": "i18next",       # best guess, or null if unrecognized
      "file_count": 2 }

Input parameters:

- `path` (string)

### `kaeris_status` (~667 tokens)

Completeness/health check for every target locale against a source file
— the "i18n firewall". Works for EVERY supported format: JSON is checked fully
offline; other formats (.arb/.strings/.po/.xml/.ftl/…) are parsed by the backend
/api/parse endpoint (no translation, no cost).

For each target language reports missing keys, extra/stale keys,
placeholder mismatches (e.g. "Hello {name}" -> "Bonjour" loses {name}, or
"{name}" -> "{nom}" which crashes str.format()/ICU at runtime), and the same
quality detectors the CLI firewall gates a merge on: number drift
("Delete 5 files" -> "Delete 50 files"), lost inline tags, broken entities
or escapes, missing ICU/CLDR plural categories. Those come back under
"faults" (RED — they set ok=false) and "warnings" (YELLOW — advisory).
Use this
to find out what's broken before deciding whether to call
kaeris_list_missing_keys (existing locale, some keys missing/broken) or
kaeris_add_language (locale doesn't exist yet at all).

Args:
    source: path to the base-language locale file, e.g. "locales/en.json" or
            "lib/l10n/app_en.arb" (typically kaeris_scan_repo's base_lang file).
    langs: target language codes to check, e.g. ["de", "fr"]. If omitted,
           falls back to kaeris.json's "langs" if present, else auto-discovers
           sibling <lang> files next to the source.
    out: directory containing the target locale files (default: source's own
         directory; each target is expected at "<out>/<lang><source-ext>",
         e.g. de.json for en.json, de.arb for en.arb).

Returns:
    { "ok": bool, "missing": {lang: [keys]}, "extra": {lang: [keys]},
      "placeholder_issues": [{"lang","key","missing","added"}, ...],
      "faults": [{"lang","key","severity":"error","msg"}, ...],    # RED — ok is false
      "warnings": [{"lang","key"?,"severity":"warn","msg"}, ...],  # YELLOW — advisory
      "missing_files": [lang, ...],  # target language has no locale file at all
      "counts": {"missing": {lang: n}, "extra"…

Input parameters:

- `langs` (array)
- `out` (string)
- `source` (string, required)

### `kaeris_list_missing_keys` (~503 tokens)

The exact keys missing or placeholder-broken in ONE target locale, with
their source-language text, so an agent knows exactly what to translate/fix.
Every supported format works (JSON offline; others via the backend /api/parse,
no cost) — use kaeris_add_language or kaeris_translate to actually fill them in.

The answer is PAGED: "missing_count" is always the exact total, while "missing" /
"missing_values" carry one page of it (default 200 entries, and never more than about
15k tokens' worth). A whole locale file returned in one tool result is not a long answer,
it is the end of the agent's session — measured 16.08.2026: a 2 MB source file, the size
the product accepts, produced 667 000 tokens in a single reply. When there is a next page,
"page.next_offset" says where it starts.

Args:
    source: path to the base-language locale file, e.g. "locales/en.json" or "app_en.arb".
    lang: the target language code to inspect, e.g. "de".
    out: directory containing the target locale file (default: source's own
         directory; expected at "<out>/<lang><source-ext>", e.g. de.json / de.arb).
    limit: how many missing keys to return in this call (default 200, max 2000).
    offset: where to start — pass "page.next_offset" from the previous call.

Returns:
    { "lang": "de", "missing_file": bool,
      "missing_count": 1234,                       # ALWAYS the exact total
      "missing": ["<dotted.key>", ...],            # one page of them
      "missing_values": {"<dotted.key>": "<source text>", ...},   # the same page
      "page": {"total", "returned", "offset", "complete", "next_offset"?, "note"?},
      "extra": ["<dotted.key>", ...], "extra_count": 12,
      "placeholder_issues": [{"key","missing","added"}, ...], "placeholder_issue_count": 3 }

Input parameters:

- `lang` (string, required)
- `limit` (integer)
- `offset` (integer)
- `out` (string)
- `source` (string, required)

### `kaeris_add_language` (~588 tokens)

Bootstrap a BRAND-NEW target locale by translating the entire source file
into it and writing the result. Use this when kaeris_scan_repo/kaeris_status
show a language with no locale file at all yet (in "missing_files").

This CALLS THE TRANSLATION API (same as kaeris_translate_file) — unlike
kaeris_scan_repo/kaeris_status/kaeris_list_missing_keys, which are local-only
and free. For an EXISTING locale that's just missing a few keys, prefer
kaeris_translate_file(..., only_new=True) so you don't re-translate the whole file.

Args:
    source: path to the base-language locale file, e.g. "locales/en.json".
    lang: the new target language code to create, e.g. "de".
    out: output directory (default: source file's own directory).
    tone: "formal" or "casual" to steer register; "" (default) is neutral.
    icu: True if the source uses ICU MessageFormat (plurals/select), so the
         model preserves the syntax instead of translating it.
    keep: optional list of terms to NEVER translate (brand/product names).
    context: one line about what the app IS, e.g. "a mobile bank for teenagers" or
          "a wildlife documentary app". The model uses it to pick the right sense of
          ambiguous strings — "Bank" becomes Ufer in the second and Bank in the first.
          You are reading the repo, so you know this: pass it. Max 300 chars.
    api_key / openrouter_key: optional auth overrides. PREFER the KAERIS_API_KEY /
          KAERIS_OPENROUTER_KEY environment variables: a key passed as a tool argument is
          written into the conversation transcript and into the MCP client's logs, where
          it outlives this task.
    job_id: leave empty to start a translation. If a previous call came back with
          {"status": "running", "job_id": ...}, pass that id (with the same source/out) to
          collect the finished result instead of paying for the work twice.

Returns:
    { "written": ["<out>/<lang>.json"], "lang": "de", "languages": ["de"] }
    or, if…

Input parameters:

- `api_key` (string)
- `context` (string)
- `icu` (boolean)
- `job_id` (string)
- `keep` (array)
- `lang` (string, required)
- `openrouter_key` (string)
- `out` (string)
- `source` (string, required)
- `tone` (string)

### `kaeris_translate` (~846 tokens)

Translate a set of UI strings into one or more languages.

Format-aware and placeholder-safe: values like "Hello, {name}" keep their
placeholders intact. Non-string values are passed through unchanged.

Includes Translation QA so you can trust the output: it flags translations that
dropped a placeholder or that grew long enough to risk overflowing the UI. With
verify=True it also back-translates each result into back_lang so you can check the
meaning is right even in a language you can't read.

Args:
    strings: key → source-text pairs, e.g. {"greeting": "Hello", "save": "Save"}.
    target_languages: language codes from kaeris_list_languages, e.g. ["es", "fr", "ja"].
    keep: optional list of terms to NEVER translate — kept verbatim in every language
          (brand/product names), e.g. ["KAERIS", "GitHub"].
    context: one line about what the app IS, e.g. "a mobile bank for teenagers" or
          "a wildlife documentary app". The model uses it to pick the right sense of
          ambiguous strings — "Bank" becomes Ufer in the second and Bank in the first.
          You are reading the repo, so you know this: pass it. Max 300 chars.
    verify: back-translation and meaning check for your review — back-translates into
          back_lang and flags lines whose meaning may have changed (uses more tokens).
    back_lang: language for the verify back-translation (default "en").
    tone: "formal" or "casual" to steer register; "" (default) is neutral.
    icu: True if values may contain ICU MessageFormat (plurals/select) so the
         model preserves the syntax instead of translating it.
    reuse: optional {lang: {key: previous_translation}} translation-memory map —
           strings that are unchanged from a prior run are reused verbatim
           server-side and only new/changed strings are actually translated.
    api_key / openrouter_key: optional auth overrides. PREFER the KAERIS_API_KEY /
          KAERIS_OPENROUTER_KEY environment variables: a key pass…

Input parameters:

- `api_key` (string)
- `back_lang` (string)
- `context` (string)
- `icu` (boolean)
- `job_id` (string)
- `keep` (array)
- `openrouter_key` (string)
- `reuse` (object)
- `strings` (object, required)
- `target_languages` (array, required)
- `tone` (string)
- `verify` (boolean)

### `kaeris_translate_file` (~643 tokens)

Translate a strings file on disk and write the results next to it.

Supports JSON, YAML, .strings, Xcode String Catalogs (.xcstrings), .po, ARB,
Android XML, CSV, XLIFF 1.2, Java/Spring .properties, .NET RESX, Mozilla Fluent
(.ftl) and Markdown/MDX — every format the API accepts. With only_new=True
(JSON), translates just the keys missing from existing target files and merges.

Args:
    file_path: path to the source file, e.g. "locales/en.json".
    target_languages: language codes, e.g. ["de", "uk", "zh"].
    out_dir: where to write outputs (default: the source file's directory).
    only_new: reproducible incremental mode — translate only new AND edited keys, tracked via
              kaeris.lock (a tone/ICU/glossary change re-translates all); unchanged stays
              stable. JSON and ARB only — for any other format the whole file is translated
              (and charged), and the result says so in "note".
    keep: optional list of terms to NEVER translate — kept verbatim in every language
          (brand/product names), e.g. ["KAERIS", "GitHub"].
    context: one line about what the app IS, e.g. "a mobile bank for teenagers" or
          "a wildlife documentary app". The model uses it to pick the right sense of
          ambiguous strings — "Bank" becomes Ufer in the second and Bank in the first.
          You are reading the repo, so you know this: pass it. Max 300 chars.
    verify: back-translation and meaning check for your review; with only_new the
            result carries them as "back_translations".
    back_lang: language for the verify back-translation (default "en").
    tone: "formal" or "casual" to steer register; "" (default) is neutral.
    icu: True if values may contain ICU MessageFormat (plurals/select) so the
         model preserves the syntax instead of translating it.
    reuse: optional {lang: {key: previous_translation}} translation-memory map —
           strings unchanged from a prior run are reused verbatim server-side…

Input parameters:

- `api_key` (string)
- `back_lang` (string)
- `context` (string)
- `file_path` (string, required)
- `icu` (boolean)
- `job_id` (string)
- `keep` (array)
- `only_new` (boolean)
- `openrouter_key` (string)
- `out_dir` (string)
- `reuse` (object)
- `target_languages` (array, required)
- `tone` (string)
- `verify` (boolean)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/kaeris-io-kaeris-mcp/kaeris-mcp#diagnostics

## Score history

- 2026-11-05: 54
- 2026-11-04: 69
- 2026-11-03: 68
- 2026-11-02: 68
- 2026-11-01: 67
- 2026-10-31: 67
- 2026-10-30: 67
- 2026-10-29: 50
- 2026-10-28: 65

## Common questions

### What is the KAERIS i18n MCP server?

KAERIS i18n is an MCP server listed in the public MCP registry as io.github.kaeris-io/kaeris-mcp. Translate app language files into 46 languages and check placeholders, plurals and missing keys. This page covers its PyPI package (kaeris-mcp).

### Is the KAERIS i18n MCP server safe to use?

KAERIS i18n scores 54 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the KAERIS i18n MCP server expose?

KAERIS i18n exposes 7 tools: kaeris_list_languages, kaeris_scan_repo, kaeris_status, kaeris_list_missing_keys, kaeris_add_language, and 2 more. Their descriptions and schemas cost roughly 3,718 tokens of context every time the server is loaded.

### Is the KAERIS i18n MCP server still maintained?

KAERIS i18n is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the KAERIS i18n MCP server under?

KAERIS i18n declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

### What did VerifyMCP test on the KAERIS i18n MCP server?

VerifyMCP ran 15 checks on KAERIS i18n, covering Known CVEs, Install scripts, Dependency health, Source repository and 11 more. One item could not be completed, a gap on our side rather than a finding about KAERIS i18n: Malware scan. Endpoint Security and Transport & Reachability do not apply to a PyPI package, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.

## Links

- PyPI project: https://pypi.org/project/kaeris-mcp/
- Socket report: https://socket.dev/pypi/package/kaeris-mcp
- Repository: https://github.com/kaeris-io/kaeris-mcp
- Website: https://kaeris.dev/mcp-localization.html
- Changelog RSS feed: https://verifymcp.io/servers/kaeris-io-kaeris-mcp/kaeris-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/kaeris-io-kaeris-mcp/kaeris-mcp/changelog.json
- Trust report (JSON): https://verifymcp.io/servers/kaeris-io-kaeris-mcp/kaeris-mcp.json
- HTML version of this page: https://verifymcp.io/servers/kaeris-io-kaeris-mcp/kaeris-mcp
