MCP Tools Reference
Every tool exposed by the SocialRails MCP server, with arguments, required scopes and worked examples.
This page documents the fourteen tools the SocialRails MCP server exposes. If you have not connected yet, start with Connect SocialRails to Claude or MCP Server Setup.
Every tool maps onto an endpoint of the Public API and runs the same validation, so anything documented in API Endpoints about limits and behaviour holds here too.
All tools at a glance
Working across workspaces
If you keep each client in its own workspace, create your key with All my workspaces turned on (Settings > API). That key covers every workspace you own.
Every tool except list_workspaces and search_stock_photos then accepts an optional workspace argument: the workspace name or id. Names match without regard to case, and a unique partial name works too ("acme" finds "Acme Coffee" if nothing else matches).
- When the key covers more than one workspace,
workspaceis required. Leaving it out returnsWORKSPACE_REQUIREDwith the list of names, so a post can never land in a client's workspace by default. - A name that matches several workspaces returns
WORKSPACE_AMBIGUOUSwith the candidates. - A key without All my workspaces only reaches its own workspace. Naming any other returns
WORKSPACE_NOT_FOUND.
Results from a workspace-scoped call include "workspace": "<name>", so the assistant can confirm which client it acted on.
list_workspaces
No arguments. Returns each workspace's id, name and is_default (the workspace the key was created in), plus account_wide_key.
Choosing pages and boards
One LinkedIn login often manages several company pages, and one Facebook login several Facebook pages. Pick the destination by name:
- Call
list_destinationsto see what each connected account can post to. - Pass the names to
create_post,create_post_batchorupdate_post:
Leave them out and the post goes to the workspace default, marked is_default in list_destinations. For LinkedIn with no default set, that is the personal profile.
Names match the same way workspace names do: without regard to case or quote style, and a unique partial name works. A name that matches two pages returns an error listing both, and nothing is created. Results include "posting_to" with the page names used, so the assistant can confirm where the post will go.
This works the same whether you keep clients in one workspace with several pages under one login, or in separate workspaces. With several workspaces, pass workspace too, and the page names are looked up in that workspace only.
create_post {
"workspace": "Acme Coffee",
"platform": "linkedin",
"content": "Our fall menu is here.",
"linkedin_pages": ["Acme Coffee Roasters"],
"scheduled_for": "2026-11-12T09:00:00Z"
}list_destinations
Returns, per connected platform, each destination's name, id, type and is_default. Platforms that are not connected in the workspace are left out. If a connection has expired, the platform carries needs_reauth: true and an error; reconnect it in the dashboard.
Other platforms (Instagram, TikTok, X, Threads, Bluesky, YouTube) post to the connected account itself, so there is nothing to choose.
Reading
list_accounts
No arguments. Returns each connected account with its id, provider, name and status. Status is connected, needs_reauth or expired.
Worth calling before scheduling. A post created for a platform whose token has expired will be accepted and then fail at publish time.
get_workspace
No arguments. Returns the workspace, its plan, and this month's usage against the plan limits. Useful when an assistant needs to know how much headroom is left before scheduling a batch.
list_posts
get_post
Returns one post. If publishing failed, the reason is in error_message.
get_analytics
Writing
create_post
Creates one post for one platform. Omit scheduled_for and it is saved as a draft.
Note that thread replaces content with its first item, so the two are not additive.
create_post_batch
The same content across up to nine platforms in one call. Each platform counts as one post against your monthly limit.
update_post
Only drafts and scheduled posts can be updated. Published posts return an error.
delete_post
Only drafts and scheduled posts can be deleted. A published post cannot be removed from the platform through the API.
generate_content
This spends AI credits from your plan. When you are already talking to a capable assistant, it will usually write the copy itself, which costs you nothing. Reach for this tool when you specifically want SocialRails AI.
Attaching media
Media is a two step flow, and this is the part assistants most often get wrong on the first try.
- Call
upload_media_from_urlwith a public HTTPS URL. It returns akey. - Pass that
keyin themediaarray ofcreate_postorcreate_post_batch.
Limits: images up to 10MB (JPEG, PNG, GIF, WebP), MP4 video up to 100MB, PDF up to 100MB. For a video post, upload the video and a thumbnail image, then pass both keys.
PDFs publish as LinkedIn document carousels. LinkedIn only, one PDF per post, no other media alongside it.
Example of the full sequence:
upload_media_from_url { "url": "https://example.com/launch.jpg" }
returns { "key": "abc123/api-uploads/images/def456.jpg" }
create_post {
"content": "Our new pricing is live.",
"platform": "linkedin",
"scheduled_for": "2026-09-11T09:00:00Z",
"media": ["abc123/api-uploads/images/def456.jpg"]
}Media keys are scoped to your workspace. A key from another workspace is rejected.
Finding a photo
search_stock_photos
Searches free stock photos from Pexels. Each result carries an image_url sized for posting (1080 pixels wide for portrait and square, 1920 for landscape) plus a small preview the assistant can see, so it can pick a photo that fits or show you the options first.
To use a result, pass its image_url to upload_media_from_url, then the returned key to create_post:
search_stock_photos { "query": "cozy coffee shop", "orientation": "portrait" }
returns photos[0].image_url = "https://images.pexels.com/photos/.../pexels-photo-....jpeg?auto=compress&cs=tinysrgb&w=1080"
upload_media_from_url { "url": "<that image_url>" }
returns { "key": "abc123/api-uploads/images/def456.jpg" }Pexels photos are free to use, including commercially. Crediting the photographer is not required but is appreciated, and each result includes their name and profile link.
Errors
Tool errors come back as readable text with the API error code in front, so the assistant can act on them rather than guessing:
FORBIDDEN: API key does not have write scope.LIMIT_EXCEEDED: Monthly post limit reached (900/900 posts). Upgrade your plan for more.BAD_REQUEST: Field "scheduled_for" must be in the future.The codes are the same ones the REST API returns. See API Errors for the full list.
Two failures are worth calling out because they are not tool errors and will surface differently in your client:
- 401 on every call. An authentication problem, not a tool problem. Check the header.
- 429 on every call. You have exhausted the hourly request limit. An assistant in a retry loop can do this quickly.
Things the tools do not do
- One post, one platform.
create_posttargets a single platform. Usecreate_post_batchfor several. - No publishing straight away. Posts are created as drafts or scheduled. There is no publish-right-now tool.
- No account management. Connecting and reconnecting social accounts happens in the dashboard.
- No webhook management. Webhooks are REST only. See API Webhooks.
- No file uploads from the chat. A photo or video you drop into a conversation cannot be passed to SocialRails. Media must be reachable at a public HTTPS link that returns the file itself. A Dropbox share link works if you change the ending to
?dl=1. A normal Google Drive share link does not, because it opens a web page rather than the file. For your own photos, uploading them in the SocialRails dashboard is the simplest route, or usesearch_stock_photosfor stock images.