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(aliashttps://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/mcpin 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.
{
"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:
{
"mcpServers": {
"postgale": {
"url": "https://staging.postgale.com/mcp",
"headers": {
"Authorization": "Bearer sk_…"
}
}
}
}Claude Code:
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):
{
"mcpServers": {
"postgale": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://staging.postgale.com/mcp",
"--header",
"Authorization:${POSTGALE_AUTH}"
],
"env": {
"POSTGALE_AUTH": "Bearer sk_…"
}
}
}
}VS Code:
{
"servers": {
"postgale": {
"type": "http",
"url": "https://staging.postgale.com/mcp",
"headers": {
"Authorization": "Bearer sk_…"
}
}
}
}Raw HTTP, to check a key:
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.
| Tool | What it does | Kind |
|---|---|---|
| Accounts & connect | ||
get_api_key_info | The key in use, its organization and the effective approval policy | Read-only |
list_accounts | Connected social accounts (ids for create_post), optionally by externalId | Read-only |
connect_account | OAuth 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 soon | Write |
select_connection | List pending connections (no pendingId), the options of one (e.g. Facebook Pages), and connect the chosen ones | Write |
get_account_health | Token validity, granted scopes, missingPermissions, publishing limit and recommendations | Read-only |
update_account | Set externalId, display overrides or the profile of an account | Write |
manage_profiles | List, create, update or delete profiles (groups of accounts per brand or client) | Destructive |
manage_account_groups | List, create, update or delete named account groups | Destructive |
bluesky_settings | Read or set a Bluesky account's default post languages | Write |
linkedin_connect_session | Connect a LinkedIn account by its web session (cookies + user agent), no OAuth; queued for approval | Write |
| Approvals | ||
list_actions | Agent actions (replies, moderation, DMs, published-post changes) queued for human approval, with their status and result | Read-only |
get_action | One queued action: pending, executed with its result, failed with the error, or rejected | Read-only |
| Media | ||
list_media | Recent uploaded media | Read-only |
get_media | One media file | Read-only |
upload_media | Import an image or video from a URL or base64; returns its publicUrl | Write |
| Posts | ||
list_posts | Recent posts, optionally by status | Read-only |
get_post | One post with per-platform status, URLs and errors | Read-only |
create_post | Draft, schedule or publish a post (publishNow publishes live) | Destructive |
update_post | Replace the text of an unpublished post | Destructive |
delete_post | Delete a post from Postgale (not from the platforms) | Destructive |
publish_post | Publish a draft, scheduled or failed post live now | Destructive |
manage_published_post | Edit (Facebook, Telegram, Discord) or delete (Facebook, Threads, Telegram, Discord, Bluesky, Mastodon) a live post; turn Instagram comments on or off | Destructive |
retry_post | Retry a failed or partially published post now | Destructive |
pin_post | Pin or unpin a published post (Facebook) | Destructive |
list_platform_posts | The account's recent posts as they exist on the platform, with metrics | Read-only |
bulk_upload_posts | Create posts from a CSV (dryRun validates first) | Destructive |
| Comments & mentions | ||
list_post_comments | Comments on the published targets of a post | Read-only |
reply_to_comment | Publish a reply to a comment (Instagram, Facebook, Threads) | Destructive |
list_comments | Comments and replies on Instagram, Facebook, Threads and Bluesky posts, by post or by account | Read-only |
moderate_comment | Comment, reply, hide/unhide, delete, pin/unpin, private reply; like/unlike where supported | Destructive |
like_post | Like or unlike any post as the account | Destructive |
list_mentions | Media the Instagram account was tagged in | Read-only |
list_inbox_mentions | Mentions of all accounts from the last 7 days (Instagram, Facebook), from webhooks | Read-only |
reply_to_mention | Reply where the Instagram account was mentioned | Destructive |
list_inbound_events | Events received from Meta webhooks: comments, replies, mentions, Page feed changes, direct messages | Read-only |
| Direct messages | ||
list_conversations | Instagram, Messenger, WhatsApp, X, Bluesky and Telegram conversations, latest first, with unread counts and the messaging window | Read-only |
get_conversation_messages | One conversation (incl. messagingWindow) and its messages, oldest to newest | Read-only |
send_message | Send 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_AGENT | Destructive |
mark_conversation_read | Mark read in Postgale and as seen on Instagram/Messenger | Write |
search_conversations | Search conversations by participant or message text | Read-only |
manage_message | Edit, delete, react to or unreact a message, where the platform supports it | Destructive |
send_typing | Show or clear a typing indicator | Write |
get_message_attachment | Resolve a message attachment to a URL that works now | Read-only |
delete_conversation | Delete Postgale's stored copy of a conversation (not on the platform) | Destructive |
sync_conversations | Backfill conversations of an account (or one conversation) from Meta or Bluesky | Write |
start_conversation | Bluesky (handle or DID) and X (coming soon): send the first live DM to someone | Destructive |
| Telegram | ||
telegram_bot_commands | Get, set or clear the bot commands ("/" menu) of an account; get also returns the start link for private chats | Write |
| Instagram & Facebook | ||
meta_account_settings | Ice breakers, persistent menu, greeting and Get Started for Instagram and Messenger DMs; Facebook Page info | Destructive |
instagram_lookup | Stories, story insights, tagged media, follow status; mentions, business discovery, audio, live media and collaborators (Facebook Login) | Read-only |
facebook_page_data | Page insights, post reactions and earnings, posts that tag the Page, visitor posts | Read-only |
list_reviews | Facebook Page reviews with ratings, recommendations and replies | Read-only |
reply_to_review | Publish the Page's reply to a review | Destructive |
meta_conversation_action | Accept a message request or hand a conversation over (thread control) | Destructive |
| X (coming soon) | ||
x_engagement | Coming soon: repost, like, bookmark or follow (and undo) as the X account | Destructive |
x_search_posts | Coming soon: recent search (last 7 days) with X search syntax | Read-only |
x_lookup | Coming soon: one X post (id or URL) or one user (@username) | Read-only |
whatsapp_connect_number | Connect a number with an existing token (stored encrypted) instead of Embedded Signup | Write |
whatsapp_get_phone_number | Display number, verified name, quality rating, messaging limit and onboarding state; refresh from Meta | Read-only |
whatsapp_register_number | Register or re-register the number for the Cloud API (6-digit PIN) | Write |
whatsapp_send_message | Send a live text, media, template, interactive, location or reaction message; outside 24 hours only templates | Destructive |
whatsapp_mark_read | Mark an inbound message read, optionally with a typing indicator | Write |
whatsapp_list_templates | Message templates of the WhatsApp Business Account, with status | Read-only |
whatsapp_get_template | One template with its components | Read-only |
whatsapp_create_template | Submit a template for Meta’s review | Write |
whatsapp_delete_template | Delete a template (one language or all) | Destructive |
whatsapp_upload_media | Upload a Postgale media or public URL to WhatsApp; returns the id to send | Write |
whatsapp_get_media | MIME type, size and sha256 of a WhatsApp media id (download through the REST API) | Read-only |
whatsapp_search_numbers | Numbers Postgale can buy for WhatsApp, with the monthly price (when the instance sells numbers) | Read-only |
whatsapp_buy_number | Buy a number and connect it to the WABA of a connected WhatsApp account (code captured by Postgale) | Destructive |
whatsapp_list_numbers | Numbers bought for the organization, with status and the limit | Read-only |
whatsapp_get_number | One bought number; the code captured in the last 10 minutes | Read-only |
whatsapp_release_number | Release a bought number (returned to the carrier; its account stops working) | Destructive |
whatsapp_send_flow | Send a published (or draft) Flow as a live interactive message | Destructive |
whatsapp_flows | Create, upload JSON, publish, deprecate, preview and version Flows; read submissions; encryption key | Destructive |
whatsapp_groups | Group chats: create, update, delete, invite link, participants, join requests | Destructive |
whatsapp_automation | Ice breakers, slash commands and the welcome message | Write |
whatsapp_business_profile | Business profile and photo, username (and suggestions), display name | Write |
whatsapp_block_users | Block, unblock and list blocked users; check one | Destructive |
whatsapp_calling | Business Calling: config, permission prompt, live calls, estimates, history, recordings | Destructive |
whatsapp_commerce | Commerce settings and connected catalogs | Write |
whatsapp_conversions | Click-to-WhatsApp conversion events to Meta (dataset created automatically) | Write |
whatsapp_insights | Live number info, pricing analytics and Meta account events | Read-only |
whatsapp_manage_templates | Template edits by name or id, single-language deletes, Meta template library | Destructive |
whatsapp_sandbox | Sandbox sessions on the shared test number | Write |
| Broadcasts & contacts | ||
broadcasts | WhatsApp template broadcasts: drafts, recipients, send now or schedule, cancel, per-recipient delivery | Destructive |
contacts | Contacts with channels per account: search, create, bulk import, update, delete | Destructive |
| TikTok (see /docs/tiktok) | ||
tiktok_get_creator_info | Creator nickname, allowed privacy levels, disabled interactions and max video length; required before every TikTok post | Read-only |
tiktok_get_profile | Profile and lifetime stats: followers, following, likes, public videos | Read-only |
tiktok_list_videos | Public videos with views, likes, comments and shares (paged), or specific video ids | Read-only |
| Discord (see /docs/discord) | ||
discord_connect_channel | Bind more channels of a server where Postgale's bot is installed, one account per channel | Write |
discord_settings | Connected channel, server channels, default webhook name and avatar, and switching channel | Write |
discord_pins | List, pin and unpin a channel's messages | Write |
discord_roles | List, create, edit and delete server roles; assign and remove a member's role | Destructive |
discord_members | Server members: cursor-paged list, prefix search, one member | Read-only |
discord_events | Scheduled events: list, get, create, update, cancel, delete | Destructive |
discord_message | Open a thread, crosspost an announcement, delete any message | Destructive |
discord_send_dm | A 1:1 DM from the bot to a server member (outbound only) | Destructive |
| LinkedIn (coming soon, see /docs/linkedin) | ||
linkedin_organizations | Organization pages the member administers; switch the account between the personal profile and a page | Write |
linkedin_resolve_mention | A profile or company URL as a URN and @[Name](urn) mention markup | Read-only |
linkedin_analytics | Post, personal aggregate and organization analytics, follower demographics and post reactions | Read-only |
linkedin_create_post | Session account: publish a text post (scaffold, gated, pending live execution) | Write |
linkedin_delete_post | Session account: delete a post by activityId (scaffold, gated) | Write |
linkedin_react | Session account: react to a post (LIKE/PRAISE/…) (scaffold, gated) | Write |
linkedin_unreact | Session account: remove a reaction from a post (scaffold, gated) | Write |
linkedin_comment_create | Session account: comment on a post (scaffold, gated) | Write |
linkedin_comment_delete | Session account: delete a comment (scaffold, gated) | Write |
linkedin_send_dm | Session account: send a direct message (scaffold, gated) | Write |
linkedin_send_invitation | Session account: send a connection invitation with an optional note (scaffold, gated) | Write |
linkedin_withdraw_invitation | Session account: withdraw a sent invitation (scaffold, gated) | Write |
linkedin_get_feed | Session account: read the feed (SDUI gap, documented) (scaffold) | Read-only |
linkedin_get_profile | Session account: read the member profile (/voyager/api/me) (scaffold) | Read-only |
linkedin_get_notifications | Session account: read notification cards (scaffold) | Read-only |
| Meta Ads (see /docs/ads) | ||
ads_list_ad_accounts | Ad accounts the connected Facebook user can manage | Read-only |
ads_list | Campaigns, ad sets, ads, creatives or custom audiences of an ad account | Read-only |
ads_get | One campaign, ad set, ad, creative or audience | Read-only |
ads_boost_post | Boost a published Facebook/Instagram post (PAUSED by default, needs confirm) | Destructive |
ads_create_campaign | Create a campaign (PAUSED by default, needs confirm) | Destructive |
ads_create_ad_set | Create an ad set: targeting, budget, schedule (PAUSED, needs confirm) | Destructive |
ads_create_creative | Create a creative from a post or a new link ad | Write |
ads_create_ad | Create an ad from an ad set and a creative (PAUSED, needs confirm) | Destructive |
ads_update | Rename, pause, activate or change budget/bid/schedule/targeting (spend changes need confirm) | Destructive |
ads_create_audience | Create a customer-list custom audience | Write |
ads_add_audience_users | Add hashed emails or phones to a custom audience | Write |
ads_get_insights | Impressions, reach, clicks, spend, CPC, CPM, CTR | Read-only |
ads_search_targeting | Search interests, locations and other targeting options | Read-only |
| Analytics | ||
get_analytics | Post and account insights, demographics, online followers, best posting times, publishing limit | Read-only |
get_analytics_report | Stored analytics: dashboard, daily metrics, posts, post timeline, posting frequency, content decay, follower stats, delta feed | Read-only |
sync_external_posts | Read the account's recent platform posts now and store their metrics | Write |
| Webhooks | ||
list_webhooks | Webhook endpoints | Read-only |
create_webhook | Register an HTTPS endpoint; returns the signing secret once | Write |
webhook_deliveries | List deliveries, redeliver one, or send a webhook.test event | Write |
delete_webhook | Remove a webhook endpoint | Destructive |
Publishing
create_postwithoutpublishNoworscheduledForsaves a draft.scheduledFor(ISO 8601 with a time zone) schedules it.publishNowandpublish_postpublish 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
requestIdto retry safely. - Instagram, Facebook, Threads and TikTok media must be hosted: call
upload_mediaand pass itspublicUrlasmediaUrl(or inmediaUrls). Instagram images must be JPEG. TikTok requiresprivacyLevel. 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_accountlink. When the OAuth result is a pending selection, callselect_connectionwithout arguments to find itspendingId(it is also sent in theconnection.pendingwebhook), then with thependingIdand nooptionIdsto list the Pages, then again with the chosenoptionIdsto 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 inlist_conversations(and asmessage.receivedwebhooks);sync_conversationsbackfills older threads (Meta returns details for the 20 most recent messages per conversation). send_messagesends 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 tagHUMAN_AGENTwhen a human writes the reply (the Meta app needs the Human Agent permission). Outside the window the tool fails withoutside_messaging_windowand nothing is sent;messagingWindowon each conversation shows when it closes.- Sent messages cannot be edited or deleted.
get_conversation_messagesdoes not mark anything read;mark_conversation_readdoes, and sends a read receipt unlessplatformis false.
- One account per business phone number.
connect_accountwithwhatsappreturns a link to Meta's Embedded Signup for the number's owner;whatsapp_connect_numberconnects a number with a token you already have. whatsapp_send_message(orsend_messagein a WhatsApp conversation) sends live messages. Free-form messages only within 24 hours of the person's last message; otherwise only an approved template, elseoutside_messaging_window.- Templates:
whatsapp_list_templates,whatsapp_create_template(reviewed by Meta;template.statuswebhook),whatsapp_delete_template. Media:whatsapp_upload_media, then send withwhatsappMediaId. - 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_approvaluntil an owner or admin approves them in the dashboard.get_api_key_infoshows 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 approvedcreate_webhookshows the signing secret once to the person who approves it, in the dashboard; the action's result and theaction.*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_actionandlist_actionsshow the status:executedwith the result,failedwith the error, orrejected. Theaction.*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_requiredinstead. 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.
| Code | Meaning |
|---|---|
approval_required | Approval applies to this key, organization or account; ads tools are refused (other actions are queued for approval instead) |
missing_permission | The account did not grant the permission this needs: add it to the Meta app, then reconnect the account |
reconnect_required | The token is no longer valid; the account is flagged needs_reconnect and must be reconnected |
rate_limited | The platform rate-limited the request; retry later |
not_supported | The platform does not offer this feature (e.g. deleting Instagram posts) |
invalid_request | The platform rejected the input |
platform_error | Any other platform failure |
outside_messaging_window | send_message outside Meta's window: 24 hours after the person's last message, 7 days with tag HUMAN_AGENT. Nothing was sent |
recipient_unavailable | The person cannot receive messages from this account right now |
sync_required | sync_conversations with a conversationId needs a previous sync of the account |
pending_expired | The pending connection expired (30 minutes) or was already completed |
template_error | WhatsApp: Meta rejected the template name, language, parameters or status |
recipient_not_allowed | WhatsApp test number: the recipient is not in the allowed list |
phone_number_not_registered | WhatsApp: call whatsapp_register_number first |
account_restricted | WhatsApp: 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.
Errors & rate limits
The error shape, every stable error code and the request rate limit.
Instagram, Facebook and Threads
DM settings (ice breakers, persistent menu, greeting, Get Started), interactive DMs and private replies, reactions, typing and handover, Facebook reviews, Page info and analytics, and Instagram stories, tags, mentions and follow status through the Postgale API and MCP server.