PostMCP AI
एक API कुंजी के साथ LinkedIn, X, Facebook, Instagram, Threads, Bluesky और YouTube Shorts पर पोस्ट प्रकाशित और शेड्यूल करें।
दस्तावेज़
PostMCP AI Model Context Protocol (MCP) Server
Official PostMCP AI Model Context Protocol (MCP) Server. Connect your social media publishing pipelines directly into AI assistants, desktop applications, IDE workflows, and web environments like Claude Desktop, Claude.ai, Cursor, and ChatGPT Custom GPTs.
Supported platforms include LinkedIn, X (Twitter), Facebook, Instagram, Threads, Bluesky, and YouTube Shorts.
🚀 Features & Capabilities
- 🤖 17 Built-in Tools: Workspaces, connected accounts and their token health, the post queue, pre-flight checks, create/schedule/reschedule/publish/retry/delete, per-post and per-profile analytics, and image generation.
- 🖼️ Carousels & galleries: Pass
mediaUrlsto publish a carousel on Instagram and Threads, a multi-photo post on Facebook and LinkedIn, or a four-image gallery on X and Bluesky - one call, every network's ceiling checked up front. - ⚡ Dual Transport Modes: Native Stdio mode (for local desktop apps & IDEs) and Streamable HTTP mode (for web services, Claude.ai, and remote connectors).
- 🔑 Flexible Authentication: Auto-detects API key from environment variables (
POSTMCPAI_API_KEY), URL query parameters (?apikey=YOUR_KEY), or HTTP authorization headers (x-api-key,Bearer token). - 🗂️ Multi-Workspace Aware: The API key carries its own workspace, so a bare key is enough. To act on another one, every tool takes an optional
workspaceId, also settable per connection (?projectId=...,x-project-id) or per process (POSTMCPAI_PROJECT_ID). - 🤖 ChatGPT Actions Compatible: Includes built-in OpenAPI 3.0 specification generator (
/openapi.json) and REST endpoints (/api/tools/:name) for ChatGPT Custom GPT integration. - 🔒 OAuth 2.0 & RFC 9728 Support: Advertises PKCE authorization server metadata for seamless dynamic client registration with Claude.ai.
📁 Repository Architecture
mcp-server/
├── bin/
│ └── cli.js # Executable CLI entry point (Stdio / HTTP mode runner)
├── src/
│ ├── config.js # Centralized configuration & environment loader
│ ├── client.js # Backend API client, API key & workspace extraction
│ ├── platforms.js # Platform limits, credit pricing & post cost helper
│ ├── tools/
│ │ ├── definitions.js# MCP tool JSON schemas & parameter specifications
│ │ ├── handlers.js # MCP tool execution handlers
│ │ └── index.js # Tool definitions aggregator
│ ├── server.js # MCP Server instance factory
│ ├── routes/
│ │ ├── oauth.js # OAuth 2.0 & RFC 9728 discovery endpoints
│ │ ├── openapi.js # OpenAPI 3.0 schema & ChatGPT REST endpoints
│ │ ├── mcpHttp.js # MCP Streamable HTTP transport (/mcp)
│ │ └── health.js # Health check & system metadata endpoints
│ ├── app.js # Express application factory
│ └── index.js # Main library entry point
├── index.js # Executable wrapper script
├── package.json
└── README.md
⚙️ Environment Configuration
| Environment Variable | Description | Default Value |
|---|---|---|
POSTMCPAI_API_KEY | Required. Your secret API key from the PostMCP AI dashboard. | None |
POSTMCPAI_API_URL | Backend API root. Only set for a self-hosted or local backend. | https://api.postmcpai.com |
POSTMCPAI_PROJECT_ID | Optional. Overrides the workspace the API key is bound to. Overridden in turn by a call's workspaceId. | The workspace the API key was issued from |
PORT | Setting this launches the server in Remote Streamable HTTP Mode. | None (Defaults to Stdio Mode) |
🛠️ MCP Tools Reference
Every tool below also accepts an optional workspaceId (from list_workspaces) to act on a specific workspace.
Reading
| Tool Name | Description | Required | Optional |
|---|---|---|---|
get_user_info | Authenticated user: plan, credit balance, active workspace and role. | — | workspaceId |
list_workspaces | Every workspace the user belongs to, with ids, roles, and connected platforms. | — | — |
get_connected_accounts | Connected social profiles with the profileId needed to target them. | — | workspaceId |
get_account_health | Connections whose token expired or is close to it and need reconnecting. | — | workspaceId |
get_profile_analytics | A connected profile's followers, following, post count and views from its network. Stored reading is free; refresh reads the network now for 1 credit. | platform, profileId | refresh |
list_posts | Post queue, newest first, with per-profile delivery status, pagination and counts. | — | status, page, limit, all |
get_post | One post in full: which profiles received it, live URLs, and per-profile errors. | id | — |
get_post_analytics | Views, likes, comments, shares, saves and clicks per profile, plus the raw platform metrics. Stored reading is free; refresh reads the networks now for 1 credit. | id | refresh |
Writing
| Tool Name | Description | Required | Optional |
|---|---|---|---|
preflight_post | Dry run: character limits, unconnected profiles, missing media, carousel ceilings, credit cost. Publishes nothing. | content | targetAccounts, platforms, mediaUrl, mediaUrls |
create_post | Draft, schedule, or immediately publish a post to named profiles. Each profile becomes its own post with its own id. Several mediaUrls publish as a carousel. | content | targetAccounts, variants, platforms, publishImmediately, scheduleDate, scheduleTime, timezone, mediaUrl, mediaUrls, youtube |
publish_post_now | Publish an existing post immediately; also retries a failed post, skipping delivered profiles. | id | — |
update_post | Update content, target profiles, schedule, media, or status. mediaUrls replaces the whole attachment set. | id | content, targetAccounts, platforms, scheduleDate, scheduleTime, timezone, mediaUrl, mediaUrls, youtube, status |
reschedule_post | Move a post to a new slot, keeping copy and targets. Re-arms failed and draft posts. | id, scheduleDate, scheduleTime | timezone |
reset_stuck_post | Release a post stuck mid-publish so it can be retried. Delivered profiles keep their state. | id | force |
delete_post | Cancel and delete a scheduled or failed post. | id | — |
generate_image | Generate a post image and return its hosted URL for mediaUrl. Costs 20 credits; paid plans only. | prompt | styleImageUrl |
Batching
| Tool Name | Description | Required | Optional |
|---|---|---|---|
multicall | Run up to 20 of the tools above in one request, in order. Tool names are validated before anything executes, so a typo cannot leave half a batch written. Cannot nest. | calls | stopOnError, workspaceId |
{
"calls": [
{ "id": "img", "tool": "generate_image", "arguments": { "prompt": "launch banner" } },
{
"tool": "create_post",
"arguments": {
"content": "We shipped it 🚀",
"targetAccounts": [
{ "platform": "linkedin", "profileId": "lin_7741903" },
{ "platform": "twitter", "profileId": "tw_1293847", "content": "We shipped it 🚀" }
],
"scheduleDate": "2026-09-01",
"scheduleTime": "10:00",
"timezone": "Asia/Kolkata"
}
}
],
"stopOnError": true
}
The reply carries one entry per call — { id, tool, ok, result } or { id, tool, ok: false, error } — plus counts and, when a failure stopped the batch, the calls that were skipped.
Carousels
mediaUrls is the ordered attachment set. One URL is an ordinary media post; two or more publish as a multi-media post on every network but YouTube, with the first URL as the cover:
| Platform | Items per post | Video in a set of several? | Lands as |
|---|---|---|---|
| 2–10 | yes | Carousel | |
| Threads | 2–20 | yes | Carousel |
| up to 10 | no | Multi-photo post | |
| up to 20 | no | Multi-image post | |
| X / Twitter | up to 4 | no | Gallery on one tweet |
| Bluesky | up to 4 | no | Gallery on one post |
| YouTube | 1 | — | One video per upload |
{
"content": "Five things we learned shipping v2 👉",
"targetAccounts": [
{ "platform": "instagram", "profileId": "17841400000000" },
{ "platform": "threads", "profileId": "9988776655" },
{ "platform": "twitter", "profileId": "tw_1293847",
"mediaUrls": ["https://cdn.example.com/v2/1.png", "https://cdn.example.com/v2/2.png", "https://cdn.example.com/v2/3.png", "https://cdn.example.com/v2/4.png"] }
],
"mediaUrls": [
"https://cdn.example.com/v2/1.png",
"https://cdn.example.com/v2/2.png",
"https://cdn.example.com/v2/3.png",
"https://cdn.example.com/v2/4.png",
"https://cdn.example.com/v2/5.png"
],
"scheduleDate": "2026-09-01",
"scheduleTime": "10:00",
"timezone": "Asia/Kolkata"
}
- Only Instagram and Threads mix video into a carousel; everywhere else a set of several must be images only, and a video goes out on its own.
create_postrefuses a set a target will not take before any credits are spent, naming the profile and the rule.preflight_postwith the samemediaUrlsreports the same thing plus amediaSetLimitsmap, so check first when one carousel goes to several networks.- A profile can carry its own
mediaUrlson itstargetAccountsentry (or invariantsas{ "twitter": { "mediaUrls": [...] } }), replacing the shared set - the way to give X and Bluesky a four-slide cut of a longer carousel. - Every slide is copied into PostMCP's own storage at write time, like a single attachment, so a host that expires the links later does not break the scheduled post. One slide failing at publish time fails that profile's post rather than publishing a shorter carousel;
publish_post_nowretries it. update_postwithmediaUrlsreplaces the whole set (add, remove or reorder slides); an empty array removes all media. Every post returned bylist_posts/get_postcarriesmediaUrlsalongsidemediaUrl.
Notes for clients
- Target profiles, not platforms.
targetAccountssends only to the profiles named;platformsfans out to every connected profile on each platform. - One post per profile.
create_poststores a separate post per targeted profile, so each can be edited, retried or cancelled on its own. Give per-profile copy throughtargetAccounts[].contentor thevariantsmap. - Always pass
timezonewhen a wall-clock time matters. The backend defaults to UTC, so a 9:00 IST post scheduled without a zone goes out at 14:30 IST. - Credits are charged per profile delivered to (X/Twitter costs 5, others 1), plus a one-off 50-credit surcharge when the copy contains a link.
preflight_postreports this before you commit. - Analytics are read on request, never in the background.
list_postsandget_connected_accountscarry what the last reading stored, free.get_post_analytics(one post, every network it went to) andget_profile_analytics(one connected profile: followers, posts, views) withrefresh: trueread the network now for 1 credit each; without it, the stored reading is free.engagementsis likes + comments + shares on every network, so it compares across platforms. Anullmeans the network does not report that metric (Bluesky has no views), anerrornaming reconnect means the account predates the insights permission and its owner must reconnect it, andunavailable: truemeans the network never answers for that kind of post (LinkedIn personal profiles).
💻 Client Integration Guides
1. Claude Desktop App (Stdio Mode)
Add the configuration below to your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"postmcpai": {
"command": "npx",
"args": ["-y", "@postmcpai/server"],
"env": {
"POSTMCPAI_API_KEY": "pmcp_sec_your_secret_api_key_here"
}
}
}
}
2. Cursor IDE
- Open Cursor Settings -> Features -> MCP.
- Click + Add New MCP Server.
- Fill in the details:
- Name:
postmcpai - Type:
command - Command:
npx -y @postmcpai/server
- Name:
- Under Environment Variables, add:
POSTMCPAI_API_KEY=pmcp_sec_your_secret_api_key_here
- Click Save.
3. Claude.ai & Remote Web Connectors (Streamable HTTP / SSE Mode)
Host this server on any cloud service (Render, Railway, Fly.io, Vercel) or tunnel your local machine using ngrok.
Launching in HTTP Mode:
export POSTMCPAI_API_KEY="pmcp_sec_your_secret_api_key_here"
export PORT=3000
npm run start:sse
Connecting to Claude.ai:
- Provide your public MCP URL with your API key attached:
https://your-hosted-domain.com/mcp?apikey=pmcp_sec_your_secret_api_key_here - Claude.ai will discover tool capabilities via
/mcpand authenticate seamlessly. - That URL is all you need: the key is bound to the workspace it was issued from, so tools act on that workspace without being told. To point the same key at a different workspace, append
&projectId=YOUR_WORKSPACE_ID(or send anx-project-idheader); individual tool calls can still override either withworkspaceId.
4. ChatGPT Custom GPTs (REST Actions)
- When configuring a Custom GPT Action, specify your server URL (e.g.
https://your-hosted-domain.com). - Import the OpenAPI schema directly from:
https://your-hosted-domain.com/openapi.json - Set Authentication to API Key (Header Name:
Authorizationorx-api-key).
5. Programmatic Node.js Library Usage
You can also use @postmcpai/server as a library in your own Node.js backends:
import { createServer, createExpressApp, makeBackendRequest } from "@postmcpai/server";
// Create a standalone MCP Server instance
const mcpServer = createServer(() => process.env.POSTMCPAI_API_KEY);
// Or create an Express app with all remote routes attached
const app = createExpressApp();
app.listen(3000);
🧪 Local Testing & Development
# Clone the repository
git clone https://github.com/postmcp/postmcp-mcp-server.git
cd postmcp-mcp-server
# Install dependencies
npm install
# Start in Stdio Mode
npm start
# Start in HTTP Mode with hot reload
npm run dev
📄 License
Distributed under the MIT License. Copyright © 2026 PostMCP AI.