Onlypult MCP Server
Connect AI agents β Claude, Cursor, ChatGPT, Windsurf, Codex, Antigravity, and any MCP-compatible client β directly to your Onlypult account via Model Context Protocol. Let AI publish, schedule, and manage your social content.
Hosted MCP URL: https://mcp.onlypult.com/mcp (Streamable HTTP β no install)
Local package (disk uploads): npx -y @onlypult/mcp@latest β stdio on your machine; works in any client that supports command + args MCP config (Cursor, Claude Desktop, Windsurf, Codex, Antigravity, β¦).
What you can do
Ask your AI assistant things like:
- "Show my connected social profiles"
- "Post 'Hello world!' to Instagram now"
- "Schedule a LinkedIn post for tomorrow at 9am"
- "Cross-post this to Instagram and Facebook"
- "Post this image to Instagram" (with browser upload flow)
- "List my failed posts and retry them"
- "Create an Instagram Reels post with this video"
Setup
The hosted MCP server at mcp.onlypult.com requires no local installation. Configure your AI client to connect over HTTP, then authenticate.
Get your API key
Create a personal API key in Onlypult. See the Authentication guide for step-by-step instructions.
Quick link: app.onlypult.com/settings β API Keys.
Configure your client
Pick your client below. Hosted HTTP needs no install; local stdio (@onlypult/mcp) adds media_upload_file from disk paths.
Restart your client
After saving MCP config, restart the client completely so the integration loads.
OAuth path: For Claude.ai and ChatGPT, skip the API key β add the MCP URL and sign in via the browser consent page. See OAuth 2.1.
Authentication
The MCP server supports two authentication methods depending on how your AI client connects.
| Method | When to use | How it works |
|---|---|---|
| API Key | Hosted HTTP (Cursor, Windsurf, β¦) or local stdio (@onlypult/mcp) |
Authorization: Bearer op_... header, or ONLYPULT_API_KEY in stdio env |
| OAuth 2.1 | Claude.ai, ChatGPT, Claude Desktop (Connectors) | OAuth Authorization Code + PKCE β user logs in once via browser |
OAuth 2.1
When adding the hosted MCP server to Claude.ai, ChatGPT or other cloud AI platforms, authentication happens via OAuth 2.1 Authorization Code + PKCE. The AI client redirects the user to the Onlypult consent page β no manual API key setup required.
How the flow works
GET /.well-known/oauth-authorization-server
GET /authorize?client_id=claude&code_challenge=...&state=...
app.onlypult.com/mcp-oauth/authorize?session_id=...
mcp.onlypult.com/callback?code=AUTH_CODE&session_id=...
AUTH_CODE to AI client via redirect_uri?code=...&state=...
POST /token {code, code_verifier}
POST /v1/oauth/mcp/exchange-code {code} on Onlypult API (internal, protected by shared secret)
omt_... access token + opr_... refresh β MCP server returns OAuth token response (expires_in: 30 days)
Authorization: Bearer omt_... β refresh via POST /token when access expires
OAuth endpoints
| Method | Path | Description |
|---|---|---|
| GET | /authorize | Start OAuth flow, redirect to consent page |
| GET | /callback | Receive auth code from dashboard after consent |
| POST | /token | Exchange code + PKCE verifier for access token |
| POST | /register | Dynamic client registration (RFC 7591) |
Pre-registered clients
These clients are pre-registered and don't need dynamic registration:
claudeβ redirect tohttps://claude.ai/api/mcp/auth_callbackchatgptβ redirect tohttps://chatgpt.com/aip/p/mcp/auth_callback
Any other client can register dynamically via POST /register per RFC 7591.
Connect Cursor
Cursor supports two setups. Pick based on whether you need local file upload (media_upload_file) from disk paths in your project.
| Setup | Best for | Media from disk |
|---|---|---|
@onlypult/mcp (stdio) | Posting images/videos by file path (./assets/photo.jpg) | media_upload_file |
| Hosted HTTP | Profiles, posts, scheduling β no local paths | Browser flow (media_get_upload_url) |
Option A β Local package (recommended for file uploads)
Installs automatically via npx. The MCP server runs on your machine (stdio), so it can read workspace files and upload them with media_upload_file.
Add to .cursor/mcp.json in your project root, or to global Cursor MCP settings:
{
"mcpServers": {
"onlypult": {
"command": "npx",
"args": ["-y", "@onlypult/mcp@latest"],
"env": {
"ONLYPULT_API_KEY": "op_your_api_key_here"
}
}
}
}
Requires Node.js 18+. No separate npm install β Cursor runs the package on first use.
Option B β Hosted HTTP (no install)
Connect directly to mcp.onlypult.com. Same tools except local disk upload β use the browser upload flow for images and videos.
{
"mcpServers": {
"onlypult": {
"type": "http",
"url": "https://mcp.onlypult.com/mcp",
"headers": {
"Authorization": "Bearer op_your_api_key_here"
}
}
}
}
Get your API key β see Authentication guide.
Connect Claude Desktop
Claude Desktop supports the same two modes as Cursor. claude_desktop_config.json is stdio-only (command + args) β use the local package there. For the hosted server, add a connector in the app UI (not type: http in the JSON file).
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"onlypult": {
"command": "npx",
"args": ["-y", "@onlypult/mcp@latest"],
"env": {
"ONLYPULT_API_KEY": "op_your_api_key_here"
}
}
}
}
Requires Node.js 18+. Enables media_upload_file from paths on your machine.
Open Claude Desktop β Settings β Connectors β Add custom connector:
- Name:
Onlypult - URL:
https://mcp.onlypult.com/mcp
Click Connect β sign in with Onlypult β Allow access (OAuth). No API key paste. Use browser upload for media (media_get_upload_url).
Same flow as Claude.ai β see step-by-step guide if Connectors look different on your build.
Restart Claude Desktop after saving the config file or adding a connector.
Other MCP clients
Any MCP-compatible app can connect to Onlypult. Config file location varies; the JSON shape is the same.
| Goal | Config |
|---|---|
| No install β posts, scheduling, browser media upload | Hosted https://mcp.onlypult.com/mcp + API key header or OAuth (if the client supports remote MCP) |
Upload files by disk path (media_upload_file) | Local stdio β npx -y @onlypult/mcp@latest + ONLYPULT_API_KEY |
Examples: Windsurf (.windsurf/mcp.json), Cursor (.cursor/mcp.json), Claude Desktop (claude_desktop_config.json), OpenAI Codex, Google Antigravity β check your app's MCP / Integrations settings and paste the same block as in Cursor local setup or hosted HTTP setup, depending on whether the client supports remote servers.
Local stdio template (copy into your client's MCP config):
{
"mcpServers": {
"onlypult": {
"command": "npx",
"args": ["-y", "@onlypult/mcp@latest"],
"env": {
"ONLYPULT_API_KEY": "op_your_api_key_here"
}
}
}
}
Connect Claude.ai
Claude.ai connects to Onlypult via OAuth 2.1 β no API key needed. Add a custom connector in settings, authorize once, then use MCP tools directly in chat.
Step-by-step guide with screenshots: Connect Onlypult to Claude.ai β
Quick summary:
- Settings β Connectors β click Add β Add custom connector
- Name
Onlypult, URLhttps://mcp.onlypult.com/mcpβ Add - Click Connect β sign in with Onlypult β Allow access
- In chat, ask e.g. Show my connected social profiles β approve tool calls when prompted
Free plan: Claude.ai allows one custom connector on the free tier. Remove an existing connector first if the slot is taken.
Connect ChatGPT
ChatGPT connects to Onlypult via OAuth 2.1 β no API key paste. There are two ways to add the MCP server, depending on your ChatGPT plan and available settings.
Option A β Custom Connectors (Plus / Pro)
Available on paid plans: Settings β Connectors β Add custom connector.
Open ChatGPT Connectors
Go to Settings β Connectors β Add custom connector.
Enter the server URL
https://mcp.onlypult.com/mcp
Complete authorization
ChatGPT will redirect you to the Onlypult login and consent page. After approval the integration is active.
Option B β Developer mode (free)
No Connectors menu? Use ChatGPT Developer mode instead β enable it under Settings β App Preferences β Apps, create a private app with the MCP URL, authorize via OAuth, then mention @Onlypult in chat.
Step-by-step guide with screenshots: Connect Onlypult to ChatGPT β
Quick summary:
- Settings β App Preferences β Apps β enable Developer mode in Advanced settings
- Create app β name
Onlypult, Server URLhttps://mcp.onlypult.com/mcp, Authentication OAuth - Connect β Sign in with Onlypult β Allow access
- In chat, type
@Onlypultbefore your request (e.g. @Onlypult Show my connected social profiles)
Available Tools
The MCP server exposes hand-crafted tools for profiles, posts, and media. Call profiles_list first to discover profile IDs before creating posts.
Profiles
| Tool | Description |
|---|---|
| profiles_list | List all connected social media profiles |
| profiles_get | Get a specific profile by ID |
| profiles_platforms_list | List all supported platforms |
| profiles_get_pinterest_boards | List Pinterest boards for a profile |
| profiles_get_youtube_categories | List YouTube categories for a profile |
Posts
| Tool | Description |
|---|---|
| posts_create | Create a post β draft, scheduled, or publish immediately |
| posts_create_story | Create a Story (Instagram, Facebook, VK) |
| posts_create_reels | Create Instagram/Facebook Reels |
| posts_create_shorts | Create YouTube Shorts |
| posts_publish_now | Publish immediately (shortcut for posts_create) |
| posts_cross_post | Post the same content to 2+ profiles at once |
| posts_list | List posts with optional status and profile filters |
| posts_list_failed | List all posts that failed to publish |
| posts_get | Get a single post by ID |
| posts_update | Update a draft or scheduled post |
| posts_delete | Delete a draft or scheduled post |
| posts_retry | Retry a specific failed post |
| posts_retry_all_failed | Retry all failed posts (optionally filter by profile) |
Media
| Tool | Description |
|---|---|
| media_get_upload_url | Browser upload URL β remote MCP or manual upload by user |
| media_upload_file | Direct upload from local file path β @onlypult/mcp stdio only (not hosted mcp.onlypult.com) |
| media_check_status | Poll browser upload session and retrieve file IDs |
Tool Reference
Detailed parameters for each MCP tool. Required fields must always be provided; optional fields can be omitted.
Profiles
profiles_list
List all connected social media profiles. No parameters. Returns profile id, name, platform, username, and status for each account.
profiles_get
| Parameter | Type | Description | Required |
|---|---|---|---|
| profile_id | string | Profile ID from profiles_list | Yes |
profiles_platforms_list
List supported platforms (instagram, facebook, twitter, tiktok, youtube, linkedin, telegram, bluesky, threads, pinterest, googleGmb, wordpress, vkontakte). No parameters.
Posts
When you have multiple profiles on the same platform, pass explicit profile_ids to target the right account. Call profiles_list first to discover IDs.
posts_create
Create a social media post. Can be saved as draft, scheduled, or published immediately.
Choose the correct mode based on user intent:
- DRAFT MODE (
is_draft=true): user says "draft", "save for later", "don't publish". Post is saved but not scheduled or published. - IMMEDIATE MODE (
publish_now=true): user says "publish now", "post now", "immediately". Post goes live right away. - SCHEDULED MODE (default): user says "schedule", "tomorrow at 9am". Provide
scheduled_atin ISO 8601 format.
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
| profile_ids | string[] | Profile IDs to post to (from profiles_list) | Yes | β |
| content | string | Post text. Required unless media_ids or media_urls provided | No* | β |
| is_draft | boolean | Save as draft without publishing or scheduling | No | false |
| publish_now | boolean | Publish immediately | No | false |
| scheduled_at | string | Schedule time in ISO 8601, e.g. 2026-07-10T09:00:00. Required if not draft and not publish_now | No | β |
| timezone | string | Timezone name, e.g. Europe/Moscow | No | UTC |
| title | string | Post title (required for YouTube, recommended for Pinterest) | No | β |
| media_ids | string[] | Media file IDs from media_check_status | No | β |
| media_urls | string[] | Public image/video URLs (downloaded server-side, up to 10) | No | β |
| platform_options | object | Per-platform settings β see platform_options | No | β |
posts_create_story
Same parameters as posts_create. Automatically sets is_story=true for Instagram, Facebook, and VK. Requires image or video media.
posts_create_reels
Same parameters as posts_create. Automatically sets is_reels=true for Instagram and Facebook. Requires vertical video media.
posts_create_shorts
Same parameters as posts_create. Automatically sets youtube.is_shorts=true. Requires short vertical video.
posts_publish_now
Convenience wrapper β sets publish_now=true.
| Parameter | Type | Description | Required |
|---|---|---|---|
| profile_ids | string[] | Profile IDs to post to | Yes |
| content | string | Post text | No* |
| title | string | Post title (required for YouTube) | No |
| media_ids | string[] | Media file IDs | No |
| media_urls | string[] | Public media URLs | No |
| platform_options | object | Per-platform settings | No |
posts_cross_post
Post the same content to multiple profiles at once.
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
| profile_ids | string[] | At least 2 profile IDs | Yes | β |
| content | string | Post text | No* | β |
| publish_now | boolean | Publish immediately to all profiles | No | false |
| scheduled_at | string | Schedule time in ISO 8601 | No | β |
| timezone | string | Timezone name | No | UTC |
| media_ids | string[] | Media file IDs | No | β |
| media_urls | string[] | Public media URLs | No | β |
| platform_options | object | Per-platform settings | No | β |
posts_list
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
| status | string | Filter: draft, scheduled, published, failed | No | β |
| profile_id | string | Filter by profile ID | No | β |
| limit | integer | Max posts to return (1β100) | No | 20 |
| page | integer | Page number | No | 1 |
posts_list_failed
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
| profile_id | string | Filter by profile ID | No | β |
| limit | integer | Max posts to return (1β100) | No | 20 |
posts_get / posts_delete / posts_retry
| Parameter | Type | Description | Required |
|---|---|---|---|
| post_id | string | The post ID | Yes |
posts_update
Update a draft or scheduled post. Cannot update published posts.
| Parameter | Type | Description | Required |
|---|---|---|---|
| post_id | string | The post ID to update | Yes |
| content | string | New post text | No |
| scheduled_at | string | New schedule time (ISO 8601) | No |
| timezone | string | New timezone | No |
| title | string | New title | No |
| media_ids | string[] | New media file IDs (replaces existing) | No |
| media_urls | string[] | Public URLs merged with media_ids | No |
| platform_options | object | Per-platform settings | No |
posts_retry_all_failed
| Parameter | Type | Description | Required |
|---|---|---|---|
| profile_id | string | Only retry failed posts for this profile | No |
platform_options
Per-platform settings object passed to post create/update tools. Keys match platform: instagram, facebook, youtube, tiktok, telegram, linkedin, pinterest, twitter, threads, bluesky, wordpress, google_my_business, vkontakte.
{
"instagram": { "is_reels": true },
"youtube": { "is_shorts": true, "privacy": "public", "category": "22" }
}
| Field | Type | Description |
|---|---|---|
| is_story | boolean | Instagram/Facebook/VK Story (mutually exclusive with is_reels, is_shorts) |
| is_reels | boolean | Instagram/Facebook Reels |
| is_shorts | boolean | YouTube Shorts |
| title | string | Platform-specific title (overrides top-level title) |
| privacy | string | YouTube: public|unlisted|private. TikTok: PUBLIC_TO_EVERYONE|SELF_ONLY|β¦ |
| category | string | YouTube category ID |
| disable_comment | boolean | TikTok: disable comments |
| disable_duet | boolean | TikTok: disable duet |
| disable_stitch | boolean | TikTok: disable stitch |
| disable_notification | boolean | Telegram: send silently |
| pin_message | boolean | Telegram: pin after publish |
| visibility | string | LinkedIn: PUBLIC or CONNECTIONS |
| board_id | string | Pinterest board ID |
| link | string | Pinterest destination link |
| alt_text | string | Pinterest image alt text |
Media
Which upload tool?
- Local stdio (
@onlypult/mcpon your machine) + file path on disk βmedia_upload_file - Hosted MCP (
mcp.onlypult.com), Claude.ai, ChatGPT βmedia_get_upload_url+ browser +media_check_status - Public HTTP(S) URL β
media_urlsinposts_create(no upload tools)
media_get_upload_url
When to use: hosted MCP or when the user must upload manually in a browser. Call profiles_list first β pass profile_id for the target post (drives platform-specific media processing).
When NOT to use: local stdio with a readable file_path (use media_upload_file) or public URL (use media_urls).
The flow is:
- Call
profiles_listβ pickprofile_id - Call this tool with
profile_idβ getupload_urlandtoken - Ask the user to open the URL in their browser
- User uploads files through the drag & drop web page
- Call
media_check_statuswith the token to get uploaded file IDs - Use those IDs in
media_idswhen callingposts_create,posts_update, or story/reels tools
If posting a Story or Reels, set matching flags here and in platform_options when creating the post (e.g. is_story=true + posts_create_story).
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
| profile_id | string | Profile ID from profiles_list (same as posts_create) | Yes | β |
| is_story | boolean | Upload as Instagram/Facebook story | No | false |
| is_reels | boolean | Upload as Instagram Reels | No | false |
media_upload_file
When to use: local stdio via @onlypult/mcp (npx -y @onlypult/mcp@latest) β Cursor, Claude Desktop, Windsurf, Codex, Antigravity, and other clients that run MCP on your machine. Pass a path the server can read (workspace-relative or absolute).
When NOT to use: hosted mcp.onlypult.com (server cannot read your disk), Claude.ai, ChatGPT β use browser flow. Chat-only attachments without a disk path.
Reliable flow: profiles_list β media_get_upload_url(profile_id) β media_upload_file with file_path + token β posts_create with same profile_ids.
| Parameter | Type | Description | Required |
|---|---|---|---|
| file_path | string | Local path readable by MCP server | Yes |
| profile_id | string | Profile ID from profiles_list (required when token omitted) | No* |
| token | string | Upload session token from media_get_upload_url (strongly recommended; auto-created if omitted) | No |
| is_story | boolean | Upload as story | No |
| is_reels | boolean | Upload as Reels | No |
Returns file id immediately for media_ids. Files > 5MB use multipart upload internally.
media_check_status
When to use: after browser upload when the user says "done". Not needed after media_upload_file.
| Parameter | Type | Description | Required |
|---|---|---|---|
| token | string | Upload token from media_get_upload_url | Yes |
Returns file IDs to use in media_ids when calling posts_create. Supported: JPG, PNG, WebP, GIF, MP4, MOV, WebM. Max file size depends on your Onlypult plan.
Example conversations
You: Post "Just launched our new feature!" to Instagram now
Assistant: calls profiles_list β posts_publish_now with profile_ids
You: Schedule a LinkedIn post for tomorrow at 9am: "Excited to announce our Series A!"
Assistant: calls posts_create with scheduled_at and timezone
You: Post "Big news coming soonβ¦" to Instagram and Facebook
Assistant: calls posts_cross_post with two profile_ids
You: Post ./assets/hero.png to Instagram with caption "Launch day"
Assistant: media_upload_file(file_path="./assets/hero.png") β posts_create with media_ids
You: I want to post a product photo to Instagram
Assistant: media_get_upload_url β user uploads in browser β media_check_status β posts_create with media_ids
Uploading images & videos
Onlypult supports three ways to attach media. The assistant picks the right one based on where the MCP server runs and where the file lives.
| Situation | Method |
|---|---|
Local stdio (@onlypult/mcp), file on disk | media_upload_file |
mcp.onlypult.com, Claude.ai, ChatGPT | media_get_upload_url β browser β media_check_status |
| File already at public URL | media_urls in posts_create |
Local file upload (stdio / @onlypult/mcp)
With the local npm package in any stdio-capable MCP client, give a file path on your machine, for example:
Post ./marketing/video.mp4 to Instagram as a Reel
The assistant calls media_upload_file, gets a file ID, and creates the post β no browser step.
Browser upload (remote MCP)
For hosted MCP connections, the server cannot read your disk. The assistant generates a one-time link; you upload in the browser; the assistant picks up file IDs.
Alternatively, if the image or video is already hosted at a public URL, the assistant can use media_urls in posts_create β no browser upload needed.
Ask to create an upload link
Say something like: "I want to post an image to Instagram" or "Attach this video to my scheduled post".
The assistant calls media_get_upload_url and returns a unique link, for example:
https://app.onlypult.com/mcp-upload?token=abc123...
For Stories or Reels, mention it upfront β the assistant will pass is_story or is_reels to the upload tool and use the matching post tool (posts_create_story, posts_create_reels).
Upload your file
Open the link in any browser. You'll see a simple upload page where you can choose files or drag & drop. Multiple files can be uploaded in one session.
- No Onlypult login required β the link is tied to your API key session
- The link expires in 10 minutes
- After upload, the page shows each file with its ID
Confirm upload
Return to your AI assistant and say "done" or "uploaded". The assistant calls media_check_status with the token, retrieves file IDs, and creates or updates the post with media_ids.
If upload is still processing, the assistant will ask you to wait a moment and check again.
Supported file types
- Images: JPG, PNG, WebP, GIF
- Videos: MP4, MOV, WebM
Maximum file size: depends on your Onlypult plan (shown on the upload page).
Example: posting with an image
I want to post a product photo to Instagram with the caption "New collection is live!"
Upload link generated! Open this link in your browser to upload your photo:
https://app.onlypult.com/mcp-upload?token=β¦
Say "done" when you've finished uploading.
done
Upload completed β 1 file ready (ID: 98765). Publishing to Instagramβ¦
Post published successfully.
Example: Reels with video
Post this vertical video as an Instagram Reel: "Behind the scenes π¬"
Calls media_get_upload_url with is_reels=true β you upload in browser β media_check_status β posts_create_reels with media_ids and caption.