i18n-le-mcp

An MCP server that audits a set of
translation catalogues against one of them — missing and extra keys,
placeholders dropped or renamed in translation, constructs from another i18n
convention, empty values, keys defined twice, and a path that is an object in
one locale and a string in another — the audit engine behind the
i18n-LE editor extension, exposed as a
tool an agent can call.
Only key names and structural facts come back — never a translated string.
An agent asking whether Spanish is complete does not need the Spanish: a
renamed placeholder is proved by its tokens, and an untranslated string by the
fact that it is byte-identical to the source.
The library is named, never guessed. Which library wrote a catalogue
decides what {name} means — a placeholder in next-intl, literal text in
i18next — and working that out needs manifests, config files and call sites,
none of which this server can see. The caller names it, or gets a refusal.
No dependencies, no network calls, no filesystem access. Content goes in,
structured results come out.
Use it
Point any MCP host at npx i18n-le-mcp.
Claude Code
claude mcp add i18n-le -- npx -y i18n-le-mcp
Anything with a JSON config — Cursor, Windsurf, Claude Desktop:
{
"mcpServers": {
"i18n-le": {
"command": "npx",
"args": ["-y", "i18n-le-mcp"]
}
}
}
VS Code needs nothing here. Install the extension instead — it
carries this server and registers it for you:
VS Code Marketplace
· Open VSX
No Node? The same check_catalogues tool ships in a static Rust binary:
cargo install i18n-le, then i18n-le mcp
(crates.io). The two servers answer
identically — one corpus runs against both, and a differential test feeds both
thousands of generated catalogue sets, broken ones included, and compares every
answer. This server reads no files.
Prefer a global install to npx on every launch:
npm install -g i18n-le-mcp
{
"mcpServers": {
"i18n-le": { "command": "i18n-le-mcp" }
}
}
No environment variables, no API key, no configuration of its own. To check it
before wiring it into anything:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | npx -y i18n-le-mcp
If that prints the tool name, the server works.
The tool
check_catalogues
library | string | required. Which library wrote the catalogues: i18next, next-intl, vscode-l10n or flutter-arb. It supplies the placeholder grammar, the plural model and which keys are metadata. |
files | object[] | required. The catalogues, each { path, content } with an optional locale. JSON, nested or flat. A locale left out on every file is read from the names together. |
source | string | Which catalogue is the contract — a path or a language tag. Without it, exactly one English candidate must exist or the audit is refused. |
keysAreSource | boolean | The key is itself the English string, as in a VS Code bundle.l10n.json. |
maxResults | number | Default 500, ceiling 5000. |
Findings name the file and the key, and carry only structural evidence —
tokens, counts, styles, shapes, occurrence counts, or a construct and its byte
offset:
{
"ok": true,
"data": {
"schema": 3,
"status": "findings",
"system": { "library": "i18next", "version": null, "layout": null, "keysAreSource": false, "evidence": [] },
"source": { "path": "en.json", "locale": "en", "keys": 2 },
"files": [
{ "path": "en.json", "locale": "en", "keys": 2 },
{ "path": "es.json", "locale": "es", "keys": 1 }
],
"findings": [
{ "severity": "error", "kind": "missing-key", "file": "es.json", "key": "nav.home" },
{
"severity": "error",
"kind": "placeholder-name-mismatch",
"file": "es.json",
"key": "metrics.window",
"sourceTokens": ["timeframe"],
"targetTokens": ["periodo"]
}
],
"diagnostics": [],
"summary": { "files": 2, "findings": 2 }
},
"diagnostics": [],
"meta": { "tool": "check_catalogues", "count": 2, "truncated": false }
}
A catalogue that will not parse is named in diagnostics with the parser's
reason and position, and the rest are still audited. ok means the audit ran,
not that the answer was yes.
Also in the MCP registry
io.github.nolindnaidoo/i18n-le —
registry.modelcontextprotocol.io
Eleven more like it
One tool each, same shape: content in, structured data out, no network and no
filesystem. Every one is on npm as <name>-mcp and in the MCP registry as
io.github.nolindnaidoo/<name>.
Every tool in the family, one page: letools.dev
Built by
Nolin Naidoo — Chief Engineer, AI/ML & Platform
Architecture. nolindnaidoo.com ·
GitHub ·
LinkedIn
Also from the same workshop
Twelve Rust tools built the same way: small, single-purpose, and driven by a
machine rather than a person. pixelcoords and pixelactions make up one loop —
pixelcoords answers where, pixelactions acts there. The ten LE crates are
the terminal half of the extensions they sit in: the same detection, held to
the extension's own corpus, and an exit code instead of a results editor.
Licence
MIT © Nolin Naidoo