Authentication
Every request to https://mcp.postnext.io/api requires an Authorization header with a Bearer token. You have two ways to get one.
OAuth (recommended for AI clients)
AI clients run Dynamic Client Registration on first connect, then walk the user through an OAuth consent screen. The /mcp/connect page handles this automatically. Your client receives a 30-day access token.
API key
For scripts and CI, generate a personal API key in the PostNext app under Account → API Keys. The key starts with apikey_ and is presented as a bearer token like any other.
Endpoint
All tool calls go to a single JSON-RPC 2.0 endpoint over HTTPS POST.
Tools
list_scheduled_posts
List your scheduled posts (queued for publish but not yet sent).
Arguments
limitfromReturns
An object with posts: [{id, platform, content, scheduledAt, status}]. Up to limit results.
Example
curl -X POST https://mcp.postnext.io/api \
-H "Authorization: Bearer apikey_xxx" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","id":1,
"params":{"name":"list_scheduled_posts",
"arguments":{"limit":5}}}'
list_drafts
List your draft posts (not yet scheduled).
Arguments
limitReturns
An object with drafts: [{id, platform, content, updatedAt}]. Up to limit results.
Example
{"jsonrpc":"2.0","method":"tools/call","id":2,
"params":{"name":"list_drafts","arguments":{"limit":10}}}
list_connected_accounts
List the social accounts connected to your team.
Arguments
No arguments.
Returns
An object with accounts: [{platform, handle, connected, lastSyncAt}].
Example
{"jsonrpc":"2.0","method":"tools/call","id":3,
"params":{"name":"list_connected_accounts","arguments":{}}}
get_account_healthPaid plan
Get a health summary across all connected platforms.
Arguments
platformwindowDaysReturns
An object with windowDays, postsScheduled, postsPublished, postsFailed, a byPlatform breakdown and topErrors[].
Example
{"jsonrpc":"2.0","method":"tools/call","id":4,
"params":{"name":"get_account_health",
"arguments":{"windowDays":30}}}
create_post_draft
Create a new draft post. Drafts are not auto-published.
Arguments
platformcontentmediaUrlsclientRequestIdReturns
An object with the new draft: {id, platform, content, status: "DRAFT", createdAt}.
Example
{"jsonrpc":"2.0","method":"tools/call","id":5,
"params":{"name":"create_post_draft",
"arguments":{"platform":"twitter",
"content":"Hello from MCP"}}}
update_post_draft
Update an existing draft. At least one of content or mediaUrls must be provided.
Arguments
postIdcontentmediaUrlsclientRequestIdReturns
An object with the updated draft: {id, platform, content, mediaUrls, status, updatedAt}.
Example
{"jsonrpc":"2.0","method":"tools/call","id":6,
"params":{"name":"update_post_draft",
"arguments":{"postId":"",
"content":"Updated copy"}}}
connect_channel
Generate a one-time URL the user can open to authorize a new platform connection.
Arguments
platformReturns
An object with authUrl (one-time link the user opens to authorise), expiresAt and platform.
Example
{"jsonrpc":"2.0","method":"tools/call","id":7,
"params":{"name":"connect_channel",
"arguments":{"platform":"linkedin"}}}
schedule_post
Move a draft (status DRAFT) into the BullMQ publish queue at a future timestamp. Idempotent within ±60s drift; rejects re-schedule attempts at a different time without explicit cancel first.
Arguments
postIdscheduledAtReturns
An object with postId, scheduledAt (ISO), status: SCHEDULED.
Example
{"jsonrpc":"2.0","method":"tools/call","id":8,
"params":{"name":"schedule_post",
"arguments":{"postId":"",
"scheduledAt":"2026-05-10T09:00:00Z"}}}
cancel_scheduled_post
Cancel a scheduled post and remove it from the publish queue. The underlying draft is preserved.
Arguments
postIdReturns
An object with postId and status: CANCELLED.
Example
{"jsonrpc":"2.0","method":"tools/call","id":9,
"params":{"name":"cancel_scheduled_post",
"arguments":{"postId":""}}}
delete_draft
Permanently delete a draft post. Refuses non-DRAFT posts (use cancel_scheduled_post for SCHEDULED).
Arguments
postIdReturns
An object with postId and deleted: true.
Example
{"jsonrpc":"2.0","method":"tools/call","id":10,
"params":{"name":"delete_draft",
"arguments":{"postId":""}}}
get_post
Return the full PostGroup for a given postId with provider-by-platform content + status + timestamps.
Arguments
postIdReturns
An object with postId, status, scheduledAt, createdAt, updatedAt and providers (record of platform → content).
Example
{"jsonrpc":"2.0","method":"tools/call","id":11,
"params":{"name":"get_post",
"arguments":{"postId":""}}}
search_posts
Substring (case-insensitive) search across post content for the active team. Filters: status, platform, limit (1-100, default 20).
Arguments
querystatusplatformlimitReturns
An object with posts: [{postId, status, platforms, snippet, scheduledAt, updatedAt}]. Snippet contains the matching context with ellipsis on either side.
Example
{"jsonrpc":"2.0","method":"tools/call","id":12,
"params":{"name":"search_posts",
"arguments":{"query":"launch","limit":10}}}
list_teams
Return the teams the authenticated user owns or admins, with the currently active team flagged.
Arguments
No arguments.
Returns
An object with currentTeamId and teams: [{teamId, teamName, isCurrent}].
Example
{"jsonrpc":"2.0","method":"tools/call","id":13,
"params":{"name":"list_teams","arguments":{}}}
set_current_team
Switch the active team for this Bearer token. The user must be a member. Persisted on the OAuth token doc; in-session mutation makes it effective immediately for subsequent tools in the same conversation.
Arguments
teamIdReturns
An object with teamId, teamName, persisted (true if OAuth, false if API key) and an optional note.
Example
{"jsonrpc":"2.0","method":"tools/call","id":14,
"params":{"name":"set_current_team",
"arguments":{"teamId":"team_xxxxx"}}}
get_plan_limits
Read the user's current subscription tier and per-tier quotas (channels, storage, AI credits, posting). Available on every plan. Useful before mutating tools to predict whether the call will be blocked.
Arguments
No arguments.
Returns
An object with tier, tierDisplayName, isPaid, isTrial, upgradeUrl, limits (channels/storage/aiCalls/posts each as {limit, current, exceeded} or {limit, allowed}) and creditsAvailable ({total, subscriptionRemaining, purchasedBalance} or null).
Example
{"jsonrpc":"2.0","method":"tools/call","id":15,
"params":{"name":"get_plan_limits","arguments":{}}}
get_post_metrics
Fetch engagement metrics for a published post across every platform it was sent to. Twitter and Instagram return populated metrics (likes, retweets/shares, comments/replies, impressions); LinkedIn, Threads and TikTok return publish status and URL only (engagement collection deferred to a later release). A normalised totals roll-up sums likes/comments/shares/impressions across whichever platforms reported them.
Arguments
postId PostNext post id from a list call.
Returns
An object with postId, status, providers: [{platform, publishedPostId, publishedUrl, publishedAt, status, metrics}] and totals: {likes, comments, shares, impressions}. metrics is an object of numeric counts per platform, or null when the platform does not yet collect engagement.
Example
{"jsonrpc":"2.0","method":"tools/call","id":16,
"params":{"name":"get_post_metrics",
"arguments":{"postId":""}}}
get_publish_status
Diagnose what happened to a scheduled post: queue state, per-platform success/error, processing time, and the worker's job id. Returns isScheduled=false for posts that exist as drafts but were never moved into the publish queue, with a hint pointing at schedule_post.
Arguments
postId PostNext post id from a list call.
Returns
An object with postId, isScheduled, status, scheduledAt, publishedAt, platforms, processingTimeMs, jobId, topLevelError, and results: [{platform, success, publishedPostId, publishedAt, error}]. Includes hint when isScheduled is false.
Example
{"jsonrpc":"2.0","method":"tools/call","id":17,
"params":{"name":"get_publish_status",
"arguments":{"postId":""}}}
update_brand_profile
Patch the user's active brand profile. Whitelisted fields: bio, brandVoice, personalityTraits, mainThemes, expertiseAreas, preferredHashtags, audienceSize. Anything else is silently dropped. Resolves "active" as team default first, then the user's first own active profile.
Arguments
brandVoice Array of brand-voice descriptors (e.g. ["professional", "concise"]).
Other patchable fields: bio, personalityTraits, mainThemes, expertiseAreas, preferredHashtags, audienceSize.
Returns
An object with profileId, name, updated: [field names that were patched], and the current values of bio, brandVoice, personalityTraits, mainThemes, expertiseAreas, preferredHashtags, audienceSize after the patch.
Example
{"jsonrpc":"2.0","method":"tools/call","id":18,
"params":{"name":"update_brand_profile",
"arguments":{"brandVoice":["professional","concise"]}}}
get_best_time_to_post Paid plan
Recommend the top N (dayOfWeek, hour) slots for the next post on a given platform, ranked by engagement-per-post over the past 90 days. Twitter and Instagram return engagement-weighted scores; LinkedIn, Threads, TikTok rank by post-frequency only. Times are in the supplied IANA timezone (default UTC). Paid plan required.
Arguments
platform Social platform: twitter, instagram, linkedin, threads, or tiktok.
timezone IANA timezone name (e.g. Europe/Berlin, America/New_York). Defaults to UTC.
topN Number of slot recommendations to return (1-24, default 5).
Returns
An object with platform, timezone, sampleWindowDays, sampleSize, metricsAvailable, and recommendations: [{dayOfWeek (1-7, Mon=1), dayLabel, hour (0-23), score, basedOn: {posts, avgEngagement}}]. Includes hint for cold-start or metrics-unavailable cases.
Example
{"jsonrpc":"2.0","method":"tools/call","id":19,
"params":{"name":"get_best_time_to_post",
"arguments":{"platform":"twitter","timezone":"Europe/Berlin","topN":5}}}
search_tools
Search the MCP tool catalog by free-text query, category, or intent. Returns categories, requiresScope, one-line descriptions, and the use-case tags that matched. Free for all plans (discovery surface).
Arguments
All optional. Call with no arguments to list every available tool.
query Free-text search across tool names, descriptions, and use-case tags.
category Filter to one category: posts, accounts, analytics, brand, teams, discovery, other.
Returns
An object with totalTools, matchCount, categories: [string[]], and tools: [{name, category, requiresScope, description, useCases, matchedOn: [name|category|description|use_case]}]. Includes hint when no match or no filter.
Example
{"jsonrpc":"2.0","method":"tools/call","id":20,
"params":{"name":"search_tools",
"arguments":{"query":"why did my post fail"}}}
MCP Resources
Resources are read-only context the client can fetch via the MCP resources/read method. Claude pulls them at conversation start so it has account/team/brand context without you re-asking each session.
postnext://account/summary
Account email and handle (so Claude can confirm which account it's operating on), plan, AI credits used / limit, draft count, scheduled count, connected channel count. Counts capped at 100 each for fast load.
postnext://channels/connected
Same shape as list_connected_accounts result; exposed as a resource so Claude pulls it once at conversation start (no tool-call round-trip).
postnext://brand-profiles/active
The user's active brand profile (team default, falling back to first own profile). Returns only LLM-relevant fields: bio, expertiseAreas, personalityTraits, brandVoice, mainThemes, audienceSize, preferredHashtags.
postnext://teams/current
Current team metadata (teamId, teamName) plus totalTeamsAvailable count. Pair with list_teams + set_current_team to switch.
Named workflows
Slash-menu shortcuts that orchestrate multiple tools. Pick one and let your AI assistant walk through a multi-step task with confirmation before mutating anything.
/weekly-plan
Read brand profile, connected channels and queued posts, then propose 5-10 drafts spread Monday to Friday.
/draft-thread
Write a 5-10 post Twitter or Threads thread on a topic or URL you supply, in your brand voice.
/audit-queue
Walk the next 7 days of scheduled posts and flag duplicates, platform overload, and gaps.
/channel-sweep
Compare connected channels against the supported set and suggest which to connect or refresh.
Discovery and OAuth endpoints
Standards-compliant metadata so any MCP client can auto-configure.
GET /.well-known/oauth-protected-resource/api— RFC 9728GET /.well-known/oauth-authorization-server— RFC 8414GET /oauth/.well-known/openid-configuration— OIDCPOST /oauth/reg— Dynamic Client Registration (RFC 7591)GET /oauth/auth— Authorize (PKCE-S256 required)POST /oauth/token— Token exchange
Open source
Paste-ready recipes and a developer-facing reference live in our public docs repo. MIT-licensed; pull requests welcome. github.com/postnextio/postnext-mcp
Run your social channels from any AI assistant
Plan, draft, schedule, and audit posts across 6 platforms by chatting with Claude, ChatGPT, or Cursor. One secure connection, every PostNext feature.