Build a CrewAI social media crew: end-to-end tutorial with Posta

This tutorial builds a working CrewAI crew that posts to social media. The interesting part: instead of one agent for everything, we wire up per-platform specialist agents — a LinkedIn specialist with a long-form voice, a Bluesky specialist with a short-form voice, a YouTube Shorts specialist tuned for vertical video promos — and let CrewAI orchestrate them. All three share the same Posta MCP server as a tool source.

What you'll build

A hierarchical CrewAI crew with a research agent that gathers context, a router/manager agent that decides which platforms get a post, and three platform specialists that draft and schedule for their network. All four agents share the Posta MCP server's tool set — they reach for the same createPost / schedulePost tools but call them with platform-specific voices.

Prerequisites

  • Python 3.11+ and pip.
  • A Posta account with LinkedIn, Bluesky, and YouTube connected. 14-day free trial.
  • A Posta API token.
  • An Anthropic or OpenAI API key.

Step 1 — Install dependencies

pip install crewai crewai-tools

Step 2 — Load the Posta tools via MCPServerAdapter

CrewAI's MCPServerAdapter loads any MCP server's tools and exposes them to the crew. Wrap the Posta server config in a with block so the stdio process gets cleaned up after the crew runs:

# crew.py
import os
from crewai import Agent, Task, Crew, Process
from crewai_tools import MCPServerAdapter

posta_params = {
    "command": "npx",
    "args": ["-y", "posta-mcp"],
    "env": {"POSTA_API_TOKEN": os.environ["POSTA_API_TOKEN"]},
}

LLM = "anthropic/claude-sonnet-4-6"

with MCPServerAdapter(posta_params) as posta_tools:
    # Three platform specialists — same tool set, different voices.
    linkedin_specialist = Agent(
        role="LinkedIn Specialist",
        goal="Draft long-form, professional, insight-driven LinkedIn posts.",
        backstory="A B2B content strategist with 10 years of LinkedIn-native writing.",
        tools=posta_tools,
        llm=LLM,
        verbose=True,
    )
    bluesky_specialist = Agent(
        role="Bluesky Specialist",
        goal="Draft short, punchy, link-friendly Bluesky posts under 300 chars.",
        backstory="A dev-Twitter veteran who moved to Bluesky early.",
        tools=posta_tools,
        llm=LLM,
        verbose=True,
    )
    shorts_specialist = Agent(
        role="YouTube Shorts Specialist",
        goal="Draft promo posts for vertical-video Shorts with a hook in 5 seconds.",
        backstory="A YouTube creator-economy strategist focused on Shorts pacing.",
        tools=posta_tools,
        llm=LLM,
        verbose=True,
    )

    # Custom manager that orchestrates the specialists. With Process.hierarchical
    # CrewAI uses manager_agent= for a hand-rolled manager (manager_llm= would
    # spin up its own — don't mix). The manager isn't in agents=[] either.
    manager = Agent(
        role="Campaign Manager",
        goal="Decide which platforms get a post and delegate drafting.",
        backstory="A multi-network campaign manager who briefs specialists.",
        llm=LLM,
        allow_delegation=True,
        verbose=True,
    )

    task = Task(
        description=(
            "We shipped v2 of our SDK today: per-platform caption limits, "
            "batch media endpoint, OpenAPI updates. Brief each specialist. "
            "Each should draft and schedule a post for tomorrow 9am CET as "
            "a draft (so we can review)."
        ),
        expected_output="A summary of each scheduled post (platform + draft ID).",
    )

    crew = Crew(
        agents=[linkedin_specialist, bluesky_specialist, shorts_specialist],
        tasks=[task],
        process=Process.hierarchical,
        manager_agent=manager,
    )

    result = crew.kickoff()
    print(result)

Step 3 — Run it

export POSTA_API_TOKEN=posta_...
export ANTHROPIC_API_KEY=sk-ant-...

python crew.py

On the first run the manager agent reads the brief, lists the platforms by calling listAccounts through one of the specialists, and delegates per-platform drafting. Each specialist drafts in its own voice, calls createPost + schedulePost for its platform, and reports back with the Posta draft ID. The hierarchical process serializes the delegations and the manager assembles the final summary.

Why per-platform specialists?

You could ask a single agent to "draft for LinkedIn, Bluesky, and YouTube Shorts." It will — and it will produce three nearly-identical posts with different lengths. Per-platform specialists let you bake in platform-specific writing tradition: LinkedIn rewards earnest insight, Bluesky rewards specificity and self-deprecation, Shorts rewards a hook in the first five seconds. The voices shouldn't be identical.

When to use Flows instead

CrewAI Flows are the right surface when you need explicit control over what runs in what order — non-deterministic delegation can be hard to debug when something goes wrong. The same Posta tools work the same way in Flow steps; the only thing that changes is the orchestration shape.

Pitfalls

  • Wrap MCPServerAdapter in a with block. Without it, the stdio process leaks across reruns.
  • Cap the manager's recursion. Hierarchical crews can ping-pong delegations forever if you don't set a clear expected_output contract.
  • Give each specialist its own LLM only if needed. Setting a cheaper model on the manager and Claude on specialists is a common cost-saving tweak; resist the urge to over-optimize before profiling.
  • Always start with "save as draft." Crew runs are non-deterministic; you want the option to abort before LinkedIn sees a post you don't want.

Where to go from here

Read the CrewAI integration reference for Flow and sequential-process examples. Compare with the LangChain and OpenAI Agents SDK approaches in the LangChain tutorial and the OpenAI Agents SDK tutorial. For the broader pattern map, see agentic social media workflows. 14-day free trial.

Ready to simplify your social media workflow?

Join creators and teams who save hours every week with Posta.