MCP Server
Schedule posts from Claude, ChatGPT, Cursor, or any MCP-compatible client, over stdio (npm) or HTTP.
posterly speaks the Model Context Protocol so any MCP-compatible AI client can list connected accounts, schedule posts, and pull analytics on the user's behalf. Two connection options are available, pick the one that fits your client.
New accounts that start from /mcp pay for a plan plus API & MCP in one Stripe subscription, charged immediately (Starter + API is $10/month). That path has no free trial. After checkout, create a key at Dashboard → API & MCP.
Two connection options
1. Stdio (npm package), desktop AI clients
For Claude Desktop, ChatGPT Desktop, Cursor, Windsurf, Cline, and other clients that run an MCP server as a local subprocess.
You do not need to install anything globally. Add this to your client's MCP config and let npx run the current server:
{
"mcpServers": {
"posterly": {
"command": "npx",
"args": ["-y", "posterly-mcp-server@latest"],
"env": {
"POSTERLY_API_KEY": "pst_live_your_key_here"
}
}
}
}
Quick setup, copy for your AI: Paste this into Claude, ChatGPT, or Cursor and it will configure everything for you:
"I want to connect posterly via MCP. Add this to my MCP config:
{ "mcpServers": { "posterly": { "command": "npx", "args": ["-y", "posterly-mcp-server@latest"], "env": { "POSTERLY_API_KEY": "YOUR_KEY" } } } }, merge it with my existing config, then remind me to restart."Replace
YOUR_KEYwith your API key from Dashboard → API & MCP.
If the user has not signed up yet, install the same server without POSTERLY_API_KEY. The public tools get_agent_signup_info, start_signup, and get_signup_session work before a key exists, so the AI can start paid signup, send the posterly checkout handoff URL, and poll progress while the user pays and sets a password in the browser.
2. HTTP, browser-based AI clients
For Claude in Chrome, ChatGPT (developer mode apps), Cursor in browser, Grok Bot, or any web-based or cloud agent that can't spawn a local process. Dedicated connect pages: Claude, ChatGPT, Cursor, Grok Bot, Poke, Hermes, and OpenClaw. First-schedule walkthroughs: ChatGPT, Claude, Cursor, Poke, Hermes, OpenClaw, Grok Bot Marketplace. Media bodies: Solving the 4MB MCP limit.
- Endpoint:
POST https://www.poster.ly/api/mcp - Wire format: JSON-RPC 2.0 (single request, no SSE in v1)
- Auth header:
Authorization: Bearer pst_live_your_key_here - Capability hint:
GET /api/mcpreturns server info without auth.
Quick smoke test from any terminal:
curl -s https://www.poster.ly/api/mcp \
-H "Authorization: Bearer pst_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Both connection options use the same API key, the same paywall, and the same route-aware API limits. They expose the same authenticated toolset, but media upload ergonomics differ by transport because hosted HTTP MCP tool calls are JSON only.
Create-post calls are limited to 100 requests per hour per key. This does not mean you can only schedule 100 posts per hour: use create_posts_batch to create up to 25 posts in one confirmed request. Media writes and read-only calls have separate higher limits.
User-created API keys are tier-based: Starter 1, Pro 2, Power 3, Agency 4. Keys can also be scoped to one workspace; connection handoff and webhook tools use the scoped workspace automatically and reject a different workspace_id.
Managed connection through Smithery
Smithery provides a managed connection to the same hosted HTTP MCP endpoint. It uses posterly OAuth, so users authorize their own account without pasting a posterly API key into Smithery.
- Open the posterly server on Smithery.
- Add or connect it to your Smithery toolbox.
- Sign in to posterly, or create an account if needed.
- Review the requested account, post, media, and analytics scopes.
- Select Allow, then return to Smithery and test with
whoamiorlist_accounts.
Each OAuth connection belongs to the posterly user who approved it. Other Smithery users cannot access that user's accounts, posts, media, or analytics. An active posterly plan plus the API/MCP add-on is still required; Smithery does not provide free posterly API access.
For permission explanations, example prompts, and troubleshooting, read the Smithery social media MCP setup guide.
Media upload: where the 4MB limit exists, and how to get past it
Vercel caps request bodies to posterly API routes at about 4MB. Hosted MCP (POST /api/mcp) is JSON on that same path, so a base64 file inside upload_media counts against it. Base64 also inflates the file, so hosted upload_media is only for small images. Our relay cap is 5MB decoded; treat anything larger as signed upload.
This is not an MCP-protocol file limit, and it is not posterly's plan storage cap. It is the function body on Vercel.
| Path | Hits the ~4MB Vercel body? | What to use it for |
|---|---|---|
Hosted MCP upload_media (base64 JSON to /api/mcp) | Yes | Small images only |
REST POST /api/v1/media/upload (base64) | Yes | Small images only |
Legacy PUT /api/v1/media/signed-upload/upload | Yes | Do not use. Returns FUNCTION_PAYLOAD_TOO_LARGE on large videos |
upload_media_from_url / create_post with a third-party media_url | The JSON call is small. posterly then fetches the URL on the server | Small public files. About 5MB on the relay path, 60MB remote-fetch hard cap. Large R2/S3 URLs fail with remote_media_too_large |
MCP create_signed_upload, then PUT bytes to upload_url | No. The PUT goes to object storage (R2/Supabase), not Vercel | Videos and large images. Plan caps: Starter 500MB, Pro 750MB, Power 1GB, Agency 4GB |
MCP create_media_drop, human opens /drop/<token> | No. The browser PUTs to object storage | ChatGPT web and Claude.ai laptop files. Agent then calls list_media |
Stdio upload_media with file_path | No. The npm server reads the disk and uses signed upload for large files | Cursor, Claude Code, Claude Desktop, Codex, Hermes: give a real local path |
CLI media:signed-upload then PUT | No | Scripts and coding agents that can HTTP PUT |
| Dashboard composer and Media Library | No. They already use signed / direct storage | Humans in the app |
create_signed_upload is the bypass when the agent can PUT the file itself (know filename, content_type, and exact size, then PUT raw bytes to upload_url with the returned headers, then pass public_url to create_post). Cursor, Claude Code, and Codex can do that.
ChatGPT web and Claude.ai cannot PUT a laptop file, and chat paperclips never reach MCP. For those clients call create_media_drop, send the user drop_url (https://www.poster.ly/drop/<token>), wait, then call list_media. HEIC and PDF are rejected. Plan video caps still apply: Starter 500MB, Pro 750MB, Power 1GB, Agency 4GB.
Why the 4MB number exists, and which tool to call on each runtime: Solving the 4MB MCP limit.
Local stdio MCP can read a local file path and automatically use signed upload for larger media. Use this when the agent is on the same machine as the file.
Hosted HTTP MCP has no binary channel. For larger media on a client that can PUT:
- Call
create_signed_uploadwithfilename,content_type, andsize. - PUT the raw file bytes to the returned
upload_url(object storage). Do not PUT to aposter.lyAPI route. - Pass
public_urlintovalidate_post/create_post.
Do not pass a 500MB to 2GB Cloudflare R2, S3, or other remote URL straight to create_post. That fetch fails with remote_media_too_large. Download it (or PUT it) via signed upload instead.
Uploaded media is analyzed automatically in the background. If a video can never reach a selected platform (for example, it is longer than the platform allows, or too large for the platform's file size limit), create_post rejects that combination with an actionable message such as "This video is too large for Telegram (20 MB limit). Export it under 20 MB to include Telegram." Relay the message to the user.
If a destination would need a pixel-changing conversion and the video is HDR, full-range, not Rec.709, or missing complete colour tags, posterly publishes the original file rather than converting it or failing. Compatible originals, remuxes, and video-copy repairs still pass. See Video colour compatibility.
create_post also rejects, at creation time, media combinations that no platform call could satisfy: a PDF sent anywhere other than LinkedIn, an .avi or .mkv video sent to Instagram, and an Instagram account that is missing its business account id (which needs reconnecting in posterly). These used to be accepted and then fail at publish. Relay the message rather than retrying.
The .mov, .webm and .m4v containers remain accepted at creation. Whether a repair is needed depends on the inspected input and destination; compatible originals can pass through unchanged. If colour conversion is unsafe, posterly publishes the original rather than asking for a Rec.709 re-export.
Agent response style
MCP signup and connect tools return user-facing guidance by default. Agents should narrate progress in plain language, send the secure browser links, and avoid showing raw curl commands, HTTP payloads, or JSON unless the user asks for debugging.
Use debug: true only when you deliberately need the raw signup or connect response for troubleshooting. The tools that support this are start_signup, get_signup_session, get_connect_link, create_connect_session, and get_connect_session.
Post tools also return posterly dashboard links. After creating, listing, reading, or deleting posts, share the returned View in posterly link so the user lands in the right dashboard view. Current-month scheduled posts open in Calendar with the post selected; general/future post lists fall back to Table.
Auto-discovery for agents
posterly publishes the standard .well-known discovery endpoints so agents can find everything programmatically:
| URL | Purpose |
|---|---|
/.well-known/mcp/server-card.json | MCP server card, describes both connection options + tools |
/.well-known/api-catalog | RFC 9727 linkset describing the REST API surface |
/.well-known/oauth-authorization-server | RFC 8414, authorize/token/register endpoints, refresh-token grant |
/.well-known/oauth-protected-resource | RFC 9728, bearer methods, scopes, where to mint tokens |
/.well-known/agent-skills/index.json | Cloudflare Agent Skills index, links to SKILL.md files |
/api/openapi | Full OpenAPI 3.1 spec for the REST API |
Public marketing pages also emit RFC 8288 Link headers pointing at all of the above, so agents that crawl https://www.poster.ly discover the API surface without any prior configuration.
Auth & billing handoff (RFC 6750)
When an agent calls a tool with a missing/invalid token or no API add-on, posterly returns a WWW-Authenticate header that tells the agent exactly what to do, surface this to the user and they can subscribe inside the agent conversation.
- 401 invalid_token,
WWW-Authenticate: Bearer ... token_uri="https://www.poster.ly/dashboard/api" - 403 insufficient_subscription,
WWW-Authenticate: Bearer ... error_uri="https://www.poster.ly/dashboard/api?upgrade=api_addon" - 403 insufficient_scope,
WWW-Authenticate: Bearer ... scope="posts:write" - 403 origin_not_allowed, browser caller from an Origin not on the trusted MCP host list (Claude, ChatGPT, posterly, localhost, plus
MCP_TRUSTED_ORIGINS). - 429, body includes
retry_after,limit,remaining, andreset, plus aRetry-Afterheader.
Hosted MCP clients (Claude.ai, ChatGPT, and similar)
Browser-hosted MCP clients can complete a full OAuth connect flow without manual allowlisting via RFC 7591 Dynamic Client Registration:
POST /api/oauth/register, send a JSON metadata document (client_name,redirect_uris,scope), receive aclient_idimmediately.- The new client starts the standard authorization-code + PKCE flow at
https://www.poster.ly/oauth/authorize. - If you are new and still need a plan, posterly sends you to choose a plan and then returns you to the consent screen. The API add-on is still required before the access token activates.
- The consent screen flags self-registered clients so the user can decide whether to trust the source.
- Access tokens issued via OAuth live 1 hour. Refresh tokens live 30 days and rotate on every use; reuse revokes the chain.
grant_type=refresh_tokenat/api/oauth/tokento renew.
The discovery document at /.well-known/oauth-authorization-server advertises registration_endpoint, token_endpoint, and the supported grants so MCP hosts can wire this up automatically. API keys still work for stdio MCP and scripts.
Available tools
The local stdio server exposes 89 tools. The public setup tools work without POSTERLY_API_KEY; authenticated tools require a posterly API key. The HTTP MCP connection is authenticated and exposes 86 tools.
-
get_mcp_status, show the installed server version, latest npm version, MCP endpoint health, API auth health, and update guidance.
-
get_agent_signup_info, explain the safe agent-led signup flow before an API key exists.
-
start_signup, start paid signup and return a posterly checkout handoff URL plus signup poll URL.
-
get_signup_session, poll checkout, payment, password, and agent-access status.
-
whoami, show the user, workspaces, and scopes your key can access.
-
create_api_key, create a new scoped API key after explicit confirmation. The calling key must be a dashboard-created key, and new scopes cannot exceed the calling key.
-
delete_api_key, revoke a user-created API key after explicit confirmation. The endpoint refuses to revoke the key currently authenticating the request.
-
list_accounts, show all connected social accounts.
-
disconnect_account, disconnect a connected social account after explicit confirmation. It preserves reconnect metadata, archives Instagram analytics, and emits
account.disconnectedwebhooks. -
get_connect_link, inspect dashboard connection links, provider readiness, required scopes, and connected account counts.
-
connect_account, connect a credential-based account (telegram, bluesky, discord, wordpress, devto, hashnode, lemmy) directly, no browser session needed.
-
create_connect_session, create a guided browser handoff for connecting a social account.
-
get_connect_session, poll connection progress while the user logs in, approves OAuth, or enters credentials.
-
list_oauth_clients / create_oauth_client / update_oauth_client / delete_oauth_client, manage self-serve public OAuth 2.1 + PKCE developer clients after confirmation.
-
list_platforms / get_platform_schema, inspect supported integrations, post types, settings fields, media limits, analytics support, and planned provider possibilities.
-
trigger_platform_helper, run helper discovery such as
pinterest.boards,youtube.playlists,tiktok.creator_info,linkedin.recent_mentions, orx.quota. -
list_brands, show brands/clients available in the current workspace context.
-
get_brand, inspect one brand/client in detail.
-
list_brand_accounts, show the social accounts assigned to a brand/client.
-
get_brand_profile, read the saved brand voice/profile for a brand/client. Also returns
learned_voice: the voice posterly has learned from each connected account's real published captions. -
get_learned_voice, read the voice learned from one account's real published captions (the "learned captions" shown on the dashboard), keyed by social account ID. Returns a narrative summary, voice traits, style guidelines, and observed posting habits. Read-only; never overwrites the saved brand profile.
-
list_posts / get_post / get_post_missing, browse scheduled content and inspect missing content/settings before publish.
-
ask_support, ask authenticated docs-backed support questions with read-only account/post diagnostics. If the user asks for a human, agent, real person, or an escalation, Support AI files a ticket. Agent-initiated handoff still uses
request_humanplusconfirm_escalation. -
create_post, schedule or immediately publish one post. Pass
thread_posts: string[](2+ entries) for X or Threads chains, andplatform_settingsfor platform-specific composer controls. For media, pass URLs returned by the media upload tools. -
validate_post, validate the complete payload without creating a post, copying remote media, consuming post-item/storage quota, reserving X quota, emitting webhooks, or enqueueing publication. Resolve warnings, show the final preview, and ask for explicit confirmation before calling
create_post. -
submit_agent_feedback, submit bounded private operational telemetry after a concrete workflow outcome. Never include secrets, prompts, captions, media URLs, personal data, or fabricated outcomes.
-
submit_product_feedback, file a product bug, idea, or feedback on the public posterly feedback board after the user explicitly approves the title and category (
confirm=true). Do not use this for tool failures; usesubmit_agent_feedbackfor private operational telemetry. -
create_posts_batch, create up to 25 confirmed posts in one API request. Each item accepts the same fields as
create_post, and partial failures return the item index. Third-party media URLs are copied into posterly storage before each post is saved. -
update_post / update_post_status / update_post_release_id / delete_post / delete_post_group, manage scheduled content, repair release/group metadata, and clean up grouped drafts/scheduled posts after confirmation.
-
upload_media, small base64 files on hosted HTTP (Vercel ~4MB body). Stdio
file_pathuses signed upload for large files. -
upload_media_from_url, fetch a public image/video URL into posterly storage with SSRF protections (small files; large R2/S3 URLs fail).
-
create_signed_upload, mint an object-storage PUT URL so large files never enter the Vercel body. The client must PUT the bytes.
-
create_media_drop, mint a no-login
https://www.poster.ly/drop/<token>page so a human can upload a laptop file. Chat paperclips still never reach MCP. -
list_media, list newest media assets, or files from one drop session, then pass
public_urltovalidate_post/create_post. -
find_available_slot, find the next open posting slot honoring the 1h gap.
-
generate_captions, generate or adapt brand-aware caption suggestions without creating a post. Captions are checked against the brief and the workspace's business facts; unverifiable prices, dates, times, links, phone numbers and handles are removed, as is any never-say phrase set on a fact, so fewer variants than requested may come back.
-
generate_image, create AI images with Nano Banana.
-
get_video_options, inspect read-only Veo video models, durations, input modes, and credit-cost estimates.
-
run_video_function, run read-only Veo helpers for cost estimation and request validation.
-
generate_video, queue a cost-guarded Veo video job after user confirmation.
-
get_credits, read the AI credit balance for the caller's workspace wallet. Read-only, spends nothing.
-
get_video_job, poll one Veo job or list recent video jobs until
video_urlis ready. -
get_account_analytics, follower growth, reach, views, engagement rate for social platforms, and API-provided native
display_metricssuch as Google Business Profile's Profile Views, Search Views, Maps Views, Customer Actions, and Posts (Instagram, Facebook Pages, LinkedIn, Google Business Profile, Pinterest, YouTube, and Threads). Acceptspresentation: "compact" | "table" | "json"so Telegram can stay bullet-based while Markdown clients or custom renderers can choose tables/structured data. -
get_post_analytics, per-post likes, comments, reach, impressions, saves, shares, plays. Also accepts
presentation: "compact" | "table" | "json". -
get_performance_profile, read the read-only performance profile posterly derives for one account from the last 90 days of per-post analytics (top formats, timing, caption-length patterns, an engagement-rate trend, and a narrative summary), keyed by social account ID. Requires a Pro plan or higher.
-
get_post_insights, list per-post feedback-loop insights for recently published posts: the performance tier (great/good/mixed/poor), a diagnosis, a suggested next action, metrics, and the baseline each was compared against. Filter by
account_id,post_id, andcheckpoint(1h, 6h, 24h, 72h, 7d). Requires a Pro plan or higher. -
list_post_suggestions, list evidence-based weekly post drafts written in each account's learned voice, each with a
rationaletying it back to what has performed well. Filter byaccount_idandstatus(pending, scheduled, dismissed). Requires a Pro plan or higher. -
dismiss_suggestion, dismiss a post suggestion after user confirmation. Never dismisses a suggestion that was already turned into a scheduled post.
-
list_conversations, list Instagram and Facebook Page inbox DMs. Threads has no DMs. Requires a Pro plan or higher.
-
get_conversation, get one inbox conversation and its messages.
-
send_message, send a DM reply after explicit confirmation. Honors Meta 24-hour messaging windows.
-
list_comments, list Instagram, Facebook Page, and Threads inbox comments.
-
get_comment, get one inbox comment and its replies.
-
reply_to_comment, reply to a comment after explicit confirmation. Facebook has no private comment replies; Threads is public-only.
-
update_comment, hide/unhide a comment or mark it read. Hide is reversible and does not delete.
-
delete_comment, delete an Instagram or Facebook Page inbox comment after confirmation. Irreversible. Admin only. Threads replies cannot be deleted; hide them with update_comment.
-
sync_inbox, pull the latest inbox data for one Instagram, Facebook, or Threads account, with a 30-second cooldown.
-
list_google_business_reviews, list GBP reviews for one location or every accessible location. Returns every review Google holds (it pages past Google's own 50-per-page cap), with the full untruncated review text and its date. Filter by
ratingandunanswered, and page withlimit(default 200, max 1000) andoffset;has_moretells you when more remain. Each location also reports itstotal_review_countandaverage_ratingfrom Google, plus anerrorfield, so a location with no reviews is distinguishable from one that failed to sync. -
get_google_business_review_link / audit_google_business_profile, generate review request links and run local-profile audits.
-
suggest_google_business_review_reply, generate brand-aware reply options without posting.
-
reply_google_business_review / delete_google_business_review_reply, manage public GBP review replies after explicit confirmation.
-
list_google_business_media, list the photos and videos on a GBP profile gallery (the media shown on Maps and Search).
-
add_google_business_media / delete_google_business_media, add a photo/video to the profile gallery from a public URL, or remove one, after explicit confirmation.
Google Business tip: pass
account_id(the integeridfromlist_accounts) to every GBP tool. If you uselocation_idinstead, it is the numericlocation_idfromlist_accounts(the GBP location id), not theChIJ...Place ID thatget_google_business_review_linkreturns. Passing the Place ID resolves to no account and returns "Google Business Profile account not found".
- list_activity, read the agent notifications feed of post activity, publish attempts, failures, and retries.
- get_updates, get the latest posterly product updates and news from the updates feed. Requires an active posterly subscription.
- list_webhooks, inspect webhook subscriptions and delivery status.
- create_webhook / update_webhook / delete_webhook / test_webhook, manage signed webhook subscriptions after explicit confirmation.
- get_x_posting_quota, inspect workspace X posting allowance and URL-block status.
- get_subscription, read the user's posterly subscription status, tier, cancel/pause state, and period end. Requires the
billing:readscope. - cancel_subscription, cancel the subscription after explicit confirmation. The agent must ask the user for a cancellation
reasonfirst (a fixed catalog value) and passconfirm: true;immediatedefaults to cancel-at-period-end. Requires thebilling:writescope. - pause_subscription, pause the subscription for 30 days (one pause per 90-day cooldown) after
confirm: true. Requires thebilling:writescope. - resume_subscription, resume a paused subscription. Requires the
billing:writescope. - downgrade_subscription, downgrade one tier (or to an explicit lower
tier) at the next renewal afterconfirm: true. Requires thebilling:writescope.
Subscription management runs on the same API key but does not require the paid API add-on, so a paused or cancel-pending user can still resume or manage their plan. The destructive actions (
cancel_subscription,pause_subscription,downgrade_subscription) requireconfirm: trueafter explicit user confirmation, andcancel_subscriptionalso requires areason. Reactivating a pending cancellation, restarting a lapsed plan, and retention offers stay in the dashboard.
Usage examples
In Claude, ChatGPT, or any MCP client:
- "Schedule a LinkedIn post about our Q1 results for tomorrow at 10am"
- "What accounts do I have connected to posterly?"
- "Disconnect the old Instagram account after I confirm the exact account ID"
- "Pause post 971 after I confirm it is the right scheduled post"
- "Upload this image and create an Instagram post with it"
- "Schedule this as an Instagram Reel, add @partner as a collaborator, and use this image as the Reel cover"
- "Schedule this YouTube video as unlisted, add these tags, and put it in our launch playlist"
- "Post this TikTok with comments on, duet off, stitch off, and public privacy"
- "Turn this Google Business update into an event post with a Learn more CTA"
- "How did my Instagram perform over the last 14 days?"
- "Which of my recent LinkedIn posts got the most engagement?"
- "Post this 5-tweet thread on my X account at 3pm tomorrow" (uses
thread_postsfor X / Threads chains)
platform_settings covers the same scheduling controls exposed by the composer: Instagram feed/story/reel/carousel options plus parent-container is_ai_generated and licensed Reel audio_id (Facebook Login / Meta-linked only), Facebook stories/reels/backgrounds, YouTube thumbnails/privacy plus notify_subscribers, add_shorts_hashtag, and optional brand_partner, LinkedIn document, mention, poll, and content_call_to_action_label settings (including BUY_NOW and SHOP_NOW), TikTok video and photo slideshow controls (including video_cover_timestamp_ms to pick the cover frame on direct-post videos), Pinterest board/link/title/product_tags, Google Business event/offer/CTA/recurrence fields, X polls, reply settings (incl. subscribers/verified), and paid_partnership, Threads reply controls, polls, topic tags, text attachments, ghost posts, spoilers, reply approvals, GIPHY, and share_to_instagram, Telegram polls, inline CTA buttons, video cover, and live photo, Slack markdown/blocks, Mastodon visibility/quote/poll (media plus poll allowed), and Bluesky language, alt-text, content warnings, hidden tags, quote posts, and disable-quotes settings. Pass ai_generated: true to label a post as AI-generated on TikTok, X, YouTube, Pinterest, and Instagram.
For TikTok you do not need to set a post type for images. posterly auto-detects image media and schedules it as a photo slideshow of 1 to 35 images (sending every image), so "Schedule these 5 photos as a TikTok" just works. A single video schedules as a standard TikTok video.
See the MCP marketing page for client-specific setup screenshots.
Claude Code plugin alternative
If you use Claude Code, you can install the official posterly plugin instead of editing MCP config by hand. The plugin bundles this MCP server plus the agent skill and a guided /posterly:setup flow.
/plugin marketplace add awpthorp/posterly-agent
/plugin install posterly@posterly-agent
Full steps: Claude Code plugin.