Claude Codeでソーシャルメディアを自動化する
Claude CodeからTwitter/XとLinkedInへの投稿を自動化する:プラットフォーム別の下書き生成、直接API呼び出し、ブラウザMCPとの連携、スケジュール出力。
設定をやめて、構築を始めよう。
AIオーケストレーション付きSaaSビルダーテンプレート。
どのサイドプロジェクトも、会社のブログも、同じ壁にぶつかります。共有する価値のあるものを書いたのに、それをTwitter/X、LinkedIn、その他のプラットフォーム向けの投稿に変えるのは、元の文章を書くよりも時間がかかります。Claude Codeはその作業のほとんどを自動化できます。コンテンツ生成からAPIベースの投稿まで。
インストールして忘れられる魔法の「ソーシャルメディアMCP」は存在しません。機能するのは、Claude Codeの文章生成とブラウザ自動化MCP、直接API呼び出し、スケジュールツールへのエクスポートを組み合わせることです。実際に今日コピーできるコードとともに、それぞれのアプローチを解説します。
実際に機能すること(と機能しないこと)
現状を正直に話しましょう。MCPエコシステムは開発ツール、データベース、ファイルシステムには強いです。ソーシャルメディア?自分で構築してください。
今日できること:
- Claude Codeで直接プラットフォーム最適化されたコンテンツを生成する
- ブラウザ自動化MCP(Puppeteer/Playwright)でソーシャルプラットフォームを操作する
- プラットフォームAPIを叩くカスタムMCPサーバーを構築する
- Buffer、Typefully、Hootsuiteなどのスケジューラーにフォーマットされたコンテンツをエクスポートする
できないこと:
- 公式レジストリから既成の
social-media-mcpをインストールする - 自分で統合を書かずにすぐ使えるOAuthフローを手に入れる
それでも、以下のアプローチは専用ソーシャルMCPに求めるものの約90%をカバーします。トレードオフは、一度構築すれば最初から最後まで自分のものになるということです。
アプローチ1:コンテンツ生成ワークフロー
最もシンプルなパターンはMCPのセットアップが不要です。Claude Codeはすでにプラットフォームの慣習、文字数制限、エンゲージメントパターンを理解しています。
単発の投稿生成
claude "Write a Twitter thread (5 tweets) about why developers should use terminal-based AI tools instead of browser chat. Make the first tweet a hook, include one specific metric or example per tweet, and end with a call to action. Keep each tweet under 270 characters."
Claudeはプラットフォームのルールを自動的に処理します。本当の威力はバッチワークフローから来ます。
ブログをソーシャルに変換するパイプライン
これが多くのチームが求めるワークフローです。ブログ記事を公開した後、Claudeはすべてのソーシャルバリエーションを生成します:
claude "Read the blog post at apps/web/src/content/blog/guide/mechanics/claude-md-mastery.mdx and create:
1. A Twitter thread (5-7 tweets) highlighting the key insight about orchestration vs onboarding
2. A LinkedIn post (200-300 words) with a professional angle about team productivity
3. Three standalone tweets I can schedule throughout the week, each covering a different point from the post
Format each as a separate section with the platform name as header."なぜ汎用AIライティングより優れているか:Claudeは実際のソースファイルを読むので、ソーシャルコピーは公開済みの記事と一言一句一致します。コピペのずれも、記憶からの要約も起きません。
プラットフォーム固有の慣習
各プラットフォームには暗黙のルールがあります。Claudeはそれを明示すれば従います:
claude "Convert this release announcement into platform-specific posts:
Source: 'Claude Code v5.0 ships with Agent Teams - 18 specialized agents that coordinate on complex tasks, 5 lifecycle hooks, and team orchestration built in.'
For Twitter/X: Hook format, 1-2 hashtags max, conversational tone
For LinkedIn: Professional tone, tag the company, 3-4 paragraphs with line breaks
For Reddit r/programming: Technical focus, no marketing language, lead with what it does not what it is"アプローチ2:投稿のためのブラウザ自動化
実際に投稿する必要がある場合(下書きだけでなく)、Puppeteer MCPがClaudeに直接ブラウザのコントロールを与えます。人間と同じ方法でプラットフォームを使うため、API制限を完全に回避できます。
セットアップ
設定にPuppeteer MCPサーバーを追加します:
{
"mcpServers": {
"puppeteer": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-puppeteer"]
}
}
}ブラウザ経由で投稿する
接続が完了すると、Claudeは任意のソーシャルプラットフォームを開いて操作できます:
claude "Using Puppeteer, navigate to twitter.com, log in with the session already saved in Chrome, compose a new tweet with this text: 'Just shipped Agent Teams in Claude Code v5.0 - 18 agents that coordinate in real time. The future of coding is parallel, not sequential.', and post it."
ブラウザ自動化の注意点:
- すでにログインしている必要がある(または自動化で認証を処理する)
- プラットフォームは予告なくDOMを変更し、セレクタを壊す
- レート制限は依然として適用され、急速な自動投稿はアカウントにフラグが立つ可能性がある
- 二要素認証フローで複雑さが増す
- 散発的な投稿や少量のバッチには適しているが、大量のスケジューリングには向かない
ブラウザ自動化はClaudeにフルフローを処理させたい単発の投稿や少量のバッチで効果を発揮します。量が多い場合はAPIルートやスケジューラーエクスポート(後述)の方が効果的です。
アプローチ3:Twitter/X API用カスタムMCPサーバー
信頼性の高い繰り返し可能な投稿には、Twitter/X APIを直接呼び出すカスタムMCPサーバーを構築します。初期設定は多いですが、長期的に最も堅牢な選択肢です。
前提条件
APIアクセス付きのTwitter開発者アカウントが必要です。無料ティアは投稿に月1,500ツイートをカバーし、個人や小チームのほとんどのニーズに合います。twitter-api-v2 Node.jsパッケージも必要です。
MCPサーバーの構築
// src/twitter-mcp.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { TwitterApi } from "twitter-api-v2";
const client = new TwitterApi({
appKey: process.env.TWITTER_API_KEY!,
appSecret: process.env.TWITTER_API_SECRET!,
accessToken: process.env.TWITTER_ACCESS_TOKEN!,
accessSecret: process.env.TWITTER_ACCESS_SECRET!,
});
const server = new Server(
{ name: "twitter-poster", version: "1.0.0" },
{ capabilities: { tools: {} } },
);
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "post_tweet",
description: "Post a tweet to Twitter/X",
inputSchema: {
type: "object",
properties: {
text: {
type: "string",
description: "Tweet text (max 280 characters)",
},
},
required: ["text"],
},
},
{
name: "post_thread",
description: "Post a thread of connected tweets",
inputSchema: {
type: "object",
properties: {
tweets: {
type: "array",
items: { type: "string" },
description: "Array of tweet texts in thread order",
},
},
required: ["tweets"],
},
},
{
name: "get_my_tweets",
description: "Get your recent tweets for context",
inputSchema: {
type: "object",
properties: {
count: {
type: "number",
description: "Number of tweets to fetch (max 100)",
},
},
},
},
],
}));
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
try {
if (name === "post_tweet") {
const result = await client.v2.tweet(args.text);
return {
content: [
{
type: "text",
text: `Tweet posted successfully. ID: ${result.data.id}\nURL: https://twitter.com/i/status/${result.data.id}`,
},
],
};
}
if (name === "post_thread") {
const tweets = args.tweets as string[];
let lastTweetId: string | undefined;
const postedIds: string[] = [];
for (const tweetText of tweets) {
const result = lastTweetId
? await client.v2.tweet(tweetText, {
reply: { in_reply_to_tweet_id: lastTweetId },
})
: await client.v2.tweet(tweetText);
lastTweetId = result.data.id;
postedIds.push(result.data.id);
}
return {
content: [
{
type: "text",
text: `Thread posted (${postedIds.length} tweets).\nFirst tweet: https://twitter.com/i/status/${postedIds[0]}`,
},
],
};
}
if (name === "get_my_tweets") {
const count = Math.min(args.count || 10, 100);
const me = await client.v2.me();
const timeline = await client.v2.userTimeline(me.data.id, {
max_results: count,
"tweet.fields": ["created_at", "public_metrics"],
});
const tweetSummary = timeline.data.data
.map(
(t) =>
`[${t.created_at}] ${t.text.substring(0, 100)}... (${t.public_metrics?.like_count || 0} likes)`,
)
.join("\n");
return {
content: [{ type: "text", text: tweetSummary }],
};
}
} catch (error) {
return {
content: [
{
type: "text",
text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`,
},
],
isError: true,
};
}
});
const transport = new StdioServerTransport();
server.connect(transport);MCPサーバーの登録
Claude Codeの設定に接続します:
{
"mcpServers": {
"twitter": {
"command": "node",
"args": ["./dist/twitter-mcp.js"],
"env": {
"TWITTER_API_KEY": "your-api-key",
"TWITTER_API_SECRET": "your-api-secret",
"TWITTER_ACCESS_TOKEN": "your-access-token",
"TWITTER_ACCESS_SECRET": "your-access-secret"
}
}
}
}MCPサーバーの使い方
これでClaude Codeから直接ツイートを書いて投稿できます:
claude "Read my last 10 tweets to understand my voice and topics. Then write and post a tweet about the new context engineering techniques I covered in today's blog post. Match my usual tone."
またはスレッドを投稿する:
claude "Write a 5-tweet thread breaking down the key differences between CLAUDE.md as documentation vs as an operating system. Post it as a thread."
Claudeは最初にボイスマッチングのために get_my_tweets を呼び出し、コンテンツを下書きし、その後 post_tweet または post_thread を呼び出して公開します。
アプローチ4:スケジュールツールへのエクスポート
Buffer、Typefully、Hootsuite、または類似のツールを使っているチームには、Claude Codeが適切にフォーマットされたエクスポートを出力できます:
claude "Generate a week of social media content about Claude Code development tips. Format as CSV with columns: date, platform, content, hashtags. Use dates starting next Monday. Include 2 tweets and 1 LinkedIn post per day."
出力はほとんどのスケジューラーに直接インポートできるCSVです。APIキーもMCPセットアップも不要。すでにスケジュールツールを使っているチームには最も摩擦の少ない選択肢です。
Typefully(Twitterスレッドで人気)用には:
claude "Write 3 Twitter threads about agentic coding. Format each as a Typefully draft with tweets separated by blank lines, and add a scheduling note at the top of each."
APIアクセスの現実
カスタムソーシャルMCPの構築はプラットフォームAPIへのアクセスにかかっており、状況は一様ではありません:
| プラットフォーム | APIアクセス | コスト | 投稿サポート |
|---|---|---|---|
| Twitter/X | 開発者ポータル、段階制 | 無料〜100ドル以上/月 | あり(制限付き) |
| 承認済みアプリのみ | 無料(承認された場合) | 制限あり | |
| Bluesky | オープンAPI、承認不要 | 無料 | あり |
| Mastodon | インスタンスごとのオープンAPI | 無料 | あり |
| ビジネスAPIのみ | 無料(Metaデベロッパー) | 制限あり |
BlueskyとMastodonはAPIがオープンでドキュメントが充実しているため最も簡単なターゲットです。Twitter/Xは有料開発者ティアに入れば機能します。LinkedInはアプリ承認が厳しいため最も難しいです。
うまくいかないこと
時間を節約するために正直な失敗例をいくつか:
- 大量投稿のためのブラウザ自動化。 プラットフォームがUIを更新すると壊れます。散発的な使用には問題ないが、毎日のスケジューリングには向かない。
- 人間のチェックなしで投稿する完全自律型ソーシャルエージェント。 ソーシャルのミスは公開されて永続します。レビューステップは絶対に省かないこと。
- 1つのサーバーですべてのプラットフォームを処理しようとするクロスプラットフォームMCP。 1プラットフォームにつき1つ構築すること。認証とAPIのパターンが大きく異なる。
- ブラウザ自動化による画像投稿は不安定。ファイルアップロードダイアログはプラットフォームとOS環境によって動作が異なる。
まとめ:実際のワークフロー
実際に機能するワークフローを示します。上記のアプローチを組み合わせたものです:
ステップ1: ソースマテリアルからコンテンツを生成する
claude "Read my latest blog post and generate social content for all platforms"
ステップ2: レビューと編集(絶対に省いてはいけない人間のステップ)
ステップ3: 選んだ方法で投稿またはスケジュール
- カスタムMCP経由でTwitter/XにAPIで直接投稿する
- マルチプラットフォーム配信のためスケジュールツールにエクスポートする
- APIアクセスのないプラットフォームへの単発投稿にブラウザ自動化を使う
ステップ4: エンゲージメントを見てイテレートする
claude "Check my last 10 tweets. Which topics got the most engagement? Suggest 3 follow-up tweets based on what performed well."
次のステップ
Claude Codeでのソーシャルメディア自動化はDIYアドベンチャーです。コンテンツ生成(セットアップ不要)から始めて、スケジュールエクスポート(最小限のセットアップ)に移り、量が正当化されたらカスタムAPI統合に進みましょう。
関連ガイド:
- PlaywrightとPuppeteer MCPを使ったブラウザ自動化(フルブラウザコントロールのセットアップ)
- カスタムMCPサーバーの構築(MCP開発の完全ガイド)
- MCPの基本と設定(MCPサーバーが初めての場合)
- 人気MCPサーバー(探索する価値のある他の統合)
- Claude Codeでのコンテンツ作成(さらなるプロンプトテンプレート)
MCPエコシステムは毎週成長しています。公式MCPレジストリを時々確認してください。専用のソーシャルMCPが登場したとき、上記のカスタムサーバーパターンがその統合のヘッドスタートになります。
設定をやめて、構築を始めよう。
AIオーケストレーション付きSaaSビルダーテンプレート。