CLAUDE LABEN
CODE — Claude Codeに大型の品質・信頼性アップデート。/rewindでの巻き戻し、MCPレジリエンス向上、OAuthハンドリングの安定化が入りましたCODE — ストリーミングと長時間セッション中のCPU・メモリ使用量が削減され、長く回す自動運用が安定しますADMIN — 組織向けモデル制限が追加され、管理者が利用可能なモデルを制御できるようになりましたMCP — 構造化出力・リモートMCP・セッション再開(resume)の信頼性が向上しましたMODEL — Claude Fable 5が一般提供。100万トークン文脈・常時アダプティブ思考・128K出力が特徴ですLINEUP — 主力はOpus 4.8・Sonnet 4.6・Haiku 4.5。用途に応じて使い分けられますCODE — Claude Codeに大型の品質・信頼性アップデート。/rewindでの巻き戻し、MCPレジリエンス向上、OAuthハンドリングの安定化が入りましたCODE — ストリーミングと長時間セッション中のCPU・メモリ使用量が削減され、長く回す自動運用が安定しますADMIN — 組織向けモデル制限が追加され、管理者が利用可能なモデルを制御できるようになりましたMCP — 構造化出力・リモートMCP・セッション再開(resume)の信頼性が向上しましたMODEL — Claude Fable 5が一般提供。100万トークン文脈・常時アダプティブ思考・128K出力が特徴ですLINEUP — 主力はOpus 4.8・Sonnet 4.6・Haiku 4.5。用途に応じて使い分けられます
記事一覧/Claude Code
Claude Code/2026-06-27上級

OAuthトークンが切れた瞬間に無人実行が手詰まりになる — リモートMCPを止めないトークンライフサイクル設計

リモートMCPコネクタはOAuthで認可されますが、アクセストークンは短命です。対話実行ではブラウザで再認可できても、無人のスケジュール実行では誰もダイアログを押せません。期限を自分で持ち、先読みで更新するトークンライフサイクル設計をまとめました。

Claude Code169MCP36OAuth3認証3個人開発90

プレミアム記事

深夜2時に動くはずだったジョブが、朝になっても何も生み出していない。ログをたどると、リモートMCPのツール呼び出しが一度だけ失敗していて、原因はアクセストークンの期限切れでした。対話的に使っているときは、トークンが切れても画面に認可ダイアログが出て、ブラウザでボタンを一度押せば何事もなく続きます。けれど無人で回しているスケジュール実行には、そのボタンを押す人がいません。

私自身、個人開発で複数サイトの自動投稿を回しているのですが、リモートMCPコネクタをつないだ直後はうまく動くのに、数十時間後に静かに止まる、という経験を何度かしました。コネクタの設定そのものは正しいのです。崩れているのは「トークンの寿命」を誰も管理していなかった、その一点でした。

ここからは、リモートMCPコネクタのOAuthトークンを「自分が管理する状態」として持ち、実行前と実行中に先読みで更新して、無人実行を止めないための設計を、動くコードと一緒に組み立てていきます。

なぜ対話実行ではトークン切れが見えないのか

OAuthのアクセストークンは、たいてい数十分から数時間で失効する短命のものです。これに対してリフレッシュトークンは長命で、これを使えば新しいアクセストークンを無人でも取り直せます。

対話的なクライアントは、この更新を裏側で自動的に行ってくれます。アクセストークンが切れていれば、リフレッシュトークンで黙って取り直し、それも失効していれば、ブラウザを開いて「認可しますか?」と人間に尋ねます。つまり「人間がいつでも認可ボタンを押せる」という前提が、トークン切れを目に見えない問題に変えているわけです。

無人実行ではこの前提が崩れます。ブラウザを開いても押す人がいないので、アクセストークンもリフレッシュトークンも切れた瞬間に、そのジョブは前に進めなくなります。しかも失効は「401」として返ってきて、MCPクライアントの層では汎用的なツールエラーに丸められがちです。「ツールが失敗した」としか見えず、本当の理由が「認可の期限切れ」だと気づくのが遅れます。

ですから無人運用では、トークンの更新をクライアント任せにせず、自分でライフサイクルを握る必要があります。順番に組み立てていきましょう。

トークンを「期限つきの状態」として持つ

最初の一歩は、アクセストークン・リフレッシュトークン・失効時刻をひとまとめにして永続化することです。失効時刻を持っていないと「いつ切れるか」が分からず、先読み更新ができません。

import json
import os
import time
import tempfile
from dataclasses import dataclass, asdict
from pathlib import Path
 
@dataclass
class TokenSet:
    access_token: str
    refresh_token: str
    expires_at: float  # UNIX秒。アクセストークンが失効する絶対時刻
 
    def expires_in(self) -> float:
        return self.expires_at - time.time()
 
class TokenStore:
    """トークンをJSONで永続化する。書き込みは原子的に行う。"""
 
    def __init__(self, path: str):
        self.path = Path(path)
 
    def load(self) -> TokenSet:
        data = json.loads(self.path.read_text(encoding="utf-8"))
        return TokenSet(**data)
 
    def save(self, tokens: TokenSet) -> None:
        # 同一ディレクトリに一時ファイルを書いてからrenameする。
        # 途中でプロセスが落ちても、半端なファイルで上書きしないため。
        d = self.path.parent
        d.mkdir(parents=True, exist_ok=True)
        fd, tmp = tempfile.mkstemp(dir=d, suffix=".tmp")
        try:
            with os.fdopen(fd, "w", encoding="utf-8") as f:
                json.dump(asdict(tokens), f)
            os.replace(tmp, self.path)
            os.chmod(self.path, 0o600)  # トークンファイルは本人だけが読めるように
        finally:
            if os.path.exists(tmp):
                os.unlink(tmp)

ここで地味に大事なのは、保存を原子的(一時ファイル+rename)にしている点です。トークンの保存中にプロセスが落ちると、ファイルが半端な状態で残り、次回の読み込みで壊れます。更新は無人実行のたびに起きるので、ここが壊れると静かな停止の温床になります。chmod 0o600 でファイル権限を絞っているのも、トークンは秘密情報だからです。

プロバイダによってトークンエンドポイントが返すのは expires_at(絶対時刻)ではなく expires_in(残り秒数)であることが多いので、受け取った瞬間に time.time() + expires_in で絶対時刻へ変換して保存します。残り秒数のまま持つと、いつ取得したかを別途覚えておく必要があり、ずれの原因になります。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
アクセストークンの期限を自分で保持し、実行前にスキューを見て先読み更新する設計
リフレッシュトークンのローテーション失効と時計ずれに強いトークンストアの実装
更新に失敗したときに黙って止めず、構造化スキップで気づける撤退設計
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

Claude Code2026-06-20
MCP コネクタの認可を一箇所に集める — 参照先が増えても崩れない個人開発の設計
Claude チャット・Claude Code・Cowork で同じ MCP コネクタを別々に設定していると、認可がずれて無音で壊れます。管理型コネクタの「一度つないで使い回す」発想を、個人開発でも再現する設計をまとめました。
Claude Code2026-05-06
Claude Code × MCP で構築する個人開発 AI 自動化ハブ — 複数サービス横断の設計と実装
Claude Code と MCP を組み合わせ、GitHub・Notion・Slack を横断する個人開発向けの AI 自動化ハブを設計・実装します。サービス間の文脈維持・エラーハンドリング付きコード例・トークンコスト削減の実測までまとめました。
Claude Code2026-04-26
Claude Code の「Authorization Failed」エラーを解きほぐす — OAuth・MCP・dynamic client registration の全体像
Claude Code を使っていて突然出る「authorization failed」「incompatible auth server: does not support dynamic client registration」というエラー。MCPサーバーやOAuth周りの噛み合わせを丁寧にひも解いて、現場で使える対処手順をまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →