Social Publish MCP
Publishes or schedules Facebook Page reels through Meta Business Suite in the logged-in browser session, filling in captions, hashtags and schedule details, and returning the confirmed schedule, video link, or a DOM summary and screenshot on failure.
Uploads and publishes or schedules videos via TikTok Studio using the user's existing TikTok login, setting captions, hashtags and the exact posting time, and can cross-post the same file to TikTok, YouTube and Facebook in a single call with per-platform captions.
Uploads and publishes or schedules videos (including Shorts) to YouTube by driving YouTube Studio in the user's own logged-in Chrome session, filling in title, description, hashtags, playlists, visibility and an exact scheduled time with time zone, then reporting back the confirmed schedule and video link.
Automates the YouTube Studio web UI through Chrome DevTools: attaches the video file by path (no upload size cap), types captions as trusted input, sets scheduling options and stops before or after the final publish button, returning per-step failure evidence such as screenshots when a flow breaks.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Social Publish MCPpost intro.mp4 to YouTube, TikTok and Facebook with captions"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Social Publish MCP
Let any AI agent upload, schedule and publish your videos on YouTube, Facebook and TikTok — through the Chrome you are already logged into. No API keys. No developer apps. No app review.
Social Publish MCP is a Model Context Protocol server plus a small companion Chrome extension. Ask Claude, Cursor, Codex, Gemini CLI, VS Code Copilot or any other MCP agent:
"Schedule
short_07.mp4on YouTube, TikTok and Facebook tomorrow at 17:00 Cairo time, with these captions."
and it opens YouTube Studio, TikTok Studio and Meta Business Suite in your own Chrome, uploads the file, fills in the title, description, hashtags, playlists and schedule exactly like you would, and reports back the scheduled time and the video link.
⚡ Quick install
Option A: let your AI agent install it. Paste this into Claude Code, Cursor, Codex, Gemini CLI, Windsurf, VS Code or any agent that can run commands:
Install Social Publish MCP for me by following https://github.com/h4775346/social-publish-mcp/blob/main/docs/AGENT_INSTALL.mdOption B: one command.
# Windows (PowerShell)
irm https://raw.githubusercontent.com/h4775346/social-publish-mcp/main/install.ps1 | iex# macOS / Linux
curl -LsSf https://raw.githubusercontent.com/h4775346/social-publish-mcp/main/install.sh | shEither way, everything is set up for you:
uv: installed if missing.
Server: installed as the
social-publish-mcpcommand.Chrome extension: copied to
~/.social-publish-mcp/extension.Agent skill: installed for Claude Code.
MCP registration: in every AI client found on your computer (Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, Gemini CLI, Codex).
The only thing left for you (Chrome allows extensions only by hand). The installer has already opened the page and the folder:
In
chrome://extensions, turn on Developer mode.Click Load unpacked, choose
~/.social-publish-mcp/extension.Restart your AI client and ask it: "check my social accounts".
Related MCP server: Upload-Post
Contents
Features
Three platforms | YouTube Studio (Shorts and regular videos), Facebook Page reels (Meta Business Suite), TikTok Studio |
Publish or schedule | Publish now, or schedule in the platform's own scheduler at an exact time with a time zone |
Cross-post in one call | One video to all three platforms in parallel, each with its own caption |
Batches | A week of posts from one JSON file; everything is validated before anything is touched |
Full quality, any size | Files are attached by path over the Chrome DevTools Protocol: no file dialog, no upload size cap |
Real typing | Captions are typed as trusted input: Arabic/RTL, emoji, hashtags and line breaks come out exactly right |
Dry runs | Fill in everything and stop before the final button, to check a new template safely |
Verified results | Each result carries the confirmed schedule (as the platform displays it) and, where available, the link |
Failure evidence | Every failure returns the failed step, a screenshot and (Facebook) a DOM summary |
Works with every MCP agent | Claude Code, Claude Desktop, Cursor, VS Code, Windsurf, Codex, Gemini CLI, Cline, Zed, OpenCode, … |
Shared by several agents | Several agents (and the CLI) can use it at the same time through one bridge |
Why not the official APIs?
The official APIs are the right choice for large publishers. For one creator or a small team they mean an OAuth app per platform, review processes and hard restrictions:
YouTube Data API: uploads from unaudited API projects are locked to private.
TikTok Content Posting API: requires an audited developer app; unaudited apps can only post privately.
Facebook Graph API: needs a Meta app, permissions review and long-lived page tokens.
You already have all three sites open in Chrome. Social Publish MCP lets an agent do exactly what you would do there, at human pace, on your own accounts.
How it works
flowchart TB
A["AI agent<br/>(Claude, Cursor, Codex, Gemini CLI, VS Code, ...)"] -- "MCP (stdio)" --> S
subgraph S["social-publish-mcp (Python)"]
direction TB
T["server.py — MCP tools + CLI"] --> R["runner.py — validate · one tab per job · history"]
R --> D["drivers/ — youtube.py · facebook.py · tiktok.py"]
D --> P["page.py — click · type · set files · screenshot (CDP)"]
P --> B["bridge.py — WebSocket on 127.0.0.1:8797"]
end
B -- "ws://127.0.0.1:8797" --> E["Chrome extension (MV3)<br/>generic DevTools relay"]
E -- "chrome.debugger" --> W["studio.youtube.com · business.facebook.com · tiktok.com<br/>(your logged-in sessions)"]The extension contains no site logic. It opens a tab in a dedicated Social Publish window, attaches the Chrome debugger to that tab only, and relays DevTools commands.
All site flows live in the Python drivers, so a site redesign is fixed with a server update; the extension does not need to change.
Each job gets its own tab, which is closed when the job ends.
Requirements
Python | 3.10 – 3.13 |
recommended installer (pip/pipx also work) | |
Browser | Google Chrome 116+ (or Edge/Brave/another Chromium browser that loads unpacked MV3 extensions) |
OS | Windows, macOS, Linux |
Accounts | logged in to YouTube Studio / Meta Business Suite / TikTok Studio in that browser profile |
UI language | English platform UI (the drivers read English labels such as "Schedule", "Next") |
Installation
1. Install the server
Install uv if you do not have it:
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Then install Social Publish MCP as a command-line tool, straight from GitHub:
uv tool install git+https://github.com/h4775346/social-publish-mcp
social-publish-mcp --version# run without installing (always the latest commit)
uvx --from git+https://github.com/h4775346/social-publish-mcp social-publish-mcp --version
# from a local clone (needed anyway for the extension folder)
git clone https://github.com/h4775346/social-publish-mcp.git
cd social-publish-mcp
uv tool install .
# with pipx or pip
pipx install git+https://github.com/h4775346/social-publish-mcp
pip install git+https://github.com/h4775346/social-publish-mcp
# upgrade later
uv tool upgrade social-publish-mcpThen let it set up the extension folder, the skill and your AI clients in one go:
social-publish-mcp setup # every client found on this computer
social-publish-mcp setup --client cursor # or only the ones you name (repeatable)
| Effect |
| configure only these clients: |
| do not install the Claude Code skill |
| do not copy the extension folder |
| do not open |
Config files are merged (your other MCP servers are kept) and backed up as *.bak first.
2. Load the Chrome extension
social-publish-mcp setupcopies the extension to~/.social-publish-mcp/extension(Windows:C:\Users\<you>\.social-publish-mcp\extension). You can also use theextension/folder of a clone.Open
chrome://extensions(Edge:edge://extensions, Brave:brave://extensions).Turn on Developer mode (top right).
Click Load unpacked and select the
extensionfolder of the repository.Pin Social Publish MCP to the toolbar. Its badge shows:
off (red): no server running. This is normal until an agent or the CLI starts the server.
on (green): connected and idle.
a number (amber): jobs running.
The first extension that connects is trusted and pinned (its id is saved in ~/.social-publish-mcp/extensions.json);
connections from any other extension or from web pages are refused.
When a job runs, Chrome shows "Social Publish MCP started debugging this browser". This is how the extension clicks and types. Do not press Cancel while a job is running.
3. Log in to the platforms
In the same Chrome profile, log in as you normally do:
Platform | Page that must work | Notes |
YouTube | If your Google account owns several channels, pass | |
Posts go to the Page selected in Business Suite; pass | ||
TikTok |
4. Verify
social-publish-mcp --checkThe command starts the bridge, waits for the extension, opens each upload page in its own tab and prints:
{
"youtube": { "logged_in": true, "account": "My Channel (UC0123456789abcdefABCD_-)", "detail": "..." },
"facebook": { "logged_in": true, "account": "My Page", "detail": "Business Suite open" },
"tiktok": { "logged_in": true, "account": "", "detail": "TikTok Studio upload page open" }
}Connect your AI agent
social-publish-mcp setup does this automatically for Claude Code, Claude Desktop, Cursor, Windsurf, VS Code,
Gemini CLI and Codex. The snippets below are for doing it by hand, or for other clients.
Every client below starts the same stdio server. If you installed with uv tool install, the command is simply
social-publish-mcp. If you prefer not to install, replace it with
uvx --from git+https://github.com/h4775346/social-publish-mcp social-publish-mcp.
Windows: if your client cannot find the command, use the full path printed by
where social-publish-mcp(usuallyC:\Users\<you>\.local\bin\social-publish-mcp.exe).
claude mcp add social-publish --scope user -- social-publish-mcpInstall the skill so Claude knows the publishing rules (approval first, ISO times with offsets, dry runs):
# macOS / Linux
mkdir -p ~/.claude/skills/social-publish && cp skill/SKILL.md ~/.claude/skills/social-publish/# Windows
New-Item -ItemType Directory -Force "$HOME\.claude\skills\social-publish" | Out-Null
Copy-Item skill\SKILL.md "$HOME\.claude\skills\social-publish\"Edit claude_desktop_config.json
(macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop:
{
"mcpServers": {
"social-publish": { "command": "social-publish-mcp" }
}
}Long uploads report progress every 10 seconds, so the client does not time out.
~/.cursor/mcp.json (global) or .cursor/mcp.json (project):
{
"mcpServers": {
"social-publish": { "command": "social-publish-mcp" }
}
}.vscode/mcp.json in your workspace (or MCP: Add Server from the command palette):
{
"servers": {
"social-publish": { "type": "stdio", "command": "social-publish-mcp" }
}
}~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"social-publish": { "command": "social-publish-mcp" }
}
}codex mcp add social-publish -- social-publish-mcpor in ~/.codex/config.toml:
[mcp_servers.social-publish]
command = "social-publish-mcp"
tool_timeout_sec = 1800 # uploads can take minutes~/.gemini/settings.json:
{
"mcpServers": {
"social-publish": { "command": "social-publish-mcp", "timeout": 1800000 }
}
}MCP Servers → Configure (cline_mcp_settings.json):
{
"mcpServers": {
"social-publish": { "command": "social-publish-mcp", "timeout": 1800, "disabled": false }
}
}settings.json:
{
"context_servers": {
"social-publish": { "command": { "path": "social-publish-mcp", "args": [] } }
}
}opencode.json:
{
"mcp": {
"social-publish": { "type": "local", "command": ["social-publish-mcp"], "enabled": true }
}
}Register a stdio server with command social-publish-mcp and no arguments. Allow long tool calls
(≥ 30 minutes) if the client has a timeout setting: a large upload can take several minutes.
Usage
Talking to your agent
You do not need to remember the tool names. Typical requests:
Check which of my accounts are logged in.
Dry-run this on TikTok: video D:\videos\short_07.mp4, caption "Wait for the last second 🌅 #sunset #fyp",
schedule tomorrow 19:00 Cairo time.
Schedule D:\videos\short_07.mp4 on all three platforms tomorrow:
YouTube 17:00 (title "Sunset over the Nile in 30 seconds", playlist "Shorts"),
TikTok 19:00, Facebook 21:00, all Cairo time. Use the captions in captions/short_07_*.txt.
Publish my-reel.mp4 to Facebook now with this caption: ...
What did we post this week? Why did the last TikTok post fail?With the bundled skill installed, the agent shows you a plan (video, text, platform, time) and waits for your OK before posting, and uses dry runs for new templates.
Tools reference
Tool | Purpose |
| Extension connected?, versions, running jobs, open tabs, last results. Call first. |
| Opens each upload page, returns |
| One video to one platform. |
| Several jobs (same fields as |
| Last results, newest last (also failures with their screenshot path). |
Parameters:
platform:youtube·facebook·tiktokvideo: absolute path to the file on this computercaption: YouTube description / Facebook reel description / TikTok caption, hashtags included, posted as writtentitle: YouTube only (required there, max 100 characters)tags: YouTube tagsschedule_at: ISO 8601 with a UTC offset, e.g.2026-11-01T17:00+02:00; omit to publish nowdry_run: fill everything, stop before the final buttonkeep_tab: leave the job tab open afterwards (useful withdry_runto inspect the form)
Each result:
{
"platform": "tiktok",
"ok": true,
"status": "scheduled",
"url": "https://www.tiktok.com/tiktokstudio/content",
"post_id": "",
"scheduled_for": "2026-11-01T17:00:00+02:00",
"message": "Nov 1, 5:00 PM (GMT+2) Cairo; picker zone: Africa/Cairo UTC+0200",
"screenshot": ""
}status is one of published, scheduled, dry_run, failed.
Platform options
Platform | Option | Default | Meaning |
youtube |
| — | Channel to upload to ( |
|
| Exact playlist names to add the video to | |
|
|
| |
|
| Audience setting | |
|
| "Altered or synthetic content" disclosure | |
| — | Business Suite Page asset id (from the | |
| — | Fail if the composer's "Post to" does not show this Page | |
|
| "Remixing and use of original audio" | |
tiktok |
|
|
|
|
| Comments on/off | |
|
| TikTok's AI-generated content label |
Command line
Everything the agent can do is also available from a terminal:
social-publish-mcp # MCP server on stdio (what agents launch)
social-publish-mcp setup [--client NAME] [--no-open] # install extension + skill, register AI clients
social-publish-mcp --check [--platforms youtube,tiktok]
social-publish-mcp status
social-publish-mcp history -n 20
social-publish-mcp --version
# one post (dry run first)
social-publish-mcp post --platform youtube \
--video ./short_07.mp4 \
--title "Sunset over the Nile in 30 seconds" \
--caption-file ./captions/short_07_youtube.txt \
--tags nile,sunset,shorts \
--schedule 2026-11-03T17:00+02:00 \
--option channel_id=UC0123456789abcdefABCD_- \
--dry-run
# a batch
social-publish-mcp batch examples/jobs.example.json [--max-parallel 3] [--dry-run] [--keep-tab]Exit codes: 0 all ok · 1 at least one post failed · 2 invalid input or no extension connected.
Batch files
{
"max_parallel": 3,
"jobs": [
{
"platform": "youtube",
"video": "videos/short_01.mp4",
"title": "Sunset over the Nile in 30 seconds",
"caption_file": "captions/short_01_youtube.txt",
"tags": ["nile", "sunset", "shorts"],
"schedule_at": "2026-11-03T17:00+02:00",
"options": { "playlists": ["Shorts"] }
},
{
"platform": "tiktok",
"video": "videos/short_01.mp4",
"caption": "Wait for the last second 🌅 #nile #sunset #fyp",
"schedule_at": "2026-11-03T19:00+02:00"
},
{
"platform": "facebook",
"video": "videos/short_01.mp4",
"caption": "Wait for the last second 🌅 #nile #sunset",
"schedule_at": "2026-11-03T21:00+02:00",
"options": { "asset_id": "123456789012345" }
}
]
}Relative video and caption_file paths are resolved against the batch file's folder.
Concurrency: jobs run in parallel up to max_parallel, but one job per platform at a time (sites dislike
parallel uploads from one account). One video to three platforms goes out in parallel; seven YouTube posts go out
one after another.
Scheduling rules and validation
Before any tab opens, every job is checked. If one job is invalid, nothing runs.
Check | Rule |
Video | exists and is not empty |
YouTube | title 1–100 characters, no |
TikTok | caption 1–4000 characters |
caption 1–2200 characters | |
Time | ISO 8601 with offset; YouTube ≥ 15 min ahead; TikTok 15 min – 10 days; Facebook 20 min – 29 days |
Duplicates | no two jobs with the same (platform, video, time) in one batch |
Times are converted to the time zone each platform's scheduler shows. TikTok schedules in 5-minute steps, so a time like 17:02 is rounded up to 17:05 and the result says so. Every driver reads the date and time back from the page and refuses to click Schedule if they do not match.
Configuration
Variable / file | Default | Purpose |
|
| Bridge port (set the same port in the extension popup) |
|
| State folder |
| — | Extra extension ids to accept, comma separated |
| One JSON line per result | |
| Screenshots and DOM dumps of a job ( | |
| Pinned extension id | |
| Random token for additional local server instances (see below) |
Several agents at once. Only one process can own the bridge port. The first server (say, Claude Desktop's)
becomes the hub; later ones (Claude Code, the CLI) detect this and forward their work to the hub, authenticated
with token.txt. There is always one extension connection, one set of tabs and one history. If the hub exits,
the next call takes over the port.
Troubleshooting
Symptom | Fix |
Extension badge says off | Normal when no agent is running. Start your agent (or run |
| Same as above: the server is not running. Harmless; it retries automatically. |
| Another extension id is pinned. Delete |
| Open the platform page in that Chrome profile and log in. YouTube "permission" page means the wrong channel: pass |
A job failed at a step | Open the screenshot in the result ( |
"started debugging this browser" bar cancelled | The running job fails cleanly; start it again. |
Times are off by an hour | Pass |
The site was redesigned | Update the server ( |
FAQ
Is my password or session sent anywhere?
No. The server listens on 127.0.0.1 only, talks only to your extension, and the extension acts inside your own
browser. Nothing is sent to third parties.
Does it work headless or on a server? It needs a real Chrome with the extension and your logged-in sessions; keep the machine awake during uploads.
Can it upload thumbnails, first comments or collaborators? Not yet. Contributions are welcome.
Instagram, X, LinkedIn? The architecture is generic (any site can get a driver). They are on the roadmap.
Why English UI? The drivers locate buttons by their English labels. Other languages can be added per driver.
Security and privacy
The bridge binds to
127.0.0.1; web pages cannot connect (their origin is refused), and only the pinned extension id may take the extension role.The debugger is attached only to the tabs the extension opened for jobs, never to your other tabs.
No telemetry. Results and screenshots stay in
~/.social-publish-mcp.
See SECURITY.md to report a vulnerability.
Terms of service and fair use
This tool automates your own accounts in your own browser, at human pace, doing what you would do by hand. It is not for spam, fake engagement, mass account operation or anything the platforms' rules forbid. You are responsible for what you post, for having the rights to it, and for complying with each platform's terms (including disclosure of AI-generated or altered content). Use at your own risk.
Development
git clone https://github.com/h4775346/social-publish-mcp.git
cd social-publish-mcp
uv sync --extra dev
uv run pytest -q # bridge, runner and all three drivers, with a fake extension and fake pages; no browser needed
uv run ruff check .Project layout:
src/social_publish_mcp/
server.py MCP tools and CLI
runner.py validation, one tab per job, parallelism, history
bridge.py local WebSocket bridge to the extension
page.py browser API for drivers (CDP: click, type, files, screenshots)
models.py PostJob, PostResult, DriverError
drivers/ youtube.py · facebook.py · tiktok.py
extension/ Chrome MV3 extension (generic CDP relay)
skill/SKILL.md agent skill: rules for publishing safely
docs/ platform_notes.md: verified selectors and site behaviour
tests/ unit tests with fakesAdding a platform means writing one driver module with START_URL, check_login(page) and
publish(page, job, dry_run=False). See CONTRIBUTING.md and docs/platform_notes.md.
License
Available Tools
5 toolscheck_accountsARead-onlyIdempotent
Open each platform's upload page in Chrome and report which account is logged in (tabs are closed after).
platforms: any of "youtube", "facebook", "tiktok" (default: all). Returns {platform: {logged_in, account, detail}}.
| Name | Required | Description | Default |
|---|---|---|---|
| platforms | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/idempotent/non-destructive, and the description adds genuinely new behavioral facts: it drives a real Chrome browser, opens platform upload pages, and closes the tabs afterward. It says nothing about failure modes if Chrome is unavailable or no user is logged in, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly three short lines, front-loaded with the action and scope, followed by the parameter note and return shape. Nothing is repeated or wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering the safety profile and a real output schema defining the return shape, the description gives everything needed to invoke it correctly. Only the environmental precondition (Chrome must be available/authenticated) is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema only offers an untyped string array with a null default. The description compensates well by naming the accepted values ("youtube", "facebook", "tiktok") and mapping the null default to "all". It does not address invalid or mixed-case platform strings.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: opens each platform's upload page in Chrome and reports the logged-in account, plus the cleanup detail (tabs are closed after). It is clearly distinguishable from the write-oriented siblings (publish, publish_batch), though it never names them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The pre-publish/preflight use case is implied by the 'which account is logged in' framing, but there is no explicit statement of when to use this versus status or history, nor any prerequisite such as a running Chrome session.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
historyARead-onlyIdempotent
The last limit posting results (newest last), from /history.jsonl.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so the safety profile is covered. The description adds genuinely new behavioral detail: results are ordered oldest-to-newest, and data is read from a local file at <state dir>/history.jsonl. It does not say whether history is truncated or session-scoped, so it sits at an adequate 3.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the result set and its ordering, with the storage location trailing as supporting detail. Nothing redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering safety, the description only needs to convey scope and the parameter's effect, which it does. The remaining gap is whether history is bounded (e.g., only this session or the whole state file), which an agent could reasonably want.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the single `limit` parameter has no description in the schema beyond a default of 20. The description compensates by defining what `limit` controls (how many of the most recent results are returned) and by clarifying the resulting ordering ('newest last'), which is meaning the schema does not carry.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource (posting results) and the exact selection rule ('the last `limit` results, newest last'), so an agent knows it is a retrieval of past posting attempts. It never mentions `status` or `check_accounts`, so sibling differentiation is only implicit, which keeps it out of the 5 tier.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus `status` (current state) or `check_accounts`, and no exclusions or prerequisites. The use case (reviewing recent posting outcomes) must be inferred from the phrase 'posting results'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publishA
Upload one video to one platform through the user's logged-in Chrome, and publish or schedule it.
Only call this after the user approved this exact post (video, text, platform, time). platform: "youtube" | "facebook" | "tiktok". video: absolute path of the video file on this computer. caption: YouTube description / Facebook reel description / TikTok caption, hashtags included, written as-is. title: YouTube title (required for YouTube, max 100 chars; ignored elsewhere). tags: YouTube tags. schedule_at: ISO 8601 with UTC offset (e.g. "2026-11-01T17:00+02:00"); omit to publish now. options: youtube {channel_id, playlists, made_for_kids, altered_content, visibility}; facebook {asset_id, allow_remix}; tiktok {visibility, ai_generated, allow_comments}. dry_run: fill everything but stop before the final Publish/Schedule click (use it first for a new template). keep_tab: leave the tab open afterwards (to look at a dry run). Returns {ok, results:[{platform, ok, status, url, post_id, scheduled_for, message, screenshot}]}.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | ||
| title | No | ||
| video | Yes | ||
| caption | Yes | ||
| dry_run | No | ||
| options | No | ||
| keep_tab | No | ||
| platform | Yes | ||
| schedule_at | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real context beyond the annotations: it runs through the user's logged-in Chrome (auth model), options vary per platform, dry_run stops before the final click, and keep_tab keeps the tab open for inspection. It does not warn that publish is non-idempotent (a retry may create a duplicate post) or describe failure handling, which is the notable gap given the annotations declare openWorldHint and idempotentHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and the approval precondition, then a compact per-parameter glossary with no filler. It is dense but every line conveys operative detail; only minor cost is the terse line-wrapped enumeration style.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so skipping return-value detail would be fine, yet it still sketches the result shape. For a high-stakes, open-world, one-shot publish action, the remaining gap is error/retry behavior and what happens if the Chrome session is not logged in.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and does: each parameter is explained with platform-specific meaning (caption = YouTube description / FB reel description / TikTok caption), title constraints (required for YouTube, max 100 chars, ignored elsewhere), schedule_at format with a worked ISO 8601 example, per-platform option keys, and dry_run/keep_tab semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and scope: upload one video to one platform via the user's logged-in Chrome, then publish or schedule. The 'one video to one platform' phrasing implicitly separates it from publish_batch, and the platform/video/caption mapping makes the resource concrete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly gates invocation on prior user approval of this exact post (video, text, platform, time), and gives a concrete sequencing rule: use dry_run first for a new template, and omit schedule_at to publish now. This is what/when guidance an agent can act on.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_batchA
Run several posts: e.g. one video to three platforms at once, or a week of scheduled posts.
Only call this after the user approved every post in the batch. jobs: list of {platform, video, caption, title?, tags?, schedule_at?, options?} (same fields as publish; caption_file may replace caption). All jobs are validated first: if one is invalid nothing runs. Jobs run in parallel tabs (max_parallel), but one job per platform at a time. Returns {ok, results:[...]} in the input order.
| Name | Required | Description | Default |
|---|---|---|---|
| jobs | Yes | ||
| dry_run | No | ||
| keep_tab | No | ||
| max_parallel | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, it discloses important behavior: all jobs are validated first and nothing runs if any job is invalid, jobs run in parallel tabs subject to max_parallel, only one job per platform runs at a time, and results are returned in input order. These details materially help an agent anticipate side effects and execution semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: it states the operation, approval guard, job shape, validation/execution behavior, and return shape without filler. Every sentence carries useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema and annotations, the description covers most of what an agent needs: batch purpose, job fields, atomic validation, parallelism, and return ordering. It still omits dry_run/keep_tab semantics and does not clarify what happens if a job fails after validation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description partly compensates by documenting the jobs item structure and explaining max_parallel. It leaves dry_run and keep_tab undocumented, so parameter semantics are only partially covered.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Run several posts') and gives concrete batch examples, clearly distinguishing it from the single-post sibling publish. An agent can immediately tell this is the batch-publishing tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a strong usage prerequisite ('Only call this after the user approved every post in the batch') and batch scenarios such as one video to three platforms or a week of scheduled posts. However, it does not explicitly name publish as the alternative for single posts or state when not to batch.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statusARead-onlyIdempotent
Is the Chrome extension connected? Server/extension versions, running jobs, open tabs, last results.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and a closed-world scope, so the safety profile is fully covered by structured data. The description adds that the call surfaces live operational state (running jobs, open tabs, last results), which hints it is a snapshot read with no side effects, but it does not say whether the call blocks, whether it fails when disconnected, or how stale the data is.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the single most important question an agent would ask, followed by a compact field list. No filler and nothing to trim.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and zero parameters, the description does not need to explain return values, and the rich annotations cover safety. What remains missing is only the usage context (when to reach for this instead of check_accounts or history), which is a minor gap for such a simple diagnostic tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline 4 applies for a no-arg tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description frames the tool as a connectivity/diagnostic check ('Is the Chrome extension connected?') and enumerates the payload (versions, running jobs, open tabs, last results), which is specific enough to distinguish it from publish/publish_batch. It lacks an explicit verb like 'returns status of', but the question form plus the field list makes the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus siblings. A natural use case — verifying the extension/server is alive before publishing, or diagnosing a failed publish — is only inferable, and the relationship to check_accounts (also a 'check' tool) is left entirely unaddressed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
check_accounts - First observed
history - First observed
publish - First observed
publish_batch - First observed
status
TDQS
Scored across 5 tools
Each tool has a distinct role: publish for one post, publish_batch for multiple jobs, check_accounts for login detection, status for connection/job state, and history for past results. The only mild overlap is publish vs publish_batch for a single job, but the batch description clearly frames it as multi-post execution with all-or-nothing validation.
Mostly readable, but conventions are mixed: publish and publish_batch are verb-based, check_accounts is verb_noun, while status and history are bare nouns. The names are predictable enough to use, but do not follow a single consistent pattern.
Five tools is well-scoped for a social publishing server: one core action, a batch variant, account validation, connection status, and history. Each tool clearly earns its place without redundancy.
Core publishing, scheduling, batching, account checks, status, and history are covered. However, there is no explicit cancel/delete or list-scheduled-posts operation, which are notable gaps for a toolset that supports scheduling, forcing agents to work around via browser tabs or history.
Maintenance
Related MCP Connectors
Publish and schedule videos to TikTok, YouTube Shorts, Instagram, Facebook, LinkedIn, Pinterest, Bluesky, Threads and X from Claude, Cursor or any MCP client. Upload once, post everywhere, track views in unified analytics, and retry failed posts. Official platform APIs only, free plan available. Docs: https://docs.multi-upload-tool.com/mcp
Build, run, schedule, and publish AI video pipelines to YouTube and TikTok from any MCP client.
MCP server for QPost — lets AI agents publish video and image posts to YouTube, TikTok, Instagram.
Schedule and publish social posts across 9 platforms (Instagram, LinkedIn, X, TikTok, Facebook, Threads, Pinterest, Bluesky, Mastodon) straight from Claude, ChatGPT, Cursor, or any MCP client. Create, edit, and reschedule posts, upload media, and pull account and post analytics, follower demographics, and best-time windows. 20 tools, free on every plan.
Related MCP Servers
- AlicenseAqualityBmaintenanceSchedule and manage social media posts across 10 platforms (Instagram, Facebook, TikTok, X, LinkedIn, YouTube, Threads, Pinterest, Bluesky, Telegram) from any MCP-compatible AI assistant. Supports batch posting, media uploads, analytics, and platform-specific features like Reels, Shorts, and carousels.11455 npm7MIT

Upload-Postofficial
AlicenseBqualityAmaintenanceUpload-Post is the all-in-one social media MCP server the Model Context Protocol server for social media publishing, scheduling and analytics. Connect any MCP-compatible AI agent (Claude, Cursor, ChatGPT, Claude Desktop, n8n, and more) and publish, schedule and analyze content across 13+ social networks from one API: TikTok, Instagram, YouTube, YouTube Shorts, Instagram Reels, LinkedIn, Facebook72558 npm13MIT- AlicenseAqualityBmaintenanceEnables MCP clients like Claude or Cursor to upload videos from your local machine directly to YouTube, schedule them, and manage channel content through Runsheet.11123 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to publish social posts and Reddit comments to connected platforms by executing jobs in the user's own logged-in desktop Chrome session, with OAuth and without platform API keys.MIT