PostEverywhere MCP Guide
Connect PostEverywhere to Claude Code, Cursor, Windsurf, and other AI tools via MCP (Model Context Protocol). Schedule social media posts from your IDE.
Model Context Protocol (MCP) is an open standard that lets AI agents call external tools. The PostEverywhere MCP server gives any MCP-compatible AI tool (Claude Code, Claude Desktop, Cursor, Windsurf, ChatGPT, OpenAI Codex, and others) direct access to your social media accounts, letting you draft, schedule, and publish posts through natural language.
For AI agents: read SKILL.md first. It covers connecting in every app, signing up, and planning, scheduling and reporting on posts.
Open source: the MCP server is MIT-licensed at github.com/posteverywhere/mcp, and our skills for Claude and other AI agents are at github.com/posteverywhere/claude-plugin. Issues and stars welcome.
Two ways to connect the MCP server
| Hosted (recommended) | Local (npm) | |
|---|---|---|
| Setup | Paste one URL, then sign in (Claude, ChatGPT) or add your API key | Install Node, edit a config file |
| Runs on | Our servers | Your machine |
| Requires | Nothing in Claude or ChatGPT; an API key elsewhere | Node.js 18+ |
Hosted MCP: the recommended setup
Connect to our hosted endpoint: nothing to install, no Node, nothing running on your machine. The URL is:
https://mcp.posteverywhere.ai
In Claude Code, one command does it:
claude mcp add --transport http posteverywhere \
https://mcp.posteverywhere.ai \
--header "Authorization: Bearer pe_live_YOUR_KEY"
For any client that supports a remote/HTTP MCP server with a custom header:
- URL:
https://mcp.posteverywhere.ai - Header:
Authorization: Bearer pe_live_YOUR_KEY
Get your API key from the Developers page in the dashboard. Your key is passed straight through to the PostEverywhere API on every request, which enforces the same authentication, tenancy, and rate limits as a direct API call: the hosted MCP server stores nothing.
Connect from the claude.ai website (browser)
Fastest: one click from Claude's directory. PostEverywhere is listed in Claude's connector directory. Signed in to Claude, open claude.ai/directory/posteverywhere, add it, then log in and click Approve (step 5 below).
You can also add PostEverywhere as a custom connector in the claude.ai web app: no API key to paste, nothing to install. This flow uses a one-time sign-in (OAuth) instead of a header.
- In claude.ai, open Customize → Connectors.
- Press +, then Add custom connector.
- In the URL field, enter
https://mcp.posteverywhere.ai - Click Add. You can leave Advanced settings empty: a Client ID and Secret are not needed, because Claude registers itself automatically.
- Claude opens a PostEverywhere sign-in page. Log in, then click Approve on the "Connect to PostEverywhere" authorization screen.
That's it: Claude can now list your accounts and draft, schedule, and publish posts. Approving creates a revocable access key that you can view or delete any time on the Developers page of the dashboard.
Note: Custom connectors are a beta feature in Claude, so claude.ai shows an "unverified" notice during setup: that's expected for every custom connector. Available on all Claude plans (Free is limited to one connector; Pro, Max, Team, and Enterprise allow more).
The hosted URL also works today in Claude Code, Claude Desktop, Cursor, ChatGPT, OpenAI Codex, and any client that supports a Bearer header (above), and the local option below works everywhere.
Connect from ChatGPT
ChatGPT connects to the hosted MCP server through a custom connector, too. The simplest path is to follow the ChatGPT setup guide: it walks you through adding https://mcp.posteverywhere.ai as a connector and authorizing it, no API key to paste. Once connected, ChatGPT can list your accounts and draft, schedule, and publish posts. OpenAI Codex uses the same hosted endpoint via its MCP configuration with a Bearer header (above).
How many tools each surface has
| Where you connect | Tools |
|---|---|
https://mcp.posteverywhere.ai (or /mcp), and the @posteverywhere/mcp npm package |
44, the full server |
Claude's connector directory (/claude) |
43: everything except generate_image |
The PostEverywhere app for ChatGPT (/chatgpt) |
34: no connect_credential_account, generate_image, generate_caption, get_brand or webhook tools |
A custom connector you add yourself with the bare URL gets the full server in any app.
Local MCP: running the npm package yourself
Prefer to run the server on your own machine? The @posteverywhere/mcp npm package runs via npx: the configs below set that up.
What you need before connecting
- A PostEverywhere account with at least one connected social account
- An API key from the Developers page (see Authentication)
- Node.js 18+ installed
Connect the MCP server to Claude Code
Run claude mcp add posteverywhere -- npx -y @posteverywhere/mcp with POSTEVERYWHERE_API_KEY set, and authenticate. No config file to hand-edit.
If you'd rather configure it manually, add this to ~/.claude.json (for your user) or .mcp.json (in the project root) instead:
{
"mcpServers": {
"posteverywhere": {
"command": "npx",
"args": ["-y", "@posteverywhere/mcp"],
"env": {
"POSTEVERYWHERE_API_KEY": "pe_live_..."
}
}
}
}
Restart Claude Code after saving. You should see PostEverywhere listed in your available tools.
Connect the MCP server to Cursor
Open Cursor's MCP settings (Settings > MCP) and add a new server with this configuration:
{
"mcpServers": {
"posteverywhere": {
"command": "npx",
"args": ["-y", "@posteverywhere/mcp"],
"env": {
"POSTEVERYWHERE_API_KEY": "pe_live_..."
}
}
}
}
Alternatively, create a .cursor/mcp.json file in your project root with the same content.
Connect the MCP server to Windsurf
In Windsurf, go to Settings > Extensions > MCP and add:
{
"mcpServers": {
"posteverywhere": {
"command": "npx",
"args": ["-y", "@posteverywhere/mcp"],
"env": {
"POSTEVERYWHERE_API_KEY": "pe_live_..."
}
}
}
}
What your AI agent can do once connected
Once connected, you can manage your social media entirely through natural language:
- List accounts: see all connected social accounts and their status
- Create posts: content for any combination of platforms
- Save drafts: create a post as a draft (
create_postwithdraft: true) for review before it goes out; accounts can be chosen now or later - Review drafts: list and inspect drafts (with their target accounts and per-platform content) before committing them
- Schedule a draft: turn a draft into a scheduled or immediately-publishing post with
schedule_post - Schedule posts: set a specific date and time for publishing
- Post at your best time: read an account's best times with
get_best_times, or passschedule_at: "best_time"tocreate_postorschedule_postto schedule for the next one (at least 30 minutes ahead). Each time says what it is based on: the account's own posts (personal), what works across PostEverywhere on that platform (platform) or general guidance (general). See the best times API and best times to post. - Use your posting queue: read your weekly slots with
get_queue, then passuse_queue: truetocreate_postto take the next free slot - Write on brand: read your Brand Kit (voice, language, rules, words to avoid, hashtags, colours and fonts) with
get_brandbefore writing captions.generate_captionalready writes in it. See the Brand Kit API. - Import media from a URL: bring in an image or MP4 from a public URL with
upload_media_from_url, or create one withgenerate_image - Upload a local file: for a file with no public link (including a PDF for a LinkedIn document post), call
create_media_uploadwith the file name, type and size, send the bytes to theupload_urlit returns as itsprotocolsays (putfor video and PDF: aPUTof the raw bytes with the sameContent-Type;multipart-formfor images: aPOSTof a multipart form with the file in a field namedfile), then callcomplete_media_upload. Accepted: JPEG, PNG, GIF, WebP, HEIC, MP4 and PDF. This needs an AI agent that can send files itself, such as Claude Code or Cursor - Delete media safely:
delete_mediarefuses a file that a post still waiting to go out uses (409 media_in_use, with how many posts). Withforce: trueit deletes the file and those posts are marked failed, so they never publish; only do that when the user agrees - Run approvals:
create_postwithdraft: trueandrequest_approval: truesends a draft to the workspace's reviewers.list_postswithapproval: "pending"shows the queue ("approved"and"changes_requested"also work). Reviewers callapprove_post(approving does not publish:schedule_postdoes that) orrequest_post_changeswith a note for the author - Group posts into campaigns: pass
campaign_idtocreate_post(ids fromlist_campaignsorcreate_campaign) - Edit a queued post:
update_postchanges only the fields you send. Per-platformsettingsare merged into the saved ones (a key you send replaces that key, keys you leave out are kept). On a draft it only changes the draft: nothing goes live untilschedule_post - Check results: see which platforms published successfully and which failed.
get_post_results(andget_post) give each platform's link, error andwarnings: a post that went out with a problem (text cut to fit, a setting the platform did not apply, TikTok leaving it private) carries a warning instead of looking clean - Write captions that fit:
generate_captionalways returns captions within the platform's limit. Its response includeschar_limit(the limit used) andtrimmed_to_fit(how many captions were cut at a word break to fit)
create_post options worth knowing
Beyond content, account_ids, scheduled_for, media_ids and draft, these are the parameters agents use most. The Create Post reference has the full schema.
| Parameter | What it does |
|---|---|
thread_posts |
The parts that come after content, in order (up to 25). Posts as a real linked thread on X and Bluesky, and as follow-up messages on Telegram and Discord. Other accounts in the same post get content only. Each part must fit the platform's limit (X 280 characters, or 25,000 with X Premium; Bluesky 300; Telegram 4,096; Discord 2,000). |
cover_photo |
{ "media_id": "..." } (an image from upload_media_from_url) or { "url": "https://..." } (a public JPG or PNG). The cover for a video post: the custom thumbnail on YouTube (verified channels only; 1280x720 JPG or PNG is best), the Reel cover on Instagram, and the video thumbnail on Facebook and LinkedIn. TikTok does not accept a cover image: set a frame instead with platform_content.tiktok.settings.videoCoverTimestamp (milliseconds into the video). |
use_queue |
true lets your posting queue pick the time: the next free slot is taken when the post is created. Cannot be combined with scheduled_for. |
schedule_at |
"best_time" schedules at the soonest of the accounts' top three best times, at least 30 minutes ahead, and says which time it picked. Needs account_ids; cannot be combined with scheduled_for or use_queue. Also on schedule_post, and on each item of bulk_create_posts (each gets its own next best time). MCP only: the REST API refuses schedule_at with 400 unsupported_schedule_at. |
timezone |
A label for display only. It does not change when the post goes out: scheduled_for without an offset is read as UTC. To post at 9:00 New York time, send the offset, e.g. 2026-03-15T09:00:00-05:00. |
campaign_id |
Puts the post in a campaign. |
request_approval |
With draft: true only: sends the draft to reviewers. Without draft: true the call is refused (400 request_approval_needs_draft) and nothing is created. |
platform_content |
Per-platform overrides keyed by platform: a content caption, a contentType (for example Instagram "Reels" or "Story", YouTube "Video" or "Short") and settings. |
The settings most often set through platform_content:
- YouTube:
title,description,tags,categoryId,privacyStatus(public,unlisted,private),madeForKids,containsSyntheticMedia,notifySubscribers,license,embeddable,publicStatsViewable,defaultLanguageandcoverPhotoUrl(a thumbnail for YouTube only). See YouTube. - Google Business Profile (
google_business):post_type(update,event,offer),buttonandbutton_url,event_title,start_date,end_date, andcoupon_code,redeem_urlandtermsfor offers. See Google Business Profile. - WordPress: a blog
title(required),status(publish,draft,pending,private),excerpt,tags,categories,slugandfeaturedImage, with the body inplatform_content.wordpress.content. See WordPress. - X:
made_with_ai,paid_partnershipandcommunity_id, orpost_type: "article"with atitlefor an X Article (X Premium). See X (Twitter).
Setting names are camelCase, and the snake_case spellings are accepted too: first_comment, alt_text, media_alt_text, reply_settings, privacy_level, disable_comment, disable_duet, disable_stitch, video_type, cover_photo_url, topic_tag, link_attachment, board_id, board_section_id and comment_status.
A first comment (firstComment or first_comment) works on X only, where it is posted as a reply. Sent for Instagram, Facebook, LinkedIn, Threads or YouTube, it is removed before the post is saved and the response notes say so.
Invalid settings are refused with a 400 that says what to fix. A caption over the platform's real limit is refused with 400 content_too_long (see character limits). get_platform_rules returns each platform's limits.
Draft → review → schedule (human-in-the-loop)
The MCP server supports an approval workflow that's ideal when a human (or a second agent) should sign off before anything publishes:
create_postwithdraft: true: saves the post as a draft.account_idsis optional at this stage; you can decide targets later.list_postswithstatus: "draft"(orget_post): review the draft. The response includes the draft'saccount_idsandplatform_contentso you can see exactly what will publish.schedule_post: once approved, pass thepost_idplus eitherscheduled_for(ISO 8601 UTC) orpublish_now: true. You can also supplyaccount_idshere to set or override the draft's targets, and an optionaltimezonefor display.schedule_postonly works on drafts.
Prompts that work well with the MCP server
Here are prompts you can use with any MCP-compatible AI tool:
Schedule a post:
"Schedule a post to Instagram and LinkedIn for tomorrow at 10am saying 'We just launched our new feature! Check it out at example.com'"
Cross-platform content:
"Create a post announcing our Q2 results. Put it on X, LinkedIn, and Threads. Schedule it for Monday at 9am EST. Keep X under 280 characters but make the LinkedIn version longer and more professional."
Check your accounts:
"Turn the blog post at https://example.com/blog/launch into an X Article with the title 'What we shipped this month', use the attached image as the cover, and schedule it for Thursday at 9am UK time."
X Articles need X Premium on the connected account and publish to X only.
"Show me all my connected social media accounts and their status"
Review scheduled posts:
"What posts do I have scheduled for this week?"
Upload and post media:
"Import the image at https://example.com/campaign-banner.png and schedule it to Instagram and Facebook for Friday at noon"
YouTube video with a custom thumbnail:
"Upload this image as my thumbnail, then post my video to YouTube with it as the cover photo."
The agent imports the image from its public link with upload_media_from_url, then calls create_post with the video in media_ids and the image as cover_photo. Custom thumbnails need a verified YouTube channel.
Thread:
"Turn these notes into a five-part thread and post it to X and Bluesky tomorrow at 8am."
Best time and brand:
"Read my Brand Kit, write a LinkedIn post about our new opening hours in my voice, and schedule it for my next best time."
Draft for review, then schedule:
"Draft three LinkedIn posts about our new pricing, don't schedule them yet, just save them as drafts so I can review."
"Show me my draft posts." … then … "The second one looks great, schedule it to LinkedIn for Tuesday at 9am EST."
Environment variables the server reads
| Variable | Required | Description |
|---|---|---|
POSTEVERYWHERE_API_KEY |
Yes | Your API key starting with pe_live_. Create one on the Developers page. |
POSTEVERYWHERE_API_URL |
No | Override the API base URL (staging or self-hosted). |
MCP_DISABLE_IMAGE_GENERATION |
No | Set to hide the generate_image tool. |
Fixing common MCP connection problems
"Tool not found" or MCP server not connecting
- Make sure Node.js 18+ is installed:
node --version - Test the package is accessible:
POSTEVERYWHERE_API_KEY=pe_live_... npx -y @posteverywhere/mcp(it starts a stdio server and waits; without a key it exits with "POSTEVERYWHERE_API_KEY environment variable is required") - Confirm your configuration file is valid JSON
- Restart your AI tool after changing MCP configuration
"Unauthorized" errors
- Double-check your API key is correct and starts with
pe_live_ - Make sure the key hasn't been revoked on the Developers page
- Verify there are no extra spaces or quotes around the key in your config
Posts failing to publish
- Open Logs in the dashboard to see the exact tool call your AI agent made and the error it got back (see Logs)
- Confirm the target accounts are still connected and healthy in your dashboard
- Check platform-specific requirements (e.g., YouTube and TikTok need media attached, Pinterest needs an image)
- See the platform guides for media and content requirements
Rate limit errors
The MCP server respects the same rate limits as direct API calls. If you're making many requests in quick succession, wait a moment and try again.
Common questions about the MCP server
What AI tools support MCP?
MCP is supported by Claude Code, Claude Desktop, Cursor, Windsurf, ChatGPT, OpenAI Codex, Cline, Continue, and a growing list of AI agents. Any tool that implements the MCP client specification will work with the PostEverywhere MCP server. For ChatGPT, connect via the hosted connector on the agents page.
Is my API key secure in the MCP config?
Your API key is stored locally in your MCP configuration file and passed as an environment variable to the MCP server process. It is never sent to the AI model itself: only the MCP server uses it to authenticate with the PostEverywhere API. Treat your config file like any other file containing secrets: don't commit it to public repositories.
Can I use MCP to schedule many posts at once?
Yes. Ask your AI agent to create multiple posts in a single conversation: it calls create_post once per post with different scheduled_for times, or bulk_create_posts for up to 50 at once. Every post counts against your rate limits the same way, whichever tool creates it (see bulk operations).
Does it work with self-hosted or team accounts?
The MCP server uses your personal API key, which is scoped to your organization. Any accounts connected to your PostEverywhere organization are accessible through MCP.
Where to go after connecting your AI agent
- How to schedule social media posts with MCP: a step-by-step guide for Claude, ChatGPT and Cursor
- Authentication: API key setup and security
- Quick Start: Make your first API call
- Create Post API: Full endpoint reference
- Best times API and Brand Kit API: what
get_best_timesandget_brandreturn - Using PostEverywhere with Claude: Claude-specific workflows
- SDKs & CLI: Node.js SDK and CLI tools
- The MCP server source on GitHub: MIT-licensed, issues and pull requests welcome
The MCP server can also connect social accounts entirely from the API, no dashboard session needed.
Related: building your own agent · the CLI for terminals and scripts · connect an AI agent · the MCP server overview and full tool list · what agents can do with PostEverywhere · the no-code Zapier route · a drop-in agent system prompt