asc-revenuecat-catalog-sync について
App Store Connect と RevenueCat の商品カタログを照合し、承認済みの変更を適用するワークフロースキルです。読み取り専用監査から始め、商品 ID に基づいて対応付け、厳格な検証後にマッピングします。
主な機能
- 01両システムのカタログ差分を作成
- 02productId に基づく商品マッピング
- 03RevenueCat リソースの作成と関連付け
- 04ASC のサブスクリプションと IAP を検証
- 05書き込み前に明示的な承認を要求
- 06失敗を報告し監査結果を保存
活用シーン
- 01既存の ASC カタログから RevenueCat を構築
- 02不足するサブスクリプションや IAP を作成してマッピング
- 03リリース前にカタログの差異を確認
MCP 対応
RevenueCat MCP サーバーを使い、アプリ、商品、エンタイトルメント、Offering、Package を読み取り・管理して App Store Connect の商品に関連付けます。MCP は ASC 商品を作成せず、その作成には asc コマンドを使います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rorkai/ app-store-connect-cli-skills --skill asc-revenuecat-catalog-syncインストール後、Claude Code で/asc-revenuecat-catalog-syncを入力して読み込まれたか確認します。
同梱ファイルexamples.mdreferences.md
詳細
asc RevenueCat カタログ同期
このスキルを使用して、App Store Connect(ASC)とRevenueCatの整合性を保ちます。ASCに不足している項目を作成し、RevenueCatのリソースにマッピングすることもできます。
使用する場面
- 既存のASCカタログを基にRevenueCatを初期設定したい場合。
- ASCに不足しているサブスクリプションやIAPを作成し、それらをRevenueCatにマッピングしたい場合。
- リリース前に差異を監査する必要がある場合。
- 識別子に基づいて決定的に商品をマッピングしたい場合。
前提条件
ascの認証が設定されている(asc auth loginまたはASC_*環境変数)。- RevenueCat MCP サーバーが設定され、認証済みである。
- CursorとVS Codeでは、RevenueCat MCPのOAuth認証を利用できます。APIキー認証にも対応しています。
- 以下が分かっていること:
- ASCアプリID(
APP_ID) - RevenueCatの
project_id - 対象となるRevenueCatアプリの種類(
app_storeまたはmac_app_store)と、作成フロー用のバンドルID
- ASCアプリID(
- 変更を適用する際は、書き込み権限のあるRevenueCat API v2キーを使用します。
安全性のデフォルト設定
- 監査モード(読み取り専用)から開始します。
- 書き込みの前に、明示的な確認を必須とします。
- このワークフローではリソースを削除しません。
- 項目ごとの失敗があっても処理を続行し、最後にすべての失敗を報告します。
正式な識別子
- システム間の主要キー:ASCの
productId== RevenueCatのstore_identifier。 - 商品が公開された後は、
productIdを変更しないでください。 - 一意な識別子として表示名を使用しないでください。
対象範囲
- RevenueCat MCPが設定するのはRevenueCatのリソースです。App Store Connectの商品を直接作成することはありません。
- RevenueCatへのマッピングに先立ち、不足しているASCのサブスクリプショングループ、サブスクリプション、IAPは
ascコマンドを使って作成します。
モード
1)監査モード(デフォルト)
- ASCのソースカタログを読み取ります。
- RevenueCatの対象カタログを読み取ります。
- 次のアクションを含む差分を作成します。
- ASCにない
- RevenueCatにない
- マッピングの競合(識別子/種類/アプリの不一致)
- 計画を提示します。監査のみのリクエストでは結果を報告して終了します。適用リクエストでは、現在の差分全体を対象とする承認が必要です。更新後の差分に変更がなければ、以前の承認を再利用します。
2)適用モード(明示的な指定が必要)
承認されたアクションを次の順序で実行します。
- ASCのグループ/サブスクリプション/IAPが存在することを確認します。
- RevenueCatのアプリ/商品が存在することを確認します。
- エンタイトルメントと商品の関連付けが存在することを確認します。
- オファリング/パッケージとパッケージの関連付けが存在することを確認します。
- 検証し、最終的な照合サマリーを出力します。
手順
ステップA - 現在のASCカタログを読み取る
asc subscriptions groups list --app "APP_ID" --paginate --output json
asc iap list --app "APP_ID" --paginate --output json
# for each subscription group:
asc subscriptions list --group-id "GROUP_ID" --paginate --output json
ステップB - 現在のRevenueCatカタログを読み取る(MCP)
これらのMCPツールを使用します(該当する場合は project_id とページネーションを指定してください)。
mcp_RC_get_projectmcp_RC_list_appsmcp_RC_list_productsmcp_RC_list_entitlementsmcp_RC_list_offeringsmcp_RC_list_packages
ステップC - マッピング計画を作成する
ASCの商品タイプをRevenueCatの商品タイプにマッピングします。
- ASCサブスクリプション -> RevenueCat
subscription - ASC IAP
CONSUMABLE-> RevenueCatconsumable - ASC IAP
NON_CONSUMABLE-> RevenueCatnon_consumable - ASC IAP
NON_RENEWING_SUBSCRIPTION-> RevenueCatnon_renewing_subscription
推奨するエンタイトルメントのポリシー:
- サブスクリプション:サブスクリプショングループごとに1つのエンタイトルメント(またはユーザーが指定した明示的なマッピング)
- 非消耗型IAP:商品ごとに1つのエンタイトルメント
- 消耗型IAP:ユーザーからの要望がない限り、デフォルトではエンタイトルメントなし
ステップ D - 不足している ASC 項目を確保する(リクエストされた場合)
書き込みを行う前に、すべての親項目とバージョンを解決します。グループは参照名の完全一致で、製品は productId で照合します。表示名を識別子として扱わないでください。リソースがすでに存在する場合は正規 ID を再利用し、ページネーションをすべて完了した読み取りで不足していることが確認できた場合にのみ作成コマンドを実行します。RevenueCat の製品マッピングは、対応する ASC サブスクリプションがレビュー可能であることの証明にはなりません。
# Resolve GROUP_ID by exact referenceName.
asc subscriptions groups list --app "APP_ID" --paginate --output json
# If and only if the fully paginated list has zero exact matches:
asc subscriptions groups create --app "APP_ID" --reference-name "Premium" --output json
# For one match, reuse its ID. For more than one, stop and require an explicit GROUP_ID.
# Resolve SUB_ID by exact productId within GROUP_ID. Run setup only for a missing
# parent or an explicitly approved reconciliation of that same product ID.
asc subscriptions list --group-id "GROUP_ID" --paginate --output json
# If and only if the fully paginated list has zero exact matches, run setup:
asc subscriptions setup \
--app "APP_ID" \
--group-id "GROUP_ID" \
--reference-name "Monthly" \
--product-id "com.example.premium.monthly" \
--subscription-period ONE_MONTH \
--review-screenshot "./review.png" \
--price "3.99" \
--price-territory "USA" \
--territories "USA" \
--no-verify \
--output json
# For one match, reuse its ID. For more than one, stop and require an explicit SUB_ID.
# Re-run setup for an existing SUB_ID only for an explicitly approved reconciliation.
# Resolve the unique mutable group version for this review lifecycle.
asc subscriptions groups versions list --group-id "GROUP_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# If and only if the list has zero matches:
asc subscriptions groups versions create --group-id "GROUP_ID" --output json
# For one match, reuse .data[0].id. For more than one, stop and require an explicit GROUP_VERSION_ID.
# Resolve the en-US localization on GROUP_VERSION_ID. Create it only when
# missing; update the resolved localization ID when its values differ.
asc subscriptions groups versions localizations list --version-id "GROUP_VERSION_ID" --paginate --output json
asc subscriptions groups versions localizations create --version-id "GROUP_VERSION_ID" --locale "en-US" --name "Premium" --output json
asc subscriptions groups versions localizations update --id "GROUP_LOC_ID" --name "Premium"
# Resolve the unique mutable subscription version for this review lifecycle.
asc subscriptions versions list --subscription-id "SUB_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# If and only if the list has zero matches:
asc subscriptions versions create --subscription-id "SUB_ID" --output json
# For one match, reuse .data[0].id. For more than one, stop and require an explicit SUBSCRIPTION_VERSION_ID.
asc subscriptions versions localizations list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output json
asc subscriptions versions localizations create --version-id "SUBSCRIPTION_VERSION_ID" --locale "en-US" --name "Premium Monthly" --description "Unlock all premium features." --output json
asc subscriptions versions localizations update --id "SUBSCRIPTION_LOC_ID" --name "Premium Monthly" --description "Unlock all premium features."
# Read back the exact versions selected above, then run the final strict validator.
asc subscriptions groups versions localizations list --version-id "GROUP_VERSION_ID" --paginate --output table
asc subscriptions versions localizations list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output table
asc validate subscriptions --app "APP_ID" --strict --output table
# Resolve IAP_ID by exact productId.
asc iap list --app "APP_ID" --paginate --output json
# If and only if the fully paginated list has zero exact matches:
asc iap create \
--app "APP_ID" \
--type NON_CONSUMABLE \
--ref-name "Lifetime" \
--product-id "com.example.lifetime" \
--output json
# For one match, reuse its ID. For more than one, stop and require an explicit IAP_ID.
# Resolve the unique mutable IAP version for this review lifecycle.
asc iap versions list --iap-id "IAP_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# If and only if the list has zero matches:
asc iap versions create --iap-id "IAP_ID" --output json
# For one match, reuse .data[0].id. For more than one, stop and require an explicit IAP_VERSION_ID.
asc iap versions localizations list --version-id "IAP_VERSION_ID" --paginate --output json
asc iap versions localizations create --version-id "IAP_VERSION_ID" --locale "en-US" --name "Lifetime" --description "Unlock all premium features." --output json
asc iap versions localizations update --localization-id "IAP_LOC_ID" --name "Lifetime" --description "Unlock all premium features."
asc iap versions localizations list --version-id "IAP_VERSION_ID" --paginate --output table
上記の隣接する各作成/更新ペアは条件付きであり、むやみに連続して実行するものではありません。リストに一致する項目がない場合は作成し、解決された一致項目の値が異なる場合は更新し、すでに一致している場合は何もしません。作成レスポンスからは .data.id を、直前のリストからは .data[].id を取得し、後続コマンドで使う正規 ID として保持します。各バージョンリストで PREPARE_FOR_SUBMISSION に一致する項目が 0 件なら作成し、1 件ならその ID を再利用し、2 件以上なら停止して、ユーザーに明示的なバージョン ID の選択を求めます。曖昧さを解消するためにバージョンを作成しないでください。実環境でのテストでは、親項目を削除しても IAP またはサブスクリプションのバージョンが確実に連動して削除されるわけではありませんでした。
subscriptions setup は、親項目、App Review のスクリーンショットの配信、完全な App Store 価格マトリックス、販売可能状況を完了します。バージョン単位のコマンドは、RevenueCat では対応できないグループおよびサブスクリプションのローカライズを完了します。販売可能状況はリクエストされた地域に限定してください。価格設定には、引き続き Apple の完全な均等化地域マトリックスが必要です。この分割ワークフローでは --no-verify を意図的に使用します。最終検証はバージョンのメタデータが存在してから行う必要があるためです。明示的な読み戻しとバリデーターが最終ゲートとなります。
API で作成した既存のサブスクリプションが、選択された基本価格に変更がないにもかかわらず MISSING_METADATA のままの場合は、同じセットアップ入力を --repair を付けて再実行してください。修復では完全な均等化価格マトリックスをアトミックに再構築して再保存します。単一価格の POST を重複して実行するものではありません。
解決された ASC サブスクリプションごとに、RevenueCat 製品を作成またはアタッチする前に、次の最終ゲートを必須とします。サブスクリプションと選択したバージョンを ASC への書き込みなしで再利用した場合も、ASC の最終調整後に実行してください。
mkdir -p "./audit"
asc validate subscriptions --app "APP_ID" --strict --output json --pretty \
> "./audit/subscriptions-validation.json"
解決された ASC IAP ごとに、RevenueCat 製品を作成またはアタッチする前に、IAP ゲートを必須とします。IAP と選択したバージョンを ASC への書き込みなしで再利用した場合も、ASC の最終調整後に実行してください。
mkdir -p "./audit"
asc validate iap --app "APP_ID" --strict --output json --pretty \
> "./audit/iap-validation.json"
どちらのコマンドも厳密なマッピングゲートであり、書き込み後のスモークテストではありません。検証結果に警告、エラー、MISSING_METADATA、COMPLETE ではないレビュー用スクリーンショット、または不完全もしくは未検証の価格カバレッジがある間は、解決済みまたは再利用したサブスクリプションをマッピングしないでください。バリデーターが警告またはエラーを報告している間は、解決済みまたは再利用した IAP をマッピングしないでください。書き込みがゼロの監査または適用実行でも、該当するゲートを実行し、RevenueCat 製品の作成またはアタッチ前に終了ステータスが 0 であることを必須とします。直接リダイレクトすることで、各バリデーターの終了ステータスが保持されます。最終的な監査証拠として ./audit/subscriptions-validation.json と ./audit/iap-validation.json を保持してください。
ステップ E - RevenueCat アプリと製品を確保する
MCP を使用します。
- アプリがない場合は作成します:
mcp_RC_create_app - 製品を作成します:
mcp_RC_create_productstore_identifier= ASC のproductIdapp_id= RevenueCat アプリ IDtypeは上記のマッピングに従います
ステップ F - エンタイトルメントとアタッチメントを確保する
MCP を使用します。
- エンタイトルメントを一覧表示/作成します:
mcp_RC_list_entitlements、mcp_RC_create_entitlement - 製品をアタッチします:
mcp_RC_attach_products_to_entitlement - アタッチメントを確認します:
mcp_RC_get_products_from_entitlement
ステップ G — オファリングとパッケージを確認する(任意)
MCP を使用します。
- オファリングを一覧表示/作成/更新します。
mcp_RC_list_offeringsmcp_RC_create_offeringmcp_RC_update_offering(依頼された場合に限りis_current=trueを設定)
- パッケージを一覧表示/作成します。
mcp_RC_list_packagesmcp_RC_create_package
- 商品をパッケージに追加します。
eligibility_criteria: "all"を指定してmcp_RC_attach_products_to_package
推奨されるパッケージキー:
ONE_WEEK->$rc_weeklyONE_MONTH->$rc_monthlyTWO_MONTHS->$rc_two_monthTHREE_MONTHS->$rc_three_monthSIX_MONTHS->$rc_six_monthONE_YEAR->$rc_annual- 買い切り IAP ->
$rc_lifetime - カスタム ->
$rc_custom_<name>
期待される出力形式
次の内容を含む最終サマリーを返します。
- ASC の作成数(グループ/サブスクリプション/IAP)
- RevenueCat の作成数(アプリ/商品/エンタイトルメント/オファリング/パッケージ)
- 紐付け数(エンタイトルメントと商品の紐付け、パッケージと商品の紐付け)
- スキップした既存項目
- 対応可能なエラー内容を含む失敗項目
例:
ASC: created groups=1 subscriptions=2 iap=1, skipped=14, failed=0
RC: created apps=0 products=3 entitlements=2 offerings=1 packages=2, skipped=27, failed=1
Attachments: entitlement_products=3 package_products=2
Failures:
- com.example.premium.annual: duplicate store_identifier exists on another RC app
エージェントの動作
- apply モードの場合も、必ず最初に監査を実行します。
- 作成/更新操作については、現在の差分全体を対象とする承認を再利用します。承認がない場合、または追加の操作や大幅に変更された操作が承認の対象外である場合に限り、再度確認します。
- まず
store_identifierで照合します。 - 全ページを取得します(ASC では
--paginate、RevenueCat ツールではstarting_afterを使用)。 - 項目ごとの失敗が発生しても処理を続行し、すべての失敗をまとめて報告します。
- このスキルでは、ASC または RevenueCat のリソースを自動削除してはいけません。
- 解決したすべてのサブスクリプションについて、書き込みを行わず既存項目を再利用する場合も含めて、
asc validate subscriptions --app "APP_ID" --strict --output json --prettyを実行し、その JSON を保存します。ゲートが終了コード 0 で終了し、メタデータの不足や価格設定の未完了がない場合を除き、RevenueCat の作成または紐付けを行ってはいけません。 - 解決したすべての IAP について、書き込みを行わず既存項目を再利用する場合も含めて、
asc validate iap --app "APP_ID" --strict --output json --prettyを実行し、その JSON を保存します。ゲートが終了コード 0 で終了しない場合、RevenueCat の作成または紐付けを行ってはいけません。
よくある問題
- RevenueCat の
project_idまたはアプリ ID が誤っている。 - 間違ったプラットフォームアプリに RC 商品を作成している。
- 消耗型商品を誤ってエンタイトルメントに割り当てている。
- ASC で作成した後の再読み込み手順を省略している。
- ASC でローカライズ、審査スクリーンショットの提出、完全な価格マトリックス、提供状況の設定が完了する前に RevenueCat 商品を紐付けている。
- 商品作成後のオファリング/パッケージの確認が漏れている。
追加リソース
- ワークフローの例:examples.md
- ソース参照:references.md