
「スキルを最新にして」——たった一言で、すべての環境が最新版に揃う。今はそうなった。でも、ここに至るまでに丸一日を費やし、セキュリティ事故を起こし、ファイルを取り違え、チャットを安全フィルターで強制停止された。これは、その記録である。
冒頭の対話シーン
私「あれ、このスキル、昨日直したはずなのに古い版が動いている……」
Claude「どこで直しましたか?」
私「えっと……職場のPCで……Claudeに頼んで GitHub に上げて……」
Claude「そのあと、自宅の PC では何かしましたか?」
私「……何もしてない」
Claude「それが原因です」
この会話、心当たりがある方はいませんか。Claudeのカスタムスキルを複数の PC や環境で使っている人なら、一度は経験したことがあるはずだ。私自身がまさにこれだった。
発端:「スキルを更新して」が、チャットごと消えた
私は Claudeのカスタムスキルをいくつか自作して日常業務に組み込んでいる。
ブログ記事の投稿支援、日報の自動生成、スキルの GitHub 同期など、どれも「毎日使う道具」として育ててきたものだ。
ある日、スキルの改良を Claude に依頼した。修正内容を Claude が生成し、GitHub に反映しようとした——そのとき、チャットが突然停止した。
画面には Anthropic の安全フィルターに関するサポートページへのリンクだけが残された。

原因は、GitHub の Personal Access Token(認証トークン)がチャット内に平文で表示されていたことだった。
Claudeがトークンを使って GitHub API を呼び出すために、Chromeのブラウザ経由で JavaScript を実行し、その中にトークンを埋め込んでいたのだ。
Anthropicの安全フィルターは、これを「外部に機密情報を送信する危険な操作」と判断してセッションを止めた。
根本原因:「同期しているはず」が、そもそも嘘だった
チャット停止のショックから立ち直って冷静に調べてみると、もっと根深い問題が見えてきた。
私は「スキルを GitHub に上げれば全環境で最新になる」と思い込んでいた。しかし実際には、Claudeのスキルは3つの独立した保管場所に分かれていて、どれも自動では同期されない。

ひとつめは、claude.aiのサーバー(Anthropicのクラウド上、アカウントに紐づく領域)。ブラウザやモバイルアプリからアクセスするとき、Claudeはここに保存されたスキルを読む。
なお、claude.aiでも Claude Desktop 版で利用しているとと カスタムスキルを改良するとこんな感じでボタンが現れるが、保存先はローカルPCではなくclaude.aiのサーバーだ。

ふたつめは、各PCのローカルファイル。Claude Code や Claude Cowork はこちらを参照する。
みっつめは GitHub。バージョン管理と PC 間の橋渡し役だが、Claudeが直接読みに行く場所ではない。
つまり、GitHub に push しただけでは、claude.ai 側もローカル側も古いままなのだ。
3つの保管場所にそれぞれ別々の方法で反映しなければならない。
この「3系統の保管場所」という構造を理解していなかったことが、すべての混乱の出発点だった。
事態を悪化させた「自動化スキル」
3系統を手動で揃えるのは面倒だ。
そこで私は「sync-to-github」というカスタムスキルを作った。
Claudeに「スキルをGitHubに同期して」と頼むだけで、自動的にpushしてくれる——はずだった。

しかし、このスキルには設計上の問題がいくつも潜んでいた。
まず、名前と実態の不一致。「sync(同期)」と名乗っているのに、実装されていたのはpush(アップロード)だけだった。pull(ダウンロード)の機能がない。
職場PCでpushしたスキルを自宅PCで取得するには、結局手動でgit pullを実行する必要があった。スキルがそれを教えてくれないので、自宅PCではいつも古い版のまま作業していた。
次に、脆い技術経路への依存。claude.aiのサンドボックス環境ではGitHubに直接アクセスできない。そこでこのスキルは、ChromeブラウザのJavaScript実行ツールを経由してGitHub APIを呼び出す、という迂回路を使っていた。
スキルファイルの全文をJavaScriptの文字列リテラルに埋め込み、base64でエンコードして送信する——技術的には動くが、日本語やバッククォートなどの特殊文字が含まれると文字化けする。
しかも「コミット成功」と表示されるのに中身が壊れている、という最悪のパターンが起きる。

そして冒頭のチャット強制停止。認証トークンが平文でチャットに表示されたことで安全フィルターが反応した。自動化スキルが、むしろ問題を増やしていたのだ。
丸一日かけたリカバリと再設計
ここから丸一日をかけて、問題の整理とスキルの再設計に取り組んだ。Claudeと対話しながら、ひとつずつ原因を潰していった。
最初にやったのは、流出したトークンの失効(Revoke)と新トークンの発行。次に、誤ったファイルでコミットされていた GitHub リポジトリの revert(巻き戻し)。そして、sync-to-github スキルの全面的な再設計。
再設計の方針はシンプルだった。「脆い経路は使わない。素直な方法でやる」。
Chrome JavaScript 経由の GitHub API 呼び出しは完全に削除した。
代わりに、ローカルの git コマンドを使って普通に push/pull する。認証トークンは Windows の資格情報マネージャーに保管させ、チャットには一切表示しない。ファイルの受け渡しに Downloads フォルダを経由するのも禁止した(同名ファイルの衝突で取り違えが起きるため)。
さらに、これまで push しかなかった同期スキルにpull 経路を追加した。
「スキルを最新にして」と言えば、GitHub から最新版を取得してローカルに一括コピー。「GitHub に上げて」と言えば push する。
明示的な方向指示がなければ、git の状態を見て自動的にどちらが必要か判定する。
ようやく「同期」の名に恥じない設計になった。
作業中にスキルが自分自身を検証した
面白かったのは、再設計したスキルの有効性が、そのスキルを配置する作業の中で証明されたことだ。
新しいスキルには「push する前に、対象ファイルの先頭5行をユーザーに表示して確認する」というステップを入れた。
ファイル名が同じ SKILL.md でも、中身が別のスキルだったら先頭の name フィールドで気づける。
実際、配置作業中に3回のファイル受け渡しがあり、そのうち2回で取り違えが発生した。
1回目は検出できずに誤コミット→ revert になった。
2回目は先頭5行確認で「行数が 239 のはずが 333 になっている」と気づいて止めた。3回目でようやく正しいファイルが配置された。
スキルの「アンチパターン(やってはいけないこと)」セクションに書いた
「Downloads フォルダ経由でファイルを受け渡さない」というルールも、まさに作業中の事故から生まれたものだ。
設計書と実装が同時に検証される、という稀有な体験だった。
4層の複合要因——なぜ「最新版が使えない」が続いたのか
振り返ると、「いつまでも最新版のスキルが使えない」という現象は、4つの層が重なって起きていた。
第1層(構造的な制約):Anthropicがスキルの環境間同期機能をまだ実装していない。3つの保管場所が独立している以上、ユーザー側で手動同期が必要。これは製品の成熟を待つしかない。
第2層(スキル設計の問題):自動化スキルが Chrome JavaScript 経由という脆い技術経路を使い、しかも「sync」と名乗りながら push しかしていなかった。結果として「同期した=最新」という誤った安心感を生んでいた。
第3層(可視性の欠如):どの環境のどの版が最新かが分からない。CHANGELOGもなく、「いつ何を変えたか」がスキル本体に記録されていなかった。
第4層(操作上の事故):ファイル取り違え、文字化け、安全フィルター停止。Downloads フォルダに複数の同名ファイルが溜まり、ブラウザの自動リネームで別名保存されたことに気づかないまま古い版をコピーしてしまう。
どれか一つだけなら対処は簡単だ。しかし4層が同時に作用すると、「直したはずなのに直っていない」「成功したはずなのに中身が壊れている」「同期したはずなのに古いまま」という、原因の特定すら難しい状況が生まれる。
今の運用:「スキルを最新にして」で揃う世界
再設計後の sync-to-github スキル(v2.2)では、次の流れで3系統すべてに反映できるようになった。
push 方向(スキルを編集した PC で):git add → commit → push → 「スキルを保存」ボタンで claude.ai にも反映。pull 方向(別の PC で):「スキルを最新にして」と言うだけで、GitHubから最新版を取得してローカルに一括コピー。
明示的な方向指示がなければ、git の状態を自動判定して push か pull かを提案してくれる。
また、push 前には必ず「対象ファイルの先頭5行を確認」するステップが入るので、ファイル取り違えがあってもコミット前に検出できる。
完璧ではない。Anthropicがスキルの環境間同期を公式に実装してくれれば、このスキル自体が不要になる。
それまでの繋ぎとしての設計だ。しかし、「脆い経路を構造的に排除し、素直な方法でやる」という原則は、どんなツールを使うときにも通用する考え方だと思う。
この体験から得た教訓
丸一日のトラブルシューティングから得た教訓を、3つにまとめておきたい。
「自動化スキルの設計は、AI 自身の判断を左右する」
スキルに「この手順でやれ」と書くと、Claudeはその手順に忠実に従う。
たとえもっと良い方法(ローカルの git コマンド)があっても、スキルが指示していなければ視野に入らない。
スキルの設計は、AIの行動を構造的に制約する。
だからこそ「やるべきこと」だけでなく「やってはいけないこと」も明記する必要がある。
「認証情報は、チャットに一度でも貼った時点で『漏れた』と考える」
GitHubのトークンをチャットに貼ると、会話履歴に残る。
たとえセッションが終了しても、ログに残っている可能性がある。
安全フィルターで止められるのは、実は「助けてもらった」のだ。
認証情報はOSの資格情報マネージャーに保管して、チャットには一切表示しない設計にすべきだ。
「名前と実態を一致させる」
「sync」と名乗るなら、pushとpullの両方を実装する。片方向しかないのに「同期」と呼ぶと、ユーザー(この場合は自分自身)に誤った安心感を与える。
これはAIスキルに限らず、業務システムの命名でも同じことだ。
HABAねっとは、北陸を拠点に中小企業・個人事業主のDX伴走支援を行っています。AIツールの導入は「使い始めたら終わり」ではなく、使いながら育てていくものです。自社で育てた仕組みが壊れたとき、原因を突き止めて直す——その過程こそが、本当のDXだと私は考えています。