MCP server

Let AI assistants run your posting queue.

Sprkly implements the Model Context Protocol, so any MCP client can read your schedule, draft and validate captions, and queue posts — using your own account and your own connected platforms.

Endpoint
https://sprkly.app/api/mcp
Transport
Streamable HTTP
Sessions
Stateless
Auth
OAuth 2.1 or API key
Tools
13

Quick start

Two ways to authenticate. Pick by what your client supports.

Recommended

Connect with OAuth

For Claude Cowork, claude.ai, Claude Desktop, Claude Code and ChatGPT. Add the endpoint as a custom connector and sign in — nothing to copy, and the connection is tied to your Sprkly login rather than a long-lived secret.

  1. 1. Add https://sprkly.app/api/mcp as a custom connector.
  2. 2. Click Connect and approve the permissions.
  3. 3. Ask your assistant what you have scheduled.
Per-client setup →

Scripts, CI, self-hosted agents

Send an API key

Create a key in Settings → API Keys and send it as a bearer token. There is no exchange step and no short-lived token to refresh.

curl
curl -s https://sprkly.app/api/mcp \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
MCP access requires an active paid plan — the same entitlement as the REST API. Trial accounts get a 403 with plan_required.

Transport

Streamable HTTP, stateless. JSON-RPC 2.0 messages are POSTed to a single endpoint and answered with application/json. No session id is issued, so there is nothing to track between calls.

MethodBehaviour
POSTCarries every MCP message. Include Accept: application/json, text/event-stream.
GET405 — this server offers no server-initiated SSE stream.
DELETE405 — stateless, so there is no session to terminate.

Protocol versions

Negotiated on initialize: the server echoes your revision when it supports it, otherwise it answers with its newest. Supported: 2025-11-252025-06-182025-03-26. Send the negotiated value as MCP-Protocol-Version on subsequent requests — an unsupported value is a 400.

Methods

initialize, ping, tools/list, tools/call, resources/list and prompts/list (both empty). Notifications are acknowledged with 202 and no body.

Authentication

initialize, ping and tools/list work without credentials, so a client can show what Sprkly offers before anyone signs in. The first tools/call is challenged.

The 401 challenge

Response
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token",
  error_description="Missing bearer credentials",
  resource_metadata="https://sprkly.app/.well-known/oauth-protected-resource/api/mcp",
  scope="profile mcp:read mcp:write"

Follow resource_metadata to learn which authorization server to use. That document names this origin, whose metadata lives at https://sprkly.app/.well-known/oauth-authorization-server.

OAuth 2.1

API key scopes

A key can hold *, sprkly:*, or any of post:read, post:write, post:draft, account:read, approval:request. A key scoped to specific accounts only ever sees and touches those.

Never put an API key or token in the connector URL as a query parameter. URLs are recorded in logs, proxies and browser history, and the MCP specification prohibits it. Use the Authorization header or OAuth.

Tools

13 tools. Arguments below are exactly what tools/list returns.

sprkly_delete_scheduled_postWriteDestructiveIdempotent

Remove a post from the queue. This is a soft delete — the user can restore it from the Deleted tab for 30 days. Posts that have already published cannot be deleted this way. Always confirm with the user before calling.

ArgumentTypeDescription
post_idrequiredstringThe scheduled post id to delete.
sprkly_draft_postWrite

Compose a caption from a content hint and save it as a draft in Sprkly, shaped to the tightest caption limit among the target platforms. Returns a draft id; the draft appears under /drafts for the user to review.

ArgumentTypeDescription
content_hintrequiredstringWhat the post should be about — a topic, phrase or key message.
platformsstring[]Intended platforms, used to pick the caption length ceiling.
tonestringVoice for the draft.casual · professional · promotional
namestringOptional label for the draft.
profile_idsstring[]Optional accounts to pre-select on the draft. From sprkly_list_profiles.
sprkly_get_account_summaryRead-only

Plan tier, trial state, connected account count, scheduled post counts by status, and the next three upcoming posts. Never returns tokens or secrets.

No arguments.

sprkly_get_billing_summaryRead-only

Subscription status, current plan, period end, purchased handles and the last few billing events. No payment method details; the Stripe customer id is truncated.

No arguments.

sprkly_get_post_approval_statusRead-only

Whether a post is awaiting human review, approved or rejected, including reviewer notes and timestamps.

ArgumentTypeDescription
post_idrequiredstringThe scheduled post id.
sprkly_get_post_statusRead-only

Full detail for one post: status, targets, scheduled and published times, permalink, and the failure reason if it did not publish.

ArgumentTypeDescription
post_idrequiredstringThe scheduled post id.
sprkly_list_connected_social_accountsRead-only

Every social account linked to this Sprkly account: platform, handle, follower count, whether it is active, and whether it needs reconnecting. Never returns access tokens.

No arguments.

sprkly_list_profilesRead-only

The profile ids needed to target a post, with each one's platform and handle. Call this before sprkly_schedule_post.

No arguments.

sprkly_list_scheduled_postsRead-only

The post queue, newest first, with a caption preview, targets, status and failure reason. Supports a status filter and cursor pagination.

ArgumentTypeDescription
statusstringFilter by status.draft · pending_approval · scheduled · posted · failed
limitinteger (1–50)Maximum posts to return.
cursorstringPagination cursor — pass the nextCursor value from a previous response.
sprkly_request_post_approvalWrite

Submit a draft post for human review. Moves the post to pending_approval and returns an approval id to poll with sprkly_get_post_approval_status. Use this when the user wants a person to sign off before anything publishes.

ArgumentTypeDescription
post_idrequiredstringThe draft post id to submit.
notestringOptional context for the reviewer.
sprkly_schedule_postWrite

Queue a post for publishing. Runs the same quota, duplicate-content and platform pre-flight checks as the Sprkly app. Instagram and TikTok require media at submission time; YouTube requires a title. Confirm the date, time and target accounts with the user first.

ArgumentTypeDescription
captionstringPost caption, max 2200 characters.
platformsstring[]Platforms to publish to. Every active account on each platform is targeted unless profile_ids is given.
profile_idsstring[]Specific accounts to publish to, from sprkly_list_profiles. Preferred over platforms when the user has more than one account on a platform.
scheduled_timestringISO 8601 timestamp to publish at. Must be in the future. Defaults to the next available slot.
media_urlsstring[]Publicly reachable image or video URLs to attach.
media_idstringId of a media file already uploaded to Sprkly.
titlestringPost title. Required for YouTube, max 100 characters.
categorystringOptional content category, e.g. "fitness".
platform_metaobjectPlatform-specific publishing options, keyed by platform.
sprkly_update_scheduled_postWriteIdempotent

Change the caption, publish time, target accounts or attached media on a post that has not published yet. Only posts with status "scheduled" can be edited.

ArgumentTypeDescription
post_idrequiredstringThe scheduled post id.
captionstringReplacement caption, max 2200 characters.
scheduled_timestringNew ISO 8601 publish time. Must be in the future.
profile_idsstring[]Replacement target accounts. Platforms are re-derived from them.
media_idstringReplacement Sprkly media file id.
sprkly_validate_post_policyRead-only

Check a caption against each target platform's posting rules before scheduling: caption length, media requirements, hashtag ceilings, whether links are clickable, required YouTube titles, and PII or prohibited-content warnings. Pure analysis — writes nothing.

ArgumentTypeDescription
captionrequiredstringThe caption to check.
platformsrequiredstring[]Target platforms to check against.
mediaUrlsCountinteger (0–-)How many images or videos will be attached. Instagram and TikTok require at least one.
hashtagsstring[]Hashtags posted alongside the caption, if they are not already in it.
titlestringPost title. Required for YouTube, max 100 characters.
platformMetaobjectPlatform-specific publishing options, keyed by platform.

Client setup

The full walkthrough for each client lives on the integrations page. The short version:

Claude Cowork

Server URL
https://sprkly.app/api/mcp

Claude & Claude Desktop

Server URL
https://sprkly.app/api/mcp

Claude Code

Terminal
claude mcp add --transport http sprkly https://sprkly.app/api/mcp

ChatGPT

Server URL
https://sprkly.app/api/mcp

Cursor

~/.cursor/mcp.json
{
  "mcpServers": {
    "sprkly": {
      "url": "https://sprkly.app/api/mcp"
    }
  }
}

VS Code

.vscode/mcp.json
{
  "servers": {
    "sprkly": {
      "type": "http",
      "url": "https://sprkly.app/api/mcp"
    }
  }
}

Anything else

curl
curl -s https://sprkly.app/api/mcp \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Worked example

Initialize, list the tools, then schedule a post. Substitute your own credential.

bash
TOKEN="sk_live_…"
MCP="https://sprkly.app/api/mcp"

# 1. Initialize (no credentials needed)
curl -s "$MCP" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize",
       "params":{"protocolVersion":"2025-11-25",
                 "capabilities":{},
                 "clientInfo":{"name":"curl","version":"1.0"}}}'

# 2. Which accounts can I post to?
curl -s "$MCP" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"sprkly_list_profiles","arguments":{}}}'

# 3. Check the caption before committing to it
curl -s "$MCP" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"sprkly_validate_post_policy",
                 "arguments":{"caption":"Launch day.",
                              "platforms":["instagram"],
                              "mediaUrlsCount":1}}}'

# 4. Queue it
curl -s "$MCP" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call",
       "params":{"name":"sprkly_schedule_post",
                 "arguments":{"caption":"Launch day.",
                              "profile_ids":["profile_…"],
                              "media_urls":["https://example.com/launch.jpg"],
                              "scheduled_time":"2026-08-04T18:00:00.000Z"}}}'

Discovery

Machine-readable descriptions of this server, for agents that find it on their own.

Deprecated

These still work. Nothing new needs them.

Need a hand?

MCP access follows the same entitlement as the REST API. If a connector will not connect, the fastest signal is whether an unauthenticated tools/call returns a 401 with a WWW-Authenticate header.