Social Media Automation with Claude Code
Automate social posts with Claude Code. Generate platform-specific content, build API integrations, and schedule output with code you own.
Every side project and company blog hits the same wall. You wrote something worth sharing, but turning it into platform-specific posts for Twitter/X, LinkedIn, and the rest takes longer than writing the original piece. Claude Code can automate most of that work, from content generation all the way to API-based posting.
There is no magic "social media MCP" you install and forget. That does not exist. What works is pairing Claude Code's writing with browser automation MCPs, direct API calls, and scheduling tool exports. Here is what each approach looks like in practice, with code you can copy today.
What Actually Works (and What Does Not)
Let's be honest about the current state. The MCP ecosystem is strong for developer tools, databases, and file systems. Social media? Build it yourself.
What you can do today:
- Generate platform-optimized content with Claude Code directly
- Use browser automation MCPs (Puppeteer/Playwright) to drive social platforms
- Build custom MCP servers that hit platform APIs
- Export formatted content to schedulers like Buffer, Typefully, or Hootsuite
What you cannot do:
- Install a pre-built
social-media-mcpfrom the official registry - Get turnkey OAuth flows without writing the integration yourself
Even so, the approaches below cover about 90% of what you would want from a dedicated social MCP. The tradeoff is that you build it once and own it end to end.
Approach 1: Content Generation Workflows
The simplest pattern needs zero MCP setup. Claude Code already knows platform conventions, character limits, and engagement patterns.
Single Post Generation
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 handles the platform rules automatically. The real lift comes from batch workflows.
Blog-to-Social Pipeline
This is the workflow most teams reach for. Once a blog post ships, Claude spins up all the social variants:
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."Why this beats generic AI writing: Claude reads your actual source file, so the social copy matches the published article word for word. No copy-paste drift, no summarizing from memory.
Platform-Specific Conventions
Each platform has unwritten rules. Claude follows them once you spell them out:
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"Approach 2: Browser Automation for Posting
When you need to actually post (not just draft), Puppeteer MCP gives Claude direct browser control. That sidesteps API restrictions entirely because you are using the platforms the same way a person would.
Setup
Drop the Puppeteer MCP server into your config:
{
"mcpServers": {
"puppeteer": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-puppeteer"]
}
}
}Posting Through the Browser
Once it is wired up, Claude can open any social platform and work it:
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."
Caveats with browser automation:
- You have to be logged in already (or handle auth in the automation)
- Platforms change their DOM without warning, breaking selectors
- Rate limits still apply, and rapid automated posting can flag your account
- Two-factor auth flows add complexity
- Good for occasional posting, not high-volume scheduling
Browser automation shines on one-off posts or small batches where you want Claude to handle the full flow. For volume, the API route or scheduler export (below) works better.
Approach 3: Custom MCP Server for Twitter/X API
For reliable, repeatable posting, build a custom MCP server that calls the Twitter/X API directly. More setup up front, but the most solid long-term option.
Prerequisites
You need a Twitter Developer account with API access. The free tier covers 1,500 tweets/month for posting, which fits most individual and small-team needs. You also need the twitter-api-v2 Node.js package.
Building the MCP Server
// 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);Register the MCP Server
Wire it into your Claude Code config:
{
"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"
}
}
}
}Using the MCP Server
Now you can write and ship tweets right from 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."
Or post a thread:
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 calls get_my_tweets first for voice matching, drafts the content, then calls post_tweet or post_thread to publish.
Approach 4: Export to Scheduling Tools
For teams on Buffer, Typefully, Hootsuite, or similar, Claude Code can emit properly formatted exports:
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."
The output is a CSV you can import straight into most schedulers. No API keys, no MCP setup. Lowest-friction option for teams already on a scheduling tool.
For Typefully specifically (popular for Twitter threads):
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 Access Reality Check
Building custom social MCPs hinges on platform API access, and the landscape is uneven:
| Platform | API Access | Cost | Posting Support |
|---|---|---|---|
| Twitter/X | Developer portal, tiered | Free to $100+/mo | Yes, with limits |
| Restricted to approved apps | Free (if approved) | Limited | |
| Bluesky | Open API, no approval needed | Free | Yes |
| Mastodon | Open API per instance | Free | Yes |
| Business API only | Free (Meta dev) | Limited |
Bluesky and Mastodon are the easiest targets because their APIs are open and well documented. Twitter/X works once you are on a paid developer tier. LinkedIn is the hardest due to restrictive app approval.
What Does Not Work Well
A few honest misses to save you time:
- Browser automation for high-volume posting. Breaks when platforms ship UI updates. Fine for occasional use, not daily scheduling.
- Fully autonomous social agents that post without a human check. Social mistakes are public and permanent. Keep a review step.
- Cross-platform MCPs that try to handle every platform in one server. Build one per platform; the auth and API patterns differ too much.
- Image posting through browser automation is fragile. File upload dialogs behave differently across platforms and OS environments.
Putting It Together: A Real Workflow
Here is the workflow that holds up in practice, combining the approaches above:
Step 1: Generate content from your source material
claude "Read my latest blog post and generate social content for all platforms"
Step 2: Review and edit (the human step you should never skip)
Step 3: Post or schedule using your chosen method
- Direct API posting via custom MCP for Twitter/X
- Export to a scheduling tool for multi-platform distribution
- Browser automation for one-off posts on platforms without API access
Step 4: Watch engagement and iterate
claude "Check my last 10 tweets. Which topics got the most engagement? Suggest 3 follow-up tweets based on what performed well."
Next Steps
Social media automation with Claude Code is a build-your-own-adventure. Start with content generation (zero setup), move to scheduling exports (minimal setup), and graduate to custom API integrations once the volume justifies it.
Related guides:
- Browser automation with Playwright and Puppeteer MCPs for the full browser control setup
- Building custom MCP servers for the complete MCP development guide
- MCP basics and configuration if you are new to MCP servers
- Popular MCP servers for other integrations worth exploring
- Content creation with Claude Code for more prompt templates
The MCP ecosystem grows weekly. Check the official MCP registry from time to time. When a dedicated social MCP does ship, the custom server patterns above give you a head start on integrating it.
Stop configuring. Start building.
Browser Automation MCP for Claude Code
Wire Playwright or Puppeteer into Claude Code over MCP and drive real browsers with plain-language requests instead of selector scripts.
Build Your Own MCP Server for Claude Code
A working MCP server in Node.js. Tool definitions, handlers, REST and database patterns, and the config Claude Code needs to load it.