「AIで仕事を自動化したい」。エンジニアなら誰でも一度は考えたことがあるはずです。僕はそれを本気でやってみました。Mac mini M4 Pro を24時間稼働させて、毎朝ニュースを収集し、ブログ記事を生成し、SNSに投稿案を出し、連絡先を管理し、プロジェクトの状態を可視化します。全部AIがやります。人間がやることは「朝起きてDiscordの通知を見て、承認ボタンを押すだけ」。この記事では、そのシステム「masu-agent」を1から自作した過程を、コードとアーキテクチャの実物を見せながら解説します。
- AIエージェントを自分で組んでみたいエンジニア
- Claude Agent SDKに興味がある人
- 「自動化」と言いつつ結局手動になりがちな人
僕は福祉事業のCTOをしながら、フリーランスと個人事業を掛け持ちしています。Claude Codeでの開発が日常になっている中で、「待ってる間に別のClaude Codeが仕事を進めてくれたら最高じゃないか」と思ったのが全ての始まりでした。
- 1 なぜ自作したのか — SaaSを使わない理由
- 2 アーキテクチャ全体像 — 3層構造で回す
- 3 Discord Bot — 人間とAIの唯一の接点
- 4 Orchestrator — 31個のcronジョブが勝手に動く
- 5 Dashboard — SQLiteの中身を可視化する
- 6 Agent Core — Claude CLIをラップする心臓部
- 7 MCP DB Server — Claudeが直接DBを読み書きする
- 8 Content Machine — 記事生成からSNS投稿まで自動化
- 9 運用の実態 — 電気代・メモリ・稼働率のリアル
- 10 コスト比較 — VPSより安い自宅サーバー
- 11 手動運用に固執した人が直面する壁
- 12 この記事を書いている理由
なぜ自作したのか — SaaSを使わない理由
世の中にはAIエージェントのSaaSが山ほどあります。Dify、n8n、Zapier AI Actionsなどなど。でも、僕がほしかったのは「自分のMacの中で完結するシステム」でした。理由は3つです。
- ローカルDBへの自由なアクセス。SQLiteにプロジェクト情報、連絡先、アイデア、ナレッジを全部入れて、Claude に直接読み書きさせたかったんです。SaaSだとAPIの壁があります
- 既に払っているサブスクを最大限活用。Claude MAXは月$200で使い放題。追加のAPI課金はゼロ。寝ている間も動かさないともったいない。SaaSのAIエージェントは従量課金でコストが見えません
- 自分の仕事に最適化したい。ニュース収集、ブログ生成、連絡先管理、プロジェクト追跡。どれも微妙に既存SaaSと噛み合いません。自作なら100%自分仕様にできます
Mac miniをAIエージェントの母艦にするセットアップ手順は別記事にまとめていますので、ハードウェア選定から始めたい人はそちらを参照してください。
アーキテクチャ全体像 — 3層構造で回す
masu-agentは、npm workspacesのモノレポ構成で、5つのアプリと4つの共通パッケージからなります。TypeScript約40,000行、161ファイルです。
人間との対話窓口"] 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
@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レジストリです。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_id、total_cost_usd、num_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/ に実装した、コンテンツ自動生成パイプラインです。
テーマ選定"] --> 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ステップです。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従量課金 |
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でお気軽にどうぞ。