MCP for AI agents
MCP tools
The 19 tools PostNinja's MCP server gives your agent. Parameter tables come straight from the server's own input schemas. Results are a short summary followed by JSON; the same data is in structuredContent.result.
All tools
| Tool | What it does | Access |
|---|---|---|
list_accounts | List accounts | read |
get_workspace | Get workspace settings | read |
list_profiles | List profiles | read |
list_templates | List post templates | read |
list_posts | List posts | read |
get_post | Get a post | read |
create_post | Create or schedule a post | write |
update_post | Change a post | write |
delete_post | Delete a post | write |
approve_post | Approve a post | write |
request_changes | Ask for changes to a post | write |
get_queue | Get the posting queue | read |
update_queue | Change the posting queue | write |
get_analytics | Get analytics | read |
list_comments | List comments | read |
reply_to_comment | Reply to a comment | write |
list_messages | List direct messages | read |
reply_to_message | Reply to a direct message | write |
upload_image | Upload an image | write |
A typical flow: list_accounts → (get_workspace / list_profiles for the brand voice) → upload_image if there's a photo → create_post → later, get_post to check it went out.
list_accounts
List accounts. The connected social accounts you can post to (every platform), with their ids.
Read-only. Needs posts:read.
When to use it: Call it first in almost every conversation: other tools take account ids. status: needs_reconnect means the account must be reconnected in the app before it can post. profileId says which profile (client or brand) an account belongs to.
Parameters
None.
get_workspace
Get workspace settings. The workspace's name, its brand voice (how posts should sound) and whether members' posts need approval.
Read-only. Needs posts:read.
When to use it: Before writing posts, to match the workspace's brand voice, and to know whether members' posts need approval.
Parameters
None.
list_profiles
List profiles. The profiles in this workspace (usually one per client or brand: a set of connected accounts), each with its own brand voice. Use a profile's brand voice when writing for its accounts, and its id (profileId) to filter list_posts.
Read-only. Needs posts:read.
When to use it: When the workspace runs several brands or clients. Write in a profile's brandVoice when posting to its accounts (it wins over the workspace's), and pass its id as profileId to list_posts, get_analytics or update_queue. Profiles are part of the Pro and Agency plans; on Personal the list is empty.
Parameters
None.
list_templates
List post templates. Ready-made post templates (the built-in library and the team's saved ones). Each has {key} blanks described in fields: replace them with real details (drop lines whose optional blank you leave empty), then pass the text to create_post.
Read-only. Needs posts:read.
When to use it: When the user wants a post of a known kind (a sale, a launch, a restock, an event) or asks for ideas. Fill every {key} blank with real details, drop lines whose optional blank you leave empty, then pass the text to create_post.
Parameters
categorystringOne of: promote (Sales and offers), launch (Launches and news), engage (Engagement), educate (Tips and how-tos), proof (Social proof), behind (Behind the scenes), events (Events and seasons), story (Stories and personal brand), community (Community), creator (Creators and influencers), or saved (the team's own).
searchstringWords to look for in the name and description. Up to 100 characters.
limitinteger1 to 100. Default
30.
list_posts
List posts. Posts in this workspace, newest scheduled time first. Filter by time range, status or profile.
Read-only. Needs posts:read.
When to use it: To see what's scheduled, find drafts, check what failed, or review posts waiting for approval (status: awaiting_approval). Times are compared with each post's scheduled time.
Parameters
fromstring (ISO 8601)Only posts scheduled at or after this time.
tostring (ISO 8601)Only posts scheduled before this time.
statusstringawaiting_approval: posts waiting for an owner or admin to approve them. One of
draft,awaiting_approval,scheduled,publishing,published,partial,failed.profileIdstring (uuid)Only posts going to at least one of this profile's accounts (see list_profiles).
limitinteger1 to 100. Default
50.
get_post
Get a post. One post with its per-account status, links to the published posts, any errors, and its approval history.
Read-only. Needs posts:read.
When to use it: To check whether a post went out: each target has its own status, a link (url) once published, or the reason it failed (error). Also returns the approval history.
Parameters
postIdstring (uuid)requiredThe post's id.
create_post
Create or schedule a post. Creates a post for one or more accounts. Set scheduledAt to schedule it, queue to put it in the next free queue slot, publishNow to post right away, or draft to save it without scheduling. Every platform's rules are checked (X: 280 characters, up to 4 photos or 1 video; Instagram: 1-10 photos/videos required, 2,200-character caption; Threads: 500 characters; TikTok: a video or photos; YouTube Shorts: one vertical video up to 3 minutes; Pinterest: photos or a video, 800-character description).
Changes data. Needs posts:write (or a Read & write API key).
When to use it: To schedule (scheduledAt), publish right away (publishNow: true), queue (queue: true) or save a draft (draft: true). Every selected platform's rules are checked first, so an error message tells you exactly what to fix. Give platforms their own text with platformContent.
Parameters
contentstringThe post's text. Used on every platform that doesn't have its own text in platformContent. Up to 10,000 characters.
platformContentobjectOptional text per platform that replaces
contentthere, e.g. {"x": "Short version"}. Keys:x,instagram,threads,facebook,tiktok,youtube,pinterest.xThread(string or object)[]X only: follow-up posts, in order, that turn the X version into a thread. The first post is the X text (platformContent.x or content). Each is a string, or { "text": "...", "mediaIds": [...] } to give that post its own photos or video. Each is up to 280 characters and costs credits like any X post. Up to 24 items.
xThread[].textstringrequiredUp to 10,000 characters.
xThread[].mediaIdsstring (uuid)[]This post's own photos (up to 4) or one video. Up to 4 items.
instagramFormatstringInstagram only: "post" (feed photo, carousel or Reel, the default) or "story" (exactly one photo or video; captions are not shown on Stories). Default
"post".tiktokobjectTikTok only: who can see the post, which interactions to allow, and commercial content disclosure.
tiktok.privacystringWho can see the TikTok post. Left out: public if the account allows it. Ask the user rather than guessing. One of
PUBLIC_TO_EVERYONE,MUTUAL_FOLLOW_FRIENDS,FOLLOWER_OF_CREATOR,SELF_ONLY.tiktok.allowCommentsbooleanAllow comments. Default true.
tiktok.allowDuetbooleanAllow Duet (videos only). Default true.
tiktok.allowStitchbooleanAllow Stitch (videos only). Default true.
tiktok.yourBrandbooleanCommercial content promoting the user's own business. TikTok labels it "Promotional content".
tiktok.brandedContentbooleanPaid partnership promoting a third party. TikTok labels it "Paid partnership"; it can't be private (SELF_ONLY).
tiktok.coverTimestampMsintegerVideos: which moment of the video is the cover, in milliseconds from the start.
firstCommentstringOptional first comment, posted under the post right after it goes out, where the platform allows it (e.g. links or hashtags). Empty removes it. Up to 2,200 characters.
youtubeTitlestringYouTube only: the video title (up to 100 characters). Left out: the first line of the text.
youtubeThumbnailIdstring (uuid) or nullYouTube only: an uploaded photo (under 2 MB) to use as the video's custom thumbnail. null removes it.
queuebooleanPut the post in the next free slot of the posting queue (the accounts' profile's slots, else the workspace's) instead of at scheduledAt.
accountIdsstring (uuid)[]Accounts to post to (from list accounts). Up to 200 items.
mediaIdsstring (uuid)[]Uploaded media, in display order (from upload media). Up to 10 items.
scheduledAtstring (ISO 8601)When to publish, ISO 8601 with a time zone, e.g. 2026-10-05T09:00:00Z.
publishNowbooleanPublish as soon as possible instead of at scheduledAt.
draftbooleanSave as a draft without scheduling it.
Note: When approvals are on and the person who signed in is a member, the summary says the post was sent for approval and status is awaiting_approval.
Note: X posts use credits; if the workspace can't afford them the call fails with a message saying how many are needed.
update_post
Change a post. Changes a draft, scheduled or waiting-for-approval post. Only the fields you pass change; the rest stay as they are. When an owner or admin (or an API key) schedules a post that was waiting for approval, that approves it.
Changes data. Needs posts:write (or a Read & write API key).
When to use it: To change the text, accounts, media, time or options of a draft, scheduled or waiting post. Only the fields you pass change. Send scheduledAt to move a post, draft: true to unschedule it, or queue: true to put it in the queue. Posts that already went out can't be changed.
Parameters
contentstringThe post's text. Used on every platform that doesn't have its own text in platformContent. Up to 10,000 characters.
platformContentobjectOptional text per platform that replaces
contentthere, e.g. {"x": "Short version"}. Keys:x,instagram,threads,facebook,tiktok,youtube,pinterest.xThread(string or object)[]X only: follow-up posts, in order, that turn the X version into a thread. The first post is the X text (platformContent.x or content). Each is a string, or { "text": "...", "mediaIds": [...] } to give that post its own photos or video. Each is up to 280 characters and costs credits like any X post. Up to 24 items.
xThread[].textstringrequiredUp to 10,000 characters.
xThread[].mediaIdsstring (uuid)[]This post's own photos (up to 4) or one video. Up to 4 items.
instagramFormatstringInstagram only: "post" (feed photo, carousel or Reel, the default) or "story" (exactly one photo or video; captions are not shown on Stories).
tiktokobjectTikTok only: who can see the post, which interactions to allow, and commercial content disclosure.
tiktok.privacystringWho can see the TikTok post. Left out: public if the account allows it. Ask the user rather than guessing. One of
PUBLIC_TO_EVERYONE,MUTUAL_FOLLOW_FRIENDS,FOLLOWER_OF_CREATOR,SELF_ONLY.tiktok.allowCommentsbooleanAllow comments. Default true.
tiktok.allowDuetbooleanAllow Duet (videos only). Default true.
tiktok.allowStitchbooleanAllow Stitch (videos only). Default true.
tiktok.yourBrandbooleanCommercial content promoting the user's own business. TikTok labels it "Promotional content".
tiktok.brandedContentbooleanPaid partnership promoting a third party. TikTok labels it "Paid partnership"; it can't be private (SELF_ONLY).
tiktok.coverTimestampMsintegerVideos: which moment of the video is the cover, in milliseconds from the start.
firstCommentstringOptional first comment, posted under the post right after it goes out, where the platform allows it (e.g. links or hashtags). Empty removes it. Up to 2,200 characters.
youtubeTitlestringYouTube only: the video title (up to 100 characters). Left out: the first line of the text.
youtubeThumbnailIdstring (uuid) or nullYouTube only: an uploaded photo (under 2 MB) to use as the video's custom thumbnail. null removes it.
queuebooleanPut the post in the next free slot of the posting queue (the accounts' profile's slots, else the workspace's) instead of at scheduledAt.
accountIdsstring (uuid)[]Accounts to post to (from list accounts). Up to 200 items.
mediaIdsstring (uuid)[]Uploaded media, in display order (from upload media). Up to 10 items.
scheduledAtstring (ISO 8601)When to publish, ISO 8601 with a time zone, e.g. 2026-10-05T09:00:00Z.
publishNowbooleanPublish as soon as possible instead of at scheduledAt.
draftbooleanSave as a draft without scheduling it.
postIdstring (uuid)requiredThe post's id.
delete_post
Delete a post. Deletes a post (draft, scheduled, waiting or sent). A post that was already published stays live on the platform; it's only removed from PostNinja.
Changes data. Needs posts:write (or a Read & write API key). Destructive: it can't be undone.
When to use it: To cancel a draft or scheduled post. Deleting a post that already went out only removes it from PostNinja; it stays live on the platforms. Credits held for accounts it hadn't reached yet are given back.
Parameters
postIdstring (uuid)requiredThe post's id.
approve_post
Approve a post. Approves a post waiting for approval (status awaiting_approval), so it's scheduled for its time, or goes out now if that time has passed. Only the workspace owner or an admin can approve.
Changes data. Needs posts:write (or a Read & write API key).
When to use it: When an owner or admin asks you to review what the team submitted: list posts with status: awaiting_approval, show them, and approve the ones they're happy with. A post whose time has passed goes out right away.
Parameters
postIdstring (uuid)requiredThe post's id.
notestringOptional note for the author. Up to 1,000 characters.
request_changes
Ask for changes to a post. Sends a post waiting for approval back to its author's drafts with a note saying what to change; the author gets it by email. Only the workspace owner or an admin can do this.
Changes data. Needs posts:write (or a Read & write API key).
When to use it: To send a waiting post back to its author's drafts. The note is required and emailed to the author, so say exactly what to change.
Parameters
postIdstring (uuid)requiredThe post's id.
notestringrequiredWhat needs changing. The author gets it by email. Up to 1,000 characters.
get_queue
Get the posting queue. The posting queue's weekly time slots (weekday 0 = Monday … 6 = Sunday, 24-hour HH:MM in the queue's time zone): the workspace's (profileId null) and each profile's own. create_post with queue: true takes the next free slot of the accounts' profile, else the workspace's.
Read-only. Needs posts:read.
When to use it: Before queueing posts, to see the weekly slots and their time zone. profileId: null slots are the workspace's; a profile with its own slots uses those instead.
Parameters
None.
update_queue
Change the posting queue. Replaces one set of weekly queue slots: a profile's (profileId) or the workspace's (profileId null). Send the complete new list; an empty list removes a profile's own slots so it uses the workspace's. Only the workspace owner or an admin can do this. Posts already queued keep their times.
Changes data. Needs posts:write (or a Read & write API key).
When to use it: To set up or change posting times. Send the complete list for one set (it replaces the old one). An empty list removes a profile's own slots, so it falls back to the workspace's. Posts already queued keep their times.
Parameters
profileIdstring (uuid) or nullWhose slots to replace: a profile's id (from list_profiles), or null for the workspace's own slots. Default
null.slotsobject[]requiredThe complete new list of weekly slots. An empty list removes them (a profile then uses the workspace's slots). Up to 100 items.
slots[].weekdayintegerrequired0 = Monday … 6 = Sunday. 0 to 6.
slots[].timestringrequired24-hour HH:MM in the queue's time zone.
get_analytics
Get analytics. Published posts' stats and follower growth for a date range (UTC days, default the last 30), compared with the period before: headline numbers, one row per account and the top posts. Filter by profile, account or platform.
Read-only. Needs posts:read.
When to use it: For reports: how posts did over a period, which accounts grew, and the top posts. Numbers come from stats already synced, so this costs nothing and is fast. Compare kpis with kpis.previous (the same number of days before).
Parameters
fromstringFirst day, YYYY-MM-DD (send with to).
tostringLast day, YYYY-MM-DD (send with from).
profileIdstring (uuid)Only this profile's accounts (see list_profiles).
accountIdstring (uuid)Only this account (see list_accounts).
platformstringOnly this platform, e.g. instagram or youtube.
Note: X posts have no stats in PostNinja, so they count as published without numbers. Instagram, Threads, Facebook, TikTok, YouTube and Pinterest posts have stats.
list_comments
List comments. Comment conversations on the connected accounts' posts (Instagram, Facebook Pages, Threads, YouTube), latest first. Pass commentId to get one conversation with every message. Reply with reply_to_comment.
Read-only. Needs posts:read.
When to use it: To answer comments: list conversations with filter: needs_reply, then open one with commentId to read every message and the post it's on. Reading here doesn't mark comments as read in the app.
Parameters
filterstringneeds_reply: the latest message isn't ours. One of
all,unread,needs_reply,replied,hidden. Default"all".platformstringOne of
instagram,facebook,threads,youtube.accountIdstring (uuid)commentIdstring (uuid)Get this conversation in full instead of the list.
limitinteger1 to 100. Default
30.
reply_to_comment
Reply to a comment. Replies publicly to a comment as the connected account it was left on. Use a commentId from list_comments.
Changes data. Needs posts:write (or a Read & write API key).
When to use it: To reply publicly as the account the comment was left on. Use the conversation's id from list_comments. Keep replies within the platform's limit (maxLength in the conversation).
Parameters
commentIdstring (uuid)requiredtextstringrequiredUp to 2,200 characters.
list_messages
List direct messages. Direct-message conversations on the connected Instagram and Facebook Page accounts, latest first, with each one's reply window. Pass conversationId to get one conversation with its messages. Reply with reply_to_message while window.state isn't "closed".
Read-only. Needs posts:read.
When to use it: To answer direct messages on Instagram and Facebook Pages: list conversations with filter: needs_reply, then open one with conversationId to read its messages. Check window: replies are only possible while window.state is open (24 hours after the person's last message). Reading here doesn't mark messages as read in the app.
Parameters
filterstringneeds_reply: they wrote last. One of
all,unread,needs_reply. Default"all".platformstringOne of
instagram,facebook.accountIdstring (uuid)conversationIdstring (uuid)Get this conversation in full instead of the list.
limitinteger1 to 100. Default
30.
Note: Attachment links point at Instagram's or Facebook's servers and stop working after a while.
reply_to_message
Reply to a direct message. Sends a private direct message in a conversation, as the connected account. Instagram and Messenger only allow it within 24 hours of the person's last message; after that it's refused. Instagram messages can be up to 1,000 bytes, Facebook up to 2,000 characters.
Changes data. Needs posts:write (or a Read & write API key).
When to use it: To answer a direct message privately as the account it was sent to. Use the conversation's id from list_messages. Only while the reply window is open; once it has closed the tool returns an error and the person has to write again first.
Parameters
conversationIdstring (uuid)requiredtextstringrequiredUp to 2,000 characters.
upload_image
Upload an image. Uploads a JPEG, PNG or WebP image (base64, up to about 3 MB) and returns a media id to use in create_post. For videos and larger files, use the REST API: POST /api/v1/media.
Changes data. Needs posts:write (or a Read & write API key).
When to use it: When the user gives the agent an image to post. Send it base64-encoded (no data: prefix), then pass the returned id in mediaIds. For videos or images over about 3 MB, upload with the REST API (POST /api/v1/media) and give the agent the id.
Parameters
datastringrequiredThe image file, base64-encoded (no data: prefix).
mimeTypestringrequiredOne of
image/jpeg,image/png,image/webp.