Skip to main content
Glama
posterly-mcp-server

posterly-mcp-server

by awpthorp

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
POSTERLY_API_KEYNoYour posterly API key (for example, pst_live_your_key_here). Optional for the local server: leave it out only when an assistant should start signup first. Authenticated tools require an API key, or the hosted endpoint can use OAuth/Bearer auth instead.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

posterly groups its tools into sets: core (Accounts, posting, media, schedule, analytics, and support); creative (AI image and video generation, jobs, and post suggestions); inbox (Social inbox comments and DMs); google_business (Google Business Profile reviews, media, and audits); admin (API keys, OAuth clients, webhooks, workspace members, and the publishing pause); billing (Subscription changes and Agency extra accounts); signup (Pre-auth signup for brand-new users). Every set is on by default. To load fewer tools, set POSTERLY_TOOLSETS=core,inbox (or pass --toolsets=core,inbox). The signup tools are always on. Sets only change which tools are listed; any tool can still be called by name. Merged tools pick what to do with a view, action, or type param; each tool description names every option. Tools that post publicly or delete things use preview then confirm: call once without confirm to get a preview and a preview_id, show it to the user, then call again with confirm: true and that preview_id.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_agent_signup_infoA

Explain how to use posterly MCP for agent-led signup before an API key exists, including the safe human-in-the-browser boundaries.

start_signupA

Start the public posterly signup for a user before posterly API access exists. A new account starts a 7-day free trial: Stripe Checkout collects a card, nothing is charged today, and the card is charged on day 8 unless the paid plan starts sooner. API and MCP stay limited during the trial. The API add-on is still required. Returns a signup poll URL, a browser Checkout handoff URL, and a payment object for that Checkout session (trial length, whether anything is charged today, merchant, and agent-wallet instructions). An account that already had a trial is charged at checkout instead. The user still sets a password and approves social OAuth in the browser. Never ask for card numbers, a posterly password, or social passwords in chat.

get_signup_sessionA

Poll a public posterly signup session created by start_signup. Use this to narrate the free trial (card saved, nothing charged today), password setup, and agent access status before a posterly API key is installed. An account that already had a trial is charged at checkout instead. Keep updates user-facing; do not narrate raw HTTP, curl, or API plumbing.

whoamiA

Who you are and how posterly is connected. view=identity (default): the authenticated user, API key scopes, workspaces, and onboarding next step. Pass include=api_keys to also list this account's API keys (name, prefix, scopes, created, last used). The secret is never included. ALWAYS call this at the start of a session; if onboarding.completed is false, walk the remaining onboarding steps IN THIS conversation (about you, connect, brand voice, first post) and do not send the user to /onboarding-v2 or the dashboard composer wizard. view=status: MCP server version, latest npm version, endpoint and API key health, and update guidance; works before POSTERLY_API_KEY is configured.

list_accountsA

Connected social accounts and what posterly has learned about them. view=accounts (default): connected accounts, optionally one workspace_id or one account_id. Each row has connection_status ok or needs_reconnect (reason and date, never a token). Pass connection needs_reconnect to list only accounts that need a reconnect. Instagram rows identify direct-login versus Meta-linked connections and whether native media tags/collaborators are available, so check this before Instagram user_tags or collaborators. view=learned_voice (account_id): the voice learned from the account's real published captions (summary, traits, style guidelines, habits); read-only, never overwrites the saved brand profile. view=performance_profile (account_id): 90-day coaching stats, engagement-rate trend, and summary (Pro plan or higher; platforms without per-post analytics never get one). view=connect_session (session_id): poll a session from create_connect_session and keep the user updated in plain language; stop when status is connected, failed, cancelled, or expired.

disconnect_accountA

Disconnect a connected social account from posterly. DESTRUCTIVE and IRREVERSIBLE: removes the account connection, emits account.disconnected webhooks, and may transfer Instagram scheduled posts to a replacement account.

REQUIRED BEFORE CALLING: Call list_accounts first, show the user the exact platform, username, account ID, and workspace that will be disconnected, then get explicit confirmation. Pass confirm=true only after that confirmation.

connect_accountA

Connect a credential-based social account (telegram, bluesky, discord, wordpress, devto, hashnode, lemmy) directly, without a browser session. Call list_platforms with view=connect_link first to discover the exact credential fields the platform needs. Prefer scoped secrets: app passwords (Bluesky, WordPress), bot tokens (Telegram), webhook URLs (Discord), and API tokens (Dev.to, Hashnode) over primary passwords. Warn the user that any credential they share passes through this conversation. For OAuth platforms (Instagram, X, LinkedIn, ...) use create_connect_session instead.

create_connect_sessionA

Create a short-lived posterly dashboard handoff session for connecting a social account. Send the secure connection URL to the user, then poll list_accounts with view=connect_session to narrate progress. Do not ask for social media passwords or OAuth codes; posterly handles those browser steps.

create_api_keyA

Create a new posterly API key for the authenticated user. SECRET-CREATING WRITE: only use after explicit user confirmation. The new key can only request scopes already present on the calling dashboard-created API key; OAuth and managed assistant tokens cannot mint keys. Team management (members:read, members:write) and client portal sign-in link permissions are never copied or granted here: a person turns them on in /dashboard/api.

delete_api_keyA

Revoke a posterly API key owned by the authenticated user. DESTRUCTIVE: call whoami or use a known key ID, show the user the exact key ID/prefix/name if available, and get explicit confirmation before calling. Cannot revoke the key currently authenticating this request, OAuth-issued keys, or managed assistant keys.

list_workspace_membersA

List the people in a workspace: members (with role, status, brand access and API access) and pending invites, plus seats in use. API access says whether a teammate can use this workspace's API plan from their own keys and AI apps; owners and admins also see each member's key count, connected AI apps and last use. Needs an API key with the Manage team permission. Any workspace member can list; brand-limited teammates only see brand ids they can access.

manage_workspace_memberA

Invite, update, or remove a workspace colleague. This SENDS EMAILS and CHANGES WHO CAN ACCESS the workspace. Needs an API key with the Manage team permission, and the caller must be a workspace owner or admin. ALWAYS preview first: call without confirm, show the preview to the user, and only call again with confirm: true plus the returned preview_id after the user explicitly approves. action=invite: email and role required (publisher, editor or viewer), optional brand_ids and resend; always sends a pending invite email, never adds anyone instantly. action=update: member_id or invite_id (from list_workspace_members) plus role and/or brand_ids; or member_id plus api_access (true or false, on its own) to turn API and AI app access on or off for that teammate, which lets them use the workspace API plan from their own keys and AI apps (off by default; you cannot change your own; only the owner can change it for an admin; turning it off stops their keys, AI app connections and webhooks for this workspace). action=remove: member_id (removes the teammate and revokes their API keys for this workspace) or invite_id (cancels a pending invite). Admin seats can only be granted in the posterly dashboard. The workspace owner is emailed about every change.

list_publishing_pausesA

Is publishing paused? Shows whether the workspace is paused, which brands are paused (only brands you can see), and whether you may pause, resume, or publish missed posts. Read-only. Change it with manage_publishing_pause.

manage_publishing_pauseA

Pause or resume publishing for a whole workspace or one brand (check it first with list_publishing_pauses). Only act when the user asks; never pause on your own initiative. action=pause (optional brand_id; leave it out for the whole workspace): holds every scheduled post in that scope and blocks Post now until an admin resumes. Call it first without confirm to get a preview (scope and how many scheduled posts it holds), show it to the user, and only after they agree call again with confirm=true. Publisher or higher; a seat limited to some brands can only pause those brands. action=resume (optional brand_id; admin or higher): future posts are scheduled again; posts whose time passed while paused stay paused and are listed as missed. Missed posts never publish on their own. action=publish_missed (post_ids from the resume, confirm=true after the user agrees; admin or higher): publishes those missed posts now.

get_creditsA

Get the authenticated user's posterly AI credit balance: what is available to spend now, how much of the monthly included allowance is left, purchased pack balance, plan tier, and when the included pool next resets. Credits are a shared WORKSPACE wallet, so this reports the balance the caller can actually spend, not a personal figure. Read-only, spends nothing. Requires the billing:read scope.

get_subscriptionA

Get the authenticated user's posterly subscription: status, tier, cancel-at-period-end, period end, trial end and pause state. Also reports connected accounts in use and the account limit for the workspace this caller is acting in (plan tier plus any extra slots). Call this FIRST for "upgrade", "change plan", "add accounts" or "how many accounts": it returns the plans above this user's with prices, limits and credits, the Agency extra-accounts state (owners), and the exact next steps. Read-only. Requires the billing:read scope.

cancel_subscriptionA

Cancel the authenticated user's posterly subscription. DESTRUCTIVE; requires billing:write. ALWAYS ask the user why they are cancelling FIRST and pass their answer as reason (one of the allowed values). By default an active or trialing plan is set to cancel at the end of the current period. A past_due or unpaid plan always ends now, even when immediate is false: the unpaid renewal is dropped and payment retries stop. Pass immediate=true only when the user explicitly wants an active plan cancelled right now. Only call after the user explicitly confirms.

pause_subscriptionA

Pause the authenticated user's posterly subscription for 30 days (one pause allowed per 90-day cooldown). Billing action; requires the billing:write scope. Only call after the user explicitly confirms.

resume_subscriptionA

Resume the authenticated user's paused posterly subscription, restoring active billing. Requires the billing:write scope.

downgrade_subscriptionA

Move the subscription down one tier (or to an explicit lower tier) now: the lower limits and credits apply right away, the lower price starts at the next renewal, and the rest of the current period is not refunded. Strictly downward only. Requires billing:write. Only call after the user explicitly confirms.

upgrade_subscriptionA

Upgrade to a strictly higher plan. MONEY: charges the saved card (prorated). Owner only. Call without confirm for the quote and preview_id; after the user agrees, call with confirm=true, that preview_id and the expected_ fields. 3D Secure or a decline returns a payment link; nothing changes.

manage_extra_accountA

Buy, raise, lower, or remove Agency extra-account slots. MONEY: raising charges the saved card. Owner only; billing:write. action=set (extra_accounts = desired TOTAL, 0 removes all; add 20+ at a time). Call without confirm for the quote and preview_id; after the user agrees, call with confirm=true, that preview_id and the expected_ fields from the quote. 3D Secure or a decline returns a payment link; nothing is added.

list_oauth_clientsA

List self-serve OAuth developer clients owned by the user. These are public PKCE clients for third-party app integrations.

manage_oauth_clientA

Manage self-serve OAuth 2.1 + PKCE developer clients (public clients with no client secret; list them with list_oauth_clients). action=create: client_name, allowed_redirect_uris, and default_scopes; confirm=true only after the user confirms the name, redirect URIs, and scopes. action=update: client_id plus the changed fields; confirm=true after the user confirms the changes. action=delete: client_id; prevents new authorizations (existing access tokens stay revocable as API keys); preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id.

list_platformsA

Platforms, settings schemas, and connection links. view=platforms (default): posterly platform integrations, posting capabilities, content/media limits, settings schemas, helper tools, and analytics support (include_planned shows future integration possibilities). view=schema: the settings schema for one connected account_id (preferred: returns connection-specific capabilities, needed before Instagram native tags/collaborators) or one platform; account_id wins if both are given. view=connect_link: dashboard handoff links and readiness for every target, or one target (instagram, meta, linkedin_page, twitter, telegram, reddit, wordpress, ...); use connection_url in a logged-in browser (direct OAuth URLs are intentionally not exposed); credential platforms show the credential_fields that connect_account needs.

trigger_platform_helperC

Run account-specific platform helper discovery. Available helpers: linkedin.company_lookup, linkedin.recent_mentions, pinterest.boards, tiktok.creator_info, x.quota, youtube.playlists.

list_brandsA

Brands (clients) and their saved context. view=brands (default): brands the caller can access with brand ID, name, workspace ID, source, and how many social accounts are assigned (optional workspace_id). view=brand (brand_id): one brand with its workspace, source, and linked legacy brand group. view=accounts (brand_id): the connected social accounts assigned to the brand; use it when a user refers to a brand name rather than an account handle. view=profile (brand_id): voice and tone, audience, keywords, dos and don’ts, visual notes, and other saved brand context.

manage_brandA

Create, update, or archive a brand. action=create (admin only): name, and the workspace_id from whoami when the key is not already scoped to one workspace. Optional timezone and website_url. Pass confirm=true only after the user agrees. action=update (admin only): brand_id plus name, timezone, or website_url. Pass confirm=true only after the user agrees. action=archive (admin only): preview then confirm. Call without confirm to see the brand and what archiving does, show that to the user, then call again with confirm=true and the preview_id. Archiving removes the brand from the active list. Connected accounts stay connected, and its scheduled posts are not cancelled: they still publish. The preview counts both.

list_post_suggestionsA

List proactive post suggestions: evidence-based weekly drafts posterly writes in each account's learned voice, each with a rationale tying it back to what has performed well for that account. The caption, rationale, and account id are returned in full. Filter by account_id and status (pending, scheduled, dismissed; default pending). The output says whether every matching suggestion is shown; page with offset until it does. Read-only; requires a Pro plan or higher. Use dismiss_suggestion to hide one, or pass save_as_draft true on that tool to keep it as an unpublished draft.

dismiss_suggestionA

Dismiss a proactive post suggestion so it stops appearing, or pass save_as_draft true to turn it into an unpublished draft instead. A draft is not scheduled and nothing is published. WRITE: confirm the exact suggestion with the user first. Never dismisses, and does not overwrite, a suggestion that was already turned into a post.

submit_agent_feedbackB

Submit bounded private operational telemetry after a concrete posterly workflow outcome. This does not alter product content but writes a private feedback event. Never include API keys, prompts, captions, media URLs, personal data, or fabricated outcomes.

submit_product_feedbackA

File a product bug, idea, or general feedback on the public posterly feedback board (same board users see in the dashboard). Only call this when the human explicitly asks to report a bug, suggest a feature, or send feedback to posterly. Require confirm=true after they approve the title and category. Never use this for tool failures or retries - use submit_agent_feedback for private operational telemetry. Never include API keys, secrets, captions, media URLs, or personal data about third parties.

validate_postA

Validate and normalize one post without creating it. This does not create records, copy remote media, consume post-item/storage quota, reserve X quota, emit webhooks, or enqueue publication. Third-party media may return remote_media_not_materialized because live create performs storage copy and final byte validation. Use this before showing the final preview and asking for confirmation to call create_post.

create_postA

Schedule or immediately publish a social media post. This is a DESTRUCTIVE WRITE that creates content on the user's real social accounts - once scheduled_at passes, it will be posted publicly and cannot be un-posted.

REQUIRED BEFORE CALLING:

  1. Call whoami at the start of any new session to confirm which workspace and user you are acting for.

  2. Show the user a preview containing ALL of: account(s) and platform(s), final caption text, scheduled time (in the user's timezone), media attached (if any), and workspace name.

  3. Get explicit confirmation from the user (e.g. "post it", "yes schedule that", "looks good") BEFORE calling this tool. Do NOT infer consent from earlier instructions like "post about X every Monday" - confirm each individual post or the entire batch.

  4. If scheduling multiple posts in one turn, list every post first and confirm the batch as a whole, then prefer create_posts_batch so they are created in one API request.

AFTER CALLING: Tell the user the post was created, include the posterly dashboard link returned by the tool, and offer the next natural action. Do not narrate raw HTTP, curl, or API plumbing.

Provide either account_id OR username+platform to identify the account. If scheduled_at is omitted, the post publishes immediately. If workspace_id is omitted, the server resolves one from the social account, falling back to the caller's default (personal) workspace - pass workspace_id explicitly if the user has more than one workspace.

MEDIA URLS: Posterly storage URLs are used as-is. Third-party HTTP(S) media URLs are copied into posterly storage before the post is saved, so API-created posts do not later fail on expired signed URLs. Short-lived signed URLs must still be live when this tool runs. You can also call upload_media with url first if you want to upload once and reuse the returned posterly URL across posts.

THREADS: Pass thread_posts (an array of 2+ strings) to schedule a multi-post thread on X (Twitter) or Threads (Meta). The first entry is the lead post; the rest are published as replies in the same chain. X entries are capped at 280 characters each (4000 for verified, 25000 for organization accounts); Threads entries are capped at 500 characters each. When thread_posts is set, caption is ignored.

X ARTICLES: To publish on X as a long-form Article, pass platform_settings.article ({ title, cover?: "first_image" | "none" }) for an X account. The caption becomes the Article body and is written as Markdown (headings, bold, italic, lists, quotes, code blocks, tables, dividers). Reference attached images with ![caption](media:1). Needs an X Premium account; polls, threads, paid partnership, video, and GIFs are not allowed with an Article.

PLATFORM SETTINGS: Pass platform_settings for composer-equivalent controls: Facebook story/reel/backgrounds, YouTube title/privacy/thumbnail/brandPartner, LinkedIn document titles/mentions/polls/content_call_to_action_label (including BUY_NOW and SHOP_NOW), TikTok direct-post privacy/toggles/commercial disclosure, Pinterest board/title/link/product_tags, GBP event/offer/CTA/recurrence, X reply settings/polls/paid_partnership, Threads reply controls/text attachments/ghost posts/spoilers/reply approvals/GIPHY, Telegram polls/buttons/video cover/live photo, Slack markdown/blocks, Mastodon visibility/quote/poll (media+poll allowed), and Instagram feed/story/reel/carousel/native media tags/collaborators/first comments/trial Reels/is_ai_generated/audio_id/caption add-ons. Instagram caption add-ons (caption_addon, or poll_attachment / is_comment_prompt_used) need a Facebook Login account, a non-empty caption, and a feed photo, Reel, or carousel parent. Stories are rejected. A poll and a comment prompt cannot be combined. For Instagram, @username in caption is only a caption mention; user_tags creates native media tags and collaborators sends co-author invitations only when the selected Meta-linked account reports those capabilities. Call list_platforms with view: "schema" and the account ID first. instagram_settings remains as a backwards-compatible alias.

TIKTOK MEDIA: TikTok supports a single video or a photo slideshow of 1 to 35 images, never multiple videos. Image media auto-detects as a slideshow, so you usually do not set post_type or media_type for photos and every image is posted. Pass platform_settings.media_type: "PHOTO" to force a slideshow explicitly.

create_posts_batchA

Create 1-25 scheduled or immediate social posts in one API request. This is a DESTRUCTIVE WRITE that creates content on the user's real social accounts - once scheduled_at passes, posts may go public and cannot be un-posted.

REQUIRED BEFORE CALLING:

  1. Call whoami at the start of any new session to confirm which workspace and user you are acting for.

  2. Show the user a preview of EVERY post: account/platform, final caption or thread text, scheduled time in their timezone, media, platform settings, and workspace.

  3. Get explicit confirmation for the whole batch before calling. Do not infer consent from an earlier content plan.

AFTER CALLING: Summarize the batch result in natural language, include the posterly dashboard link returned by the tool, and avoid narrating raw HTTP, curl, or API plumbing.

Each item accepts the same fields as create_post, including thread_posts, platform_settings, instagram_settings, media URLs, and workspace_id. The endpoint may partially succeed; failed items are returned with their index.

find_available_slotA

Find available time slots for posting. Respects a 1-hour gap between posts and preferred hours (8am-10pm in the given timezone). Returns up to 10 slots. IMPORTANT: pass a timezone explicitly - default is America/New_York and slots will be off if the user is elsewhere. Each slot includes the UTC instant to pass as scheduled_at. Pass workspace_id to only avoid collisions with posts in that workspace. strategy "best_engagement" (needs account_ids) ranks the next 7 days by when these accounts get the most engagement, with a 1-5 star rating and a reason per slot.

list_postsA

Posts in your workspaces, teammates' too, per your role there (brand-locked seats only see their assigned brands). If workspace_id is omitted, this searches every workspace you belong to. view=list (default): posts filtered by status (draft, scheduled, publishing, processing, awaiting_tiktok_publish, awaiting_manual, published, failed, paused, paused_due_to_token, paused_due_to_billing, or missed), platform, account_id, workspace_id, brand_id, group_id, release_id, approval_status, approval_waiting_on, and a scheduled date range: scheduled_from (inclusive) and scheduled_to (a plain date includes that whole day), read in timezone (IANA, default UTC; also the zone times are shown in). status=missed is posts that failed, scheduled posts whose scheduled time is already past, and posts a publishing pause held past their time. group_id matches the caller group (including post_group_id). release_id matches that release only. Returns limit posts (default 20, max 200) starting at offset; with a date range the order defaults to oldest first (order=asc|desc). The output always says whether every matching post was shown. If it says more are available, call again with the offset it gives and keep paging until all are shown before drawing any conclusion about totals, gaps, or how busy a client is. view=counts (scheduled_from and scheduled_to required, up to 366 days): exact totals per day, status, account, and brand for the same filters (limit, offset, and order are ignored); use it for "how many" or "is this month full" questions. Each post includes approval.pending_client_approval.

upload_mediaA

Upload an image or video to posterly storage and get a URL for create_post. Supports JPEG, PNG, GIF, WebP, MP4, MOV, WebM (PDFs are not accepted here: use create_signed_upload or create_media_drop). Images up to 10MB, videos up to 50MB. Three ways in: file_path (an explicit local path the user gave you), base64_data with filename (PREFERRED for images shared in chat, which are not on the local filesystem), or url (a public HTTPS image or video; local/private network URLs are blocked).

This writes to the user's media storage (counts against quota) but does NOT publish the file anywhere. Uploading is safe - it's the subsequent create_post call that publishes content, and that tool has its own confirmation requirements. Never guess file paths. You can also pass public HTTP(S) media URLs directly to create_post/update_post; use url here when you want to upload once and reuse the returned posterly URL. Pass asset_id (from list_media) to delete that library file: the first request previews it and deletes nothing; send it again with confirm true and that preview_id only after the user agrees. A file a post still uses is kept.

create_signed_uploadA

Create signed upload URLs for larger images, videos or PDFs, 1 to 20 files per call. Accepts JPEG, PNG, GIF, WebP, MP4, MOV, WebM, and PDF up to 50MB (a PDF is for LinkedIn document posts); HEIC is not accepted. For one file pass filename, content_type and size. For several pass files: [{filename, content_type, size}] and get one slot per file, with any file that fails reported in place. PUT the raw bytes of each file to its upload_url (object storage) with the returned headers, then pass public_url to create_post / create_posts_batch. For a PDF, create the post with post_type document, media_url set to that public_url and a document_title in settings (LinkedIn only). Pinning is available per request with pin_content_type: true, which locks each slot to the content_type you declare (a PUT with any other Content-Type then fails with 403). posterly may turn it on by default in the future, so always send the Content-Type header returned with the slot. Slots expire in 15 minutes.

create_media_dropA

Create a human drop page so ChatGPT or Claude users can upload laptop files (up to 20 per link) without dashboard login. Returns drop_url (https://www.poster.ly/drop/). Send that URL to the user, wait, then call list_media. Accepts JPEG, PNG, GIF, WebP, MP4, MOV, WebM, and PDF up to 50MB (a PDF is for LinkedIn document posts); HEIC is not accepted. This is not the chat paperclip and not create_signed_upload.

list_mediaA

List the newest media assets for the authenticated user. After create_media_drop, pass drop_session_id to see files the human uploaded on /drop/. Each file includes its filename and the time it was added. Use public_url with validate_post / create_post. A drop listing returns up to 20 files per page by default so a full drop fits one page. The output says whether every matching file is shown; page with offset (offset + limit up to 1000) when it is not.

get_video_optionsA

List read-only Veo video generation options, input modes, durations, resolutions, aspect ratios, and credit-cost estimates. This does not generate video or spend credits.

run_video_functionA

Run a read-only Google Veo or xAI Grok video helper function before generation: list_input_modes, estimate_cost, or validate_request. This does not generate video or spend credits.

generate_videoA

Queue an AI video generation job with Google Veo 3.1 or xAI Grok Imagine Video 1.5. COSTS CREDITS: confirm provider, prompt, duration, resolution, aspect ratio, audio choice, and credit cost with the user before calling. Grok supports 1 to 15 seconds and 480p to 1080p; reference-to-video is capped at 720p. Poll list_jobs with type=video for status and final video_url.

list_jobsA

AI generation jobs. type=image: one image job by job_id, or recent image jobs when job_id is omitted (filter by status, limit); poll it after generate_image for the finished urls. type=video: one Veo or Grok video job by job_id, or recent video jobs (status includes dismissed, limit); poll it after generate_video for the finished video_url.

generate_captionsA

Generate or adapt AI caption suggestions for one or more social platforms. Uses AI Caption Assist quota and returns options only; it does not create or schedule posts. After the user chooses final copy, pass it to create_post or create_posts_batch.

generate_imageA

Queue an AI image job via posterly using Nano Banana (Gemini) or Grok Imagine Image 2.0 (xAI). Returns job_id. Poll list_jobs with type=image until status is completed, then pass urls to create_post as media_url / media_urls. Gemini thinking high does not change the credit price.

COSTS CREDITS. Every call consumes part of the user's monthly AI image quota (or purchased credits once the quota is exhausted). Do NOT call speculatively - always describe the image you're about to generate (subject, style, aspect ratio, quality/thinking, resolution) to the user and get confirmation before calling.

If the user is over their plan limit and has no credits, this tool returns a 402 with upgrade info. Surface that message verbatim - do not retry.

Common aspect ratios by platform: • Instagram feed / LinkedIn: 1:1 (square) or 4:5 (portrait) • Instagram Story/Reel, TikTok, YouTube Shorts: 9:16 • YouTube thumbnail, Twitter cards, landscape feed: 16:9 • Pinterest: 2:3

get_postA

One post by ID. view=post (default): caption, status, platform, account, scheduled time, when it was created and by whom (account and channel, such as dashboard, API, or MCP), media, a link back to the post in posterly, and the failure reason when a publish failed. view=missing: each missing field (content, media, account, platform settings, or metadata) and how to fix it before the post can publish.

ask_supportA

Ask posterly Support AI an authenticated question using posterly docs plus read-only account/post diagnostics for the caller workspace. Requires POSTERLY_API_KEY with accounts:read and posts:read scopes. Human ticket creation requires request_human=true and confirm_escalation=true after explicit user confirmation.

update_postA

Change a scheduled or draft post. DESTRUCTIVE WRITE. Edit (default): caption, media, schedule, post_type, settings, account_id, or thread_posts; overwrites the existing post; cannot edit published or currently publishing posts. account_id moves the post to another account you can use in the same workspace and on the same brand, and the platform follows that account. thread_posts replaces an X or Threads reply chain with at least two non-empty parts, and the first part becomes the caption. If a client has already approved the post, a caption edit reopens caption approval, a media or thumbnail edit reopens asset approval, and a reschedule, account change, thread edit, or settings change reopens both. status (scheduled, paused, or draft, with scheduled_at when scheduling a draft): pause, resume, or move back to draft; send it on its own. release_id (with optional group_id): set or repair external release/group IDs; send it on its own. approval_action (request, approve, request_changes, or reject): change client approval. Only a workspace owner or admin may do this. The actor is the API key user, never a brand guest. request emails the brand reviewers. approve, request_changes, and reject are team-side decisions. request_changes needs approval_note. Optional approval_axis is asset or caption; omit it for both. Send approval_action on its own.

REQUIRED BEFORE CALLING: Show the user a side-by-side of the CURRENT post (caption, scheduled time, media, status) and the PROPOSED change, and get explicit confirmation ("yes update it", "apply those changes") before calling. Do not auto-edit posts based on a general instruction - each change needs its own confirmation.

delete_postA

Delete posts. DESTRUCTIVE and IRREVERSIBLE: deleted posts and captions cannot be recovered. post_id: delete one post; fetch it with get_post first, show the user what will be deleted (caption, account, scheduled time), and pass confirm=true only after explicit confirmation ("yes delete it", "remove it"). A post that is currently publishing is never deleted. A published post is taken down only when the user also explicitly confirms the live removal: delete_mode=platform with confirm_published=true takes the live post down too; delete_mode=posterly removes only the posterly record and leaves it up. Live deletion supports eligible connected platforms with saved post IDs and deletion permissions; refusals keep the record. Threads requires threads_delete. YouTube requires youtube.force-ssl or equivalent, upload alone is insufficient. A published post with no live URL and no platform id is removed from posterly only. group_id: delete every draft, scheduled, failed, or paused post matching a caller-defined group_id, post_group_id, api_group_id, or release_id. A group delete never removes published posts. Preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id. Never delete several posts one by one without listing each and confirming the full list.

list_analyticsA

Analytics for connected social accounts (Instagram, X, Facebook, LinkedIn, Google Business Profile, Pinterest, YouTube, and Threads). view=accounts (account_id): daily snapshots and a period summary with platform-native display_metrics labels. Google Business Profile account analytics includes Calls, Website clicks, and Directions along with Profile Views, Search Views, Maps Views, Customer Actions, and Posts. view=posts (account_id): per-post likes, comments/replies, reach, impressions/views, saves, shares, reposts, quotes, plays, clicks, and watch time, most recent first, with limit/offset. Google Business has no per-post rows; its totals are on view=accounts. view=insights: per-post feedback insights with a performance tier (great/good/mixed/poor), diagnosis, next action, and baseline, filtered by account_id, post_id, or checkpoint (1h, 6h, 24h, 72h, 7d); read-only, Pro plan or higher. presentation (accounts and posts): compact for Telegram/mobile, table for Markdown clients, json for custom chart/card renderers. include_extras on accounts asks for saved audience breakdowns, the last analytics sync, and entity snapshots. Those stay off until snapshot extras are switched on, and this does not start a new sync.

list_google_business_reviewsA

Google Business Profile reviews. view=reviews (default): reviews for one location/account or every accessible GBP location, paging through all reviews Google has (not just the first 50) with the full untruncated review text, its date, and each location's total review count; filter by rating or unanswered, page with limit/offset. Each review has review_name for manage_google_business_review reply/delete_reply. view=review_link (account_id or location_id): the direct public Google review link plus the Google Place ID (ChIJ...); that Place ID is output only and must NOT be passed back as location_id.

audit_google_business_profileA

Run a live local-profile audit for a connected Google Business Profile location. Returns the 0-100 completeness score, letter grade, a score for each section (profile basics, hours, categories, description, photos, attributes, review health, and service areas when the listing travels to customers), and recommendations. A service listing with no areas, or an area more than 80 miles from the business in a straight line, cannot keep a top score.

manage_google_business_reviewA

Act on Google Business Profile reviews. action=suggest_reply (star_rating, optional review_text): short, brand-aware AI reply suggestions; uses the AI Caption Assist allowance and never posts. action=reply (review_name, comment): post or update the owner reply. action=delete_reply (review_name): delete the owner reply. reply and delete_reply use preview then confirm: call without confirm to get a preview and preview_id (it repeats the review name, location, and exact reply text; show the reviewer, rating, and review text alongside it), then call again with confirm=true and that preview_id.

list_google_business_mediaA

List the photos and videos on a Google Business Profile gallery (the media shown on Maps and Search) for one location/account or every accessible GBP location. This is separate from media attached to a post. Returns each item's resource name, category, format, image URL, and date. Pages the gallery already fetched from Google: limit defaults to 50 (max 200) and offset skips that many items.

manage_google_business_mediaA

Change a Google Business Profile gallery (the photos and videos shown on Maps and Search). action=add (source_url, category): add a photo or video from a public https URL (upload it with upload_media first); COVER and PROFILE are single-slot and replace the existing one. action=delete (media_name from list_google_business_media): permanently remove an item from the public profile. Both use preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id.

list_google_business_service_areasA

Read Google Business service areas (the towns and postcodes a location covers, up to 20). view=areas (default): the current business type, country, and place list for one location. view=places (q required): search for a town or postcode to add. Place IDs from view=places are regions, not the review-link Place ID. Town search needs a maps key on the server; if it is missing, add a place with its Place ID and name on the update instead.

manage_google_business_service_areaA

Replace the service areas on a Google Business location. action=update sends the full list (1 to 20 places, each with place_id and place_name from list_google_business_service_areas view=places or a known region Place ID). business_type is CUSTOMER_AND_BUSINESS_LOCATION (customers can visit, and you also travel) or CUSTOMER_LOCATION_ONLY (you only travel to customers). CUSTOMER_LOCATION_ONLY needs region_code when Google has not set one, and clear_storefront_address=true when a street address is still on the listing. The country cannot be changed once set. Preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id. Saving the same list again is safe.

list_google_business_locationsA

Read regular opening hours and attributes for one Google Business location. Stays off until location edits are switched on, and does not call Google while it is off. Pass account_id or location_id. Does not return the business name, address, phone, or website.

manage_google_business_locationA

Change regular opening hours or attributes on a Google Business location. action=update_hours sends regular_hours.periods with open_day, close_day, open_time, and close_time as HH:MM. action=update_attributes sends attributes with a name like attributes/has_wifi and value_type BOOL, URL, or ENUM. Both use preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id. Stays off until location edits are switched on. A confirm while it is off changes nothing and does not call Google. This uses the same business management connection as posting. It does not change the business name, address, phone, or website.

list_conversationsA

Social inbox DM conversations for Instagram and Facebook Page inboxes (Threads has no DMs; Pro plan or higher plus posts:read). Without conversation_id: list conversations filtered by account, platform, unread/starred/archived, search, or since/until dates, with limit/offset paging. With conversation_id: one conversation and its messages; there limit is the number of messages (default 50, max 100) and only workspace_id may be added. When a sync has stored it, each conversation includes the Meta reply window (open until a UTC time, or closed). A reply does not extend that window, and it is not guessed from the messages loaded in the thread.

manage_conversationA

Act on the social inbox (Pro plan or higher plus posts:write). action=send (conversation_id, content): send a DM reply in an Instagram or Facebook Page conversation, honoring the 24-hour messaging window (Threads has no DMs); preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id. action=sync (account_id): pull the latest Instagram, Facebook Page, Threads, or LinkedIn inbox data for one account; 30-second cooldown (60 seconds for LinkedIn); Threads and LinkedIn sync comments only.

list_commentsA

Social inbox comments and replies for Instagram, Facebook Pages, Threads, and LinkedIn Pages (Pro plan or higher plus posts:read). Without comment_id: list comments filtered by account, platform, unread/flagged, search, or since/until dates, with limit/offset paging. With comment_id: one comment and its replies; only workspace_id may be added. YouTube and TikTok are refused rather than returned as an empty list. They stay off until each platform is reviewed and an inbox provider exists.

manage_commentA

Act on an inbox comment (Pro plan or higher plus posts:write). action=reply (comment_id, content): reply to an Instagram, Facebook Page, Threads, or LinkedIn Page comment; type private is Instagram only, the others take public replies only. action=update (comment_id, is_hidden and/or is_read): hide or unhide it on the platform, or mark it read or unread; reversible, no confirm needed. action=delete (comment_id): delete an Instagram or Facebook Page comment, irreversible and admin only; Threads replies cannot be deleted, hide them instead. reply and delete use preview then confirm: call without confirm to get a preview and preview_id, show it, then call again with confirm=true and that preview_id.

list_activityA

List recent activity and publish events for posts, including status changes, publish attempts, failures, and retries, newest first. Use this as the agent notifications feed. The output says whether more events exist; page with offset (offset + limit up to 1000) or narrow with since or post_id before concluding nothing else happened.

get_updatesA

Get the latest posterly product updates and news from the updates feed: new features, improvements, and fixes, newest first. The output says whether more updates exist; page with offset or narrow with since. Requires an active posterly subscription.

list_webhooksA

List API webhook subscriptions, their event filters, active state, and most recent delivery status. view=deliveries (webhook_id) reads recent delivery attempts for one webhook. That history stays off until it is switched on, and it does not include the signing secret or the request body.

create_webhookA

Create a webhook subscription for post/account/analytics events. WRITE WITH OUTBOUND SIDE EFFECTS: show the user the target URL, workspace, events, and active state, then get explicit confirmation before calling. The response includes the signing secret once.

manage_webhookA

Change a webhook subscription (list them first with list_webhooks). action=update (webhook_id): change URL, events, workspace, description, or active state; outbound side effects, so pass confirm=true only after explicit confirmation. action=delete (webhook_id): remove the subscription; preview then confirm: call without confirm to get a preview and preview_id, show the URL, events, and workspace, then call again with confirm=true and that preview_id. action=test (webhook_id): send a signed webhook.test delivery; confirm=true after explicit confirmation.

get_x_posting_quotaB

Get managed X posting quota for a workspace, including total monthly allowance, used posts, remaining posts, and URL-blocking status.

manage_x_posting_addonA

Buy an X posting add-on. action=buy: plan_code is x_posts_100 ($8/month, 100 extra posts), x_posts_250 ($18/month, 250), or x_posts_500 ($35/month, 500). Call without confirm to see the price. Show that price to the user. Nothing is charged on the preview. Then call again with confirm=true, the preview_id, and expected_addon_status, expected_plan_code, and expected_price_usd from the preview. Confirming returns a Stripe Checkout link. The card is charged only after the user pays on that page. If an add-on is already active, confirming opens the billing page for the workspace owner and does not buy a second plan. Read the allowance with get_x_posting_quota. Owner or admin. billing:write.

posterly_statusA

Check posterly's own publishing health: overall state from the last 4 hours of publishing success, any active incident (for example X being unavailable), and per-platform state with 7-day success rate and publish counts. Call it before scheduling a time-critical post, or when a user asks whether posterly or a platform is down or why posts are failing. Says so plainly when there is not enough recent activity to judge. Failures caused by content or account problems (expired connections, content limits) are excluded from the rates and reported separately as customer_side. Not the same as whoami view "status", which only reports the MCP server and npm package version. Read-only; aggregates only, no post or user data.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.4/5.0

Scored across 73 tools

Disambiguation3/5

Most tools target distinct resources or actions, and the descriptions often explicitly distinguish similar tools. However, the huge surface includes many near-neighbors such as create_post/create_posts_batch/validate_post/update_post, upload_media/create_signed_upload/create_media_drop, get_video_options/run_video_function, and several list/manage pairs across billing, inbox, webhooks, and Google Business. These are mostly documented, but the boundaries are not always immediately obvious.

Naming Consistency4/5

The set is overwhelmingly snake_case and follows a predictable verb_noun pattern such as list_posts, create_post, manage_brand, and get_subscription. Minor deviations like whoami, posterly_status, and broad manage_* multi-action tools keep it from being perfectly uniform, but the convention is still readable and stable.

Tool Count1/5

At 73 tools, the server is far beyond a well-scoped surface and into extreme breadth for a single MCP endpoint. Even though many tools map to real subdomains, the count makes navigation, tool selection, and maintenance costly.

Completeness5/5

The surface covers an unusually broad lifecycle: posting and scheduling, media uploads, analytics, social inbox comments and DMs, Google Business Profile management, billing, workspaces, API keys, OAuth clients, webhooks, AI image/video generation, signup, support, and status checks. CRUD and preview/confirm flows are present across nearly every domain, with only minor actions intentionally delegated to dashboard flows.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues