この記事はTVer Advent Calendar 2025 シリーズ1 の 22日目の記事です。21日目の記事は@togoeさんの「デザインシステムを「1から作り直したけど撤退した話」〜TVerデザインシステムV2お蔵入りから学んだこと〜」でした。
はじめに
みなさんは、モバイルアプリのクラッシュ対応に日々どれだけ時間を割いているでしょうか?アプリのクラッシュ状況を監視し修正するのは重要な活動ですが、新機能の開発をしながら行うのはなかなか大変なので少しでも楽になれたら良いなと考えています。
そんな課題を解決するために、本記事では、Firebase MCPサーバーを利用して、モバイルアプリのクラッシュ対応を行うClaude Codeのカスタムコマンドを紹介します。
Firebase MCPサーバーは比較的新しい機能で、AIエージェントがFirebaseの各種サービスに直接アクセスできる機能です。本記事ではその中でもCrashlytics連携に焦点を当て、クラッシュの分析から修正PRの作成までを一気通貫で行うカスタムコマンドを構築していきます。Firebase MCPサーバーは現在試験運用版ではありますが、実運用できる機能であると判断し採用しました。
前提
ここでは以下の環境やツールの利用を想定して記載していきます。
- Androidアプリのクラッシュ対応を行う
- iOSアプリなどでも応用可能です
- AIツールとしてClaude Codeを利用できる
- 他のAIコーディングツールでも応用可能です
- GitHubでIssueやコードの管理を行う
- ghコマンドでGitHub関連の操作を行える
Firebase MCPサーバー
Firebase MCPサーバーには、クラッシュの数や内容などを参照できるMCP ツールが定義されています。
これらのツールを活用することで、Crashlytics Consoleを開くことなく、ターミナル上でクラッシュ情報を取得・分析できるようになります。
セットアップ
MCP を介した Crashlytics の AI アシスタンスのページにて各種AIツールごとの導入手順がまとめられているので、参考にしてセットアップします。
カスタムコマンドの作成
それでは、クラッシュ対応ワークフローを自動化するカスタムコマンドを作成していきましょう。ここでは、fix-crashlytics-issue.mdとしてカスタムコマンドを作成します。
コマンドの概要
/fix-crashlytics-issueコマンドは、以下のワークフローを自動実行します:
事前チェック → Issue ID入力 → 情報取得 → 診断 → GitHub issue作成 → Crashlyticsにリンク追加 → ブランチ作成 → 修正実装 → PR作成
ワークフロー詳細
以降、実際のカスタムコマンドの内容を抜粋して紹介します。
0. 事前チェック
コマンド実行時、最初に環境が整っているかを確認します。
### 0. 事前チェック(Prerequisites Check) **このステップは最初に必ず実行し、すべてのチェックに合格しない場合は処理を中断すること。** #### チェック項目: 1. **Firebase MCP接続確認** - `firebase_get_environment` を実行 - チェック内容: - ✅ Authenticated User が設定されているか - ❌ 未認証の場合: 「Firebase MCPにログインしてください。`firebase login`を実行するか、Firebase MCPサーバーの設定を確認してください。」 2. **Gitリポジトリ確認** - `git status` を実行 - チェック内容: - ✅ Gitリポジトリ内で実行されているか - ✅ 作業ツリーがクリーンか(未コミットの変更がないか) - ⚠️ 未コミットの変更がある場合: 警告を表示し、続行するか確認 - ❌ Gitリポジトリでない場合: 「Gitリポジトリ内で実行してください。対象プロジェクトのディレクトリに移動してから再実行してください。」 3. **GitHub CLI (gh) 確認** - `gh --version` を実行 - チェック内容: - ✅ ghコマンドが存在するか - ✅ ghが認証済みか(`gh auth status` で確認) - ❌ ghコマンドが存在しない場合: 「GitHub CLI (gh) がインストールされていません。https://cli.github.com/ からインストールしてください。」 - ❌ gh未認証の場合: 「GitHub CLIにログインしてください。`gh auth login`を実行してください。」 #### チェック結果の表示形式: ## 事前チェック結果 | チェック項目 | 状態 | 詳細 | |-------------|------|------| | Firebase MCP | ✅ | {user}でログイン中 | | Gitリポジトリ | ✅ | クリーンな状態 | | GitHub CLI (gh) | ✅ | v{version} 認証済み | すべてのチェックに合格しました。 **いずれかのチェックが失敗した場合は、エラー内容を表示して処理を終了すること。**
いずれかのチェックが失敗した場合は、具体的なエラーメッセージと対処法を表示して処理を中断します。事前にチェックすることで、途中でエラーになって困る...という事態を防げます。
1. Crashlytics URLの入力
事前チェック完了後、対話形式でCrashlytics ConsoleのURLを入力してもらいます。
### 1. Crashlytics URLの入力 事前チェック完了後、ユーザーにCrashlytics ConsoleのURLを入力してもらう。 #### 入力形式: - **URL**: Crashlytics ConsoleのフルURL - 例: `https://console.firebase.google.com/project/{project-id}/crashlytics/app/android:{app-id}/issues/{issue-id}?time=...` #### URL解析: URLから以下の情報を抽出する: - **アプリID**: URLの `/app/android:` の後の部分(例: `android:1:123456789012:android:abc123def456` → `1:123456789012:android:abc123def456`) - **Issue ID**: `/issues/` の後の32文字の16進数(例: `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`) #### 処理: 1. ユーザーに入力を促す: Firebase Crashlytics ConsoleのURLを入力してください: (例: https://console.firebase.google.com/project/xxx/crashlytics/app/android:xxx/issues/xxx) 2. URLからアプリIDとIssue IDを抽出 3. 抽出に失敗した場合はエラーメッセージを表示: - 「URLの形式が正しくありません。Firebase Crashlytics ConsoleのフルURLを入力してください。」 4. `crashlytics_get_issue` を実行してissue情報を取得(抽出したアプリIDとIssue IDを使用) 5. 取得成功: 処理を続行 6. 取得失敗: エラーメッセージを表示 - 「Crashlytics issue (ID: {issueId}) が見つかりません。URLを確認してください。また、アプリID ({appId}) へのアクセス権限があるか確認してください。」
URLをそのままペーストするだけでOKなので、Crashlytics Consoleから簡単に連携できます。アプリIDもURLから取得するため、複数のアプリを扱う場合でも設定変更は不要です。
2. TodoListの作成
### 2. TodoListの作成 TodoWriteツールを使って以下のタスクリストを作成: 1. Crashlytics情報取得 2. 問題の診断と修正プラン作成 3. GitHub issue作成 4. CrashlyticsにGitHub issueリンクを追加 5. 修正実装の継続確認 6. ブランチ作成 7. 修正実装 8. コミット作成 9. Draft PR作成 ※ステップ5で「Issue起票のみで終了」が選択された場合、ステップ6以降はスキップされる
TodoWriteツールを使うことでAIが自身でタスクを明確に管理してくれるようになります。
3. Crashlytics情報取得
### 3. Crashlytics情報取得(ステップ1で取得済みの情報を使用) - `crashlytics_get_issue`でissue情報を取得 - `crashlytics_batch_get_events`でサンプルイベント(スタックトレース)を取得 - issue情報のsampleEventフィールドを使用 - 影響規模の取得(`crashlytics_get_top_issues`を使用): - **直近1時間**: filterのintervalStartTime/intervalEndTimeを現在時刻から1時間前〜現在に設定 - **直近24時間**: filterのintervalStartTime/intervalEndTimeを現在時刻から24時間前〜現在に設定 - 両方のissueIdフィルタに対象issue IDを指定して取得
影響規模を時間範囲別に取得することで、「今まさに急増しているクラッシュなのか」といった緊急度を判断できるようになっています。直近1時間/24時間以内の発生件数に応じて緊急度を決定しているので、このような設定にしていますが、チームの運用ルールによっては直近1ヶ月などの少し長めの期間での発生傾向を調査することもできます。
4. 問題の診断と修正プラン作成
### 4. 問題の診断と修正プラン作成 - スタックトレースから該当ファイルを特定 - 関連するファイルをReadで読み込んで分析 - 問題の根本原因を分析: - 最大3つの可能性を列挙 - それぞれの妥当性を評価 - 最も可能性の高い原因を選択 - 修正プランを作成: - **原因**: 根本原因の説明 - Fault: このコードベースの問題か、依存ライブラリの問題か - Complexity: simple / moderately simple / moderately hard / hard / Investigation Required - **修正内容**: 具体的な修正手順(ファイル名と変更内容) - **テスト方法**: 修正の検証方法
AIが複数の可能性を検討した上で、最も可能性の高い原因を提示してくれます。AIが分析した結果が間違いである可能性もあるので、どのような可能性があるか列挙し、その中でどれを選択して修正したのか提示してもらうと、人間が別の可能性を調査するときにも役立ちます。
5. ユーザー確認
### 5. ユーザーに確認(診断結果) 修正プランをユーザーに提示し、以下を確認: - 診断結果が妥当か - GitHub issueを作成してよいか **承認されなかった場合はここで終了**
修正プランをユーザーに提示し、承認を得ます。診断結果に自信がない場合は、修正を実装せずプランのみ提示するようにしています。人間の判断を挟むことで、誤った修正を防ぎます。
また、「修正は人間がすぐに行えるがGitHub Issueの作成や内容の記載が面倒」な場合には、issue作成だけAIにお願いすることも可能です。特にモバイルアプリはUI関連のコードに起因したクラッシュの場合には、修正後の動作確認を人間が行うことも多いと思います。そうした時に、全てをAIに任せず、人間と適切に分業できるように選択肢を用意しています。
6. GitHub issue作成
診断結果を含むGitHub issueを作成します。
### 6. GitHub issue作成 `gh issue create` コマンドでissueを作成: **タイトル形式:** [Crashlytics] {issue.title} **本文形式:** ## Crashlytics Issue情報 - **Issue ID**: {issue.id} - **影響規模**: - 直近1時間: {hourlyUsersCount}人 / {hourlyEventsCount}回 - 直近24時間: {dailyUsersCount}人 / {dailyEventsCount}回 - **発生バージョン**: {firstSeenVersion} → {lastSeenVersion} - **エラータイプ**: {errorType} - **Crashlytics URL**: {issue.uri} ## エラー内容 {issue.subtitle} ## スタックトレース {スタックトレースの主要部分} ## 診断結果 ### 原因 {根本原因の説明} - **Fault**: {このコードベースの問題 or 依存ライブラリの問題} - **Complexity**: {simple/moderately simple/moderately hard/hard} ### 修正内容 {修正手順} ### テスト方法 {検証方法} ### その他の可能性 {他の原因候補}
Crashlyticsの情報と診断結果がまとまっているので、後からissueを見返したときにも分かりやすいです。人間が手作業でissueを作成する場合以下のような課題があったため、AIが作成してくれるメリットは大きいです。
- 人によって書き方や情報量がバラバラ
- 全ての項目を埋めるのに時間がかかる
7. CrashlyticsにGitHub issueリンクを追加
### 7. CrashlyticsにGitHub issueリンクを追加 `crashlytics_create_note`を使って、CrashlyticsのissueにGitHub issueへのリンクをノートとして追加する。 **ノート内容:** GitHub Issue: https://github.com/your-org/your-repo/issues/{issue番号}
これにより、Crashlytics Console上からもGitHub issueを参照できるようになります。双方向にリンクされるので、どちらからでも追跡可能です。

8-10. ブランチ作成 → 修正実装 → PR作成
- ブランチ名:
issue/{GitHub issue番号} - コミットメッセージ:
#{issue番号} fix: {修正内容} - PRはDraftで作成
実行例
実際に実行するとこんな感じになります:
$ claude > /fix-crashlytics-issue ## 事前チェック結果 | チェック項目 | 状態 | 詳細 | |-------------|------|------| | Firebase MCP | ✅ | user@example.comでログイン中 | | Gitリポジトリ | ✅ | クリーンな状態 | | GitHub CLI (gh) | ✅ | v2.40.0 認証済み | すべてのチェックに合格しました。 Firebase Crashlytics ConsoleのURLを入力してください: > https://console.firebase.google.com/project/my-app/crashlytics/app/android:x:xxxxxxxxx:xxxxxxx:xxxxxx/issues/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx アプリID: x:xxxxxxxxx:xxxxxxx:xxxxxx Issue ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Issue情報を取得中... スタックトレースを分析中... ## 診断結果 ### 原因 ArrayIndexOutOfBoundsExceptionが発生。 - **Fault**: このコードベースの問題 - **Complexity**: simple ### 修正内容 HogeHoge.ktの`list.get()`を呼び出す前に、インデックスがリストの範囲内にあるかチェックを追加する。 この修正プランで進めてよいですか? [y/n] > y GitHub issue #123 を作成しました(ラベル: Firebase Crashlytics) Crashlyticsにリンクを追加しました ブランチ issue/123 を作成しました 修正を実装中... コミットを作成しました Draft PR #123 を作成しました 完了しました! PR: https://github.com/org/repo/pull/123
Crashlytics ConsoleのURLを入力するだけで、PRまで作成されました!
まとめ
Firebase MCPを活用することで、クラッシュ対応の以下のフローを自動化できました。
これにより、Crashlytics ConsoleとGitHub、エディタを行き来する手間が削減され、クラッシュ対応の効率が大幅に向上します。
ぜひみなさんも試してみてください。