MODEL CONTEXT PROTOCOL

Manage social media from your AI

Tell Claude or Cursor to post to X, LinkedIn, Instagram, and 7 more platforms. One sentence. All platforms. WriteOnce MCP exposes posting and scheduling as tools your agent can call directly.

4 tools · 10 platforms · Live at https://writeonce.one/api/mcp

01 / CONVERSATION

Just tell your AI what to do

No API calls. No tab switching. Your agent calls list_accounts, create_post, and list_scheduled under the hood.

claude · writeonce-mcp
You

Post "We just shipped MCP support. Tell your AI to schedule social posts for you." to X and LinkedIn.

AI

Called list_accounts, then create_post. Published to X and LinkedIn. Want me to schedule a follow-up for tomorrow morning?

You

Yes, schedule a reminder for 9am tomorrow on X only.

AI

Called create_post with scheduledDate 2026-07-28T09:00:00Z on x. Confirmed via list_scheduled. Anything else?

What is MCP?

MCP is an open standard for connecting AI assistants to external tools. Plug in WriteOnce, and your agent can publish and schedule posts without custom wrapper code. The server runs at /api/mcp and authenticates with the same API key you create in Settings.

  • Works with Claude Desktop, Claude Code, Cursor, Windsurf, and any MCP client
  • Same API key you create in WriteOnce Settings
  • Included with your WriteOnce plan at no extra cost
02 / TOOLS

4 tools. Full reference.

Four focused tools cover the complete post, schedule, queue, and cancel workflow. Each tool includes parameters, request examples, and response shapes your agent can rely on.

list_accounts

List the social accounts the user has connected (platform, handle, display name). Call this first to see which platforms a post can target.

When to use: Call before create_post whenever you need to know which platforms are connected, or to confirm a handle before publishing.

PARAMETERS

No parameters. Send an empty object {}.

REQUEST EXAMPLE

json
{}

RESPONSE EXAMPLE

json
[
  {
    "platform": "x",
    "accountId": "1234567890",
    "username": "writeonce",
    "displayName": "WriteOnce",
    "profilePictureUrl": "https://pbs.twimg.com/profile_images/example.jpg",
    "isActive": true
  },
  {
    "platform": "linkedin",
    "accountId": "urn:li:person:abc123",
    "username": "jane-doe",
    "displayName": "Jane Doe",
    "profilePictureUrl": null,
    "isActive": true
  }
]
  • Returns an empty array if no accounts are connected. Ask the user to connect platforms in WriteOnce Settings first.
  • Use the platform field (not displayName) when passing platforms to create_post.
create_post

Publish a post now, schedule it, or add it to the posting queue across connected platforms. Media must be public URLs.

When to use: Use after list_accounts to publish immediately, schedule for a specific time, or drop into the next free queue slot.

PARAMETERS

PARAMETERTYPEREQUIREDDESCRIPTION
contentstringYesThe post caption or text body.
platformsstring[] (instagram | x | tiktok | youtube | facebook | linkedin | threads | pinterest | reddit | bluesky)YesPlatforms to post to. Must match connected accounts from list_accounts.
media{ url: string, type: 'image' | 'video' }[]NoOptional images or videos as publicly reachable URLs. Host assets elsewhere first.
scheduledDatestring (ISO 8601)NoSchedule the post for a future datetime. Omit to publish now (unless addToQueue is true).
addToQueuebooleanNoAdd to the next free posting-queue slot instead of publishing immediately. Requires Growth plan or higher.
firstCommentstringNoOptional first comment posted right after the main post. Requires Growth plan or higher.
platformCaptionsRecord<string, string>NoPer-platform caption overrides, keyed by platform id. Requires Growth plan or higher.
subredditstringNoRequired when posting to reddit.
flairstringNoOptional Reddit flair text.
pinterestBoardIdstringNoRequired when posting to pinterest.
facebookPageIdstringNoOptional Facebook Page id when the user has multiple pages.

REQUEST EXAMPLE

json
{
  "content": "We just shipped MCP support. Tell your AI to schedule social posts for you.",
  "platforms": [
    "x",
    "linkedin"
  ],
  "media": [
    {
      "url": "https://cdn.example.com/launch-banner.png",
      "type": "image"
    }
  ]
}

RESPONSE EXAMPLE

json
{
  "requestId": "req_8f3a2b1c",
  "jobId": "job_7e4d9a0f",
  "perPlatform": {
    "x": {
      "success": true,
      "url": "https://x.com/writeonce/status/1234567890"
    },
    "linkedin": {
      "success": true,
      "url": "https://www.linkedin.com/feed/update/urn:li:share:9876543210"
    }
  },
  "pending": false,
  "scheduled": false,
  "queued": false
}
  • Growth plan or higher required for addToQueue, firstComment, and platformCaptions.
  • When posting to reddit, always pass subreddit. When posting to pinterest, always pass pinterestBoardId.
  • If some platforms fail, inspect perPlatform in the response. Successful platforms are not rolled back.
list_scheduled

List upcoming scheduled posts, including each jobId (needed to cancel).

When to use: Call when the user asks what is scheduled, or before cancel_scheduled to get a valid jobId.

PARAMETERS

No parameters. Send an empty object {}.

REQUEST EXAMPLE

json
{}

RESPONSE EXAMPLE

json
[
  {
    "job_id": "job_7e4d9a0f",
    "jobId": "job_7e4d9a0f",
    "content": "Reminder: MCP docs are live.",
    "platforms": [
      "x"
    ],
    "scheduled_date": "2026-07-28T09:00:00.000Z",
    "profile_username": "user_abc123"
  }
]
  • Use jobId or job_id from the response when calling cancel_scheduled.
  • Returns only posts belonging to the authenticated user.
cancel_scheduled

Cancel a scheduled post by its jobId from list_scheduled.

When to use: Call after list_scheduled when the user wants to remove an upcoming post.

PARAMETERS

PARAMETERTYPEREQUIREDDESCRIPTION
jobIdstringYesThe scheduled post's jobId from list_scheduled.

REQUEST EXAMPLE

json
{
  "jobId": "job_7e4d9a0f"
}

RESPONSE EXAMPLE

json
{
  "ok": true,
  "jobId": "job_7e4d9a0f"
}
  • Returns an error if the jobId does not belong to the authenticated user.
  • Re-run list_scheduled if the job was already published or cancelled.
03 / SETUP

Set up in 3 minutes

No SDK to install. One config entry in your MCP client.

1

Get your API key

Sign up for WriteOnce and open Settings. Under Developer, create an API key and copy it once. Treat it like a password.

Start free trial
2

Connect your AI client

Add the WriteOnce MCP server to Claude Desktop, Claude Code, Cursor, or Windsurf using the config examples below.

See config examples
3

Start talking

Ask your agent to list accounts, post, schedule, or cancel. It calls the same publishing pipeline as the WriteOnce dashboard.

04 / CLIENTS

Per-client setup

Replace wo_live_your_key with your key from Settings. Restart the client after saving.

Claude Code

Run the command below in your terminal. Replace the placeholder key with your wo_live_ key from Settings. Restart Claude Code if it was open, then ask: "List my connected social accounts."

bash
claude mcp add -t http \
  -H "Authorization: Bearer wo_live_your_key" \
  writeonce https://writeonce.one/api/mcp

Claude Desktop

Open Claude Desktop settings and edit your MCP config. On macOS the file is ~/Library/Application Support/Claude/claude_desktop_config.json. Merge the block below under mcpServers, replace the key, then fully quit and reopen Claude Desktop.

json
{
  "mcpServers": {
    "writeonce": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://writeonce.one/api/mcp",
        "--header",
        "Authorization: Bearer wo_live_your_key"
      ]
    }
  }
}

Cursor

Create or edit .cursor/mcp.json in your project root (or your global Cursor MCP config). Paste the block below, replace the key, and restart Cursor. Verify by asking the agent to call list_accounts.

json
{
  "mcpServers": {
    "writeonce": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://writeonce.one/api/mcp",
        "--header",
        "Authorization: Bearer wo_live_your_key"
      ]
    }
  }
}

Windsurf

Open Windsurf MCP settings (Cascade > MCP Servers, or ~/.codeium/windsurf/mcp_config.json). Add the block below under mcpServers, replace the key, and restart Windsurf.

json
{
  "mcpServers": {
    "writeonce": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://writeonce.one/api/mcp",
        "--header",
        "Authorization: Bearer wo_live_your_key"
      ]
    }
  }
}
05 / ERRORS

Error handling

When a tool call fails, these are the most common causes and what your agent should do next.

401 Unauthorized

Missing, malformed, or revoked API key in the Authorization header.

Fix: Create a new key in WriteOnce Settings under Developer. Pass it as Authorization: Bearer wo_live_...

Scheduled post not found

The jobId passed to cancel_scheduled does not belong to this user, or the job no longer exists.

Fix: Re-run list_scheduled to get current jobIds. Do not guess or reuse stale ids from earlier sessions.

Entitlement required

A Growth+ feature was requested on a Creator plan (addToQueue, firstComment, or platformCaptions).

Fix: Omit the gated parameter, or ask the user to upgrade to Growth. Core posting and scheduling work on every plan.

Platform validation failed

Missing required platform-specific fields (subreddit for reddit, pinterestBoardId for pinterest) or an unconnected platform.

Fix: Call list_accounts first. Pass subreddit and pinterestBoardId when targeting those platforms.

Media URL unreachable

A media URL is not publicly accessible, returns an error, or uses an unsupported format.

Fix: Host images and videos on a public CDN or storage bucket. Test the URL in a browser before passing it to create_post.

Partial publish

Some platforms in the request succeeded while others failed (token expired, rate limit, validation).

Fix: Inspect the perPlatform object in the create_post response. Retry only the failed platforms with corrected input.

07 / COMPARISON

How WriteOnce MCP compares

Claims below are as of July 2026. Competitor tool counts and pricing change often. Verify on their sites before deciding.

WHAT MATTERSWriteOnceOutstandPostEverywhereXreplyAI
MCP tool count4 focused tools (full list on this page)27 tools33 tools31 tools
Post now, schedule, queue, cancelYes, via create_post + list/cancel_scheduledYesYesYes
Platforms supported10 (incl. Reddit, Bluesky, Threads)11 (incl. Google Business, Vimeo)11 (incl. Discord, Telegram)15 (incl. Mastodon, Slack)
Pricing modelFlat monthly, all 10 platforms included$19/mo + usage after 3,000 postsFrom $29/mo, tiered plansFree tier; MCP on Pro from ~$20/mo
MCP on base planYes, every planYesYesPro plan and above
AI content generation via MCPNo (compose in dashboard or prompt your agent)Partial (via agent prompts)Yes (caption generation tools)Yes (voice-matched generation)
Analytics via MCPNot yet via MCPYesYesLimited
Local media upload via MCPNo, public URLs requiredYesYesYes (per-platform upload tools)
Webhooks and campaigns via MCPNot yetPartialYesNo
Claude Desktop, Code, Cursor, WindsurfYesYesYesYes
08 / PLATFORMS

10 platforms. One conversation.

InstagramTwitter / XTikTokYouTubeFacebookLinkedInThreadsPinterestRedditBluesky
09 / USE CASES

What you can do with it

Cross-platform posting

"Post this launch note to X, LinkedIn, and Threads." One create_post call, three platforms, done.

Content scheduling

"Schedule a tweet for tomorrow at 9am." create_post with scheduledDate handles the timing.

Agentic workflows

Chain list_accounts, create_post, list_scheduled, and cancel_scheduled to build a full social calendar agent.

10 / MCP FAQ

Frequently asked questions

WriteOnce MCP is a hosted Model Context Protocol server that exposes social media posting and scheduling tools to AI assistants. Your agent can list connected accounts, publish posts, schedule content, and cancel scheduled jobs through one endpoint at /api/mcp.

You are already talking to AI. Now it can post for you too.

Three minutes to set up. Same API key as the dashboard. No new tools to learn.

One post. Ten platforms.

Ready to put your posting on autopilot?

Every plan includes a 7-day free trial. Cancel anytime.