Claude アプリの Code 一覧に溜まる古いリモートセッションを自動アーカイブする
PC側ログを消しても減らないスマホ/Webの切断済みセッションを、内部APIで24h超のものだけ6時間ごとにアーカイブする hook
約5.2万トークンの節約 (API料金換算で約78円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「Claude アプリの Code 一覧に溜まる古いリモートセッションを自動アーカイブする」は、開発プロセスカテゴリのAI指示書(MDファイル)です。PC側ログを消しても減らないスマホ/Webの切断済みセッションを、内部APIで24h超のものだけ6時間ごとにアーカイブする hookこの巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約5.2万トークン(API料金換算で約78円)・87%のトークンを節約できます。
- カテゴリ
- 開発プロセス
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約6万トークン
- この巻物使用時
- 約8,000トークン
- 節約量
- 約5.2万トークン (約78円)
- 更新日
- 2026-10-15
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/claude-code-5/raw を読み込んで、この指示書どおりに実装して"
中身
Claude アプリ(スマホ/Web)の「Code」一覧に溜まる古い Remote Control セッションを自動アーカイブする
症状
Claude Code の Remote Control を使っていると、スマホアプリや claude.ai の「Code」一覧に「切断済み」のセッションが溜まり続ける。PC 側の会話ログ(~/.claude/projects/**/*.jsonl)を削除・退避しても、この一覧はサーバー側の記録なので減らない。
解決の要点
Claude Code 本体が内部で使っているセッション API で、古いセッションをアーカイブする(一覧から隠れるだけで会話は消えない)。
- 一覧:
GET https://api.anthropic.com/v1/code/sessions?limit=100&cursor=<next_cursor>(data[]とnext_cursor) - アーカイブ:
POST https://api.anthropic.com/v1/code/sessions/{id}/archive(body{}。200 = 成功、409 = 既にアーカイブ済み) - ヘッダ:
Authorization: Bearer <~/.claude/.credentials.json の claudeAiOauth.accessToken>anthropic-version: 2023-06-01anthropic-beta: ccr-byoc-2025-07-29x-organization-uuid: <~/.claude.json の oauthAccount.organizationUuid>
- 判定に使うフィールド:
status(active / archived)、connection_status(connected / disconnected)、last_event_at、title
注意: 公開ドキュメントのない内部 API。Claude Code 本体(claude 実行ファイル)の文字列から特定したもので、将来変わりうる。失敗しても何もしない作りにする。
安全な対象条件
status !== 'archived' かつ connection_status === 'disconnected' かつ last_event_at から 24 時間以上。
接続中や直近のセッションは作業中の可能性があるので触らない。
スクリプト(Node 18+、依存なし)
// purge-remote-sessions.mjs — node purge-remote-sessions.mjs [--dry-run]
import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path';
const home = os.homedir(), root = path.join(home, '.claude');
const json = (f, d = {}) => { try { return JSON.parse(fs.readFileSync(f, 'utf8')); } catch { return d; } };
const COOLDOWN = 6 * 3600e3, STALE = 24 * 3600e3, BASE = 'https://api.anthropic.com';
const dry = process.argv.includes('--dry-run'), now = Date.now();
const stateFile = path.join(root, 'purge-remote-sessions-state.json');
if (!dry && now - (json(stateFile).at ?? 0) < COOLDOWN) process.exit(0);
const token = json(path.join(root, '.credentials.json')).claudeAiOauth?.accessToken;
const org = json(path.join(home, '.claude.json')).oauthAccount?.organizationUuid;
if (!token || !org) process.exit(0);
if (!dry) fs.writeFileSync(stateFile, JSON.stringify({ at: now }));
const h = { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', 'anthropic-version': '2023-06-01',
'anthropic-beta': 'ccr-byoc-2025-07-29', 'x-organization-uuid': org };
const all = []; let cursor = '';
for (let i = 0; i < 30; i++) {
const q = new URLSearchParams({ limit: '100', ...(cursor && { cursor }) });
const r = await fetch(`${BASE}/v1/code/sessions?${q}`, { headers: h, signal: AbortSignal.timeout(15e3) });
if (!r.ok) process.exit(0);
const j = await r.json(); all.push(...(j.data ?? []));
if (!j.next_cursor || !(j.data ?? []).length) break; cursor = j.next_cursor;
}
const stale = (s) => { const t = Date.parse(s.last_event_at ?? s.updated_at ?? s.created_at);
return s.status !== 'archived' && s.connection_status === 'disconnected' && now - t >= STALE; };
const targets = all.filter(stale);
if (dry) { console.log(targets.length, targets.map((s) => (s.title ?? '').split('\n')[0]).slice(0, 20)); process.exit(0); }
let ok = 0;
for (const s of targets) {
const r = await fetch(`${BASE}/v1/code/sessions/${encodeURIComponent(s.id)}/archive`, { method: 'POST', headers: h, body: '{}' });
if (r.status === 200 || r.status === 409) { ok++; fs.appendFileSync(path.join(root, 'archived-remote-sessions.jsonl'),
JSON.stringify({ id: s.id, title: (s.title ?? '').split('\n')[0].slice(0, 60), at: new Date(now).toISOString() }) + '\n'); }
}
console.log(`archived ${ok}/${targets.length}`);
自動化
Claude Code の SessionStart / Stop hook から detached で起動する(hook をブロックしない)。6時間のクールダウンがあるので、毎回発火しても API は叩きすぎない。
// hook ランチャー(例)
import { spawn } from 'node:child_process';
const c = spawn(process.execPath, ['<path>/purge-remote-sessions.mjs'], { detached: true, windowsHide: true, stdio: 'ignore' });
c.on('error', () => {}); c.unref();
settings.json:
{ "hooks": { "SessionStart": [{ "hooks": [{ "type": "command", "command": "node <path>/launcher.mjs", "timeout": 5, "async": true }] }] } }
検証手順
--dry-runで対象件数とタイトルを確認する- 本実行後に再度一覧を取得し、
status: activeの件数が対象件数ぶん減ったことを確認する(read-back) - スマホアプリの一覧を開き直して反映を目視確認する
実績
1 アカウントで未アーカイブ 120 件 → 27 件(93 件アーカイブ、失敗 0)。会話はアーカイブ済みとしてサーバーに残る。
よくある質問
+「Claude アプリの Code 一覧に溜まる古いリモートセッションを自動アーカイブする」とは何ですか?
PC側ログを消しても減らないスマホ/Webの切断済みセッションを、内部APIで24h超のものだけ6時間ごとにアーカイブする hook
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約6万トークンかかりますが、この巻物を使えば約8,000トークンで済みます。差し引き約5.2万トークン(API料金換算で約78円)・87%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
スマホ(Remote Control)から即相談できる Claude Code タブを VS Code に毎朝自動で用意する
自作VS Code拡張で公式Claude Codeのコマンド(editor.openLast/newConversation/renameSessionTab)を叩き、名前付きタブをN本自動補充。夜間はWM_CLOSE→再起動で毎朝揃える。--bg/ターミナル経路・タブ0でのnewConversation・SendKeys再読み込みが失敗する実測付き
夜間ジョブ異常を通知で終わらせず自動修復→AI修理PR→人へ引き渡す閉ループ
監視の『検知して通知』の後段に、決定的Playbook→AIコーダーの隔離worktree修理PR→持ち越し→人への3要素引き渡し、を足す実装指示書。argvで指示を渡すな等の実測の落とし穴つき
ドキュメント駆動開発プロセス CLAUDE.md — 作るものを固めてから書かせる
「AIが暴走して意図と違うものを作る」を根絶する開発プロセス指示書。UI仕様→機能設計→実装の順をAIに強制し、1ファイルごとに承認ゲートを挟む。受託開発・チーム開発向け。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア