socialclaw

Connect any AI agent to 11+ social platforms: schedule, publish & track posts via hosted MCP.

Should I use this

Quality & Safety

A
Description quality
97%
Schema completeness
89%
Naming quality
95%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Findings (1)

  • LOWTool 'reply_instagram_comment' description lacks action verbin reply_instagram_comment

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~4,927Tokens (tool definitions)
~887 BTypical response size
Significant attention impact (3.85% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "socialclaw": {
      "url": "https://getsocialclaw.com/mcp"
    }
  }
}

Remote endpoints

https://getsocialclaw.com/mcpstreamable-http

What it can do

Tool inventory

Tools (34)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢list_accounts(provider)

List connected social accounts in the SocialClaw workspace. Optionally filter by provider (x, facebook, instagram_business, instagram, threads, linkedin, linkedin_page, pinterest, tiktok, telegram, discord, youtube, reddit, wordpress).

Input Schema

{
  "type": "object",
  "properties": {
    "provider": {
      "type": "string",
      "description": "Optional provider filter."
    }
  }
}
🟢account_capabilities(accountId, provider)

Get publish capabilities and provider rules for connected accounts: what media is allowed, text limits, and whether publishing is currently possible. Pass accountId for one account, or provider to filter, or neither for all.

Input Schema

{
  "type": "object",
  "properties": {
    "accountId": {
      "type": "string",
      "description": "Optional account id."
    },
    "provider": {
      "type": "string",
      "description": "Optional provider filter."
    }
  }
}
⚪connect_account(provider, botToken, chatId, webhookUrl)

Start connecting one of the user's own social accounts to their SocialClaw workspace. For most providers this returns an authorizeUrl; give it to the user so they sign in with the provider themselves (SocialClaw never sees their password). Telegram and Discord have no sign-in page: Telegram takes the bot token and chat id of a bot the user created and made admin of their channel, and Discord takes a webhook URL the user created for their channel. Only pass values the user gave you for this purpose.

Input Schema

{
  "type": "object",
  "properties": {
    "provider": {
      "type": "string",
      "description": "Provider to connect."
    },
    "botToken": {
      "type": "string",
      "description": "Telegram only: token of the user's own bot, from @BotFather."
    },
    "chatId": {
      "type": "string",
      "description": "Telegram chat target, e.g. @yourchannel (telegram only)."
    },
    "webhookUrl": {
      "type": "string",
      "description": "Discord only: webhook URL the user created in their channel settings."
    }
  },
  "required": [
    "provider"
  ]
}
🟡upload_asset(file, sourceUrl, filename, contentBase64)

Add an image or video to the user's SocialClaw media library so it can be attached to a post. Pass exactly one of: file (a file the user attached in this chat), sourceUrl (a direct public http(s) link to the image or video file, not a web page), or contentBase64 (small files only). Files up to 1 GB are supported through file or sourceUrl. The result is the asset: when status is ready, use its publicUrl as media_link in validate_schedule/apply_schedule. Large videos may come back with status uploading; then call get_asset with the asset id until status is ready (or failed) before scheduling.

Input Schema

{
  "type": "object",
  "properties": {
    "file": {
      "type": "object",
      "description": "A file the user attached in the conversation.",
      "properties": {
        "download_url": {
          "type": "string",
          "description": "Temporary download URL of the attached file."
        },
        "file_id": {
          "type": "string",
          "description": "Id of the attached file."
        },
        "mime_type": {
          "type": "string",
          "description": "Mime type of the attached file, if known."
        },
        "file_name": {
          "type": "string",
          "description": "Original name of the attached file, if known."
        }
      },
      "required": [
        "download_url",
        "file_id"
      ]
    },
    "sourceUrl": {
      "type": "string",
      "description": "Direct public http(s) URL of the image or video file."
    },
    "filename": {
      "type": "string",
      "description": "Optional filename including extension, e.g. launch.png. Inferred from the file or URL when omitted."
    },
    "contentBase64": {
      "type": "string",
      "description": "Base64-encoded file content. Small files only; prefer file or sourceUrl."
    }
  }
}
🟢get_asset(assetId)

Get one media asset from the user's SocialClaw library by id, including its status (uploading, ready, or failed), import progress, and publicUrl. Use it after upload_asset returns status uploading, until the asset is ready.

Input Schema

{
  "type": "object",
  "properties": {
    "assetId": {
      "type": "string",
      "description": "Asset id returned by upload_asset or list_assets."
    }
  },
  "required": [
    "assetId"
  ]
}
🟢validate_schedule(schedule)

Validate a schedule document against provider rules, media limits, account state, and publish times WITHOUT creating any posts. Always run this before apply_schedule.

Input Schema

{
  "type": "object",
  "properties": {
    "schedule": {
      "type": "object",
      "description": "SocialClaw schedule document. Minimal shape: { timezone, posts: [{ account, name, description, publish_at, media_link? }] }. Campaign documents use { timezone, campaigns: [...] }. Per-post provider settings go in settings, e.g. TikTok inbox mode: settings: { tiktokPostMode: \"draft\" } sends the media to TikTok's inbox notification flow instead of publishing, and the creator finishes the post inside the TikTok app.",
      "additionalProperties": true
    }
  },
  "required": [
    "schedule"
  ]
}
🟢preview_campaign(schedule)

Preview how a campaign schedule document expands into concrete posts and steps without creating anything.

Input Schema

{
  "type": "object",
  "properties": {
    "schedule": {
      "type": "object",
      "description": "SocialClaw schedule document. Minimal shape: { timezone, posts: [{ account, name, description, publish_at, media_link? }] }. Campaign documents use { timezone, campaigns: [...] }. Per-post provider settings go in settings, e.g. TikTok inbox mode: settings: { tiktokPostMode: \"draft\" } sends the media to TikTok's inbox notification flow instead of publishing, and the creator finishes the post inside the TikTok app.",
      "additionalProperties": true
    }
  },
  "required": [
    "schedule"
  ]
}
🟡apply_schedule(schedule, idempotencyKey)

Create a publishing run from a schedule document. Posts are scheduled or published through connected accounts. Send an idempotencyKey so retries do not create duplicate runs.

Input Schema

{
  "type": "object",
  "properties": {
    "schedule": {
      "type": "object",
      "description": "SocialClaw schedule document. Minimal shape: { timezone, posts: [{ account, name, description, publish_at, media_link? }] }. Campaign documents use { timezone, campaigns: [...] }. Per-post provider settings go in settings, e.g. TikTok inbox mode: settings: { tiktokPostMode: \"draft\" } sends the media to TikTok's inbox notification flow instead of publishing, and the creator finishes the post inside the TikTok app.",
      "additionalProperties": true
    },
    "idempotencyKey": {
      "type": "string",
      "description": "Stable key to deduplicate retries."
    }
  },
  "required": [
    "schedule"
  ]
}
🟡publish_draft(runId, startAt)

Publish a previously created draft run, optionally at a given ISO-8601 start time.

Input Schema

{
  "type": "object",
  "properties": {
    "runId": {
      "type": "string",
      "description": "Draft run id."
    },
    "startAt": {
      "type": "string",
      "description": "Optional ISO-8601 publish start time."
    }
  },
  "required": [
    "runId"
  ]
}
🟢list_posts(runId, status, account, provider, campaignId, ...)

List posts in the workspace with optional filters.

Input Schema

{
  "type": "object",
  "properties": {
    "runId": {
      "type": "string"
    },
    "status": {
      "type": "string",
      "description": "e.g. scheduled, published, action_required, failed, canceled."
    },
    "account": {
      "type": "string",
      "description": "Account handle filter."
    },
    "provider": {
      "type": "string"
    },
    "campaignId": {
      "type": "string"
    },
    "limit": {
      "type": "number",
      "description": "Maximum posts to return. Defaults to 20 and is capped at 50."
    },
    "offset": {
      "type": "number",
      "description": "Offset for paging through results."
    }
  }
}
🟢list_assets(query, kind, mime, sort, limit)

List media (images/videos) the user has uploaded to their SocialClaw library, newest first. Each asset includes a publicUrl usable directly as media_link in validate_schedule/apply_schedule. Use this to find a previously uploaded file (e.g. from the dashboard) to post. Optionally filter by kind (image/video), mime, or a text query over filename/id.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Optional text match over filename, id, kind, mime, or url."
    },
    "kind": {
      "type": "string",
      "description": "Filter by media kind: image or video.",
      "enum": [
        "image",
        "video"
      ]
    },
    "mime": {
      "type": "string",
      "description": "Optional mime prefix filter, e.g. video/mp4."
    },
    "sort": {
      "type": "string",
      "description": "created_desc (default, newest first) or created_asc.",
      "enum": [
        "created_desc",
        "created_asc"
      ]
    },
    "limit": {
      "type": "number",
      "description": "Maximum assets to return. Defaults to 24, capped at 48."
    }
  }
}
🟢get_post(postId)

Get one post including its delivery state and provider identifiers.

Input Schema

{
  "type": "object",
  "properties": {
    "postId": {
      "type": "string"
    }
  },
  "required": [
    "postId"
  ]
}
🟢post_attempts(postId)

List publish attempts for a post, including provider errors. Use this to debug failed posts.

Input Schema

{
  "type": "object",
  "properties": {
    "postId": {
      "type": "string"
    }
  },
  "required": [
    "postId"
  ]
}
🟡retry_post(postId)

Retry a failed post.

Input Schema

{
  "type": "object",
  "properties": {
    "postId": {
      "type": "string"
    }
  },
  "required": [
    "postId"
  ]
}
🔴cancel_post(postId)

Cancel a scheduled post before it publishes.

Input Schema

{
  "type": "object",
  "properties": {
    "postId": {
      "type": "string"
    }
  },
  "required": [
    "postId"
  ]
}
🟢run_status(runId)

Get the status summary of a publishing run and its posts.

Input Schema

{
  "type": "object",
  "properties": {
    "runId": {
      "type": "string"
    }
  },
  "required": [
    "runId"
  ]
}
🟢get_analytics(scope, id, window)

Get analytics snapshots for a post, an account, or a run. scope must be post, account, or run; id is the matching identifier.

Input Schema

{
  "type": "object",
  "properties": {
    "scope": {
      "type": "string",
      "enum": [
        "post",
        "account",
        "run"
      ]
    },
    "id": {
      "type": "string"
    },
    "window": {
      "type": "string",
      "description": "Optional analytics window, e.g. 7d."
    }
  },
  "required": [
    "scope",
    "id"
  ]
}
🟡refresh_analytics(postId, window)

Fetch fresh analytics for a published post from the provider and store a new snapshot, then return it. Supported providers: Instagram, TikTok, YouTube, Reddit, X, Pinterest, Snapchat (others return an unsupported snapshot). Call this before get_analytics when you need current numbers rather than the last stored snapshot.

Input Schema

{
  "type": "object",
  "properties": {
    "postId": {
      "type": "string",
      "description": "The published post id to refresh."
    },
    "window": {
      "type": "string",
      "description": "Optional analytics window, e.g. 7d (default lifetime)."
    }
  },
  "required": [
    "postId"
  ]
}
🟢list_instagram_media(account, limit, after)

List an Instagram account's recent posts (caption, permalink, timestamp, comment count) so you can find one to read or moderate comments on. account is the connected-account id or handle.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "limit": {
      "type": "number",
      "description": "Max media to return (default 25, capped at 100)."
    },
    "after": {
      "type": "string",
      "description": "Pagination cursor from a previous response."
    }
  },
  "required": [
    "account"
  ]
}
🟢get_instagram_comments(account, mediaId, limit, after)

Read the comments and replies people left on one of the user's own Instagram posts, so the user can review and answer them. Use list_instagram_media first to get a mediaId.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "mediaId": {
      "type": "string",
      "description": "The IG media id from list_instagram_media."
    },
    "limit": {
      "type": "number",
      "description": "Max comments to return (default 25, capped at 100)."
    },
    "after": {
      "type": "string",
      "description": "Pagination cursor from a previous response."
    }
  },
  "required": [
    "account",
    "mediaId"
  ]
}
⚪reply_instagram_comment(account, commentId, message)

Reply to an Instagram comment on the user's media.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "commentId": {
      "type": "string"
    },
    "message": {
      "type": "string",
      "description": "The reply text."
    }
  },
  "required": [
    "account",
    "commentId",
    "message"
  ]
}
🟡hide_instagram_comment(account, commentId, hidden)

Hide or unhide an Instagram comment on the user's media. Set hidden=false to unhide.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "commentId": {
      "type": "string"
    },
    "hidden": {
      "type": "boolean",
      "description": "true to hide (default), false to unhide."
    }
  },
  "required": [
    "account",
    "commentId"
  ]
}
🔴delete_instagram_comment(account, commentId)

Permanently delete an Instagram comment on the user's media. Prefer hide_instagram_comment when unsure.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "commentId": {
      "type": "string"
    }
  },
  "required": [
    "account",
    "commentId"
  ]
}
🟢get_instagram_media_insights(account, mediaId, mediaProductType)

Get analytics for one Instagram post (reach, likes, comments, saved, shares, views). Use list_instagram_media for the mediaId.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "mediaId": {
      "type": "string"
    },
    "mediaProductType": {
      "type": "string",
      "description": "Optional: FEED, REELS, or STORY — refines which metrics are requested."
    }
  },
  "required": [
    "account",
    "mediaId"
  ]
}
🟢get_instagram_profile(account)

Get an Instagram account's profile stats: followers, follows, media count, bio.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    }
  },
  "required": [
    "account"
  ]
}
🟢get_instagram_account_insights(account, metric, days)

Get an Instagram account's insight trend (a daily time series, e.g. reach) over the last N days.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "metric": {
      "type": "string",
      "description": "Account metric, default reach (e.g. reach, profile_views, accounts_engaged)."
    },
    "days": {
      "type": "number",
      "description": "Window in days (2-30, default 14)."
    }
  },
  "required": [
    "account"
  ]
}
⚪react_instagram_message(account, conversationId, messageId, recipientId, reaction)

React to a received Instagram direct message (e.g. love).

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "conversationId": {
      "type": "string"
    },
    "messageId": {
      "type": "string"
    },
    "recipientId": {
      "type": "string",
      "description": "The other participant's Instagram-scoped user id (IGSID)."
    },
    "reaction": {
      "type": "string",
      "description": "Reaction name, default love."
    }
  },
  "required": [
    "account",
    "conversationId",
    "messageId",
    "recipientId"
  ]
}
🟢list_instagram_mentions(limit)

List recent @mentions of the workspace's Instagram accounts (captured from Instagram mention webhooks).

Input Schema

{
  "type": "object",
  "properties": {
    "limit": {
      "type": "number",
      "description": "Max mentions (default 30, capped at 100)."
    }
  }
}
🟢list_instagram_conversations(account, limit, after)

List the Instagram direct-message conversations for an account, most recent first. Each conversation includes `counterpart` (the other person's {id, username}) — use its id as the recipientId when replying; `participants` also lists the account itself.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "limit": {
      "type": "number",
      "description": "Max conversations (default 25, capped at 100)."
    },
    "after": {
      "type": "string",
      "description": "Pagination cursor from a previous response."
    }
  },
  "required": [
    "account"
  ]
}
🟢get_instagram_messages(account, conversationId, limit, after)

Read the messages in an Instagram direct-message conversation.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "conversationId": {
      "type": "string",
      "description": "Conversation id from list_instagram_conversations."
    },
    "limit": {
      "type": "number",
      "description": "Max messages (default 25, capped at 100)."
    },
    "after": {
      "type": "string",
      "description": "Pagination cursor from a previous response."
    }
  },
  "required": [
    "account",
    "conversationId"
  ]
}
🟡send_instagram_message(account, conversationId, recipientId, text, attachment_url, ...)

Send an Instagram direct message — a text reply, or an image/video attachment via attachment_url. Only allowed within 24 hours of the recipient's last message unless a message tag (e.g. HUMAN_AGENT) is supplied.

Input Schema

{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Instagram connected-account id or handle."
    },
    "conversationId": {
      "type": "string",
      "description": "Conversation id (for routing/storage)."
    },
    "recipientId": {
      "type": "string",
      "description": "The recipient's Instagram-scoped user id (IGSID)."
    },
    "text": {
      "type": "string",
      "description": "Message body (omit when sending an attachment)."
    },
    "attachment_url": {
      "type": "string",
      "description": "Public URL of an image/video to send as an attachment."
    },
    "attachment_type": {
      "type": "string",
      "description": "Attachment type: image (default), video, or audio.",
      "enum": [
        "image",
        "video",
        "audio"
      ]
    },
    "tag": {
      "type": "string",
      "description": "Optional message tag, e.g. HUMAN_AGENT, to reply outside the 24h window."
    }
  },
  "required": [
    "account",
    "conversationId",
    "recipientId"
  ]
}
🟢workspace_usage

Get workspace usage counters and plan entitlement consumption.

Input Schema

{
  "type": "object",
  "properties": {}
}
🟢workspace_health(provider)

Get workspace health, including connection state across providers. Pass provider to check one provider's connections.

Input Schema

{
  "type": "object",
  "properties": {
    "provider": {
      "type": "string",
      "description": "Optional provider to check connection health for."
    }
  }
}
🟢get_profile

Identify the connected SocialClaw workspace: its stable id, name, and plan. Use it to confirm which workspace you are acting on.

Input Schema

{
  "type": "object",
  "properties": {}
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded34 tools
verifiedversion not recorded34 tools
verifiedversion not recorded34 tools
verifiedversion not recorded33 tools
verifiedversion not recorded32 tools
verifiedversion not recorded32 tools