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.
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 Atlas, Cursor in browser, or any web-based agent that can't spawn a local process.
- 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 limits by transport
Local stdio MCP can read a local file path and automatically use signed upload for larger media. Use this option when the agent is running on the same machine as the file and needs to upload videos or larger images.
Hosted HTTP MCP and WebMCP do not have a native binary/file channel. Their upload_media tool accepts base64 JSON and is intended for small files up to 5MB decoded. For larger media, use one of these routes:
- Use
upload_media_from_urlwhen the asset already has a public direct image/video URL that allows server-side GET requests. - Use
create_signed_uploadonly from clients that can alsoPUTthe raw file bytes to the returnedupload_url; then pass the returnedpublic_urltocreate_post. - Use the REST API, CLI, dashboard composer, or local stdio MCP when the agent only has a local file and cannot perform that raw-byte PUT itself.
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; media posterly can adapt automatically is never rejected.
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.
Consistent with the paragraph above, video containers posterly converts for itself are never rejected: .mov, .webm and .m4v are normalised to MP4 before an Instagram post publishes, so pass them straight through.
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-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" - 429, body includes
retry_after,limit,remaining, andreset, plus aRetry-Afterheader.
Available tools
The local stdio server exposes 75 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 72 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.
-
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. Human handoff requires explicit confirmation.
-
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.
-
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, upload an image or video.
-
upload_media_from_url, fetch a public image/video URL into posterly storage with SSRF protections.
-
create_signed_upload, get a direct upload URL for larger media.
-
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.
-
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_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_google_business_reviews / get_google_business_review_link / audit_google_business_profile, inspect GBP reviews, 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, Facebook stories/reels/backgrounds, YouTube thumbnails/privacy/playlists plus notify_subscribers and add_shorts_hashtag, LinkedIn document, mention, and poll settings, TikTok video and photo slideshow controls (including video_cover_timestamp_ms to pick the cover frame on direct-post videos), Pinterest board/link/title fields, Google Business event/offer/CTA fields, X polls and reply settings (incl. subscribers/verified), Threads reply controls, polls, topic tags, text attachments, and share_to_instagram (also share the published Threads post to the linked Instagram account as a Story), Telegram polls and inline CTA buttons, 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, and Pinterest.
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.