Skip to main content

MCP Server (ChatGPT / Claude / Cursor)

Upload-Post ships an official Model Context Protocol (MCP) server. Connect it to ChatGPT, claude.ai, Claude Desktop, Claude Code, Cursor, or any other MCP-compatible AI agent and your assistant can publish, schedule, analyze and manage social media on your behalf — without writing any code.

The server exposes 45 tools across the public Upload-Post API, OAuth connectors, media staging, and the hosted Upload Studio.

How authentication works

The server supports two auth modes, and chooses automatically based on what the client sends:

1. API key (Claude Desktop, Claude Code, Cursor, any MCP client with mcp.json)

Each MCP client sends its own Upload-Post API key in the Authorization header of every request. The server uses that key for the duration of the session and stores nothing.

Authorization: ApiKey YOUR_UPLOAD_POST_API_KEY

Authorization: Bearer YOUR_UPLOAD_POST_API_KEY is also accepted, for clients that only allow Bearer tokens.

2. OAuth 2.1 (claude.ai Custom Connectors, ChatGPT, any "Add via URL" client)

Clients that don't accept custom headers can connect via the standard OAuth flow — no API key copying required. The server implements:

  • RFC 9728 Protected Resource Metadata at /.well-known/oauth-protected-resource
  • RFC 8414 Authorization Server Metadata at /.well-known/oauth-authorization-server
  • RFC 7591 Dynamic Client Registration at /register
  • RFC 6749 §4.1 + PKCE (RFC 7636) authorization-code flow at /authorize + /token
  • RFC 7009 Token revocation at /revoke

The user is sent to app.upload-post.com/oauth/authorize to log in and approve. The issued access token (prefix up_oauth_) is opaque — the server resolves it to the user's API key on every request via an internal introspection call.

You can view and revoke active OAuth connectors at any time from Connected Apps in the dashboard.

Get your API key

  1. Sign in to app.upload-post.com.
  2. Open the API Keys section.
  3. Generate a new key and copy it.

Connect claude.ai (Custom Connector)

Go to Settings → Connectors → Add custom connector in claude.ai and paste:

https://mcp.upload-post.com/mcp

claude.ai will:

  1. Discover the OAuth metadata at /.well-known/oauth-protected-resource.
  2. Dynamically register itself via /register (no manual client ID needed).
  3. Open app.upload-post.com/oauth/authorize in a popup so you can log in and approve.
  4. Exchange the returned authorization code for an access token, and store it.

That's it — 45 tools become available inside claude.ai with zero local configuration. Revoke any time from Connected Apps.

Connect ChatGPT

Use the ChatGPT connector/app setup and point it to the hosted MCP endpoint:

https://mcp.upload-post.com/mcp

ChatGPT uses the same OAuth flow as claude.ai. After approval, the connector can call the Upload-Post tools and open the Upload Studio component for browser-based media uploads.

Connect Claude Desktop / Claude Code / Cursor

Add the following entry to your MCP config (~/.claude/mcp.json, ~/.cursor/mcp.json, or your IDE's equivalent):

{
"mcpServers": {
"upload-post": {
"url": "https://mcp.upload-post.com/mcp",
"headers": {
"Authorization": "ApiKey YOUR_UPLOAD_POST_API_KEY"
}
}
}
}

Restart your client. You should see 45 upload-post tools become available.

What the agent can do

GroupTools
Uploadupload_video, upload_photos, upload_text, upload_document
Statusget_status, get_job_status, get_history, get_media
Schedulelist_scheduled, cancel_scheduled, edit_scheduled
Analyticsget_analytics, get_total_impressions, get_post_analytics, get_platform_metrics
Usersget_account_info, list_users, create_user, delete_user, generate_jwt, validate_jwt
Pages / boardsget_facebook_pages, get_linkedin_pages, get_pinterest_boards, get_google_business_locations, select_google_business_location, get_reddit_detailed_posts
Commentsget_post_comments, reply_to_comment, public_reply_to_comment
DMssend_dm, list_dm_conversations, manage_autodms
FFmpegsubmit_ffmpeg_job, get_ffmpeg_job, download_ffmpeg_result, get_ffmpeg_consumption
Queueget_queue_settings, update_queue_settings, preview_queue
Media stagingcreate_media_upload, complete_media_upload, get_media_upload, delete_media_upload
Studioopen_upload_studio

Async uploads return a request_id; the agent polls get_status until success: true.

Browser media staging for ChatGPT and Claude

Hosted AI clients do not reliably hand local file paths to MCP tools. Upload-Post solves this with short-lived R2 media staging, so the browser uploads the binary directly while the MCP only orchestrates the flow.

  1. The client calls create_media_upload with filename, content_type, content_length, media_type, and source.
  2. The backend returns an upload_id and a presigned R2 upload_url.
  3. The browser uploads the file directly to R2 with PUT.
  4. The client calls complete_media_upload to validate the object and receive a temporary signed media_url.
  5. The agent passes that media_url to upload_video, upload_photos, or another upload tool.

The staging object is not the durable source of truth. The normal Upload-Post upload/scheduler flow downloads the temporary URL and stores the media in the existing durable storage path before publishing or scheduling. This keeps the existing /api/upload behavior unchanged.

Staged objects expire after 24 hours whether they were used or not. Clients can also call delete_media_upload to remove an unused object earlier.

Media staging limits

These limits are separate from normal social upload quotas and protect only the temporary browser-to-R2 ingest path.

PlanUploads / monthMax file sizeMonthly ingestPending uploads
Free / default10250 MB2 GB3
Basic / Premium100500 MB25 GB10
Professional / Pro5001 GB100 GB50
Advanced2,0002 GB500 GB200
Business10,0005 GB2 TB1,000

Production deployment notes

Deploy the backend before the MCP server. The MCP calls the new media staging endpoints, so older backend versions will not support browser uploads.

Backend environment variables are optional because production-safe defaults are built in:

UPLOADPOST_MCP_MEDIA_STAGING_PREFIX=mcp-ingest/tmp
UPLOADPOST_MCP_MEDIA_TTL_HOURS=24
UPLOADPOST_MCP_MEDIA_PUT_EXPIRES_SECONDS=900
UPLOADPOST_MCP_MEDIA_GET_EXPIRES_SECONDS=21600

Set UPLOAD_POST_R2_CONNECT_DOMAIN on the MCP only if the public host used by the presigned R2 URLs is different from the default:

UPLOAD_POST_R2_CONNECT_DOMAIN=https://0de16d5f5e344fe4757ecd62640a9ea3.r2.cloudflarestorage.com

R2 bucket CORS is required only for browser direct uploads. It does not affect API-to-API calls, scheduler workers, or the existing upload flow. Allow:

  • Origins: https://chatgpt.com, https://chat.openai.com, https://app.upload-post.com, https://mcp.upload-post.com
  • Methods: PUT, GET, HEAD
  • Headers: at least Content-Type; use * if the Cloudflare dashboard requires a broad value for presigned S3 requests

Do not add a 24-hour lifecycle rule to the whole bucket. Cleanup is handled by the backend cron and targets only objects under mcp-ingest/tmp.

Troubleshooting

  • redirect_uri not on allow-list: the Upload-Post OAuth backend must allow the client redirect URI from ChatGPT or claude.ai before /oauth/authorize can complete.
  • Browser CORS error during PUT: check the R2 CORS policy and make sure the MCP UPLOAD_POST_R2_CONNECT_DOMAIN matches the host returned in upload_url.
  • Video file not found from an agent: use media staging instead of sending local filesystem paths to upload_video.

Example prompts

Once connected, try these in your AI client:

  • "List the users in my Upload-Post account."
  • "Publish this video URL to TikTok and Instagram under the profile marketing with the caption 'Spring launch'."
  • "Schedule a text post on LinkedIn for next Monday at 10:00 Madrid time."
  • "Show me the analytics for my profile marketing over the last month."
  • "Reply privately to the latest comment on my Instagram post."

The model decides which tools to call based on the request; you don't have to name them.

Self-hosting (optional)

If you prefer to run the server yourself — for an isolated network, custom auth proxy, or stricter compliance requirements — the source repository ships with a multi-stage Dockerfile and a one-click Coolify configuration. See the project README for instructions.

Local-only stdio mode

For single-user setups (no hosted server), you can run the MCP locally via npx. Once published to npm, the configuration becomes:

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

Both modes expose the same 45 tools.

Need assistance?

Open an issue at github.com/Upload-Post/upload-post-mcp/issues or contact our support team.