MCPサーバー(GA4、Search Console)の認証が7日おきに壊れる、という問題に遭遇しました。
エラーは invalid_grant。原因を調べていくと、GCPのOAuth同意画面が「テストモード」のままになっていたせいでした。
何が起きたか
MCP連携で使っているGA4とSearch ConsoleのAPIが、ある日突然401エラーになったんですよ。エラーメッセージはこれです。
{"error": "invalid_grant", "error_description": "Token has been expired or revoked."}
再認証すれば直ります。でもしばらくすると同じエラーが出る。
「refresh_tokenってそんなすぐ切れるもの?」と調べ始めて、7日という数字に気づきました。
原因
犯人はGCPのOAuth同意画面の「テストモード」でした。
GCPでOAuthを設定するとき、同意画面の「公開ステータス」がデフォルトで「テスト」になります。このテストモードには、refresh_tokenが7日で失効するという制限がある。
本番モード(「本番環境」ステータス)だと、refresh_tokenは6ヶ月間使用がなければ失効という挙動に変わります。個人利用なら実質ほぼ永続的に使えます。
条件はこの3つが重なったとき:
- ユーザーの種類が「外部」
- 公開ステータスが「テスト」
- スコープがname/email/profile以外(GA4やSearch ConsoleのAPIスコープを含む場合)
Googleの「内部」ユーザータイプはGoogle Workspace契約者向けなので、個人アカウントでは選べません。外部+テストモードの組み合わせが一番ハマりやすい状況です。
対策
GCPコンソールのOAuth同意画面を「本番環境」に切り替えます。
- GCPコンソール →
Google Auth Platform→Audience(旧UI: APIとサービス → OAuth同意画面) - 「アプリを公開」ボタンをクリック
- 確認ダイアログで承認
- 公開ステータスが「本番環境」に変わったことを確認
変更前: 公開ステータス → テスト 変更後: 公開ステータス → 本番環境
「アプリの公開」という言葉の響きが怖いですが、個人利用であればGoogle のverification(審査)は不要です。「未確認のアプリ」という警告は出ますが、クリックスルーで進めます。この警告と7日失効は別の問題で、公開にすれば7日制限はなくなります。
切り替えた後は再認証が必要です。テストモードで取得したトークンは7日で失効するので、切り替え後に認証フローを通して新しいrefresh_tokenを取得し直します。
なぜ気づきにくいか
この罠がやっかいなのは、設定直後は何事もなく動くんですよ。
OAuthの設定が終わって疎通確認して、問題なく動いている。「よし、完了」となる。それから7日後に突然死ぬ。
設定作業とエラー発生のタイムラグが7日あるので、原因と結果が結びつきにくい。しかも invalid_grant のエラーだけ見ると「トークンを間違えてる?」とか「権限が変わった?」とか別の方向で調べ始めてしまう。
もう一つ、refresh_tokenの上限数にも注意が必要です。同一クライアントIDで発行できるrefresh_tokenは100件が上限で、超えると最も古いトークンから自動失効します。テストモードで何度も再認証を繰り返していると積み上がるので、急にトークンが切れたらこの上限を超えていないか確認するといいです。
まとめ
GCP OAuthのrefresh_tokenが7日で切れる場合、OAuth同意画面のステータスが「テスト」になっているのが原因です。
「本番環境」に切り替えるだけで7日制限は解除されます。個人利用であれば verification は不要です。
OAuth設定をしたら、同意画面の公開ステータスを確認しておくとこの罠を踏まずに済みます。