Releases: Murzav/xcstrings-mcp
Releases · Murzav/xcstrings-mcp
Release list
v1.4.1
Added
merge_xcstringsMCP tool andmergeCLI command now provide conservative ordered two-sided/three-way String Catalog merges. Dry-runs return raw-byte fingerprints, automatic choices, validation deltas, and stable paginated conflicts; apply accepts onlycurrent/incoming/baseresolutions and refuses unresolved, newly invalid, or stale results.
Changed
- BREAKING (Rust library API): the public
XcStringsMcpServernow implementsrmcp3.1.2'sServerHandlerand requires Rust 1.88. Rust embedders with a directrmcpdependency must update it from 2.x to 3.1.2.XcStringsErroris now#[non_exhaustive], so downstream exhaustive matches must add a wildcard arm. The CLI binary, stdio transport, and MCP client configuration are unchanged. - Format validation now parses Foundation arguments deterministically, including the integer
jlength modifier, preserves position, conversion, length modifier, flags, width, and precision per occurrence, permits valid positional reordering and repeated ABI-compatible argument references, and rejects incompatible reuse across simple, plural, and substitution validation paths. submit_translations, MCP XLIFF import, CLI XLIFF import, and file validation now expose non-blocking, machine-readable warnings when ambiguous percent-in-prose sequences differ.- Filesystem writes now coordinate through a stable sibling advisory lock instead of locking the replaceable destination inode. The public
FileStorehas a source-compatible conditional-write method whose default fails closed; the real store compares exact expected bytes or expected absence under the lock before temp-file fsync and atomic rename.
Fixed
- Rust 1.88 Clippy compatibility is restored for XLIFF namespace validation, keeping the documented MSRV green in the release matrix.
- Merge dry-runs with unresolved conflicts now retain the complete CLI JSON report while returning validation exit status 2. Validation deltas list only issues that remain in the candidate, MCP pagination schema matches the 1–500 runtime range, conflict metadata handles marker-like key names, and cached path aliases refresh by canonical file identity without switching the active file.
- Filesystem temp cleanup is now target-owned and performed under that target's stable lock, so starting another cooperating store cannot remove an active writer's temp. Expected-absence writes also reject and preserve dangling symlinks, existing BOM-prefixed output reports the correct key count, and unused merge resolutions are diagnosed deterministically in request order.
- Catalog aliases can no longer resolve to internal lock/temp sidecars or non-catalog files, and stable locks are opened without following redirects and accepted only as uniquely linked regular files. Reparsing a retargeted symlink now evicts its obsolete cache identity instead of leaving a duplicate
list_filesentry. - Natural percentage prose such as
100% Local Storage,You've logged 85% of..., and7.0-8.0% - Acceptable...is no longer rejected as a definite format mismatch. - Definite format arguments next to unspaced Han, Hiragana, Katakana, or Hangul text (for example
%lld日) remain blocking validation requirements, while other Unicode word continuations remain ambiguous; substitution plurals require exact%argplaceholders instead of accepting longer Unicode words or escaped percent sequences. - Zero or overflowing value, dynamic-width, and dynamic-precision positional indices now fail with
invalid_positional_argumentinstead of being interpreted as sequential arguments. - Foundation integer length modifiers now reject unsupported uppercase legacy,
i, andnconversions instead of accepting malformed pairs such as%hDor%llO. - XLIFF import now decodes and XML-normalizes
trans-unit@idandfile@target-language, preserving named and numeric character references in keys and locales. - XLIFF import now accepts both default-namespace and prefix-qualified XLIFF 1.2 documents from external tools while retaining legacy fully unqualified input compatibility. Imports require exactly one
<xliff>document root; scopefilelocales andtrans-unitdata to their enclosing frames; enforce requiredbody/source, parent order, and target cardinality; support recursive groups and schema-positioned bound extensions; and reject malformed structure, mixed file locales or namespace modes, unbound prefixes, malformed namespace references, and duplicate raw or expanded attributes before any catalog write. - XLIFF export now omits variation-only entries from both output and counts while preserving unlocalized simple keys. Import accepts Xcode's empty simple-unit IDs safely, rejects unsupported Apple
|==|variation paths, enforces per-filetrans-unit/bin-unitID uniqueness after XML attribute normalization, and fails closed on raw line-break/space or cross-file ID collisions before any catalog write. - XLIFF import now preserves decoded CDATA segments when concatenating mixed target text, CDATA, and entity content; CDATA outside the document root or left unclosed remains a no-write parse error.
v1.3.4
Changed
- rmcp (MCP SDK) 1.6 → 2.2. The server no longer emits MCP
logging/messagenotifications — theloggingcapability was never advertised, so those notifications were off-spec. Tool progress messages now go to stderr viatracingonly. - Dependency refresh: quick-xml 0.41, tokio 1.53, regex 1.13, clap 4.6.2, clap_complete 4.6.7. CI actions:
actions/checkoutv7,schneegans/dynamic-badges-action1.9.0.
Security
- quick-xml 0.41 closes RUSTSEC-2026-0194 and RUSTSEC-2026-0195 (quadratic attribute parsing, unbounded namespace allocation).
- crossbeam-epoch 0.9.20 closes RUSTSEC-2026-0204 (dev-dependency chain).
Fixed
- CI: nightly clippy lints
chunks_exact_to_as_chunks(UTF-16 strings parser) andcloned_ref_to_slice_refs(merger tests) no longer fail the pipeline.
v1.3.3
Changed
- rmcp 1.3 → 1.6 (manifest + lockfile). Required code changes:
#[prompt_router]in rmcp-macros 1.4+ generates a private associated function by default — now passesvis = "pub(crate)"soXcStringsMcpServer::new()(in a different module) can callSelf::prompt_router()once at startup.- The handler attributes now point at cached struct fields (
#[tool_handler(router = self.tool_router)],#[prompt_handler(router = self.prompt_router)]) so the routers are built once inXcStringsMcpServer::new()instead of being rebuilt on every JSON-RPC dispatch (rmcp 1.4+ macros default toSelf::tool_router()/Self::prompt_router()function calls, which would allocate a freshHashMap+ per-routeArc<closure>on eachtools/call,tools/list,prompts/get,prompts/list).
- libc 0.2.183 → 0.2.186 (manifest + lockfile).
- Lockfile-only refreshes (manifest constraints unchanged): tokio 1.50 → 1.52.1 (
spawn_blockingregression fix), indexmap 2.13 → 2.14 (hashbrown 0.16 → 0.17), clap 4.6.0 → 4.6.1, clap_complete 4.6.0 → 4.6.3, assert_cmd 2.2.0 → 2.2.1 (dev).
v1.3.2
Update dependencies: rmcp 1.3, quick-xml 0.39, insta 1.47, proptest 1.11
Migrate quick-xml API from 0.37 to 0.39 breaking changes:
- Replace removed BytesText::unescape() with decode()
- Handle new Event::GeneralRef variant for XML entity resolution using quick_xml::escape::resolve_xml_entity() and BytesRef::resolve_char_ref()
v1.3.1
Improved
- AI-facing documentation overhaul across all 27 MCP tools for better AI client comprehension:
- Server instructions restructured from flat text into workflow categories (SETUP → TRANSLATE → REVIEW → MANAGE → MIGRATE → GLOSSARY) with pagination rules
- 8 tool descriptions enriched with cross-references (e.g., get_stale → delete_keys, get_plurals → submit_translations with plural_forms) and severity levels for validate_translations
- Doc comments added to all fields of 11 model types (CompletedTranslation, TranslationUnit, PluralUnit, SubmitResult, etc.) — these generate JSON Schema descriptions visible to AI clients
- Pagination hints added to all batched tool parameters ("set to previous offset + batch_size to get the next page")
- Parameter descriptions enriched with examples, constraints, and usage guidance across 9 tool files
- Prompts improved: rejection handling guidance in translate_batch, glossary check in full_translate
v1.3.0
Added
- 11 CLI commands for direct terminal access to localization operations:
info- show file summary (source language, keys, locales)coverage- translation coverage per locale with percentage tablevalidate- check format specifiers, plural forms, empty translationssearch- find keys by pattern (case-insensitive)stale- list stale/removed keysadd-locale- add a new locale to all translatable keysremove-locale- remove a locale and all its translationsexport- export translations to XLIFF 1.2 formatimport- import translations from XLIFF files with validationmigrate- migrate legacy .strings/.stringsdict to .xcstringscompletions- generate shell completions (bash/zsh/fish/powershell/elvish)
- Auto-discovery: CLI commands automatically find .xcstrings files in the current directory tree - no path required
--jsonflag: machine-readable JSON output for CI/CD integration on all commands--dry-runflag: preview changes without writing on all mutation commands (add-locale, remove-locale, import, migrate)- Shell completions for bash, zsh, fish, powershell, elvish via
clap_complete
Changed
servicemodule now public for CLI reuse (removed_test_supportre-export hack)- Extracted
service::discoverymodule fromtools::filesfor file discovery logic reuse - Extracted
service::migratemodule fromtools::stringsfor legacy migration logic reuse - Binary now returns
ExitCodeinstead ofResultfor proper exit code handling
v1.2.0
Added
delete_keystool - delete localization keys and all their translations, completes theget_stale→delete_keyscleanup workflowrename_keytool - rename a localization key preserving all existing translations across all localesget_keytool - get all translations for a specific key across all locales in a single calldelete_translationstool - remove translations for specific keys in a locale, resetting them to untranslated statecleanup_staleprompt - guided workflow to find and remove stale/unused localization keys- Claude Code skill (
skills/xcstrings-mcp/SKILL.md) with workflows and best practices for all 26 tools - GitHub community profile: Code of Conduct, issue templates, PR template, Discussions enabled
Changed
- Write operations (
delete_keys,delete_translations) skip disk write when no changes are made - Repository topics expanded to 19 for better discoverability
- README enhanced with Features section, additional badges, and skill installation instructions
v1.1.0
Added
import_stringstool - migrate legacy.stringsand.stringsdictfiles to.xcstringsformat.stringsparser with full escape sequence support (\Unnnnsurrogate pairs,\",\\,\n,\t,\r).stringsdictXML plist parser with CLDR plural rule support (single and multi-variable)- UTF-16LE/BE encoding auto-detection via BOM with UTF-16LE heuristic fallback
- Recursive
.lprojdirectory scanning (directoryparam) - Unquoted key support for legacy old-style ASCII plist files
discover_filesnow detects legacy files - returns.strings/.stringsdictinlegacy_filesalongside.xcstringsread_bytesmethod onFileStoretrait for raw byte access- Merge mode: import into existing
.xcstringswithout overwriting dry_runmode for previewing migration results- Positional format specifier handling (
%1$lld→%arg) in stringsdict substitutions - CDATA content support in
.stringsdictXML plist parsing Base.lprojfiltering in directory discovery (not a real locale)- Symlink depth protection (max 20 levels) in
.lprojdirectory scanner - Warnings for skipped
.stringsdictentries with unsupported rule types (device/width variants)
v1.0.0
Added
create_xcstringstool - create a new empty .xcstrings file with a given source languageadd_keystool - add new localization keys with source text to an .xcstrings filediscover_filestool - recursively search a directory for .xcstrings filesupdate_commentstool - update developer comments on existing localization keysextract_stringsprompt - guided workflow to extract hardcoded strings from Swift code- Multi-locale
get_untranslated-localesparameter to find strings untranslated in any of multiple locales FileAlreadyExistserror variant for create_xcstrings safety- Service layer
creatormodule with pure functions for file creation, key addition, and comment updates
v0.5.0
Added
- MCP Logging - real-time structured log notifications to clients via MCP protocol
search_keystool - search keys by substring (case-insensitive), matches key names and source text- Xcode 26 compatibility - verified format version 1.1 roundtrip with test fixture
localization_auditprompt - complete audit: coverage, validation, stale keys, glossaryfix_validation_errorsprompt - guided workflow to fix issues by severityadd_languageprompt - add a new locale and translate all strings step-by-step
Changed
- Extracted shared
build_translation_unithelper to eliminate code duplication in extractor
Removed
- 5 unused error variants (
ValidationFailed,FormatSpecifierMismatch,MissingPluralForm,ShouldNotTranslate,Unexpected)