mcpField
B
billing-doctor

billing-doctor

ローカル
github.com/lazytitan30開発ツール06 週間前に更新

billing-doctor について

Billing Doctorは、独自のGoogle Play Billingバックエンドを運用する開発者向けのローカルCLIです。文書化されたルールで購入履歴を調べ、根拠を示します。デフォルトではデータを送信しません。

主な機能

  1. 0197ルールによるタイムライン診断
  2. 02タイムラインの検証とマスキング
  3. 03サブスクリプション状態とRTDNの説明
  4. 04ルールの絞り込みと機械可読出力
  5. 05Google状態の任意取得

活用シーン

  1. 01ログやサポート記録からサブスクリプション障害を調査
  2. 02CIで重大なタイムライン検出結果を確認
  3. 03RTDNメッセージをデコードして次の手順を把握

MCP 対応

標準入出力でMCPサーバーとして動作し、タイムライン診断、状態説明、RTDNデコード、テキストのマスキング、ルール検索など6つのツールを提供します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"lazytitan30-billing-doctor": {
"command": "npx",
"args": [
"-y",
"billing-doctor"
]
}
}
}
起動コマンドnpx -y billing-doctor

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmbilling-doctor0.1.1

ツール

6

掲載時のツール一覧 · 3 週間前に更新

パラメーター型必須説明
rulesarrayいいえこれらのルール ID のみを実行します
timelineanyはいタイムライン(オブジェクトまたは JSON テキスト)

詳細

Billing Doctor

Billing Doctor は Google Play の購入で何が起きたかを読み取り、どこで問題が発生したかを教えてくれます。ローカルマシンで動作し、外部への呼び出しや Google 側での変更は一切行わず、根拠を示します。Google とは提携していません。

Google Play Billing のバックエンドを Node、Python、PHP、Go、Java で自分で運用し、フロントエンドに Capacitor、Flutter、React Native、または Android ネイティブを使用していて、サブスクリプションプラットフォームを選択しなかった開発者向けです。サブスクリプションに問題が起きた午後 11 時に実行するツールです。

20 秒で試す

以下のフィクスチャはリポジトリに含まれているため、チェックアウトした状態から始められます。

git clone https://github.com/lazytitan30/billing-doctor && cd billing-doctor
npx billing-doctor diagnose fixtures/rules/G2-void-then-active.json

(同じフィクスチャは npm パッケージにも含まれています。npm install -g billing-doctor の実行後、$(npm root -g)/billing-doctor/fixtures/ にあります。)

billing-doctor 0.1.1: fixtures/rules/G2-void-then-active.json, 11 events, 1 finding: 1 high

HIGH
  G2  Voided purchase, then a fetch reading ACTIVE, and no revoke  [certain]
      evidence  #8 rtdn voidedPurchase tok_a1 [m-2] answered 200 (2026-09-04T10:00:00Z)
                #9 api subscriptionsv2.get tok_a1 → 200 SUBSCRIPTION_STATE_ACTIVE ack ACKNOWLEDGED (2026-09-04T10:00:01Z)
      mechanism tok_a1 was voided at #8 (the money went back); the fetch at #9 still answered ACTIVE and the ledger never revoked, so the refunded user keeps the tier.
      Google    "(1) REFUND_TYPE_FULL_REFUND - The purchase has been fully voided."
                RTDN reference: VoidedPurchaseNotification, read 2026-09-09: https://developer.android.com/google/play/billing/rtdn-reference
      observed  Seen in a live app, 2026-08: after the voided-purchase notification, purchases.subscriptionsv2.get still answered SUBSCRIPTION_STATE_ACTIVE ...
      next      Revoke tok_a1 now. In the handler, act on voidedPurchaseNotification directly: mark refunded and revoke, regardless of what subscriptionsv2.get answers afterwards.
      fix       runbook G2 (billing-doctor rule G2)

1 finding: 1 high
exit 1: a high finding is present

各指摘には、根拠となるイベント、仕組み、日付付きリンクとともに引用された Google のルール、確信度(certain、likely、possible)、次に確認すべき項目が示されます。終了コード 1 は重大な指摘があることを意味するため、このコマンドを CI のゲートとして使用できます。

できること

タイムラインを渡します。1件の購入について何が起きたかをまとめたJSONファイルで、ログ、データベース、Cloud Console、サポートチケットから組み立てます。Googleが送信した通知、APIの応答、バックエンドが書き込んだ内容、ユーザーの発言が含まれます。トークンは仮名で、ファイルに実データは入りません。

11のグループに分かれた97のルールに照らして、タイムラインをチェックします。どのルールも、Google公式ドキュメントの一文をそのまま引用し、URLと参照日を添えています。

グループ検出する問題
A. 設定と権限通知がまったく届かない、401/403、別のプロジェクトにあるトピック、否定応答、不認証のエンドポイント、2026-08-31のゲート適用後もBilling Library 8未満のリリースを使用している、一回限りの通知が有効になっていない
B. 購入と確認応答Googleが返金した未確認の購入、PENDING中の確認応答や付与、消費可能な購入が消費されずに確認応答されている、検証前の付与、二重付与、クライアントに通知されなかった確認応答の失敗、プリペイド期間、複数数量の購入を1件として付与、未確認のサブスクリプションによってプラン変更がブロックされている、ファイル内にまだ返金記録がないまま確認応答されていない購入
C. 通知同じメッセージの二重適用、順序が前後した通知、再取得せずに書き込むこと、IDのないメッセージによる取り消し、未処理のタイプ、チャージバック審査を返金として処理すること、テスト通知の適用、確認応答も適用もされないメッセージ
D. 状態の解釈誤った情報源からの有効期限、CANCELEDと猶予期間をアクセス不可として扱うこと、保留と一時停止をアクセス可能として扱うこと、EXPIREDでも付与し続けること、ラインアイテムの無視、非推奨のv1リソース、テスト購入の計上、プリペイドを自動更新として扱うこと、60日間の期間を過ぎたトークンの使用
E. ライフサイクルイベント再付与を伴わないRECOVERED、RESTARTEDを新しいトークンとして扱うこと、古い有効期限のままのDEFERRED、固定値の猶予期間と保留期間、予約済みのキャンセルと一時停止を即時として扱うこと、非推奨のタイプ8、実際には受け入れられなかった値上げによる解約
F. アップグレードとリンク済みトークン古いトークンで付与し続けること、DEFERREDによる置き換えを早期に付与すること、再登録が誤ったトークンに紐付けられること、日割り計算後に有効期限を再取得しないこと、アプリ外での再登録がリンクされないこと、アップグレード時に難読化されたアカウントIDが失われること、時間あたりの料金がより安いプランに対して日割り請求モードを使用すること
G. 返金と無効化された購入REVOKEDでも付与し続けること、状態の読み取り結果と一致しない無効化、部分返金を全額返金として処理すること、無効化された購入の全件照会がないこと、取り消しを伴わない返金、取り消すべきときのキャンセル、最新ではない注文の返金
H. アカウントの紐付けと復元対応付けできない通知、生のアカウントID、共有トークンに対するfindOne、再開時のqueryPurchasesAsyncの呼び出しがないこと、一時停止中のサブスクリプションを照会しないこと、別のGoogleアカウント
I. テストとConsole数分間隔のテスト更新、本番環境のテスト行、承認済みだが未公開、テスター12人のルール、検証済みなのに何も書き込まれないこと、3分後に返金されるテスター購入
J. 台帳の整合性冪等性キーのない付与、有効期限後も保持されるトークン、タイムライン内の実データ、現地時間での有効期限、注文IDをキーにした行
K. デバイスとPlay Billing Library空のカタログ、未接続中の呼び出し、調査されない所有済み購入、再試行されない回復可能な失敗、再試行されるべきでない回復不能な失敗、DEVELOPER_ERROR、古い商品詳細、コールバックの重複、重複するクエリ、商品IDとしてのベースプランIDの使用、サーバーに届かなかった購入、成功として報告される失敗、エラーとして扱われるキャンセル、購入時に利用不可として拒否される商品、Billing Library 8以降で消費済み購入の復元をデバイスに依存すること

billing-doctor rulesでルール一覧を表示できます。billing-doctor rule B1を実行すると、ルールを全文表示できます。

インストール

Node 20 以降が必要です。

npm install -g billing-doctor

インストールせずに実行するには、npx billing-doctor <command> を使います。

コマンド

コマンド内容
billing-doctor initいくつかの質問への回答をもとに、ポリシーブロックを入力した空の timeline.json を書き込みます
billing-doctor validate timeline.jsonファイルがスキーマに適合しているか確認します。トークン、ユーザー ID、メールアドレスが実在するものに見える場合は警告します
billing-doctor diagnose timeline.jsonすべてのルールを実行します。マシン向けの出力には --json、一部のルールのみ実行するには --rules B1,C3、ランブックを指定するには --kit <path> を使います
billing-doctor state sub.jsonpurchases.subscriptionsv2 リソースの内容を平易な言葉で説明します。--policy timeline.json を指定すると、ポリシーが Google の見解と異なる箇所を示します
billing-doctor rtdn message.jsonPub/Sub のプッシュ本文をデコードし、整数値に対応するタイプ名、トークン、次のステップを表示します
billing-doctor redact < logs.txt購入トークンを一貫した tok_ 形式の仮名に置き換え、メールアドレスを削除し、注文 ID をマスクして、秘密鍵とベアラートークンを取り除きます
billing-doctor rules と billing-doctor rule <id>ルール一覧、およびキットがある場合は Google の引用とランブックの項目を含む個別のルール
billing-doctor mcp同じ機能を 6 つの MCP ツールとして標準入出力経由で提供します

終了コード:0 は報告事項なし、1 は重大な検出事項あり(または入力をデコードできない)、2 は使用方法またはファイルのエラーです。

タイムライン

docs/timeline-format.md が仕様です。イベント種別は 6 つあります。app(デバイスから報告された内容)、api(Play Developer API の呼び出しとその応答)、ledger(バックエンドに書き込まれた内容)、rtdn(受信した通知)、support(ユーザーの発言)、console(リリースと設定変更)です。policy ブロックにはバックエンドが従うべき動作を記述します。これにより、ルールはポリシーとバグを見分けられます。

{
  "schema": "billing-doctor-timeline/1",
  "app": { "packageName": "com.example.app", "billingLibrary": "8.0.0", "backend": "node" },
  "policy": { "grantOn": ["SUBSCRIPTION_STATE_ACTIVE", "SUBSCRIPTION_STATE_IN_GRACE_PERIOD", "SUBSCRIPTION_STATE_CANCELED"], "ackWithinHours": 72 },
  "events": [
    { "t": "2026-09-01T10:00:00Z", "kind": "app", "type": "purchase_result", "token": "tok_a1", "productId": "basic_monthly", "purchaseState": "PURCHASED" },
    { "t": "2026-09-01T10:00:02Z", "kind": "api", "call": "subscriptionsv2.get", "token": "tok_a1", "status": 200, "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE", "acknowledgementState": "ACKNOWLEDGEMENT_STATE_PENDING", "expiryTime": "2026-10-01T10:00:00Z" },
    { "t": "2026-09-01T10:00:03Z", "kind": "ledger", "op": "grant", "token": "tok_a1", "userId": "u_1", "idempotencyKey": "tok_a1:grant" }
  ]
}

fixtures/ フォルダーには、各ルールに対応する最小限のタイムライン、現実的な 3 週間分のデータ、問題なしと判定されるべき正しいライフサイクル 5 件が含まれています。これらはテストスイートであり、フォーマットを学ぶのに最適です:fixtures/README.md。

コーディングエージェントと使用する

同じエンジンが標準入出力経由の MCP サーバーとして動作するため、バグを修正する際に Claude Code、Codex、Gemini CLI、Cursor から呼び出せます。ツール:diagnose_timeline、explain_subscription_state、decode_rtdn、redact_text、list_rules、get_rule。

コマンドに npx、引数に ["-y", "billing-doctor", "mcp"] を設定してください。Claude Code では、このリポジトリはプラグインとしても使えます(チェックアウトしたリポジトリから claude --plugin-dir . を実行すると、スキル /billing-doctor:diagnose を利用できます)。Gemini CLI では、gemini extensions install https://github.com/lazytitan30/billing-doctor を実行してください。

Incident Kit

無料のツールだけでも完結しています。有料のIncident Kitは、修正を早めるためのファイル一式です。各ルールのランブック項目(ユーザーが報告する症状、仕組み、修正方法、追加すべき回帰テスト)、CI で独自のハンドラーに対して再生できる現実的なインシデントタイムライン一式、検証エンドポイント、RTDN ハンドラー、照合ジョブの TypeScript リファレンス実装、Play Console、Cloud のセットアップ、ライセンスのテスト、Billing Library 8 および 9 への移行に関するチェックリストが含まれています。このフォルダーをツールの隣に ./billing-doctor-kit として配置するか(または BILLING_DOCTOR_KIT を設定すると)、billing-doctor rule G2 でランブックが表示されます。ライセンスサーバーも外部への通信もありません。キットはファイル一式です。

billingdoctor.dev — 各ルールのランブックページ、40 件のインシデントタイムライン、リファレンスバックエンド、チェックリストをご利用いただけます。

具体的な内容は次のとおりです。

ランブック各ルールにつき 1 ページ。ユーザーが報告する症状、仕組み、参照日を添えて引用した Google のルール、修正方法、追加すべき回帰テストを掲載
インシデント実際の障害から作成した 40 件のタイムラインと、それぞれから得られる調査結果に加え、問題が起きない正しいライフサイクルを 5 件掲載。CI で独自のハンドラーに対して再生できます
リファレンスバックエンドTypeScript 製。フェイルクローズドな台帳を備えた検証エンドポイント、メッセージ ID による冪等性を備えた RTDN ハンドラー、確認ウォッチドッグ、無効化された購入の一括処理、照合ジョブ、HMAC によるアカウント紐付け、保持データの削除処理、Postgres スキーマが含まれています。45 件すべてのタイムラインに合格します
チェックリストPlay Console と Cloud のセットアップ、ライセンスのテスト、管理対象の公開、Data Safety、Billing Library 8 および 9 への移行

Google のルールが変更された場合や、新しいルールが追加された場合に、新しいダウンロードとして提供する 12 か月間のアップデートが含まれます。

唯一の任意のネットワーク機能

diagnose --fetch は、独自のサービスアカウントキーを使ってタイムライン内の各トークンについて purchases.subscriptionsv2.get を読み取り、Google の回答を api イベントとして追加します。これにより、ログから作成したタイムラインに、各購入に対する Google の最新の見解を反映できます。デフォルトではオフです。データの送信先は Google のみです。

billing-doctor diagnose timeline.json --fetch --service-account ./key.json --token-map ./tokens.json --out augmented.json

タイムラインでは、仮名が維持されます。tokens.json は tok_a1 を実際の購入トークンに対応付けますが、これはお使いのマシンから外部に送信されません。追加されたイベントには仮名が使われ、書き出されるファイルに実際のトークンが含まれることはありません。このキーには、Play Console の「財務データの表示」権限が必要です。対象はサブスクリプションのみです。買い切り商品は取得されません。

プライバシー

デフォルトではネットワーク呼び出しを行いません。テレメトリーは一切ありません。ログがお使いのマシンから外部に送信されることはありません。上記の唯一の任意のネットワーク機能では、独自のキーを使い、Google とのみ通信します。

これは何ではないか

SDK、ホステッドサービス、サブスクリプションプラットフォーム、ダッシュボードではなく、法律上または財務上の助言でもありません。確認、消費、返金、取り消し、キャンセル、延期を行うことはありません。Apple の診断には対応していません。

由来

ルールは Google 独自のドキュメントに基づいており、機械で実行できるチェックにしたものです。97 件すべてに、Google が公開した文、そのページ、セクション、閲覧日が記載されています。97 件はすべて 1 つのファイル(src/google/docs.ts)にまとめられているため、ドキュメントが変更された場合は、失敗するテストと並んで 1 ファイルの差分として確認できます。参照元は、Android デベロッパーサイト、Play Developer API リファレンス、Play Console ヘルプセンター、Pub/Sub ドキュメントです。

8 件のルールには、稼働中のアプリで確認したフィールド観察も記載されています。日付と「観察」の印が付いており、常に Google の文の横に記載され、その代わりになることはありません。ドキュメントがあるべき動作を示す一方、サポート窓口には実際に起きていることが届くからです。レスポンスコードを一切表示しないラッパー、商品 ID としてベースプラン ID を返すプラグイン、何も返さずに解決し、販売が成立したように見えるウェブのフォールバックなどがあります。

各ルールには、ルールが発火することを証明するフィクスチャがあり、さらに一切の指摘が出てはならない正常なライフサイクルが 5 つあります。誤検知はリリースを阻止する要因です。お使いの環境で発生したインシデントをルールが見逃した場合は、情報を伏せたタイムラインを添えて課題を登録してください(good first incident)。これによってカタログが拡充されます。

貢献

npm test ですべてをビルドして実行します。テストランナーには --test-concurrency を使うため、Node 20.9 以降が必要です。一方、ツール本体は 20.0 で動作します(そこで確認済みです)。単独で実行できるファイルは 1 つです:node --test tests/rules-B.test.js。新しいルールには、src/engine/rules 内のファイル、src/google/docs.ts 内の Google の根拠(Google の根拠を記載するのはこのファイルのみで、それぞれ日付付き)、expected.json を含むフィクスチャ、src/engine/catalogue.ts への 1 行の追加が必要です。5 つの正常なフィクスチャでは指摘件数が 0 件でなければなりません。誤検知はリリースを阻止する要因です。

ライセンスと商標

MIT。Google Play は Google LLC の商標です。Billing Doctor は独立したプロジェクトであり、Google との提携、Google による承認、Google からの支援を受けていません。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。