Skip to Content
GuidesPost to Twitter / X via MCP

Post to Twitter / X via MCP

Quick navigation: Which path should I use? · Multi-platform example · Recovery playbook · All 9 platforms at a glance

Prerequisites: VoxBurst MCP server configured. See MCP Server setup.


The complete flow

Find the Twitter account ID

list_accounts()

Look for "platform": "twitter". The id field (e.g. acc_twitter_abc123) goes in accountIds.

Optionally validate content first

validate_content( content: "Your tweet text here", platforms: ["TWITTER"] )

Twitter is strict about the 280-character limit — validate first if your caption is close to the edge. Remember links always count as 23 characters regardless of actual length.

Create the post

See post type examples below.

Check the result

get_post(postId: "post_abc123")
{ "id": "post_abc123", "status": "published", "platforms": [ { "platform": "twitter", "status": "published", "platformPostUrl": "https://x.com/mybrand/status/1234567890", "publishedAt": "2026-06-01T15:00:03Z", "error": null } ] }

What type of post do you want?

I want to post…contentTypeMedia required?Notes
Text onlyTEXTNoMax 280 chars
Photo(s)IMAGEYes — 1–4 imagesCannot mix with video
A videoVIDEOYes — 1 videoMax 2:20
A GIFIMAGEYes — 1 GIFMax 15 MB
A threadTHREADNoUse threadPosts array

Media input options:

  • mediaUrls — public HTTPS image/video URLs (auto-registered)
  • mediaIds — VoxBurst media IDs from prior uploads

Post type examples

Text only

create_post( content: "Just shipped a new feature. Thread below 👇", accountIds: ["acc_twitter_abc123"], contentType: "TEXT" )

Image post

create_post( content: "Behind the scenes of our launch day 📸", accountIds: ["acc_twitter_abc123"], contentType: "IMAGE", mediaUrls: ["https://cdn.example.com/photo.jpg"] )

Multiple images (up to 4)

create_post( content: "Four angles of the new product →", accountIds: ["acc_twitter_abc123"], contentType: "IMAGE", mediaUrls: [ "https://cdn.example.com/a.jpg", "https://cdn.example.com/b.jpg", "https://cdn.example.com/c.jpg" ] )

Video

create_post( content: "Watch our 90-second product demo 🎬", accountIds: ["acc_twitter_abc123"], contentType: "VIDEO", mediaUrls: ["https://cdn.example.com/demo.mp4"] )

Scheduled post

create_post( content: "Big announcement dropping in 1 hour. Stay tuned 🔔", accountIds: ["acc_twitter_abc123"], contentType: "TEXT", scheduledFor: "2026-06-01T14:00:00Z" )

Thread

create_post( content: "How we grew from 0 to 10,000 users in 6 months — a thread 🧵", accountIds: ["acc_twitter_abc123"], contentType: "THREAD", threadPosts: [ { "sequence": 1, "content": "It started with a single landing page and a lot of cold DMs." }, { "sequence": 2, "content": "Month 1: 0 users. Month 2: 47 users. Month 3: 312 users." }, { "sequence": 3, "content": "The thing that changed everything: we stopped pitching features and started solving problems." } ] )

With first comment

create_post( content: "New blog post: 5 ways to schedule content smarter.", accountIds: ["acc_twitter_abc123"], contentType: "TEXT", firstComment: "Read the full post here → https://blog.example.com/content-scheduling" )

Tell your AI agent this

Text post, post now:

Post to Twitter account [acc_id]. Content: [your tweet]. Post now.

Image, scheduled:

Post to Twitter account [acc_id]. Content: [tweet text]. Attach image: [https://...]. Schedule for [ISO timestamp].

Thread:

Create a thread on Twitter account [acc_id]. Opening tweet: [text]. Then tweet 2: [text]. Then tweet 3: [text].

Validate before posting:

Validate this tweet for Twitter before posting: [tweet text]. Tell me if it’s over 280 characters.


Common failures and recovery

ErrorCauseFix
CONTENT_TOO_LONGOver 280 chars (links count as 23)Shorten the text or move link to first comment
DUPLICATE_CONTENTTwitter rejects identical recent tweetsVary the wording slightly
MEDIA_MIXED_TYPESImages and video in same tweetUse only images or only video
GIF_TOO_LARGEAnimated GIF over 15 MBCompress the GIF
INVALID_OAUTH_TOKENOAuth token expired or revokedRe-connect the Twitter account in VoxBurst settings
Post status failedVariousCall retry_post, check platforms[].error for reason

Account requirements

RequirementDetail
Account typeAny Twitter / X account
Auth methodOAuth 2.0 with PKCE
Key preconditionTWITTER_CLIENT_ID and TWITTER_CLIENT_SECRET must be configured
Re-connect triggerToken expires; INVALID_OAUTH_TOKEN signals re-connect needed

When Twitter / X is a poor fit

  • Long-form content — 280-character limit makes detailed announcements impractical; use LinkedIn or a thread instead
  • Documents or PDFs — not supported
  • Videos over 2 minutes 20 seconds — rejected
  • Content requiring clickable links in body — links are clickable but count against the 280-char limit; move links to first comment or replies
  • Identical content posted repeatedly — Twitter detects and rejects duplicate content

Cross-platform override example

Twitter needs a shorter caption than LinkedIn or Instagram. Use platformOverrides to handle this in a single post:

create_post( content: "Our new analytics dashboard is live.", accountIds: ["acc_twitter_def", "acc_linkedin_ghi", "acc_instagram_abc"], contentType: "IMAGE", mediaUrls: ["https://cdn.example.com/dashboard.jpg"], platformOverrides: { "TWITTER": { "content": "New analytics dashboard just shipped 📊 #product #analytics" }, "LINKEDIN": { "content": "Our new analytics dashboard gives teams real-time insight into post performance across every platform. Available today for all Pro and Agency plans." } } )

See the same post across all platforms guide for a full 8-platform example.


Benchmark checklist

Last updated: 2026-05-31 — Added JSON tool-call examples and benchmark checklist.

Supported content typesTEXT, IMAGE (1–4), VIDEO, THREAD
Unsupported content typesCAROUSEL, REEL, STORY
Validation gotchaLinks always count as 23 chars regardless of length; max 280 total
Media gotchaCannot mix images and video; GIFs max 15 MB
Account gotchaOAuth token expires; re-connect if INVALID_OAUTH_TOKEN appears
Example prompt”Post to Twitter account acc_id. Content: tweet text. Post now.”
Example tool callcreate_post(content: "...", accountIds: ["acc_twitter_abc"], contentType: "TEXT")
Example response{ "status": "published", "platforms": [{ "platform": "twitter", "platformPostUrl": "https://x.com/..." }] }
Recovery pathretry_post for transient errors; vary caption slightly for DUPLICATE_CONTENT
Last updated on