Browse docs
6 min read
Connect an AI agent to social media via MCP: the endpoint#
| Property | Value |
|---|---|
| Endpoint | POST https://api.skedcast.com/mcp |
| Transport | Streamable HTTP |
| Auth | OAuth 2.1 bearer token (audience-checked) |
| Discovery | /.well-known/oauth-protected-resource |
Add the server to your AI client#
Point your MCP-capable client (Claude Desktop, IDEs, agents) at the endpoint below. The client runs the OAuth flow for you — it discovers the authorization server from the protected-resource metadata, registers itself (DCR), and opens a browser for you to sign in and consent. No manual app setup.
json
{
"mcpServers": {
"skedcast": {
"url": "https://api.skedcast.com/mcp"
}
}
}Available tools#
| Tool | Scope | Type | Description |
|---|---|---|---|
list_scheduled_posts | posts.read | read | List the workspace's posts (queue, drafts, published) newest-first, with optional status / client / platform filters and free-text search (q) over captions, per-platform overrides, client names and account handles. |
list_post_targets | posts.read | read | List individual post DESTINATIONS (one row per platform account) with optional status / client / account / platform / free-text filters and a SCHEDULE-time window — the tool for "what publishes on this date". Carries total and totalPosts, so a caller can tell a full page from a complete set. |
get_post | posts.read | read | Get one post with its per-platform variants and fan-out targets. |
list_clients | clients.read | read | List the workspace's client groups (brands / influencers). |
list_accounts | accounts.read | read | List connected social accounts, optionally filtered by client or platform. |
get_analytics_overview | analytics.read | read | Reach / impressions / engagement plus a per-platform rollup over a date window. |
get_post_analytics | analytics.read | read | Per-post performance (complements get_analytics_overview): one post’s lifetime per-target breakdown by postId, or a keyset page of per-post rows with filters. |
get_account_analytics | analytics.read | read | One channel’s totals and daily series, plus the two things no other tool carries: profile-level activity (profile views, link taps, video plays) and follower demographics. |
list_library_assets | media.read | read | List content-library (DAM) assets with optional kind / folder / label / client / status / search filters. Filter status: "transcoded" for assets that are actually publishable; every row also carries status, publishable and ready. |
get_capabilities | posts.read | read | The per-platform composing rulebook: caption and hashtag limits, media rules per kind (counts, formats, file-size ceiling, duration bounds, aspect ratios), post types, native-scheduling window, default cadence, first-comment support, and the variants[].overrides keys each platform requires or accepts. Read it before composing instead of discovering a limit by failing a publish. |
get_agency | agency.read | read | The current workspace profile — name, plan, app mode, settings, and the caller’s role. |
list_reports | reports.read | read | List the workspace's saved analytics report definitions. |
get_best_times | besttimes.read | read | Worker-derived best posting times (strongest-first), optionally by client / platform. |
list_approvals | approvals.read | read | List the workspace's approval queue (pending and decided requests), newest-first, with optional status / post filters. |
get_posting_limits | accounts.read | read | Anti-ban posting limits (cadence): one account by socialAccountId, or every active channel plus the tenant bypass flag when omitted. |
get_quota | accounts.read | read | Adaptive quota pool: your scarce-bucket budget (guaranteed slice, used, burst headroom, tomorrow’s guarantee tonight, reset clock) — read before planning a batch. |
list_campaigns | campaigns.read | read | List the workspace's campaigns (named post groupings), optionally filtered by client / status. |
decide_approval | approvals.decide | write ⚠ | Approve, reject, or request changes on a pending approval request (approve releases the gated post for publishing). A write action — confirm with the user before calling. |
validate_post | posts.compose | read | Dry-run a compose request and get the per-platform verdict WITHOUT writing anything — same arguments as create_post, no post row and no draft. Returns { valid, platforms[], estimatedCostUsd }. Does not run cadence or quota admission, so valid: true means the shape is acceptable, not that a publish cannot later be deferred. |
revise_post | posts.compose | write ⚠ | Change the CONTENT of an already-scheduled post — caption, media, cover, alt text, per-platform overrides — without disturbing its destinations. Send only what you are changing. Refuses, naming them, when a destination has already published or is about to. An edit to an APPROVED post returns it to review. A write action — confirm with the user before calling. |
create_post | posts.compose | write ⚠ | Compose a post and fan it out across the selected accounts (or save it as a draft). Retry-safe: retrying with identical arguments replays the original result instead of creating a duplicate. Note: two publish-now calls with byte-identical content and targets are treated as the same post and coalesced permanently — to intentionally publish the same content twice, vary the content or use distinct scheduled times. For platform-specific settings (e.g. YouTube privacy, TikTok privacy level, Pinterest board, Telegram chat), set variants[].overrides. That same object carries firstComment: a reply posted automatically once the destination goes live, so a "link in the comments" post needs no manual follow-up. Supported on X, LinkedIn, YouTube, Instagram, Facebook, Threads, Telegram and Bluesky (not TikTok or Pinterest); spell it exactly firstComment. Overrides are free-form — an unrecognised key is accepted and silently ignored — and the comment is best-effort: if it fails the post still publishes and nothing is reported, so confirm on the published post. A write action — confirm with the user before calling. |
create_posts_bulk | posts.compose | write ⚠ | Create up to 50 posts in one call. Each item is exactly the arguments of create_post, so a bulk item carries every override a single post does (per-platform caption, title, cover, per-asset alt text, first comment, per-platform settings). Items are created one after another, each on its own: one failing never rolls back the others, and the result lists every item in order with its post id or its error. Retry-safe: retrying with identical arguments creates nothing twice. Pass validateOnly:true to check every item without writing anything. It counts one request-budget unit per item. This creates real outbound content — confirm with the user before calling. Requires the posts.compose scope. |
update_post | posts.compose | write ⚠ | Replace a draft post in place — its content, media, targets, and schedule. Only draft posts can be updated, and this never publishes (use publish_draft for that). Platform-specific settings live in variants[].overrides, same as create_post, including firstComment. A write action — confirm with the user before calling. |
publish_draft | posts.compose | write ⚠ | Publish or schedule an existing DRAFT post in place — same arguments as update_post plus the draft id; schedule decides now or later. Runs the same checks as create_post (platform validation, approval policy, quota, pacing); a client that requires approval gets the post submitted for review instead. The post keeps its id. This puts real content on connected accounts — confirm with the user before calling. |
import_media | media.manage | write ⚠ | Ingest an external image / video into the content library by URL — the file must already be reachable at a public URL. For bytes you already hold (an image you just rendered, or a local file) use upload_media instead. A write action — confirm with the user before calling. |
upload_media | media.manage | write ⚠ | Upload a LOCAL image / video into the content library and get back a media id for create_post. Sends the file inline (≤18 MiB) or returns a presigned URL for larger files. A write action — confirm with the user before calling. |
reschedule_post | posts.compose | write ⚠ | Move a pending post target to a new time (absolute scheduledAt or relative shiftMinutes). A write action — confirm with the user before calling. |
bulk_post_target_action | posts.compose | write ⚠ | Reschedule, retry or cancel up to 5000 post targets in one call — the batch form of reschedule_post / retry_post / cancel_post. Returns { jobId, accepted, skipped, skippedReasons? }; a skipped target is reported, never silently dropped. A write action — confirm with the user before calling. |
cancel_post | posts.compose | write ⚠ | Cancel a still-pending post target before it publishes. A write action — confirm with the user before calling. |
retry_post | posts.compose | write ⚠ | Re-queue a failed or rate-limited post target so it publishes again. A write action — confirm with the user before calling. |
set_post_recycle | posts.compose | write ⚠ | Set, update, or disable a post's evergreen recycle settings (interval / times / end date / max recycles). A write action — confirm with the user before calling. |
shift_campaign | campaigns.manage | write ⚠ | Move a whole campaign's pending schedule by a relative number of minutes. A write action — confirm with the user before calling. |
list_webhooks | webhooks.read | read | List the workspace's outbound webhook endpoints (url, subscribed events, active flag; secret masked). |
create_webhook | webhooks.manage | write ⚠ | Register an outbound webhook endpoint for HMAC-signed event deliveries. Subscribe to any subset of the full 40-event catalog — see /developers/webhooks, or the webhooks block in openapi.json, for the complete list with payload fields. Returns the signing secret once. A write action — confirm with the user before calling. |
delete_webhook | webhooks.delete | write ⚠ | Delete an outbound webhook endpoint by id (deliveries cascade). A write action — confirm with the user before calling. |
create_client | clients.manage | write ⚠ | Create a new client group (a brand or influencer whose accounts are managed together). A write action — confirm with the user before calling. |
create_connect_invite | accounts.connect | write ⚠ | Mint a shareable self-connect link so a client can connect the requested platforms themselves; returns the link and its expiry. A write action — confirm with the user before calling. |
get_webhook | webhooks.read | read | Read one webhook endpoint — URL, subscribed events, active state, consecutive failures, and when/why it was auto-disabled. The signing secret is never returned here. |
list_webhook_deliveries | webhooks.read | read | The delivery log for one endpoint — each attempt with its event type, response status, error and timing. How you find out WHY an endpoint stopped receiving. |
update_webhook | webhooks.manage | write ⚠ | Change an endpoint’s URL, event list, or active state — including re-enabling one auto-disabled after repeated failures. The event list REPLACES the previous one. A write action — confirm with the user before calling. |
test_webhook | webhooks.manage | write ⚠ | Send a webhook.test delivery and report the outcome, proving an endpoint is reachable and verifying signatures without waiting for a real event. Performs a real outbound request — confirm with the user before calling. |
rotate_webhook_secret | webhooks.manage | write ⚠ | Mint a new signing secret and return it ONCE — it is not readable again. The previous secret keeps verifying for a short overlap so the customer can redeploy without dropping deliveries. A write action — confirm with the user before calling. |
get_campaign | campaigns.read | read | Read one campaign in full — name, description, status, colour, date range, owning client and post counts. |
create_campaign | campaigns.manage | write ⚠ | Create a campaign — a named group of posts with an optional client, colour and date range. Posts are added with assign_to_campaign. A write action — confirm with the user before calling. |
update_campaign | campaigns.manage | write ⚠ | Change a campaign’s name, description, status, colour or date range. A write action — confirm with the user before calling. |
delete_campaign | campaigns.manage | write ⚠ | Delete a campaign. The posts in it are NOT deleted — they lose the grouping and keep their own schedules. A write action — confirm with the user before calling. |
assign_to_campaign | campaigns.manage | write ⚠ | Add up to 500 existing posts to a campaign. Grouping only — no post’s content or schedule changes. A write action — confirm with the user before calling. |
unassign_from_campaign | campaigns.manage | write ⚠ | Remove posts from a campaign. Grouping only — the posts and their schedules are untouched. A write action — confirm with the user before calling. |
get_client | clients.read | read | Read one client group in full — name, type, approval policy, posting rules, brand voice and default timezone. |
update_client | clients.manage | write ⚠ | Change a client’s name, type, approval policy, posting rules, brand voice or default timezone. A write action — confirm with the user before calling. |
delete_client | clients.manage | write ⚠ | Archive a client group. OWNER ONLY — a Manager holding the clients.manage scope cannot do this. A write action — confirm with the user before calling. |
get_post_target | posts.read | read | Read a single fan-out destination in full — status, scheduled time, platform, account, published permalink and external id, and its failure reason when it failed. |
get_post_recycle | posts.read | read | Read one post’s evergreen re-posting configuration and the worker’s bookkeeping. Returns null when the post is not enrolled. |
get_account | accounts.read | read | Read one connected social account in full — platform, handle, display name, avatar, status (including whether it needs re-authorisation) and owning client. |
get_approval | approvals.read | read | Read one approval request with the gated post’s preview and roll-up, so a reviewer can see what they are deciding on before calling decide_approval. |
get_media_asset | media.read | read | Read one content-library asset in full — filename, kind, size, dimensions, duration, folder, labels, alt text, pipeline status, and the publishable/ready flags plus the per-platform readiness map. |
get_client_analytics | analytics.read | read | One client group’s analytics — totals, a per-platform breakdown and a time series. A different projection from get_analytics_overview filtered by client. |
get_report | reports.read | read | Read one report definition with its run history — each run’s status, window, and whether an export is available. |
download_report_export | reports.read | read | Get a time-limited download URL for one completed report run’s export file. The URL expires — fetch it when you are ready to use it. |
clear_post_recycle | posts.compose | write ⚠ | Turn OFF evergreen re-posting for a post. Idempotent. Already-scheduled recycled copies are not retracted — cancel those separately. A write action — confirm with the user before calling. |
Generated from the live MCP catalog — always current.
Discovery URLs#
| URL | Purpose |
|---|---|
https://api.skedcast.com/mcp | MCP endpoint (POST; GET returns 405) |
/.well-known/oauth-protected-resource | Resource metadata + scopes (RFC 9728) |
/.well-known/oauth-authorization-server | Authorization-server metadata (RFC 8414) |
/.well-known/jwks.json | Public keys for token verification |
mcpaiclaude
FAQ
- Which AI clients can connect?
- Any client that speaks the Model Context Protocol over Streamable HTTP with OAuth — including Claude and a growing list of agent frameworks and IDEs.
- Can the agent post without my approval?
- Read tools run freely within your granted scopes. The write tools (create_post, import_media) are flagged so your MCP host asks you to confirm before they run, and they still can't exceed your role.