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.
- Hosted endpoint:
https://mcp.upload-post.com/mcp - Source: github.com/Upload-Post/upload-post-mcp (MIT)
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
- Sign in to app.upload-post.com.
- Open the API Keys section.
- 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:
- Discover the OAuth metadata at
/.well-known/oauth-protected-resource. - Dynamically register itself via
/register(no manual client ID needed). - Open
app.upload-post.com/oauth/authorizein a popup so you can log in and approve. - 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
| Group | Tools |
|---|---|
| Upload | upload_video, upload_photos, upload_text, upload_document |
| Status | get_status, get_job_status, get_history, get_media |
| Schedule | list_scheduled, cancel_scheduled, edit_scheduled |
| Analytics | get_analytics, get_total_impressions, get_post_analytics, get_platform_metrics |
| Users | get_account_info, list_users, create_user, delete_user, generate_jwt, validate_jwt |
| Pages / boards | get_facebook_pages, get_linkedin_pages, get_pinterest_boards, get_google_business_locations, select_google_business_location, get_reddit_detailed_posts |
| Comments | get_post_comments, reply_to_comment, public_reply_to_comment |
| DMs | send_dm, list_dm_conversations, manage_autodms |
| FFmpeg | submit_ffmpeg_job, get_ffmpeg_job, download_ffmpeg_result, get_ffmpeg_consumption |
| Queue | get_queue_settings, update_queue_settings, preview_queue |
| Media staging | create_media_upload, complete_media_upload, get_media_upload, delete_media_upload |
| Studio | open_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.
- The client calls
create_media_uploadwithfilename,content_type,content_length,media_type, andsource. - The backend returns an
upload_idand a presigned R2upload_url. - The browser uploads the file directly to R2 with
PUT. - The client calls
complete_media_uploadto validate the object and receive a temporary signedmedia_url. - The agent passes that
media_urltoupload_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.
| Plan | Uploads / month | Max file size | Monthly ingest | Pending uploads |
|---|---|---|---|---|
| Free / default | 10 | 250 MB | 2 GB | 3 |
| Basic / Premium | 100 | 500 MB | 25 GB | 10 |
| Professional / Pro | 500 | 1 GB | 100 GB | 50 |
| Advanced | 2,000 | 2 GB | 500 GB | 200 |
| Business | 10,000 | 5 GB | 2 TB | 1,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/authorizecan complete.- Browser
CORSerror duringPUT: check the R2 CORS policy and make sure the MCPUPLOAD_POST_R2_CONNECT_DOMAINmatches the host returned inupload_url. Video file not foundfrom an agent: use media staging instead of sending local filesystem paths toupload_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
marketingwith 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
marketingover 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.