MCP server

Connect AI agents to Postgale over the Model Context Protocol.

Updated

Postgale runs a hosted Model Context Protocol server so AI agents (Claude, Cursor, VS Code and other MCP clients) can draft, schedule and publish posts to your connected Instagram, Facebook Pages, Threads, TikTok, Telegram, Discord, Bluesky and Mastodon accounts (X is coming soon), moderate comments, answer direct messages, send WhatsApp messages and read analytics. It exposes the same operations as the REST API (OpenAPI spec), with the same permissions, rate limits and approval rules.

Endpoint and authentication

  • Endpoint: https://staging.postgale.com/mcp (alias https://staging.postgale.com/api/mcp), Streamable HTTP transport, stateless.
  • Sign in (OAuth 2.1): paste the endpoint into ChatGPT, Claude, Cursor or VS Code and sign in to Postgale. You pick the workspace the app may use; it then has the same access as an API key of that workspace. Connected apps are listed, and can be revoked, under Dashboard → Connected apps.
  • API key: Authorization: Bearer sk_… with a Postgale API key from Dashboard → API keys. The key acts for its organization only.
  • Rate limit: shared with the REST API (default 60 requests per minute per key or connected app).

Connect with sign-in (no API key)

Clients that support MCP authorization only need the URL https://staging.postgale.com/mcp. They open a Postgale sign-in and consent page in the browser, then refresh their access on their own.

  • ChatGPT: Settings → Apps & Connectors → Advanced → Developer mode, then Create (or Add connector), paste https://staging.postgale.com/mcp, authentication OAuth.
  • Claude (claude.ai, Desktop and mobile): Settings → Connectors → Add custom connector, paste https://staging.postgale.com/mcp, then Connect.
  • Claude Code: claude mcp add --transport http postgale https://staging.postgale.com/mcp, then run /mcp in Claude Code and choose Authenticate.
  • Cursor and VS Code: add the server with only its URL (no headers); the editor shows a sign-in prompt.
Add to CursorOpens Cursor with the Postgale server filled in; sign in to Postgale when it asks.
mcp.json (sign-in)
{
  "mcpServers": {
    "postgale": {
      "url": "https://staging.postgale.com/mcp"
    }
  }
}

Approve only requests you started yourself: the consent page shows the app, where it returns to, and the workspace it gets. Tick “Hold posts from this app for approval” to send everything it creates to the approval queue.

Connect a client with an API key

Cursor and most clients that accept an mcpServers file:

mcp.json
{
  "mcpServers": {
    "postgale": {
      "url": "https://staging.postgale.com/mcp",
      "headers": {
        "Authorization": "Bearer sk_…"
      }
    }
  }
}

Claude Code:

Terminal
claude mcp add --transport http postgale https://staging.postgale.com/mcp --header "Authorization: Bearer sk_…"

Claude Desktop, through the mcp-remote bridge (keep the key in the environment so it is not split on the space):

claude_desktop_config.json
{
  "mcpServers": {
    "postgale": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://staging.postgale.com/mcp",
        "--header",
        "Authorization:${POSTGALE_AUTH}"
      ],
      "env": {
        "POSTGALE_AUTH": "Bearer sk_…"
      }
    }
  }
}

VS Code:

.vscode/mcp.json
{
  "servers": {
    "postgale": {
      "type": "http",
      "url": "https://staging.postgale.com/mcp",
      "headers": {
        "Authorization": "Bearer sk_…"
      }
    }
  }
}

Raw HTTP, to check a key:

POST /mcp
curl https://staging.postgale.com/mcp \
  -H 'Authorization: Bearer sk_…' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'

curl https://staging.postgale.com/mcp \
  -H 'Authorization: Bearer sk_…' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Mcp-Protocol-Version: 2025-06-18' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

Tools

132 tools. Each declares MCP annotations (read-only, destructive, open-world) so clients can ask for confirmation before writes; the kind below follows them.

ToolWhat it doesKind
Accounts & connect
get_api_key_infoThe key in use, its organization and the effective approval policyRead-only
list_accountsConnected social accounts (ids for create_post), optionally by externalIdRead-only
connect_accountOAuth link a human opens to connect Instagram, Facebook Pages, Threads, TikTok, Discord (installs the bot), Mastodon (with the server) or WhatsApp (Embedded Signup); a one-time /connect code for Telegram; Bluesky with a handle and app password; X is coming soonWrite
select_connectionList pending connections (no pendingId), the options of one (e.g. Facebook Pages), and connect the chosen onesWrite
get_account_healthToken validity, granted scopes, missingPermissions, publishing limit and recommendationsRead-only
update_accountSet externalId, display overrides or the profile of an accountWrite
manage_profilesList, create, update or delete profiles (groups of accounts per brand or client)Destructive
manage_account_groupsList, create, update or delete named account groupsDestructive
bluesky_settingsRead or set a Bluesky account's default post languagesWrite
linkedin_connect_sessionConnect a LinkedIn account by its web session (cookies + user agent), no OAuth; queued for approvalWrite
Approvals
list_actionsAgent actions (replies, moderation, DMs, published-post changes) queued for human approval, with their status and resultRead-only
get_actionOne queued action: pending, executed with its result, failed with the error, or rejectedRead-only
Media
list_mediaRecent uploaded mediaRead-only
get_mediaOne media fileRead-only
upload_mediaImport an image or video from a URL or base64; returns its publicUrlWrite
Posts
list_postsRecent posts, optionally by statusRead-only
get_postOne post with per-platform status, URLs and errorsRead-only
create_postDraft, schedule or publish a post (publishNow publishes live)Destructive
update_postReplace the text of an unpublished postDestructive
delete_postDelete a post from Postgale (not from the platforms)Destructive
publish_postPublish a draft, scheduled or failed post live nowDestructive
manage_published_postEdit (Facebook, Telegram, Discord) or delete (Facebook, Threads, Telegram, Discord, Bluesky, Mastodon) a live post; turn Instagram comments on or offDestructive
retry_postRetry a failed or partially published post nowDestructive
pin_postPin or unpin a published post (Facebook)Destructive
list_platform_postsThe account's recent posts as they exist on the platform, with metricsRead-only
bulk_upload_postsCreate posts from a CSV (dryRun validates first)Destructive
Comments & mentions
list_post_commentsComments on the published targets of a postRead-only
reply_to_commentPublish a reply to a comment (Instagram, Facebook, Threads)Destructive
list_commentsComments and replies on Instagram, Facebook, Threads and Bluesky posts, by post or by accountRead-only
moderate_commentComment, reply, hide/unhide, delete, pin/unpin, private reply; like/unlike where supportedDestructive
like_postLike or unlike any post as the accountDestructive
list_mentionsMedia the Instagram account was tagged inRead-only
list_inbox_mentionsMentions of all accounts from the last 7 days (Instagram, Facebook), from webhooksRead-only
reply_to_mentionReply where the Instagram account was mentionedDestructive
list_inbound_eventsEvents received from Meta webhooks: comments, replies, mentions, Page feed changes, direct messagesRead-only
Direct messages
list_conversationsInstagram, Messenger, WhatsApp, X, Bluesky and Telegram conversations, latest first, with unread counts and the messaging windowRead-only
get_conversation_messagesOne conversation (incl. messagingWindow) and its messages, oldest to newestRead-only
send_messageSend a live DM (text or one attachment; WhatsApp: also templates, interactive, location, reactions; Telegram: buttons, quick replies, reply markup) to the participant, within the messaging window; tag HUMAN_AGENTDestructive
mark_conversation_readMark read in Postgale and as seen on Instagram/MessengerWrite
search_conversationsSearch conversations by participant or message textRead-only
manage_messageEdit, delete, react to or unreact a message, where the platform supports itDestructive
send_typingShow or clear a typing indicatorWrite
get_message_attachmentResolve a message attachment to a URL that works nowRead-only
delete_conversationDelete Postgale's stored copy of a conversation (not on the platform)Destructive
sync_conversationsBackfill conversations of an account (or one conversation) from Meta or BlueskyWrite
start_conversationBluesky (handle or DID) and X (coming soon): send the first live DM to someoneDestructive
Telegram
telegram_bot_commandsGet, set or clear the bot commands ("/" menu) of an account; get also returns the start link for private chatsWrite
Instagram & Facebook
meta_account_settingsIce breakers, persistent menu, greeting and Get Started for Instagram and Messenger DMs; Facebook Page infoDestructive
instagram_lookupStories, story insights, tagged media, follow status; mentions, business discovery, audio, live media and collaborators (Facebook Login)Read-only
facebook_page_dataPage insights, post reactions and earnings, posts that tag the Page, visitor postsRead-only
list_reviewsFacebook Page reviews with ratings, recommendations and repliesRead-only
reply_to_reviewPublish the Page's reply to a reviewDestructive
meta_conversation_actionAccept a message request or hand a conversation over (thread control)Destructive
X (coming soon)
x_engagementComing soon: repost, like, bookmark or follow (and undo) as the X accountDestructive
x_search_postsComing soon: recent search (last 7 days) with X search syntaxRead-only
x_lookupComing soon: one X post (id or URL) or one user (@username)Read-only
WhatsApp
whatsapp_connect_numberConnect a number with an existing token (stored encrypted) instead of Embedded SignupWrite
whatsapp_get_phone_numberDisplay number, verified name, quality rating, messaging limit and onboarding state; refresh from MetaRead-only
whatsapp_register_numberRegister or re-register the number for the Cloud API (6-digit PIN)Write
whatsapp_send_messageSend a live text, media, template, interactive, location or reaction message; outside 24 hours only templatesDestructive
whatsapp_mark_readMark an inbound message read, optionally with a typing indicatorWrite
whatsapp_list_templatesMessage templates of the WhatsApp Business Account, with statusRead-only
whatsapp_get_templateOne template with its componentsRead-only
whatsapp_create_templateSubmit a template for Meta’s reviewWrite
whatsapp_delete_templateDelete a template (one language or all)Destructive
whatsapp_upload_mediaUpload a Postgale media or public URL to WhatsApp; returns the id to sendWrite
whatsapp_get_mediaMIME type, size and sha256 of a WhatsApp media id (download through the REST API)Read-only
whatsapp_search_numbersNumbers Postgale can buy for WhatsApp, with the monthly price (when the instance sells numbers)Read-only
whatsapp_buy_numberBuy a number and connect it to the WABA of a connected WhatsApp account (code captured by Postgale)Destructive
whatsapp_list_numbersNumbers bought for the organization, with status and the limitRead-only
whatsapp_get_numberOne bought number; the code captured in the last 10 minutesRead-only
whatsapp_release_numberRelease a bought number (returned to the carrier; its account stops working)Destructive
whatsapp_send_flowSend a published (or draft) Flow as a live interactive messageDestructive
whatsapp_flowsCreate, upload JSON, publish, deprecate, preview and version Flows; read submissions; encryption keyDestructive
whatsapp_groupsGroup chats: create, update, delete, invite link, participants, join requestsDestructive
whatsapp_automationIce breakers, slash commands and the welcome messageWrite
whatsapp_business_profileBusiness profile and photo, username (and suggestions), display nameWrite
whatsapp_block_usersBlock, unblock and list blocked users; check oneDestructive
whatsapp_callingBusiness Calling: config, permission prompt, live calls, estimates, history, recordingsDestructive
whatsapp_commerceCommerce settings and connected catalogsWrite
whatsapp_conversionsClick-to-WhatsApp conversion events to Meta (dataset created automatically)Write
whatsapp_insightsLive number info, pricing analytics and Meta account eventsRead-only
whatsapp_manage_templatesTemplate edits by name or id, single-language deletes, Meta template libraryDestructive
whatsapp_sandboxSandbox sessions on the shared test numberWrite
Broadcasts & contacts
broadcastsWhatsApp template broadcasts: drafts, recipients, send now or schedule, cancel, per-recipient deliveryDestructive
contactsContacts with channels per account: search, create, bulk import, update, deleteDestructive
TikTok (see /docs/tiktok)
tiktok_get_creator_infoCreator nickname, allowed privacy levels, disabled interactions and max video length; required before every TikTok postRead-only
tiktok_get_profileProfile and lifetime stats: followers, following, likes, public videosRead-only
tiktok_list_videosPublic videos with views, likes, comments and shares (paged), or specific video idsRead-only
Discord (see /docs/discord)
discord_connect_channelBind more channels of a server where Postgale's bot is installed, one account per channelWrite
discord_settingsConnected channel, server channels, default webhook name and avatar, and switching channelWrite
discord_pinsList, pin and unpin a channel's messagesWrite
discord_rolesList, create, edit and delete server roles; assign and remove a member's roleDestructive
discord_membersServer members: cursor-paged list, prefix search, one memberRead-only
discord_eventsScheduled events: list, get, create, update, cancel, deleteDestructive
discord_messageOpen a thread, crosspost an announcement, delete any messageDestructive
discord_send_dmA 1:1 DM from the bot to a server member (outbound only)Destructive
LinkedIn (coming soon, see /docs/linkedin)
linkedin_organizationsOrganization pages the member administers; switch the account between the personal profile and a pageWrite
linkedin_resolve_mentionA profile or company URL as a URN and @[Name](urn) mention markupRead-only
linkedin_analyticsPost, personal aggregate and organization analytics, follower demographics and post reactionsRead-only
linkedin_create_postSession account: publish a text post (scaffold, gated, pending live execution)Write
linkedin_delete_postSession account: delete a post by activityId (scaffold, gated)Write
linkedin_reactSession account: react to a post (LIKE/PRAISE/…) (scaffold, gated)Write
linkedin_unreactSession account: remove a reaction from a post (scaffold, gated)Write
linkedin_comment_createSession account: comment on a post (scaffold, gated)Write
linkedin_comment_deleteSession account: delete a comment (scaffold, gated)Write
linkedin_send_dmSession account: send a direct message (scaffold, gated)Write
linkedin_send_invitationSession account: send a connection invitation with an optional note (scaffold, gated)Write
linkedin_withdraw_invitationSession account: withdraw a sent invitation (scaffold, gated)Write
linkedin_get_feedSession account: read the feed (SDUI gap, documented) (scaffold)Read-only
linkedin_get_profileSession account: read the member profile (/voyager/api/me) (scaffold)Read-only
linkedin_get_notificationsSession account: read notification cards (scaffold)Read-only
Meta Ads (see /docs/ads)
ads_list_ad_accountsAd accounts the connected Facebook user can manageRead-only
ads_listCampaigns, ad sets, ads, creatives or custom audiences of an ad accountRead-only
ads_getOne campaign, ad set, ad, creative or audienceRead-only
ads_boost_postBoost a published Facebook/Instagram post (PAUSED by default, needs confirm)Destructive
ads_create_campaignCreate a campaign (PAUSED by default, needs confirm)Destructive
ads_create_ad_setCreate an ad set: targeting, budget, schedule (PAUSED, needs confirm)Destructive
ads_create_creativeCreate a creative from a post or a new link adWrite
ads_create_adCreate an ad from an ad set and a creative (PAUSED, needs confirm)Destructive
ads_updateRename, pause, activate or change budget/bid/schedule/targeting (spend changes need confirm)Destructive
ads_create_audienceCreate a customer-list custom audienceWrite
ads_add_audience_usersAdd hashed emails or phones to a custom audienceWrite
ads_get_insightsImpressions, reach, clicks, spend, CPC, CPM, CTRRead-only
ads_search_targetingSearch interests, locations and other targeting optionsRead-only
Analytics
get_analyticsPost and account insights, demographics, online followers, best posting times, publishing limitRead-only
get_analytics_reportStored analytics: dashboard, daily metrics, posts, post timeline, posting frequency, content decay, follower stats, delta feedRead-only
sync_external_postsRead the account's recent platform posts now and store their metricsWrite
Webhooks
list_webhooksWebhook endpointsRead-only
create_webhookRegister an HTTPS endpoint; returns the signing secret onceWrite
webhook_deliveriesList deliveries, redeliver one, or send a webhook.test eventWrite
delete_webhookRemove a webhook endpointDestructive

Publishing

  • create_post without publishNow or scheduledFor saves a draft. scheduledFor (ISO 8601 with a time zone) schedules it. publishNow and publish_post publish live to the real platforms.
  • Editing an approved post sends it back for approval. The same text cannot be posted twice within 24 hours; pass requestId to retry safely.
  • Instagram, Facebook, Threads and TikTok media must be hosted: call upload_media and pass its publicUrl as mediaUrl (or in mediaUrls). Instagram images must be JPEG. TikTok requires privacyLevel. Per-platform options are listed in the REST API reference.
  • Facebook Pages: one account per Page. The owner picks the Pages after opening the connect_account link. When the OAuth result is a pending selection, call select_connection without arguments to find its pendingId (it is also sent in the connection.pending webhook), then with the pendingId and no optionIds to list the Pages, then again with the chosen optionIds to connect them (within 30 minutes).
  • Every write made through MCP is recorded in the organization's audit log.

Direct messages

  • Instagram (permission instagram_business_manage_messages) and Facebook Page Messenger (pages_messaging). Inbound messages arrive through Meta webhooks and appear in list_conversations (and as message.received webhooks); sync_conversations backfills older threads (Meta returns details for the 20 most recent messages per conversation).
  • send_message sends a live message to a real person. Meta only allows replies to people who wrote first: free-form messages within 24 hours of the participant's last message, or within 7 days with tag HUMAN_AGENT when a human writes the reply (the Meta app needs the Human Agent permission). Outside the window the tool fails with outside_messaging_window and nothing is sent; messagingWindow on each conversation shows when it closes.
  • Sent messages cannot be edited or deleted. get_conversation_messages does not mark anything read; mark_conversation_read does, and sends a read receipt unless platform is false.

WhatsApp

  • One account per business phone number. connect_account with whatsapp returns a link to Meta's Embedded Signup for the number's owner; whatsapp_connect_number connects a number with a token you already have.
  • whatsapp_send_message (or send_message in a WhatsApp conversation) sends live messages. Free-form messages only within 24 hours of the person's last message; otherwise only an approved template, else outside_messaging_window.
  • Templates: whatsapp_list_templates, whatsapp_create_template (reviewed by Meta; template.status webhook), whatsapp_delete_template. Media: whatsapp_upload_media, then send with whatsappMediaId.
  • Full guide with payloads and curl examples: /docs/whatsapp.

Approval gate

  • Approval is on by default for new organizations. When approval is required for the organization, an account, the API key or the connected app, new posts are held as pending_approval until an owner or admin approves them in the dashboard. get_api_key_info shows which rules apply.
  • While approval applies, write actions that act on the accounts are queued for a person instead of running: comment replies and moderation, changes to published posts, DMs and conversations, mention and review replies, WhatsApp sends, broadcasts, flow messages and calls, Discord and Telegram writes, X engagement, account settings changes and create_webhook. The tool returns {id, status: "pending_approval", kind} and nothing reaches the platform yet; calling it again with the same input returns the same action. An approved create_webhook shows the signing secret once to the person who approves it, in the dashboard; the action's result and the action.* webhooks carry the webhook without its secret.
  • An owner or admin approves it in Dashboard → Approvals (the stored call runs exactly as queued), edits the text (it then runs with their text) or rejects it. get_action and list_actions show the status: executed with the result, failed with the error, or rejected. The action.* webhooks report the same steps.
  • Validation, ownership and the messaging window are checked before queueing, so errors still come back at once. Ads tools and WhatsApp business-settings writes answer approval_required instead. Reads are never blocked.

Errors

Tool errors carry the same message as the REST API, with the error code appended in parentheses, e.g. … Reconnect the account. (reconnect_required). A missing_permission error means the account must be reconnected after the Meta app has been granted that permission; get_account_health lists the account's missingPermissions and the features they block.

CodeMeaning
approval_requiredApproval applies to this key, organization or account; ads tools are refused (other actions are queued for approval instead)
missing_permissionThe account did not grant the permission this needs: add it to the Meta app, then reconnect the account
reconnect_requiredThe token is no longer valid; the account is flagged needs_reconnect and must be reconnected
rate_limitedThe platform rate-limited the request; retry later
not_supportedThe platform does not offer this feature (e.g. deleting Instagram posts)
invalid_requestThe platform rejected the input
platform_errorAny other platform failure
outside_messaging_windowsend_message outside Meta's window: 24 hours after the person's last message, 7 days with tag HUMAN_AGENT. Nothing was sent
recipient_unavailableThe person cannot receive messages from this account right now
sync_requiredsync_conversations with a conversationId needs a previous sync of the account
pending_expiredThe pending connection expired (30 minutes) or was already completed
template_errorWhatsApp: Meta rejected the template name, language, parameters or status
recipient_not_allowedWhatsApp test number: the recipient is not in the allowed list
phone_number_not_registeredWhatsApp: call whatsapp_register_number first
account_restrictedWhatsApp: the business account is restricted or has a payment issue

Post state conflicts are reported the same way, e.g. (APPROVAL_REQUIRED), (ALREADY_PUBLISHED), (NOT_EDITABLE).

Limitations

  • Sign-in (OAuth) tokens work on the MCP server only; the REST API uses API keys.
  • Approving, editing and rejecting posts and queued actions is dashboard-only.
  • Posts cannot be rescheduled or unscheduled: delete the post and create it again.
  • API keys, connected apps, organization settings and disconnecting accounts are managed in the dashboard.

For plain HTTP integrations, webhook payloads and signature verification, see the REST API reference and Webhooks.

On this page