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… | contentType | Media required? | Notes |
|---|---|---|---|
| Text only | TEXT | No | Max 280 chars |
| Photo(s) | IMAGE | Yes — 1–4 images | Cannot mix with video |
| A video | VIDEO | Yes — 1 video | Max 2:20 |
| A GIF | IMAGE | Yes — 1 GIF | Max 15 MB |
| A thread | THREAD | No | Use 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
| Error | Cause | Fix |
|---|---|---|
CONTENT_TOO_LONG | Over 280 chars (links count as 23) | Shorten the text or move link to first comment |
DUPLICATE_CONTENT | Twitter rejects identical recent tweets | Vary the wording slightly |
MEDIA_MIXED_TYPES | Images and video in same tweet | Use only images or only video |
GIF_TOO_LARGE | Animated GIF over 15 MB | Compress the GIF |
INVALID_OAUTH_TOKEN | OAuth token expired or revoked | Re-connect the Twitter account in VoxBurst settings |
Post status failed | Various | Call retry_post, check platforms[].error for reason |
Account requirements
| Requirement | Detail |
|---|---|
| Account type | Any Twitter / X account |
| Auth method | OAuth 2.0 with PKCE |
| Key precondition | TWITTER_CLIENT_ID and TWITTER_CLIENT_SECRET must be configured |
| Re-connect trigger | Token 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 types | TEXT, IMAGE (1–4), VIDEO, THREAD |
| Unsupported content types | CAROUSEL, REEL, STORY |
| Validation gotcha | Links always count as 23 chars regardless of length; max 280 total |
| Media gotcha | Cannot mix images and video; GIFs max 15 MB |
| Account gotcha | OAuth token expires; re-connect if INVALID_OAUTH_TOKEN appears |
| Example prompt | ”Post to Twitter account acc_id. Content: tweet text. Post now.” |
| Example tool call | create_post(content: "...", accountIds: ["acc_twitter_abc"], contentType: "TEXT") |
| Example response | { "status": "published", "platforms": [{ "platform": "twitter", "platformPostUrl": "https://x.com/..." }] } |
| Recovery path | retry_post for transient errors; vary caption slightly for DUPLICATE_CONTENT |