Skip to main content
Glama

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.

CI License: MIT Python MCP Chrome MV3 Platforms


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.mp4 on 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.md

Option 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 | sh

Either way, everything is set up for you:

  • uv: installed if missing.

  • Server: installed as the social-publish-mcp command.

  • 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:

  1. In chrome://extensions, turn on Developer mode.

  2. Click Load unpacked, choose ~/.social-publish-mcp/extension.

  3. 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

uv

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-mcp

Then 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)

setup option

Effect

--client NAME

configure only these clients: claude-code, claude-desktop, cursor, windsurf, vscode, gemini, codex

--no-skill

do not install the Claude Code skill

--no-extension

do not copy the extension folder

--no-open

do not open chrome://extensions and the extension folder

Config files are merged (your other MCP servers are kept) and backed up as *.bak first.

2. Load the Chrome extension

  1. social-publish-mcp setup copies the extension to ~/.social-publish-mcp/extension (Windows: C:\Users\<you>\.social-publish-mcp\extension). You can also use the extension/ folder of a clone.

  2. Open chrome://extensions (Edge: edge://extensions, Brave: brave://extensions).

  3. Turn on Developer mode (top right).

  4. Click Load unpacked and select the extension folder of the repository.

  5. 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

https://studio.youtube.com

If your Google account owns several channels, pass channel_id (it starts with UC).

Facebook

https://business.facebook.com

Posts go to the Page selected in Business Suite; pass asset_id to choose a Page explicitly.

TikTok

https://www.tiktok.com/tiktokstudio/upload

4. Verify

social-publish-mcp --check

The 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 (usually C:\Users\<you>\.local\bin\social-publish-mcp.exe).

claude mcp add social-publish --scope user -- social-publish-mcp

Install 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-mcp

or 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

status()

Extension connected?, versions, running jobs, open tabs, last results. Call first.

check_accounts(platforms=["youtube","facebook","tiktok"])

Opens each upload page, returns {platform: {logged_in, account, detail}}.

publish(platform, video, caption, title="", tags=[], schedule_at=None, options={}, dry_run=False, keep_tab=False)

One video to one platform.

publish_batch(jobs, max_parallel=3, dry_run=False, keep_tab=False)

Several jobs (same fields as publish, plus caption_file). All are validated first.

history(limit=20)

Last results, newest last (also failures with their screenshot path).

Parameters:

  • platform: youtube · facebook · tiktok

  • video: absolute path to the file on this computer

  • caption: YouTube description / Facebook reel description / TikTok caption, hashtags included, posted as written

  • title: YouTube only (required there, max 100 characters)

  • tags: YouTube tags

  • schedule_at: ISO 8601 with a UTC offset, e.g. 2026-11-01T17:00+02:00; omit to publish now

  • dry_run: fill everything, stop before the final button

  • keep_tab: leave the job tab open afterwards (useful with dry_run to 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_id

—

Channel to upload to (UC…); required when the account owns several channels

playlists

[]

Exact playlist names to add the video to

visibility

public

public · unlisted · private (scheduled videos are always public)

made_for_kids

false

Audience setting

altered_content

false

"Altered or synthetic content" disclosure

facebook

asset_id

—

Business Suite Page asset id (from the asset_id= URL parameter)

page_name

—

Fail if the composer's "Post to" does not show this Page

allow_remix

true

"Remixing and use of original audio"

tiktok

visibility

everyone

everyone · friends · only_me

allow_comments

true

Comments on/off

ai_generated

false

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 < >; description ≤ 5000; tags ≤ 500 characters in total

TikTok

caption 1–4000 characters

Facebook

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

SOCIAL_PUBLISH_PORT

8797

Bridge port (set the same port in the extension popup)

SOCIAL_PUBLISH_HOME

~/.social-publish-mcp

State folder

SOCIAL_PUBLISH_EXTENSION_IDS

—

Extra extension ids to accept, comma separated

history.jsonl

One JSON line per result

artifacts/<job-id>/

Screenshots and DOM dumps of a job (job-id = YYYYMMDD-HHMMSS-<platform>-<6 hex>)

extensions.json

Pinned extension id

token.txt

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 social-publish-mcp status). Check the port in the popup matches SOCIAL_PUBLISH_PORT.

ERR_CONNECTION_REFUSED in the extension's errors page

Same as above: the server is not running. Harmless; it retries automatically.

not allowed / close code 4004

Another extension id is pinned. Delete ~/.social-publish-mcp/extensions.json and reconnect, or add the id to SOCIAL_PUBLISH_EXTENSION_IDS.

check_accounts says not logged in

Open the platform page in that Chrome profile and log in. YouTube "permission" page means the wrong channel: pass channel_id.

A job failed at a step

Open the screenshot in the result (artifacts/<job-id>/). Run the same job with dry_run=true, keep_tab=true to watch it.

"started debugging this browser" bar cancelled

The running job fails cleanly; start it again.

Times are off by an hour

Pass schedule_at with the correct offset for that date (daylight saving).

The site was redesigned

Update the server (uv tool upgrade social-publish-mcp) or open an issue with the screenshot.

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 fakes

Adding 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

MIT

Available Tools

5 tools
check_accountsA
Read-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}}.

NameRequiredDescriptionDefault
platformsNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

historyA
Read-onlyIdempotent

The last limit posting results (newest last), from /history.jsonl.

NameRequiredDescriptionDefault
limitNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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}]}.

NameRequiredDescriptionDefault
tagsNo
titleNo
videoYes
captionYes
dry_runNo
optionsNo
keep_tabNo
platformYes
schedule_atNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

NameRequiredDescriptionDefault
jobsYes
dry_runNo
keep_tabNo
max_parallelNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

statusA
Read-onlyIdempotent

Is the Chrome extension connected? Server/extension versions, running jobs, open tabs, last results.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

  1. 5 tool updatesv0.1.0
    • First observedcheck_accounts
    • First observedhistory
    • First observedpublish
    • First observedpublish_batch
    • First observedstatus

TDQS

A3.8/5.0

Scored across 5 tools

Disambiguation4/5

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.

Naming Consistency3/5

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.

Tool Count5/5

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.

Completeness3/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Schedule 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.
    11
    455 npm
    7
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    Upload-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, Facebook
    72
    558 npm
    13
    MIT