How to Post a Video to Social Media From Claude, ChatGPT or n8n
Every other guide here is about reading data off a platform. This one goes the other way: point an AI client at one MCP endpoint, tell it to post your clip, and it starts the upload for each platform you named.
What "post it from chat" actually means
MCP is the protocol that lets a chat client discover tools on a server and call them. Claude, ChatGPT, Cursor and n8n all speak it. Connect a client to a server once and that server's tools appear in the client's tool list, ready for the model to call while you are talking to it.
So the setup here is one endpoint and one sentence. You connect Social Media Uploader Pro, then you type something like "put https://cdn.example.com/clip.mp4 on TikTok and Instagram, caption new drop today, make it public" and the client picks the right tool per platform and starts the upload.
Be clear about what it is first: a router, not an uploader. It does not open a browser and no megabyte of your video passes through it. It starts the right uploader Actor for the platform you asked for, hands over your input, and gives you back a run id to poll.
The nine tools you get
Connect the server and nine tools show up in your client. Six of them post:
upload_tiktok— a video to TikTokupload_instagram_reel— an Instagram Reelupload_facebook_reel— a Facebook Reelupload_youtube_video_oauth— YouTube through Google's official Data APIupload_youtube_shortandupload_youtube_video— two browser-driven YouTube routes you should not use, for reasons below
The other three do the unglamorous work that decides whether this is usable:
list_platforms— reads each uploader's live prices and reports which of them your Apify token can actually start. It starts no upload and bills no upload event.get_upload_status— tells you whether an upload really published, which is not the same question as whether the run finished.abort_upload— stops a run that is stuck.
Make list_platforms your first call. A tool showing up in your client does not mean your token can start the Actor behind it.
Step by step: connect it and post something
- Create a free Apify account and copy your API token from the Apify Console under Settings → API & Integrations.
- In your MCP client, add a remote MCP server with the transport set to HTTP Streamable and the URL
https://dami-studio--social-media-uploader-pro.apify.actor/mcp?token=YOUR_TOKEN&apifyToken=YOUR_TOKEN, your own token in both places. Leave authentication set to none. - The token really does go in twice. Apify’s Standby gateway checks the token you authenticate with and then strips it out before the request reaches the server, so a token sent only as a Bearer header or only as
?token=arrives as nothing and every tool answersNO_APIFY_TOKEN. The second copy, underapifyToken, is the one the server reads. A client that can send custom headers can usex-apify-caller-tokenfor that second copy instead. - Ask for
list_platforms. You get back the uploaders with their prices and whether your token reaches each one. It proves the connection, the token and the tool list, and costs nothing in upload charges. - Now ask it to post. Give it a direct link to the video file — the kind of URL that starts downloading when you open it, not a page the video sits on — plus a caption and the platform or platforms.
- Ask for
get_upload_statuson each run id it hands back. Every time. A run that says it finished is not proof of a video that went live.
In n8n it is the same shape: an MCP Client Tool node on an AI Agent, same URL, same transport, Bearer auth with your Apify token. Exclude the two browser YouTube tools from the node's tool list so the agent cannot wander into them.
Start with a private test post to an account you do not mind experimenting on, and get one video actually live before you point this at a real audience.
What one post costs you
This works differently from the scrapers on this site, so read it first.
- One call posts to one platform. Ask for four platforms and your agent makes four calls.
- Each call starts a separate Actor run on your own Apify account, billed at that uploader's own published prices.
- A run that fails to publish still costs that Actor's run-start fee. Failed runs are not free here, which is the opposite of how the pay-per-result scrapers behave.
- Where an uploader bills per megabyte, those megabytes cover the bytes it moved, whether or not the video landed.
Which events an uploader bills differs per platform, and prices change. Rather than trusting a number in a guide, ask for list_platforms and read the amounts off each Actor's live price list.
Your logins, and where they travel
The server has no accounts of its own. It does not sign you in anywhere and stores nothing between calls. You pass the credentials for the platform you are posting to as arguments on the call, they go into the run that uses them, and that is that.
TikTok, Instagram and Facebook read a session you export from your own logged-in browser: a sessionid for TikTok, sessionid plus ds_user_id for Instagram, c_user plus xs for Facebook. All three take a whole cookie-jar export instead if that is easier. YouTube uses OAuth credentials from your own Google Cloud project: a client ID, a client secret and a refresh token carrying the youtube.upload scope.
Two caveats. Browser sessions expire, and when yours does the upload fails rather than logging you back in. And because these values are tool arguments, the model you are chatting with sees them on the way past. If that is not acceptable for your accounts, run the agent against a model you host yourself.
YouTube: use the OAuth route, and fix two Google settings first
There are three YouTube tools and one is worth your time: upload_youtube_video_oauth. Hand it a client ID, a client secret and a refresh token and it goes through Google's official YouTube Data API, and the Actor behind it, YouTube Video Uploader, is public and carries no maintenance flag.
The other two drive a real browser through YouTube Studio. Both are backed by Actors flagged under maintenance and no video has been published through either of them: Google's "verify it's you" checkpoint fires on browser logins from cloud machines and there is no way around it from a datacenter. Both are still listed and callable, and neither is something to build on.
Two settings in your own Google Cloud project cost you a real upload before you notice them:
- An unverified project forces every upload private. Until your Google Cloud project has passed Google's verification, YouTube stores everything uploaded through the Data API as private, whatever privacy you asked for. The upload succeeds, the video exists, and only you can watch it. The fix is Google's compliance audit, not a setting you can flip.
- A consent screen left in Testing kills your token after 7 days. Refresh tokens issued while the OAuth consent screen is in Testing stop working a week later. Move it to In production before you build a schedule on it.
When and why to use this
- Cross-posting one clip. One video, one caption, several networks, without four tabs and the caption retyped four times.
- An agent that already does the rest. If something in your stack already writes the captions or cuts the clips, a posting tool makes the last step stop being manual.
- Small teams and client accounts. One endpoint and one chat window instead of a workflow per network.
It is the wrong tool for accounts you do not control, or for a schedule that cannot afford to miss a day: sessions expire and browser routes break, so plan for a failed post rather than assuming one. And if your posting is already scripted and predictable, skip the router and run the uploader Actors directly — TikTok and Instagram are public Actors on their own. The router earns its place when you want an agent making the choice in a sentence.
Honest comparison: platform APIs, a browser bot, or this
Versus each platform's own posting API. The official routes are the sanctioned ones and the right answer if you are shipping a product. The cost is setup: TikTok and Instagram both put posting behind app registration and review, and the account types they accept are narrower than "any account you can log into". This server skips that path by using credentials you already have, which starts faster and gives you no vendor support when a platform changes something.
Versus a browser bot you run yourself. Driving the real web UI posts to anything a human can post to, and it breaks the way a human session breaks: checkpoints, captchas and "verify it's you" prompts on cloud IPs. That failure is in our own catalogue, which is why the two browser YouTube tools are flagged under maintenance instead of being left in place. Expect to babysit this route.
FAQ
Does the server keep my TikTok or Google credentials?
No. It has no accounts of its own and stores nothing between calls. Your values are arguments on the call and go into the run that uses them.
Are failed runs free, like the scrapers?
No, and this is the difference that matters. A run that fails to publish still costs that Actor's run-start fee, and per-megabyte charges cover the bytes moved either way.
Why is my YouTube video private when I asked for public?
Your Google Cloud project has not been verified, and YouTube stores every Data API upload from an unverified project as private regardless of what you set. If your token stopped working after a week instead, your consent screen is still in Testing: move it to In production and issue a fresh refresh token.
How do I know the video actually posted?
Call get_upload_status with the run id. Do not read a finished run as a published video; only the status call answers that.
Related guides
- How to scrape TikTok without the API — the reading half of the same platform
- How to scrape Instagram without logging in
- The social scrapers, side by side