AIエージェント自作記|Mac mini × Claude Agent SDKで「朝起きたら仕事が終わってる」仕組みを作った話

  • 2026年2月25日
  • 2026年2月25日
  • AI
AI

「AIで仕事を自動化したい」。エンジニアなら誰でも一度は考えたことがあるはずです。僕はそれを本気でやってみました。Mac mini M4 Pro を24時間稼働させて、毎朝ニュースを収集し、ブログ記事を生成し、SNSに投稿案を出し、連絡先を管理し、プロジェクトの状態を可視化します。全部AIがやります。人間がやることは「朝起きてDiscordの通知を見て、承認ボタンを押すだけ」。この記事では、そのシステム「masu-agent」を1から自作した過程を、コードとアーキテクチャの実物を見せながら解説します。

この記事を読んでほしい人

  • AIエージェントを自分で組んでみたいエンジニア
  • Claude Agent SDKに興味がある人
  • 「自動化」と言いつつ結局手動になりがちな人

僕は福祉事業のCTOをしながら、フリーランスと個人事業を掛け持ちしています。Claude Codeでの開発が日常になっている中で、「待ってる間に別のClaude Codeが仕事を進めてくれたら最高じゃないか」と思ったのが全ての始まりでした。

なぜ自作したのか — SaaSを使わない理由

世の中にはAIエージェントのSaaSが山ほどあります。Dify、n8n、Zapier AI Actionsなどなど。でも、僕がほしかったのは「自分のMacの中で完結するシステム」でした。理由は3つです。

  1. ローカルDBへの自由なアクセス。SQLiteにプロジェクト情報、連絡先、アイデア、ナレッジを全部入れて、Claude に直接読み書きさせたかったんです。SaaSだとAPIの壁があります
  2. 既に払っているサブスクを最大限活用。Claude MAXは月$200で使い放題。追加のAPI課金はゼロ。寝ている間も動かさないともったいない。SaaSのAIエージェントは従量課金でコストが見えません
  3. 自分の仕事に最適化したい。ニュース収集、ブログ生成、連絡先管理、プロジェクト追跡。どれも微妙に既存SaaSと噛み合いません。自作なら100%自分仕様にできます

Mac miniをAIエージェントの母艦にするセットアップ手順は別記事にまとめていますので、ハードウェア選定から始めたい人はそちらを参照してください。

アーキテクチャ全体像 — 3層構造で回す

masu-agentは、npm workspacesのモノレポ構成で、5つのアプリと4つの共通パッケージからなります。TypeScript約40,000行、161ファイルです。

graph TD subgraph "インターフェース層" Discord["Discord Bot
人間との対話窓口"] Dashboard["Dashboard UI
React + Vite"] end subgraph "エージェント層" Orchestrator["Orchestrator
31個のcronジョブ"] AgentCore["Agent Core
Claude CLI ラッパー"] end subgraph "データ層" SQLite["SQLite
masu-agent.db"] MCP["MCP DB Server
67個のDBツール"] DashAPI["Dashboard API
Express / 21ルート"] end Discord -->|メッセージ| AgentCore Orchestrator -->|スケジュール実行| AgentCore AgentCore -->|claude CLI -p| Claude["Claude MAX
$200/月"] AgentCore -->|セッション保存| SQLite Claude -->|MCP ツール| MCP MCP -->|CRUD| SQLite DashAPI -->|読み書き| SQLite Dashboard -->|REST API| DashAPI style Discord fill:#5865F2,color:#fff style Claude fill:#D97706,color:#fff style SQLite fill:#0284C7,color:#fff

Claude CLIを子プロセスとして呼び出すというアプローチです。Claude Agent SDK(@anthropic-ai/claude-code)が提供する claude -p --output-format json を使って、プログラムからClaude Codeを非対話モードで呼び出します。返ってくるJSON にセッションID、コスト、ツールコール数が含まれるので、それをSQLiteに保存しています。

Discord Bot — 人間とAIの唯一の接点

日常的に使うのはDiscordだけです。スマホからでもPCからでも、メンションすればClaude が答えてくれます。

ユーザー: @masu-agent 今週のAIニュースまとめて
Bot: 🤔 考え中...
Bot: [スレッドで回答します]

特徴的な設計が3つあります。

1. 書き込み意図の自動検出。「作成して」「削除して」のような書き込み意図を正規表現で検出し、ボタンで承認を求めます。読み取りだけなら即実行。セキュリティとUXのバランスを取りました。

2. チャンネル別の専用エージェント。コネクト(連絡先管理)チャンネルでは、メンション不要で名刺の画像を投げるだけで自動解析・DB登録します。プロフィールチャンネルでは、雑談からプロフィール情報を抽出して承認フローに回します。

3. セッション継続。Discordのスレッド = Claudeのセッション。スレッド内で会話すると --resume オプションでコンテキストが引き継がれます。「さっきの件だけど」が通じる仕組みです。

Orchestrator — 31個のcronジョブが勝手に動く

「朝起きたら仕事が終わってる」の正体がOrchestratorです。node-cron ベースで31個のジョブが登録されています。

時刻 ジョブ やること
04:30 デイリータスク生成 テンプレートから当日のタスクを自動生成
05:00 テーマ選定 GA4のPVデータ + ナレッジからブログテーマを選ぶ
06:00 記事生成 BlogPipeline(リサーチ→執筆→レビュー→修正)で本文生成
06:50 プロジェクトスキャン ~/DevelopをスキャンしてDB同期
07:00 承認リクエスト 生成記事をWordPress下書き + Discordに通知
08:00 ニュース収集 Web検索でAI/LLMニュースを5件収集
08:30 朝の配信 Discordにニュース + パーソナライズ分析を投稿
12:00/18:00/21:00 ティップス生成 X(Twitter)投稿案を生成してDiscordで承認待ち
毎週月水金 ナレッジ収集 Claude Tips / 開発トレンド / ビジネスアイデア
深夜帯 自律エージェント群 市場モニター / コード監視 / 依存関係チェック / リンクヘルス
Catchupレジストリの仕組み
特に面白いのがCatchupレジストリです。Mac miniが再起動やスリープから復帰したとき、実行されなかったジョブを検知して遅延実行します。朝5時に電源が落ちていても、7時に復帰すれば5時と6時のジョブが順番に走ります。
// 起動5秒後に取りこぼしチェック
setTimeout(async () => {
  await registry.runMissedJobs(agentCore);
}, 5000);

Dashboard — SQLiteの中身を可視化する

Express + React(Vite)のSPAです。21個のAPIルート、13のUI画面で構成されています。

主な画面:

  • 概要 — 今日のデリバラブル(カンバン)、サービス稼働状態、コスト統計
  • セッション — Claude実行履歴(エージェント名、コスト、ツールコール数)
  • ナレッジ — 収集した情報の一覧(AIニュース、Tips、トレンド等)
  • プロジェクト — ~/Developのフォルダツリーと連動したプロジェクト管理
  • コンタクト — 連絡先 + やりとり履歴のCRM
  • コンテンツ — ブログ記事・ツイートのパイプライン管理

デザインは glassmorphism + ブランドブルー(#39b7ff)。DotGothic16フォントでRPG風の見た目にしています。tmuxのセッション管理画面でウィンドウごとの稼働状況も確認できます。

認証はシンプルに、同一オリジンからのリクエストは認証スキップ。外部からは x-api-key ヘッダーが必要です。Tailscale VPN 経由でアクセスするので、インターネットに直接公開はしていません。

Agent Core — Claude CLIをラップする心臓部

Agent Coreはシステムの心臓部です。やっていることは単純で、Claude CLIを child_process.spawn で呼び出してJSONをパースするだけです。

const proc = spawn('claude', [
  '-p',                         // print mode(非対話)
  '--output-format', 'json',    // JSON出力
  '--allowedTools', tools.join(','),
  '--system-prompt', systemPrompt,
], {
  cwd: workingDirectory,
  stdio: ['pipe', 'pipe', 'pipe'],
});

// プロンプトをstdinで送信
proc.stdin.write(prompt);
proc.stdin.end();

返ってくるJSONには session_idtotal_cost_usdnum_turns が含まれます。これをSQLiteに保存して、ダッシュボードでコスト推移を追跡しています。

サブエージェントの実装
サブエージェントの実装もシンプルです。allowedTools を絞るだけで、権限分離されたエージェントになります。
// 読み取り専用エージェント
await agentCore.executeQuery(prompt, {
  name: 'ai-news-collector',
  allowedTools: ['WebSearch', 'WebFetch', 'Read'],
});

// DB書き込み可能エージェント
await agentCore.executeQuery(prompt, {
  name: 'contacts-agent',
  allowedTools: [...CONTACTS_TOOLS], // 8個の限定ツール
});

Claude Codeの生産性についての記事で書きましたが、Claude Code自体がすでに強力なエージェントです。それをプログラムから呼び出せる Agent SDK の登場で、「Claude Codeを裏で走らせる」が現実的になりました。

MCP DB Server — Claudeが直接DBを読み書きする

Model Context Protocol(MCP)は、Claudeに外部ツールを提供する仕組みです。masu-agentでは自作のMCP DBサーバーが67個のツールを公開しています。

読み取りツール34個(get_goal, list_projects, export_profile_markdown など)と、書き込みツール33個(create_contact, update_deliverable, delete_idea など)。Claudeは会話の中で自然にこれらを呼び出します。

ユーザー: 今のプロジェクト一覧を見せて
Claude: [mcp__masu_db__list_projects を実行]
        現在登録されているプロジェクトは12件です...

技術スタックは @modelcontextprotocol/sdk v1です。Zodスキーマで入力バリデーションし、stdioトランスポートでClaude CLIの子プロセスとして動きます。

Discord Botでは、MCPツールの読み取り/書き込みを分離して SAFE_TOOLS(確認不要)と ALL_TOOLS(ボタン確認必要)に分けています。ユーザーが「削除して」と言ったときだけ承認ボタンが出る、という設計です。

Content Machine — 記事生成からSNS投稿まで自動化

Content Machineは packages/content-machine/ に実装した、コンテンツ自動生成パイプラインです。

graph LR A["05:00
テーマ選定"] --> B["06:00
記事生成"] B --> C["07:00
WP下書き
Discord通知"] C --> D["人間が承認"] D --> E["自動公開
サムネ生成付き"] F["12:00/18:00/21:00
ティップス生成"] --> G["Discord通知"] G --> H["人間が承認"] H --> I["X投稿"]

BlogPipelineの4ステップ
BlogPipelineは4ステップです。Research Agent がWeb検索とナレッジDBから素材を集め、Writer Agent が記事本文を生成し、Review Agent がスコアリングし、基準に満たなければ Revision Agent が修正します。GA4のPVデータもテーマ選定にフィードバックしています。

TweetGeneratorはティップス型のツイートを生成します。過去20件のツイートと重複しないように制御し、レートリミット(1日30件・1時間4件・15分間隔)も実装済みです。

WordPress投稿、サムネイル自動生成(Gemini API)、X(Twitter)投稿、Threads投稿まで、承認ボタン1つで全部走ります。バイブコーディングの記事も、このパイプラインで下書きを生成しています。

運用の実態 — 電気代・メモリ・稼働率のリアル

3週間運用した結果をまとめます。

項目 数値
Mac mini M4 Pro 24GB RAM / 512GB SSD
アイドル消費電力 5〜7W(実測)
月間電気代 約500〜800円
Claude MAXサブスク $200/月(約30,000円)
追加API課金 0円
SQLite DBサイズ 約50MB
TypeScriptコード 約40,000行 / 161ファイル
cronジョブ数 31個
MCP DBツール数 67個
Dashboard APIルート 21個
常駐プロセス 3個(Bot / Dashboard / Orchestrator)

launchdで自動起動を設定してあるので、Mac miniが再起動しても tmuxセッションが自動で立ち上がり、3つのプロセスが走り始めます。Tailscale VPN で外出先からもアクセスできます。

メモリは24GBのうち、3つの常駐プロセス合計で約2〜3GB程度です。Claude CLIの子プロセスが立ち上がる瞬間に一時的に増えますが、終了後すぐに解放されます。

コスト比較 — VPSより安い自宅サーバー

AIエージェントを24時間動かすとして、コスト比較してみます。

方式 月額コスト
masu-agent方式(Mac mini自宅) 電気代 500〜800円 + Claude MAX $200
VPS + API課金方式 VPS 2,000〜5,000円 + Claude API 従量課金
SaaS方式(Dify等) プラン月額 + LLM API従量課金
Claude MAXの$200は固定費ですが、API従量課金だと1日31ジョブ × 30日 = 月900回以上のClaude呼び出しが走ります。Sonnet 4で1回あたり$0.05〜0.50だとすると、$45〜$450/月。MAXの方が予測可能で安いです。

Mac mini M4 Proのアイドル消費電力5〜7Wは、一般的なVPSのvCPU分よりも実質安いです。そして性能は圧倒的に上。Apple Siliconの24GBユニファイドメモリは、ローカルLLM推論を将来的に追加するときにも使えます。中国発OSSモデルのコスト革命で紹介したような軽量モデルなら、Mac mini上でも動きます。

手動運用に固執した人が直面する壁

「手動でも回るから、まだいいか」。そう思い続けると、こうなります。

  • 毎朝30分のニュースチェックが年間180時間になります。時給3,000円なら54万円分の時間が消えます
  • ブログの更新頻度が落ちて、SEO流入が減り続けます。月1万PVの差が年間のアフィリエイト収入に直接響きます
  • 連絡先の管理が雑になって、名刺交換した人の情報が埋もれます。フォローアップのタイミングを逃します
  • プロジェクトの状態が頭の中にしかなくて、「あれどうなってたっけ」が増えます
自動化の本質
自動化の本質は「やらなくていいことを人間から取り除く」ことです。AIエージェントは「やれることを増やす」のではなく、「やらなくていいことを自動で処理する」ためにあります。

この記事を書いている理由

僕自身、最初は「Claude Agent SDKってどこまで実用的なんだろう」と半信半疑でした。ドキュメントを読んでも、チュートリアルのToDoアプリレベルでは実運用の感触がわかりません。

だから実際に作りました。3週間かけて、40,000行のTypeScriptを書いて、31個のcronジョブを設定して、67個のMCPツールを定義しました。結果として、毎朝Discordを開くだけで「今日のニュース」「新しい記事の下書き」「ツイート案」が並んでいる生活になりました。

完璧ではありません。たまにClaude がJSON以外のテキストを返してパースに失敗するし、WebSearchの結果が古い記事ばかりのこともあります。でも、80%の精度で自動化されているだけで、人間がやるべき仕事の量は劇的に減ります。

もしあなたがエンジニアで、Claude Code を日常的に使っているなら、Agent SDKでの自動化は自然な次のステップだと思います。まずは1つのcronジョブ、1つのMCPツールから始めてみてください。「朝起きたら仕事が終わってる」感覚は、一度体験するともう戻れなくなります。


この記事が参考になったら、Xでシェアしてもらえるとうれしいです。この記事の裏話・開発体験談は note でも書いています。質問や相談は、X(@mamamasu_3)のDMでお気軽にどうぞ。