Claude Code で 6+1 プラットフォームのメディア運営パイプラインを構築する
個人開発で複数の SaaS を運用していると避けて通れないのが「発信の継続」です。X、Note、Threads、Instagram、Zenn、Qiita、Substack。読者層が異なるためどれも捨てがたく、しかし平日に確保できる時間は 1-2 時間しかありません。CreoLab は、この制約を Claude Code を中心に据えたパイプライン化で解こうと考えました。本記事では、追加コスト $0/月で 6+1 プラットフォームを本格運用するための設計と、実装の核を共有します。
1. 制約と方針
CreoLab が置いた制約は 3 点です。
- 追加コストは $0/月(Claude Code の月額プラン内で完結)
- 自動化レベルは L2(下書きまで自動、人間が 30 分のレビュー)
- ブランドの一貫性(フォーマル文体、中立 + 強い意見)を全プラットフォームで揃える
「全自動」を目指す代わりに「下書き完成までの 90 分を圧縮する」ことに集中する設計です。
2. アーキテクチャ
毎朝 6:00 に schedule スキル(または OS の cron)で起動し、以下 8 フェーズを直列・並列で実行します。
Phase 1 リサーチ (WebSearch + GitHub MCP)
↓
Phase 2 ネタ選定 (5 本候補 → Discord topics 通知)
↓
Phase 3 マスターコンテンツ生成 (1500-2500 字)
↓
Phase 4 プラットフォーム別リパッケージ (並列 6 Agent)
↓
Phase 5 下書き保存 (Qiita / Buffer / GitHub / Discord drafts 通知)
↓
Phase 6 人間レビュー (30 分以内)
↓
Phase 7 投稿 (08:00 / 12:00 / 18:00 / 21:00 / 22:00)
↓
Phase 8 ログ記録・分析 (週次・月次レポート)
中核は Claude Code のカスタムエージェントです。agents/*.md に役割と制約を Markdown で書き、フェーズごとに呼び分けます。
---
name: master-writer
description: 選ばれたネタから 1500-2500 字のマスターを生成
tools: Read, Write
model: claude-sonnet-4-6
---
マスター記事までは Sonnet 4.6 で品質を担保し、リパッケージは Haiku 4.5 で速度と費用を両立させます。
3. 連携スクリプトの最小実装
API 連携は TypeScript (ESM) + tsx で実装し、依存は axios / dotenv / zod の 3 つに絞りました。共通の lib/env.ts で zod 検証、lib/discord.ts で 5 チャンネル通知を提供します。
// scripts/lib/env.ts
import 'dotenv/config';
import { z } from 'zod';
const EnvSchema = z.object({
QIITA_API_TOKEN: z.string().optional(),
DISCORD_WEBHOOK_ERRORS: z.string().url().optional(),
// ...
});
export const env = EnvSchema.parse(process.env);
export function requireEnv<K extends keyof typeof env>(...keys: K[]) {
const missing = keys.filter((k) => !env[k]);
if (missing.length) throw new Error(`Missing: ${missing.join(', ')}`);
return env as { [P in K]: NonNullable<(typeof env)[P]> };
}
Qiita 投稿は API v2 を直接叩きます。本記事自体、この post-to-qiita.ts で private: true(限定共有)として作成されています。
const res = await fetch('https://qiita.com/api/v2/items', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${QIITA_API_TOKEN}`,
},
body: JSON.stringify({
title, body, tags, private: true, tweet: false, coediting: false,
}),
});
4. プラットフォーム別の境界の引き方
各プラットフォームには文字数・タグ・自動化可能範囲がそれぞれあります。
| プラットフォーム | 投稿方式 | 自動化レベル |
|---|---|---|
| Qiita | API v2 (private: true → レビュー → publish) |
全自動 (公開フラグのみ手動) |
| Zenn | GitHub 連携 (published: false で下書き保持) |
全自動 |
| X / Threads | Buffer 無料版キュー (10 件まで) | 全自動 (事前承認後) |
| Threads ネイティブミラー | 全自動 | |
| Note / Substack | API なし、手動コピペ | 手動 (規約 BAN リスク回避) |
CreoLab の見解として、無理に「全自動」を追わないこの境界の引き方こそ、個人運用の現実解だと考えます。
5. 失敗の吸収
複数 API を叩く以上、必ずどれかは失敗します。本パイプラインはエラーハンドリングを 3 階層で構成しました。
-
スクリプト層: Discord webhook
#errorsへ自動通知、部分失敗でも成功分は確定 - エージェント層: 出力ファイル存在チェック・文字数バリデーション
-
運用層:
STATUS.mdにフェーズ別ブロッカーを記録、翌朝のリトライ判断を簡単化
notifyError は通知自体が失敗してもオリジナルエラーは throw する設計です。
export async function notifyError(scriptName: string, err: unknown) {
const message = err instanceof Error ? err.message : String(err);
try {
await sendDiscord('errors', { embeds: [{ title: `❌ ${scriptName} failed`, /* ... */ }] });
console.error(`[discord] error notification sent to #errors (${scriptName})`);
} catch (notifyErr) {
console.error('Failed to send error notification:', notifyErr);
}
}
6. CodeMap との接続
このプロジェクト自体が、巨大化していくコンテンツリポジトリの可視化を必要とします。8 フェーズの実行履歴、9 つのカスタムエージェント、5 つの連携スクリプト、6+1 プラットフォームごとの下書き・投稿実績。これらの関係を見渡すには、コードベース可視化ツール CodeMap が役に立ちます。本パイプラインの拡張過程は、そのまま CodeMap のユースケース事例になる予定です。
おわりに
「平日 1-2 時間 × 追加コスト $0/月」という制約は、自動化の手抜きではなく、設計の論理を磨くための負荷です。L2 自動化と Claude Code のカスタムエージェント設計を組み合わせれば、6+1 プラットフォーム運用は十分に成立すると CreoLab は考えます。
関連プロダクト
巨大化していくコードベースやコンテンツ群を構造化して捉えたい方は、CodeMap をぜひお試しください: https://codemap.creolab.dev/
参考
- 本記事は CreoLab のメディア運営パイプライン本実装プロジェクトの設計書を基にしています
- Claude Code 公式: https://claude.com/claude-code
- Qiita API v2 公式: https://qiita.com/api/v2/docs
- Buffer API 公式: https://buffer.com/developers/api
- Zenn GitHub 連携: https://zenn.dev/zenn/articles/connect-to-github