Claude Code 始めました
手足を勝手に増やすAIアシスタントを作った話

はじめに

Anthropicの規約変更で、サードパーティのハーネスからClaude系のサブスクOAuth利用がブロックされた。世の中はそこそこ騒いでいたが、正直なところ、俺にはあんまり関係のない話だった。

Claude Code CLIは手元にある。Discordに投げたメッセージをCLIに渡して、返事をDiscordに返す。それだけの橋を架ければいい。

だから作った。


骨組みだけ作った

作ったのはLogBot。Discord上のメッセージをClaude Code CLIに転送して、応答をDiscordに返す。それだけのBot。

Discord ──→ LogBot ──→ Claude Code CLI
              ↑                │
              └── 応答を投稿 ──┘

最低限の骨組みとして、こんな機能を持たせた。

  • セッション管理 — UUIDベースでClaude Codeのセッションを維持。VSCodeのセッションとは完全に分離される
  • メッセージキュー — Claudeが処理中にメッセージが来てもキューに溜めて順番に処理。取りこぼさない
  • 承認フロー — Claudeがファイルを編集しようとしたら、Discordに通知が飛んで、リアクション(✅ / ❌)で承認か拒否を返せる
  • MCPサーバーtools/ ディレクトリにファイルを置けば、Claude側からツールとして使える

ここで大事なのは、MCPツールは最初ゼロだったということ。天気もカレンダーも電車情報も、何もない。ただの骨組み。

でも、この骨組みには一つだけ強烈な特性がある。

Claudeはファイルを書ける。 つまり tools/ にJavaScriptファイルを追加できる。MCPサーバーは tools/ 配下を自動スキャンして登録する。

Claudeが自分で自分の手足を作れる。


「時計が欲しい」から始まった

最初にDiscordからClaudeに頼んだのは些細なことだった。

「今何時?」

Claude Code CLIはシステムの時刻を取れるが、MCPツールとして切り出されていたほうがスマートだ。Claudeに「時刻を返すMCPツールを作ってくれ」と頼んだ。

数秒で tools/current-time.js が生えた。

次は「天気が知りたい」。Open-Meteoという無料の天気APIを使った tools/weather.js が生えた。APIキーすら不要。

「Googleカレンダーの予定を見たい」。OAuth認証のヘルパーごと、tools/gcal-auth.jstools/gcal-list.js が生えた。

「Gmailも読みたい」。同じ要領で、認証・一覧・本文読み取り・送信・フィルタ・一括削除まで、Gmailツール群が一式生えた。

全部、Discordから「これ欲しい」と言っただけだ。自分はコードを一行も書いていない。


CRONが叩くのはコードじゃない

ツールが揃ってくると、次に欲しくなるのは定期実行だ。

「毎朝7時に天気と電車の運行情報と今日の予定を教えてほしい」

ここで普通なら、天気APIを叩いてカレンダーAPIを叩いて運行情報をスクレイピングして整形して送信する、というスクリプトを書いてCRONに登録する。

でもせっかくClaude使うんだから、コードじゃなくてプロンプト渡した方が面白い。

{
  "cron": "0 7 * * *",
  "prompt": "朝の定期報告をして。天気(さいたま市北区、今日)・電車の運行情報・今日のカレンダー予定を教えて。おはようの挨拶も添えてね。"
}

朝7時になると、スケジューラーがClaudeを起こす。Claudeは天気ツールを叩き、カレンダーツールを叩き、電車運行情報ツールを叩き、結果をまとめてDiscordに投稿する。

何のツールをどう組み合わせるかはClaudeが判断する。ロジックはコードに書かれていない。プロンプトに書かれている。

つまり、報告のフォーマットを変えたければプロンプトを書き換えるだけ。「明日の天気も追加して」と一言Discordに送るだけで、翌朝から変わる。


出発通知——これが本題

朝の報告は序の口だった。

「今日の予定に合わせて、出発する時間になったら教えてほしい」

この一言から、出発通知の仕組みが生まれた。

やりたいこと

「14時に新宿で打ち合わせ」という予定があったら、移動時間を逆算して、出発の30分前に天気と電車の運行情報付きで通知してほしい。

普通のリマインダーとの違い

Googleカレンダーの通知は「予定の30分前」に鳴る。でも移動時間は考慮してくれない。自宅から新宿まで1時間かかるなら、13時半の通知じゃ遅い。12時半に「そろそろ出ろ」と言ってほしい。

しかも出先にいたら計算が変わる。午前中に大宮で別の用事があって、そこから新宿に向かうなら、移動時間は短くなる。

Claudeがやっていること

CRONで毎時(6時〜22時)、Claudeにこういうプロンプトが飛ぶ。

カレンダーを確認して、場所のある予定について、出発通知が必要なら登録して。

Claudeはこの指示を受けて、自分で判断する。

  1. カレンダーを見る — 今後の予定を取得。場所が設定されている予定を探す
  2. 現在地を推定する — 今進行中のカレンダー予定があれば、その場所にいると推定。なければ自宅
  3. 移動時間を計算する — Google Maps APIで現在地から目的地までの移動時間を算出。2km以内なら徒歩、それ以上は電車。日本ではTransit APIが使えないので、車の所要時間+15分で近似している。泥臭いが意外と実用的だ
  4. 出発時刻を逆算する — 予定の開始時刻 - 移動時間 = 出発時刻
  5. 通知ジョブを登録する — 出発の30分前にワンショットジョブをスケジューラーに突っ込む

そして出発30分前になると、ジョブが発火してClaudeが起き、天気と電車の運行情報を取得して通知を組み立てる。

🚨 もうすぐ出発の時間だよ!
📅 打ち合わせ(14:00開始)
📍 目的地: 新宿
🚃 電車(推定): 約55分 → 12:35出発

☁️ 今日(月) 一部曇り
 🌡️ 22.3℃ / 14.1℃ ☔ 10%

🟢 現在、異常のある路線はありません!

ロジックはどこにあるか

ここが一番伝えたいところだ。

この一連の判断ロジックは、departure-check.js というMCPツールにまとまっている。でも、このツールを作ったのもClaudeだ。「出発前に通知してほしい」と言ったら、必要なツール(移動時間、現在地推定)がまだなかったので、それらを先に作り、最後にそれらを組み合わせる departure-check.js を作った。

そしてCRONが叩いているのは、相変わらずプロンプトだ。「カレンダーを確認して、出発通知が必要なら登録して」。この一文でClaudeがツールを駆使して判断する。

個々のパーツはシンプルだ。天気を取るツール、カレンダーを見るツール、移動時間を計算するツール、電車の運行情報を取るツール。でもそれをいつ、どう組み合わせるかはClaude側にある。コードにif文を並べたんじゃない。AIが状況を見て判断している。


自己拡張する環境

ここまでの話をまとめると、こういうことだ。

  • MCPツール = 手足。個別の能力(天気、カレンダー、移動時間、メール…)
  • Claude = 頭。ツールを組み合わせて判断する
  • CRON = 目覚まし。Claudeを定期的に起こす。叩くのはプロンプト
  • Discord = 窓口。リクエストも通知もここ

そして最大の特徴は、手足が足りなければClaudeがその場で作ること。

「こういう機能欲しい」とDiscordに送れば、Claudeがツールのコードを書いて tools/ に追加する。MCPサーバーが自動で検出して登録する。次の瞬間から使える。

逆に言えば、自分がやったのは骨組みを作っただけだ。Discord-CLI間の橋と、MCPの自動スキャンと、CRONスケジューラー。


おわりに

今は朝7時に天気と予定を教えてくれて、外出前に移動時間を逆算して運行情報付きで通知してくれて、メールの管理もしてくれる。もちろんツールの挙動を手直しした場面もあるが、基本はDiscordから「これ欲しい」と言って増えていった。

こんなAI初心者のアイデアで当たり前かもしれないけど、GitHubで公開しておきます

OpenCClaw — Discord経由でClaude Code CLIを操作するBotシステム。