# Upload-Post [Health: Active]

**Category:** 🌐 Social Media  
**Repository:** https://github.com/Upload-Post/upload-post-mcp  
**GitHub Stars:** 16  
**npm Downloads (last month):** 1052  
**Views:** 4  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/upload-post

## Description
Publish, schedule & analyze posts on TikTok, Instagram, YouTube, LinkedIn, X & 10+ social networks

## Tools
Capabilities this server exposes over MCP:

- **upload_video** — Publish a video to one or more platforms. Use `videoPathOrUrl` only for public/signed HTTPS URLs, or for absolute local paths when the MCP server runs on the same machine as the file. `videoBase64` is only for clients that can provide raw bytes directly and is capped by UPLOAD_POST_MAX_INLINE_MB (default 100). Returns a `request_id` you can poll with `get_status`. Supports per-platform overrides (tiktokPrivacyLevel, youtubePrivacyStatus, youtubePlaylistId, youtubeThumbnailUrl, youtubeTags, facebookPageId, instagramMediaType, etc.). Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target. A hosted MCP server cannot read files on the user's machine or chat attachments (`/mnt/data`, sandbox paths). To publish a local file: (1) if this client can run HTTP requests itself (for example a coding agent with a shell), stage it with `create_media_upload` (returns `upload_id` + `upload_url`), PUT the raw file bytes to `upload_url` with the same Content-Type, call `complete_media_upload` and pass the returned `media_url` as the media URL; (2) otherwise ask the user for a public HTTPS URL of the file, or tell them to publish it from the dashboard at https://app.upload-post.com. Staged media is deleted after 24 hours.
- **upload_photos** — Publish one or more photos (single image or carousel). Each item in `photosPathsOrUrls` may be a public URL or a local path. Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target.
- **upload_text** — Publish a text-only post. `linkUrl` (or platform-specific *LinkUrl) attaches a link preview where supported. Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target.
- **upload_document** — Publish a document (PDF / PPT / PPTX / DOC / DOCX) to LinkedIn. Title is required.
- **get_status** — Check the status of an async upload by `request_id`. Poll this until `status` is 'success' or 'failed'.
- **get_job_status** — Check the status of a scheduled or queued upload by `job_id`. Use this for posts created with `addToQueue` or `scheduledDate`.
- **get_history** — Paginated history of uploads across all profiles.
- **get_media** — Retrieve recent media (videos, photos, text posts) pulled directly from a profile's connected social accounts. Supports instagram, tiktok, youtube, linkedin, facebook, x, threads, pinterest, bluesky, reddit. Useful for browsing what already exists on a platform before posting more. Paginated: the response carries `pagination` = { limit, next_cursor, has_more }; pass `next_cursor` back as `cursor` for the next page (the last page returns next_cursor null and has_more false).
- **list_scheduled** — List all currently scheduled (not-yet-published) posts.
- **cancel_scheduled** — Cancel a scheduled post by its `job_id`.
- **edit_scheduled** — Edit a pending scheduled post in place, keeping its job ID and media: reschedule it (scheduledDate/timezone) and/or fix its text. `title` and `caption` rewrite the text for EVERY platform of the post; to change only some platforms, send `platformContent` instead, e.g. {"instagram":{"caption":"..."},"tiktok":{"caption":"..."}} — platforms not listed keep their text. First comments cannot be edited on a pending post.
- **get_analytics** — Aggregated analytics for a profile across selected platforms (followers, views, engagement). Instagram also returns two audience breakdowns with the same shape (age / gender / country / city): `follower_demographics` for the account's followers and `engaged_audience_demographics` for the accounts that engaged with its content.
- **get_total_impressions** — Sum of impressions for a profile from daily snapshots. Use `period` for presets, or `startDate`/`endDate` for custom ranges.
- **get_post_analytics** — Per-platform metrics for a specific post identified by `request_id`. `post_metrics` carries whatever each platform reports, so its shape is not the same everywhere: on TikTok it adds `retention` (the curve, second by second), `impression_sources` (For You, following, search, profile…), `audience_types` (followers vs non-followers), `new_followers` won by the post, `reach` and the watch times (`average_time_watched`, `total_time_watched`, `full_video_watched_rate`) on top of the usual counters.
- **get_cached_post_analytics** — Replays per-post metrics Upload-Post already fetched, instead of calling the platforms again. ONLY contains posts previously fetched through `get_post_analytics`; there is no background refresh, so `captured_at` is the last time that post was read live and a post never queried live will be absent. Unlike `get_post_analytics` it never hits the platforms, so it is not subject to the live analytics rate limit (100 requests / 5 minutes) — prefer it when scanning many posts or paging through a profile's history. Paginated: pass `next_cursor` from the response back as `cursor` until `has_more` is false.
- **get_platform_metrics** — Reference: which metrics are available per platform (impressions, likes, …) and their human labels.
- **get_audience** — Who follows the profile, when they are online and what they tap on it. One endpoint for every network, chosen with `platform`. Returns `audience.countries` / `.cities` / `.ages` / `.genders`, `activity_by_hour` (followers online per hour of the day — use it to pick posting times), `followers_daily` (total / new / lost), `profile_actions` and `bio_description`. It always returns `benchmark_categories` (the 25 values `benchmark_category` accepts), and when `benchmark_category` is set it adds a `benchmark` object with that niche's averages (engagement rate, likes, views, follower growth…) to compare the account against. The window is clamped by the server — at most 60 days, always ending before today — so a wider range is trimmed, not rejected; `range` in the response says which window was actually used. Requires the 'profile_analytics' capability on the profile's TikTok account (see the `capabilities` array in list_users).
- **get_suggestions** — What to write about: the hashtags or the searches a network suggests around a word. One endpoint for both questions, told apart by `type`, and one endpoint for every network, chosen with `platform`. `type: 'hashtags'` returns `{ hashtags: [{ name, view_count }] }` — pick tags that actually have reach for a caption; `type: 'keywords'` returns `{ keywords: [...] }`, what people really search around `q`, useful for the next video topic. Requires the 'profile_analytics' capability on the profile's TikTok account (see the `capabilities` array in list_users). Keyword suggestions need 'trend_search' instead, granted the same way.
- **get_account_info** — Validate the current API key and return account information. Useful as a first call to confirm credentials before doing real work.
- **list_users** — List all Upload-Post profiles in the account, with their connected social accounts. The TikTok account object carries a `capabilities` array (music, location, cover_image, cover_timestamp, draft, photo_privacy, video_privacy, inbox_fallback, profile_analytics) telling which optional TikTok fields that connection accepts.
- **create_user** — Create a new Upload-Post profile (logical container for connected socials).
- **delete_user** — Permanently delete a profile and disconnect its socials.
- **generate_jwt** — Generate a JWT + connection URL so an end-user can connect socials inside an embedded Upload-Post flow (white-label integration).
- **validate_jwt** — Verify a JWT previously issued by `generate_jwt`. The returned `profile` object echoes the connection page settings, including `language` and any `ui_labels`.
- **get_facebook_pages** — Facebook pages connected to a profile.
- **get_linkedin_pages** — LinkedIn company pages connected to a profile.
- **get_pinterest_boards** — Pinterest boards available to a profile.
- **tiktok_music_trending** — Trending tracks from the TikTok Commercial Music Library, to soundtrack a TikTok video. Pass the returned track `id` as `tiktokMusicId` in upload_video's platformOptions (not `commercial_music_id`, which TikTok rejects on public posts). Available on TikTok connections that declare the `music` capability (see `capabilities` on the TikTok account in list_users).
- **tiktok_music_search** — Find a TikTok Commercial Music Library track by song title or artist, to soundtrack a TikTok video. Pass the returned track `id` as `tiktokMusicId` in upload_video's platformOptions (not `commercial_music_id`, which TikTok rejects on public posts). IMPORTANT: TikTok has no music search endpoint, so this searches the trending charts Upload-Post caches per genre/country/period, NOT TikTok's whole catalogue — a song that is not trending in the chart you query will not be found; widening the search means trying another genre, country or period. Matching is case- and accent-insensitive and every word must match. Available on TikTok connections that declare the `music` capability (see `capabilities` on the TikTok account in list_users).
- **tiktok_location_search** — Search TikTok places to tag on a post. TikTok needs both parts, so pass the returned `location_id` as `tiktokLocationId` and `location_name` as `tiktokLocationName` in upload_video's platformOptions. Available on TikTok connections that declare the `location` capability (see `capabilities` on the TikTok account in list_users).
- **tiktok_publishing_settings** — What the connected TikTok account is allowed to publish. Call this before setting `tiktokPrivacyLevel`: TikTok narrows the four privacy values per account (a private account has no PUBLIC_TO_EVERYONE), and sending one the account does not have fails the upload with error_code tiktok_privacy_unavailable. Returns `privacy_level_options` plus the account's max video duration and its comment/duet/stitch switches.
- **get_google_business_locations** — Google Business Profile locations the profile can post to.
- **get_google_business_reviews** — List reviews for a Google Business Profile location. Pass the profile that owns the connected Google Business account; location_id defaults to the account's selected location.
- **reply_to_google_business_review** — Create or update the owner reply to a Google Business review. Provide review_name (the full resource path from get_google_business_reviews) or review_id + location_id.
- **get_reddit_detailed_posts** — Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target. Recent Reddit posts published from a profile, with the platform-side metadata (subreddit, flair, score, …).
- **get_post_comments** — List comments on a post. One endpoint for every network, chosen with `platform`. Identify the post by either `postId` or `postUrl` (YouTube: postId=videoId; LinkedIn: postId=the post urn; TikTok: postId=the video id, `postUrl` is not accepted). Add `commentId` to get the REPLIES hanging off that one comment instead of the post's top-level comments — replies are the same question with one more parameter, not another tool. TikTok: Requires the 'comments' capability on the profile's TikTok account (see the `capabilities` array in list_users). It is granted at connection time, so an account connected earlier has to reconnect TikTok before this works.
- **reply_to_comment** — Send a private DM to the author of an Instagram comment (within Instagram's 7-day reply window).
- **public_reply_to_comment** — Post a public reply visible under the original Instagram comment.
- **create_comment** — Post a top-level comment or a reply on a post. Provide exactly ONE of `commentId` (reply to a comment), `postId`, or `postUrl` (top-level). LinkedIn: postId=the post urn. Instagram requires `commentId` (replies only). TikTok always needs `postId` (the video id); add `commentId` on top of it to reply inside that thread. TikTok: Requires the 'comments' capability on the profile's TikTok account (see the `capabilities` array in list_users). It is granted at connection time, so an account connected earlier has to reconnect TikTok before this works.
- **delete_comment** — Delete a comment by `commentId`. LinkedIn also requires `postId` (the post urn); TikTok needs only the `commentId`. TikTok: Requires the 'comments' capability on the profile's TikTok account (see the `capabilities` array in list_users). It is granted at connection time, so an account connected earlier has to reconnect TikTok before this works.
- **comment_action** — Moderate or react to a comment on one of the profile's own posts. One endpoint for every network, chosen with `platform`; each network supports its own verbs and answers 400 `platform_not_supported` / invalid action otherwise. TikTok: hide/unhide (postId), like/unlike (no postId), pin/unpin (postId). Facebook: hide/unhide, like/unlike, edit (needs `message`). Instagram: hide/unhide a comment, or enable_comments/disable_comments on a post (postId, no commentId). YouTube: hide/unhide/hold (postId; `banAuthor` only with hide). Threads: hide/unhide, approve/ignore. Every action has an inverse, so nothing here is permanent. Deleting a comment is a different tool: delete_comment. TikTok: Requires the 'comments' capability on the profile's TikTok account (see the `capabilities` array in list_users). It is granted at connection time, so an account connected earlier has to reconnect TikTok before this works.
- **retry_post** — Retry a failed upload. Identify it by either `requestId` (async upload) or `jobId` (scheduled/queued upload).
- **unpublish_post** — Delete a post already published to a platform. Instagram and TikTok are not supported.
- **send_dm** — Send an Instagram DM to a recipient from a connected Upload-Post profile. Use a recipient_id returned by Instagram comments or DM conversation tools.
- **list_dm_conversations** — Recent DM conversations for a profile on a given platform.
- **manage_autodms** — Control Instagram AutoDM monitors. For action='start', provide post_url, reply_message, and profile_username. For stop/pause/resume/delete/logs, provide monitor_id. For status, optionally set include_inactive=true.
- **submit_ffmpeg_job** — Submit a private FFmpeg processing job through Upload-Post. Provide `input_url` for one input, or `files` for multiple public URLs. Optionally provide `full_command` beginning with ffmpeg for explicit trim/transcode/watermark/thumbnail commands. Returns a `job_id` you can poll with `get_ffmpeg_job`.
- **get_ffmpeg_job** — Poll the status of an FFmpeg job. When status is 'completed', call `download_ffmpeg_result` to obtain the file.
- **download_ffmpeg_result** — Returns the download URL and metadata for a completed FFmpeg job without streaming the processed file through MCP.
- **get_ffmpeg_consumption** — Monthly FFmpeg processing minutes used vs. plan allowance.
- **get_queue_settings** — Posting queue configuration (slots per day, time windows, timezone).
- **update_queue_settings** — Update posting queue configuration for a profile. Fields are flat, not nested: timezone, slots, days_of_week, and max_posts_per_slot.
- **preview_queue** — Preview the upcoming queue slots and what would land in them. Optionally `nextSlot=true` returns just the next available slot timestamp.
- **create_media_upload** — Step 1 of staging a local file for publishing. Returns `upload_id` and a short-lived `upload_url`; the caller must then PUT the raw file bytes to `upload_url` (same Content-Type and size as declared here) and call `complete_media_upload`. Only useful when this client can perform the HTTP PUT itself (for example a coding agent with a shell); the model cannot read chat attachments or `/mnt/data` paths, so for those ask the user for a public HTTPS URL or send them to https://app.upload-post.com. Staging media is deleted after 24 hours; scheduled posts are safe because upload_video copies the media into durable scheduler storage.
- **complete_media_upload** — Step 2 of staging a local file. Call it only after the file bytes were actually PUT to the `upload_url` from create_media_upload; without that PUT it fails or yields no publishable media. Returns a temporary `media_url` to pass straight to upload_video / upload_photos / upload_document.
- **get_media_upload** — Internal/app staging helper. Get status for a short-lived MCP media upload. Optionally returns a fresh temporary media_url for an already-uploaded staging object.
- **delete_media_upload** — Internal/app staging helper. Delete a short-lived MCP staging media upload from R2. This does not delete scheduler durable copies created later by upload_video.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "upload-post": {
    "command": "npx",
    "args": ["-y","@upload-post/mcp"],
    "env": {
      "UPLOAD_POST_API_KEY": ""
    }
  }
}
```

**Requires environment variables:** `UPLOAD_POST_API_KEY` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation

## What Upload-Post MCP server does

Upload-Post MCP server gives an MCP client access to Upload-Post’s social publishing and analytics API. It can publish videos, photos, carousels, text posts, and LinkedIn documents to one or more connected profiles. Supported destinations include TikTok, Instagram, YouTube, LinkedIn, Facebook, X, Threads, Pinterest, Bluesky, and others exposed by the connected Upload-Post account.

The server also supports scheduled publishing, upload history, media browsing, account and profile administration, and social performance analysis. TikTok-specific helpers can find commercial music tracks or locations for use with video publishing. Facebook pages, LinkedIn pages, and Pinterest boards can be enumerated before selecting a destination.

## How it works

Publishing calls return an asynchronous identifier rather than waiting for the platform operation to finish. Use `get_status` with the returned `request_id` until the operation succeeds or fails. Posts created with a schedule or queue use `get_job_status` and can be listed, edited, or cancelled through the scheduling tools.

Analytics can be requested at profile level, for total impressions, or for an individual post. `get_cached_post_analytics` reads metrics previously fetched live, which is useful when reviewing many posts without making another platform request. Audience data includes follower characteristics, activity by hour, account actions, and optional niche benchmarks. Suggestion queries return hashtag reach or search terms for a selected network.

A local stdio deployment runs the package through `npx` and passes an Upload-Post API key in the environment. A hosted deployment exposes the streamable HTTP endpoint and accepts each user’s key through an `Authorization` header. OAuth connection flows are also available in supported hosted clients and through JWT-based connection tools.

## Setup and configuration

For local use, configure an MCP client with a command equivalent to:

```json
{
  "command": "npx",
  "args": ["-y", "@upload-post/mcp"],
  "env": {
    "UPLOAD_POST_API_KEY": "YOUR_API_KEY"
  }
}
```

API keys are obtained from the Upload-Post application. Hosted deployments use the `/mcp` endpoint and can authenticate with either `Authorization: ApiKey YOUR_KEY` or, for clients that require it, `Authorization: Bearer YOUR_KEY`.

Video inputs must be public or signed HTTPS URLs, or absolute local paths readable by a local server. A hosted server cannot access files on the user’s computer or chat attachments. For local files with an HTTP-capable client, stage the bytes with the media-upload flow, complete the upload, and pass the resulting media URL to the publishing tool. Staged media is removed after 24 hours. Inline base64 video is limited by `UPLOAD_POST_MAX_INLINE_MB`, which defaults to 100 MB.

## Tools and capabilities

- Publish videos, photos, carousels, text posts, and LinkedIn documents.
- Schedule, inspect, edit, and cancel pending posts.
- Retrieve upload status, queued-job status, history, and connected-profile media.
- Read profile analytics, impressions, post metrics, cached metrics, and audience information.
- Manage Upload-Post profiles and generate or validate connection JWTs.
- Discover Facebook pages, LinkedIn pages, Pinterest boards, TikTok music, and TikTok locations.

## Limitations and notes

Reddit is currently unavailable as a publishing target and returns `reddit_unavailable`; do not select it when publishing. TikTok audience and suggestion features require the relevant `profile_analytics` capability, while keyword suggestions also require `trend_search`. TikTok music and location helpers depend on the corresponding capabilities of the connected account.

Analytics responses vary by platform. TikTok post metrics may include retention curves, impression sources, audience types, follower gains, reach, and watch-time fields in addition to common counters. Audience date windows are limited to 60 days and end before the current day. Cached post metrics exist only after the post has been queried live and are not refreshed in the background.

_Full upstream README: https://allmcps.com/mcp/upload-post/readme_

