🚀 xcstrings-mcp
このプロジェクトは、Xcodeの.xcstringsファイルを扱うための__Model Context Protocol (MCP)サーバ__をRustで実装したものです。翻訳カタログをMCPツールに公開するとともに、チームがブラウザから文字列の閲覧、検索、編集ができる__軽量なWebエディタ__を提供します。
🚀 クイックスタート
前提条件
- Rust 1.75以降:Homebrewを使用してインストールすることをおすすめします(macOSで推奨):
brew install rust
または、公式インストーラを使用してインストールします:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
インストール後、ターミナルを再起動するか、source ~/.cargo/envを実行してPATHを更新してください。
サーバの実行
cargo run -- [path-to/Localizable.xcstrings] [port]
cargo install --path .
path-to/Localizable.xcstrings:オプション。省略した場合、サーバはワークスペース内の.xcstringsファイルをスキャンします。Web UIは選択ボックスを表示したまま利用可能です(見つからない場合はプレースホルダーを表示)が、MCPツールの呼び出しでは引き続きpath引数を指定する必要があります。
port:オプション。デフォルトは8787です。
環境変数を使用してサーバを構成することもできます:
| 変数名 |
説明 |
デフォルト値 |
STRINGS_PATH |
.xcstringsファイルのパス |
未設定 (動的モード) |
WEB_HOST |
Web UIのホスト/インターフェース |
127.0.0.1 |
WEB_PORT |
Web UIのポート |
8787 |
Webインターフェースはhttp://<host>:<port>/で利用できます。
MCPの使用方法
バイナリを標準入出力トランスポート(デフォルト)で実行し、MCP対応のクライアントに接続します。以下のツールが公開されています(それぞれ、対象の.xcstringsファイルを指すpath引数を期待します):
list_translations(path, query?, limit?, include_values?)
get_translation(path, key, language)
upsert_translation(path, key, language, value?, state?, variations?)
delete_translation(path, key, language)
delete_key(path, key)
set_comment(path, key, comment?)
set_extraction_state(path, key, extractionState?)
list_languages(path)
各ツールは、JSONペイロードをテキストコンテンツにエンコードして返し、消費を容易にします。
AIツールとの統合
最新のMCP対応AIクライアントでは、JSONマニフェストを通じて外部サーバを登録できます。例として、以下のスニペットはxcstrings-mcpをClaude Codeに追加します:
claude mcp add-json xcstrings '{"command":"/Users/you/.cargo/bin/xcstrings-mcp","transport":"stdio","env":{"WEB_HOST": "127.0.0.1","WEB_PORT": "8787"}}'
また、手動で~/.claude.jsonに追加することもできます:
{
"mcpServers": {
"xcstrings": {
"command": "/Users/you/.cargo/bin/xcstrings-mcp",
"transport": "stdio",
"env": {
"WEB_HOST": "127.0.0.1",
"WEB_PORT": "8787"
}
}
}
}
保存後にクライアントを再起動すると、新しいMCPサーバ定義が読み込まれます。ツール呼び出しでpathパラメータはオプションです。指定されない場合、サーバはプロジェクト内のすべての.xcstringsファイルを自動的に検出し、Webエディタで選択できるようにリストします。
✨ 主な機能
コア翻訳機能
list_translations(path, query?, limit?, include_values?) - オプションでフィルタリングした翻訳エントリをリストします。
path:.xcstringsファイルのパス
query:結果をフィルタリングするためのオプションの大文字小文字を区別しない検索クエリ
limit:返すアイテムの最大数(デフォルトは100、制限を設けない場合は0に設定)
include_values:完全な翻訳ペイロードを含める(デフォルトはfalseで、コンパクトな要約を返します)
- 戻り値:翻訳の要約または完全なレコードのJSON配列
get_translation(path, key, language) - キーと言語で単一の翻訳を取得します。
path:.xcstringsファイルのパス
key:翻訳キー識別子
language:言語コード(例:"en", "fr", "es")
- 戻り値:バリエーションと置換を含む完全な翻訳値
upsert_translation(path, key, language, value?, state?, variations?, substitutions?) - 翻訳を作成または更新します。
path:.xcstringsファイルのパス
key:翻訳キー識別子
language:言語コード
value:翻訳テキスト(オプション)
state:翻訳状態(オプション)
variations:バリエーションセレクターからそのケース(例:複数形)へのマップ
substitutions:メタデータを持つ置換識別子のマップ
- 戻り値:更新された翻訳値
delete_translation(path, key, language) - 特定の言語の翻訳を削除します。
path:.xcstringsファイルのパス
key:翻訳キー識別子
language:削除する言語コード
- 戻り値:成功確認
キー管理機能
delete_key(path, key) - すべての言語で特定の翻訳キーを完全に削除します。
path:.xcstringsファイルのパス
key:完全に削除する翻訳キー識別子
- 戻り値:成功確認
set_comment(path, key, comment?) - 翻訳キーの開発者コメントを設定またはクリアします。
path:.xcstringsファイルのパス
key:翻訳キー識別子
comment:開発者コメントテキスト(オプション、省略するとクリアされます)
- 戻り値:成功確認
set_extraction_state(path, key, extractionState?) - 文字列キーの抽出状態を設定またはクリアします。
path:.xcstringsファイルのパス
key:翻訳キー識別子
extractionState:抽出状態値(オプション、省略するとクリアされます)
- 戻り値:成功確認
言語管理機能
list_languages(path) - xcstringsファイルに含まれるすべての言語をリストします。
path:.xcstringsファイルのパス
- 戻り値:カタログで見つかった言語コードのJSON配列
追加機能
- 非同期安全なストア:
Localizable.xcstringsのJSONを変更のたびにロードし、永続化します。
- 組み込みのAxum Web UI:翻訳の閲覧、クエリによるフィルタリング、値の編集、複数形/デバイスバリエーションの管理、コメントの管理ができます。
- 自動検出:デフォルトパスが指定されていない場合、
.xcstringsファイルを自動的に検出し、Web UIで実行時にカタログを切り替えることができます。
- デバイス固有のバリエーション:iPhone、iPad、Mac、Apple Watchなどのデバイス固有のバリエーションをサポートし、複数形とデバイスバリエーションの排他ロジックがあります。
- インライン編集:抽出状態、翻訳状態、置換プレースホルダー(
argNum、formatSpecifier、ネストされた複数形ケースを含む)の編集ができます。
- JSON優先のレスポンス:すべてのツールからJSONベースのレスポンスを返し、自動化とデバッグを容易にします。
- スキーマベースの検証:ベンダー提供のを使用して、生成されたカタログがAppleの形式と一致するようにします。
🔧 技術詳細
プロジェクト構成
src/store.rs – .xcstringsファイルの非同期ストレージレイヤー。
src/mcp_server.rs – 翻訳機能を公開するMCPツールの定義。
src/web/mod.rs – AxumのHTTPルートとHTML/JSのシングルページビュー。
src/main.rs – WebサービスとMCPサービスの両方を起動するエントリポイント。
📄 ライセンス
このプロジェクトはMITライセンスの下で配布されています。