🌐 xcstrings-mcp
MCP server for iOS/macOS .xcstrings (String Catalog) localization — parse, translate, validate, and export with any AI coding assistant
Why xcstrings-mcp?
Xcode String Catalogs (.xcstrings) are large JSON files that waste LLM context windows when loaded whole. Manual editing risks corrupting Xcode's specific formatting, there's no validation for format specifiers or plural rules, and plural-aware translation requires understanding CLDR categories across 40+ locales.
xcstrings-mcp solves this by providing structured MCP tools that let AI assistants work with .xcstrings files efficiently — reading only what's needed, validating every write, and preserving Xcode's exact JSON formatting.
Features
- 26 MCP tools + 8 prompts + 11 CLI commands covering the full localization lifecycle
- Batch translation with context window management — process 50-100 keys at a time
- Format specifier & CLDR plural validation — catch
%d/%@mismatches and missing plural forms before they ship - Atomic writes preserving Xcode's exact JSON formatting (
" : "spacing, key order, BOM handling) - Legacy migration — import
.stringsand.stringsdictfiles (UTF-8/UTF-16, plural rules, positional specifiers) - XLIFF 1.2 export/import — integrate with external translation tools and agencies
- Glossary for consistent terminology across locales
- Works with Claude Code, Cursor, VS Code + Copilot, Windsurf, Zed, OpenAI Codex, and any MCP client
Quick Start
Install
# or
# or
Configure
Add to .cursor/mcp.json:
Add to ~/.codeium/windsurf/mcp_config.json:
Add to .vscode/mcp.json:
Add to Zed settings (settings.json):
Add to your project's codex.json or configure via Codex CLI:
xcstrings-mcp communicates via stdio using JSON-RPC. Point your MCP client to the binary:
command: xcstrings-mcp
transport: stdio
Usage
Typical workflow:
- Parse the
.xcstringsfile to cache it - Get untranslated strings in batches that fit the context window
- Submit translations with automatic validation and atomic writes
parse_xcstrings → get_untranslated → submit_translations
Multi-file projects: parse each file — the server caches all of them and tracks the active one. Use list_files to see cached files.
Tools
| Tool | Description |
|---|---|
parse_xcstrings |
Parse and cache .xcstrings file |
get_untranslated |
Get untranslated strings with batching |
submit_translations |
Validate and write translations atomically |
get_coverage |
Per-locale coverage statistics |
get_stale |
Find stale/removed keys |
validate_translations |
File-wide validation report |
list_locales |
List locales with stats |
add_locale |
Add new locale with empty translations |
remove_locale |
Remove a locale from all entries |
get_plurals |
Extract keys needing plural translation |
get_context |
Find related keys by shared prefix |
list_files |
List all cached files with active status |
get_diff |
Compare cached vs on-disk file (added/removed/modified keys) |
get_glossary |
Get translation glossary entries for a locale pair |
update_glossary |
Add or update glossary terms |
export_xliff |
Export to XLIFF 1.2 for external translation tools |
import_xliff |
Import translations from XLIFF 1.2 file |
import_strings |
Migrate legacy .strings/.stringsdict files to .xcstrings |
search_keys |
Search keys by substring (matches key names and source text) |
create_xcstrings |
Create a new empty .xcstrings file |
add_keys |
Add new localization keys with source text |
discover_files |
Find .xcstrings and legacy .strings/.stringsdict files |
update_comments |
Update developer comments on localization keys |
delete_keys |
Delete localization keys and all their translations |
delete_translations |
Remove translations for specific keys in a locale, resetting to untranslated |
get_key |
Get all translations for a specific key across all locales |
rename_key |
Rename a localization key, preserving all translations |
Prompts
| Prompt | Description |
|---|---|
translate_batch |
Step-by-step instructions for batch translation |
review_translations |
Instructions for quality review of translations |
full_translate |
Complete workflow for translating an entire file |
localization_audit |
Full audit: coverage, validation, stale keys, glossary |
fix_validation_errors |
Guided workflow to fix all validation issues |
add_language |
Add a new locale and translate all strings |
extract_strings |
Extract hardcoded strings from Swift code into .xcstrings |
cleanup_stale |
Find and remove stale/unused localization keys |
Migrating from Legacy .strings
To migrate an existing project using .strings/.stringsdict files:
discover_files → import_strings → get_untranslated → submit_translations
Preview first with dry_run, then write:
import_strings(directory: "./Resources", source_language: "en", output_path: "./Localizable.xcstrings", dry_run: true)
import_strings(directory: "./Resources", source_language: "en", output_path: "./Localizable.xcstrings")
For projects with .stringsdict plural rules, also check plural keys after import:
import_strings → get_plurals → get_untranslated → submit_translations
Supports UTF-8 and UTF-16 encodings, .stringsdict plural rules (single and multi-variable with positional specifiers), developer comments, unquoted keys, and merge into existing .xcstrings files.
Getting Started from Scratch
To create a new localization file and begin translating:
create_xcstrings → add_keys → add_locale → get_untranslated → submit_translations
Or use the extract_strings prompt to automatically extract hardcoded strings from your Swift source code.
CLI Commands
In addition to the MCP server, xcstrings-mcp provides direct CLI commands for terminal use, CI/CD pipelines, and scripting.
Commands auto-discover .xcstrings files in the current directory tree -- no path required:
| Command | Description |
|---|---|
info |
File summary: source language, keys, locales |
coverage |
Translation coverage per locale |
validate |
Check format specifiers, plurals, empty values |
search <pattern> |
Find keys by substring |
stale |
List stale/removed keys |
add-locale <locale> |
Add a new locale |
remove-locale <locale> |
Remove a locale |
export |
Export to XLIFF 1.2 |
import |
Import from XLIFF with validation |
migrate |
Migrate legacy .strings/.stringsdict |
completions <shell> |
Generate shell completions |
All commands support --json for machine-readable output. Mutation commands support --dry-run.
CLI Options
| Flag | Default | Description |
|---|---|---|
--glossary-path |
glossary.json |
Path to glossary file for consistent terminology |
Claude Code Skill
xcstrings-mcp ships with a Claude Code skill that teaches Claude Code the optimal workflows, best practices, and error handling for all 26 tools. The skill auto-triggers on any localization-related request.
What it does:
- Prevents Claude from reading
.xcstringsfiles directly (wastes context, risks corruption) - Guides optimal tool sequences for every workflow (translate, migrate, audit, export)
- Handles CLDR plural categories per locale (uk needs one/few/many, ja needs only other)
- Manages glossary for consistent terminology across translations
- Parallelizes multi-locale translation with one subagent per language
Install the skill:
# One-liner
&&
Or clone the repo and copy:
The skill covers these workflows out of the box:
- Full translation — parallel subagents per locale with batch processing
- Add/remove language — locale management with coverage verification
- Coverage audit — coverage, validation, stale keys, glossary check
- Legacy migration —
.strings/.stringsdictto.xcstringswith dry-run preview - XLIFF roundtrip — export for translators, import back with validation
- Plural handling — CLDR-aware plural form management
- Glossary management — consistent terminology across locales
Performance
Binary size: ~4 MB (stripped + LTO). Zero CPU at idle.
| File | Parse | Get untranslated | Validate | RAM |
|---|---|---|---|---|
| 968KB (638 keys × 10 loc) | 0.2ms | 0.02ms | 0.04ms | 7.6 MB |
| 4.1MB (2K keys × 10 loc) | 24ms | 5ms | 7ms | 40 MB |
| 10.3MB (5K keys × 10 loc) | 60ms | 11ms | 23ms | 49 MB |
| 56.7MB (10K keys × 30 loc) | 333ms | 62ms | 221ms | 287 MB |
Scaling is linear — no degradation cliffs. Typical iOS projects (2-5K keys) parse in under 60ms.
Architecture
┌─────────────┐ stdio/JSON-RPC ┌──────────────────┐ File I/O ┌───────────────────────┐
│ Claude Code │◄───────────────────►│ xcstrings-mcp │◄──────────────►│ Localizable.xcstrings │
│ (translates)│ │ (Rust MCP server)│ │ (JSON on disk) │
└─────────────┘ └──────────────────┘ └───────────────────────┘
Layered architecture: server -> tools -> service -> model, with io injected via the FileStore trait.
- server -- MCP tool routing and handler dispatch
- tools -- individual tool implementations
- service -- pure logic (parser, extractor, merger, validator, formatter); no I/O
- model -- serde types for
.xcstringsformat, CLDR plural rules, format specifiers - io --
FileStoretrait + real filesystem implementation with atomic writes
Related
- Model Context Protocol — open protocol for AI tool integration
- Xcode String Catalogs — Apple's localization format
- CLDR Plural Rules — Unicode plural categories used for validation
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributing
See CONTRIBUTING.md for development setup and guidelines.