# xcstrings-crud CLI tool and MCP server for CRUD operations on xcstrings (String Catalog) files. ## Motivation Large xcstrings files can contain thousands of localization keys across multiple languages, resulting in massive JSON files. When AI assistants (like Claude Code) read these files directly, they consume a significant amount of tokens—potentially exceeding context limits or rapidly depleting token budgets. This tool provides a **token-efficient** approach by offering targeted CRUD operations: - **Query only what you need**: Fetch specific keys or languages instead of loading the entire file - **Incremental updates**: Add or update individual translations without reading the full content - **Quick stats**: Get coverage and progress summaries without parsing all entries - **String Catalog semantics**: Preserve Xcode metadata such as `shouldTranslate`, and exclude non-translatable keys from untranslated lists and coverage totals - **String Catalog metadata**: Preserve Xcode metadata such as autogenerated comments during read and write operations By using the MCP server or CLI, AI assistants can work with xcstrings files of any size while keeping token usage minimal. ## Installation ### Using Mise ```bash mise use -g github:Ryu0118/xcstrings-crud ``` ### Using nest ([mtj0928/nest](https://github.com/mtj0928/nest)) ```bash nest install Ryu0118/xcstrings-crud ``` ### Build from source ```bash git clone https://github.com/Ryu0118/xcstrings-crud.git cd xcstrings-crud swift build -c release ``` Binary will be at `.build/release/xcstrings-crud`. ## MCP Server The MCP server is available as a subcommand: ```bash xcstrings-crud mcp ``` ### Configuration Add to your Claude Code MCP settings: ```json { "mcpServers": { "xcstrings-crud": { "command": "xcstrings-crud", "args": ["mcp"] } } } ``` ### Available Tools | Tool | Description | |------|-------------| | `xcstrings_create_file` | Create a new xcstrings file | | `xcstrings_list_keys` | List all keys | | `xcstrings_list_languages` | List supported languages | | `xcstrings_list_untranslated` | List untranslated keys | | `xcstrings_list_stale` | List keys with stale extraction state | | `xcstrings_batch_list_stale` | List stale keys across multiple files | | `xcstrings_get_source_language` | Get source language | | `xcstrings_get_key` | Get translations for a key | | `xcstrings_check_key` | Check if key exists; suggests NFKC-equivalent keys when not found | | `xcstrings_check_coverage` | Check key language coverage | | `xcstrings_stats_coverage` | Get overall coverage statistics | | `xcstrings_stats_progress` | Get translation progress by language | | `xcstrings_batch_stats_coverage` | Get coverage for multiple files at once | | `xcstrings_batch_check_keys` | Check if multiple keys exist | | `xcstrings_batch_add_translations` | Add translations for multiple keys at once | | `xcstrings_batch_update_translations` | Update translations for multiple keys at once | | `xcstrings_add_translation` | Add translation for single language | | `xcstrings_add_translations` | Add translations for multiple languages | | `xcstrings_update_translation` | Update translation for single language | | `xcstrings_update_translations` | Update translations for multiple languages | | `xcstrings_rename_key` | Rename key | | `xcstrings_delete_key` | Delete entire key | | `xcstrings_delete_translation` | Delete translation for single language | | `xcstrings_delete_translations` | Delete translations for multiple languages | ## CLI Usage ### Create Operations ```bash # Create a new xcstrings file xcstrings-crud create path/to/Localizable.xcstrings # Create with specific source language xcstrings-crud create path/to/Localizable.xcstrings --source-language ja # Overwrite existing file xcstrings-crud create path/to/Localizable.xcstrings --overwrite ``` ### Read Operations ```bash # List all keys xcstrings-crud list keys --file path/to/Localizable.xcstrings # List languages xcstrings-crud list languages --file path/to/Localizable.xcstrings # List untranslated keys for a language xcstrings-crud list untranslated --file path/to/Localizable.xcstrings --lang ja # Keys marked `"shouldTranslate": false` are omitted from untranslated results. # List stale keys (potentially unused) xcstrings-crud list stale --file path/to/Localizable.xcstrings # List stale keys across multiple files xcstrings-crud batch stale -f file1.xcstrings file2.xcstrings file3.xcstrings # Get source language xcstrings-crud get source-language --file path/to/Localizable.xcstrings # Get translations for a key xcstrings-crud get key "Hello" --file path/to/Localizable.xcstrings xcstrings-crud get key "Hello" --file path/to/Localizable.xcstrings --lang ja # Check if key exists xcstrings-crud check key "Hello" --file path/to/Localizable.xcstrings # Check key coverage xcstrings-crud check coverage "Hello" --file path/to/Localizable.xcstrings # Non-translatable keys are treated as complete. # Check untranslated entries across specific files and languages xcstrings-crud check untranslated \ --files App/Localizable.xcstrings Package/Localizable.xcstrings \ --languages ja de fr # Emits JSON and exits with status 1 when untranslated entries are found. # Keys marked `"shouldTranslate": false` are omitted from untranslated results. # Emit hook-compatible blocking JSON instead of failing the command. xcstrings-crud check untranslated \ --files App/Localizable.xcstrings \ --languages ja \ --codex-hook xcstrings-crud check untranslated \ --files App/Localizable.xcstrings \ --languages ja \ --claude-hook # Get overall statistics xcstrings-crud stats coverage --file path/to/Localizable.xcstrings # Coverage totals exclude keys marked `"shouldTranslate": false`. # Get progress for a language xcstrings-crud stats progress --file path/to/Localizable.xcstrings --lang ja # Get batch coverage for multiple files xcstrings-crud stats batch-coverage -f file1.xcstrings file2.xcstrings file3.xcstrings ``` ### Update Operations ```bash # Add translation (single language) xcstrings-crud add key "Hello" --file path/to/Localizable.xcstrings --lang ja --value "こんにちは" # Add translation (multiple languages) xcstrings-crud add key "Hello" --file path/to/Localizable.xcstrings -t ja:こんにちは en:Hello # Update translation (single language) xcstrings-crud update key "Hello" --file path/to/Localizable.xcstrings --lang ja --value "こんにちは!" # Update translations (multiple languages) xcstrings-crud update key "Hello" --file path/to/Localizable.xcstrings -t ja:こんにちは en:Hello de:Hallo # Rename key xcstrings-crud rename key "Hello" --file path/to/Localizable.xcstrings --to "Greeting" ``` ### Delete Operations ```bash # Delete entire key xcstrings-crud delete key "Hello" --file path/to/Localizable.xcstrings # Delete translation for specific language only xcstrings-crud delete key "Hello" --file path/to/Localizable.xcstrings -l ja # Delete translations for multiple languages xcstrings-crud delete key "Hello" --file path/to/Localizable.xcstrings -l ja en fr ``` ### Batch Operations ```bash # List stale keys across multiple files xcstrings-crud batch stale -f file1.xcstrings file2.xcstrings file3.xcstrings # Check if multiple keys exist xcstrings-crud batch check --file path/to/Localizable.xcstrings -k Hello Goodbye Welcome # Check with specific language xcstrings-crud batch check --file path/to/Localizable.xcstrings -k Hello Goodbye -l ja # Add translations for multiple keys at once xcstrings-crud batch add --file path/to/Localizable.xcstrings \ -e "Hello=ja:こんにちは,en:Hello" \ -e "Goodbye=ja:さようなら,en:Goodbye" # Add with overwrite (replace existing translations) xcstrings-crud batch add --file path/to/Localizable.xcstrings --overwrite \ -e "Hello=ja:こんにちは,en:Hello" # Update translations for multiple keys at once xcstrings-crud batch update --file path/to/Localizable.xcstrings \ -e "Hello=ja:こんにちは!,en:Hello!" \ -e "Goodbye=ja:さようなら!" ``` ### Common Options - `--file `: xcstrings file path (required) - `--pretty`: Pretty-printed JSON output For `check untranslated`, `--files ` and `--languages ` are required. `--codex-hook` and `--claude-hook` are mutually exclusive and intended for CLI hook integrations only. ## Requirements - macOS 13+ - Swift 6.0+ ## License MIT