Code Kit v5.0 released for CC's new Agent Teams feature.
Claude FastClaude Fast
MCP & Extensions

Social Media Automation with Claude Code: Content, Scheduling, and API Integration

Automate social media workflows with Claude Code. Generate platform-specific content, build API integrations, and schedule posts using real code examples.

Stop configuring. Start shipping.Everything you're reading about and more..
Agentic Orchestration Kit for Claude Code.

Every developer who runs a side project or company blog hits the same wall: you've written something worth sharing, but turning it into platform-specific social posts across Twitter/X, LinkedIn, and others takes longer than writing the original content. Claude Code can automate most of this workflow, from content generation through API-based posting.

This isn't about a magic "social media MCP" you install and forget. That doesn't exist. What works is combining Claude Code's content generation with browser automation MCPs, direct API integrations, and scheduling tool exports. Here's how each approach works in practice, with code you can use today.

What Actually Works (and What Doesn't)

Let's be honest about the current state. The MCP ecosystem is strong for developer tools, databases, and file systems. Social media? It's a build-it-yourself situation.

What you can do right now:

  • Generate platform-optimized content with Claude Code directly
  • Use browser automation MCPs (Puppeteer/Playwright) to interact with social platforms
  • Build custom MCP servers that call platform APIs
  • Export formatted content for scheduling tools like Buffer, Typefully, or Hootsuite

What you can't do:

  • Install a pre-built social-media-mcp from the official registry
  • Get turnkey OAuth flows without building the integration yourself

That said, the approaches below cover 90% of what you'd want from a dedicated social MCP. The difference is you build it once and own it completely.

Approach 1: Content Generation Workflows

The simplest and most immediately useful pattern requires zero MCP setup. Claude Code already understands 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 constraints automatically. But the real power comes from batch workflows.

Blog-to-Social Pipeline

This is the workflow I use most. After publishing a blog post, Claude generates 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."

What makes this better than generic AI writing: Claude reads your actual source file, so the social content matches your published article exactly. No copy-paste drift, no summarizing from memory.

Platform-Specific Conventions

Each platform has unwritten rules that Claude handles when you're explicit about them:

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 content (not just generate it), Puppeteer MCP gives Claude direct browser control. This sidesteps API restrictions entirely since you're using the platforms through a browser, just like a human would.

Setup

Add the Puppeteer MCP server to your configuration:

{
  "mcpServers": {
    "puppeteer": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-puppeteer"]
    }
  }
}

Posting Through the Browser

Once configured, Claude can navigate to any social platform and interact with 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."

Important caveats with browser automation:

  • You need to be logged in already (or handle auth in the automation)
  • Platforms change their DOM structure without warning, breaking selectors
  • Rate limits still apply, and rapid automated posting can flag your account
  • Two-factor auth flows add complexity
  • This approach works for occasional posting, not high-volume scheduling

Browser automation is best for one-off posts or small batches where you want Claude to handle the entire flow. For volume posting, the API approach or scheduling tool export (covered 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. This is more setup upfront, but it's the most robust approach for ongoing automation.

Prerequisites

You'll need a Twitter Developer account with API access. The free tier supports 1,500 tweets/month for posting, which covers most individual and small-team needs. You'll 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

Add it to your Claude Code configuration:

{
  "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 compose and post directly 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 the get_my_tweets tool first for voice matching, drafts the content, then calls post_tweet or post_thread to publish.

Approach 4: Export to Scheduling Tools

For teams that use Buffer, Typefully, Hootsuite, or similar tools, Claude Code can generate 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."

This outputs a CSV you can import directly into most scheduling tools. No API keys needed, no MCP setup. It's the lowest-friction approach for teams already using a scheduler.

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 requires platform API access, and the landscape is uneven:

PlatformAPI AccessCostPosting Support
Twitter/XDeveloper portal, tieredFree to $100+/moYes, with limits
LinkedInRestricted to approved appsFree (if approved)Limited
BlueskyOpen API, no approval neededFreeYes
MastodonOpen API per instanceFreeYes
InstagramBusiness API onlyFree (Meta dev)Limited

Bluesky and Mastodon are the easiest platforms to build MCP integrations for because their APIs are open and well-documented. Twitter/X works with the paid developer tiers. LinkedIn is the hardest due to restrictive app approval.

What Doesn't Work Well

Transparency builds trust, so here's what I've found doesn't work reliably:

  • Browser automation for high-volume posting breaks when platforms update their UI. Fine for occasional use, not for daily scheduling.
  • Fully autonomous social media agents that post without review. Social media mistakes are public and permanent. Always keep a human review step.
  • Cross-platform MCPs that try to handle every platform in one server. Build one per platform; the auth and API patterns are too different.
  • Image posting through browser automation is fragile. File upload dialogs are inconsistent across platforms and OS environments.

Putting It Together: A Real Workflow

Here's the workflow that actually works 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 preferred method

  • Direct API posting via custom MCP for Twitter/X
  • Export to scheduling tool for multi-platform distribution
  • Browser automation for one-off posts on platforms without API access

Step 4: Monitor 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 when the volume justifies it.

Related guides:

The MCP ecosystem grows weekly. Check the official MCP registry periodically. When a dedicated social media MCP does ship, the custom server patterns above give you a head start on integrating it.

Last updated on

On this page

Stop configuring. Start shipping.Everything you're reading about and more..
Agentic Orchestration Kit for Claude Code.