Help us improve
Share bugs, ideas, or general feedback.
From Ayrshare - Unified Social Media API for AI Agents
Foundation skill for the Ayrshare MCP server: auth model, installation, client onboarding, and retry safety. Activate when configuring the plugin, resolving 401/403 errors, or onboarding new profiles.
npx claudepluginhub ayrshare/ayrshare-social-media-api-claude-plugin --plugin ayrshareHow this skill is triggered — by the user, by Claude, or both
Slash command
/ayrshare:getting-startedThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The single home for the cross-cutting model behind the Ayrshare MCP server: the **auth model** (API key connection header, plus optional profile selection by either a `Profile-Key` connection header or a per-call `profileKey` tool argument), the **client onboarding sequence**, and the **retry-safety rules**. Every other Ayrshare MCP skill points here instead of repeating it. If you only read on...
Manages client profiles for the Ayrshare MCP server: create profiles, list them, and generate social-account linking URLs for client onboarding under a Business account.
Automates Ayrshare social media API tasks (posting, analytics, scheduling) via Rube MCP and Composio. Always search for current tool schemas before executing.
Create, schedule, and manage social media posts across Instagram, TikTok, YouTube, X, LinkedIn, Facebook, Pinterest, Threads, Bluesky via Post Bridge API. Supports media upload, platform configs, drafts, analytics, tracking.
Share bugs, ideas, or general feedback.
The single home for the cross-cutting model behind the Ayrshare MCP server: the auth model (API key connection header, plus optional profile selection by either a Profile-Key connection header or a per-call profileKey tool argument), the client onboarding sequence, and the retry-safety rules. Every other Ayrshare MCP skill points here instead of repeating it. If you only read one Ayrshare MCP skill, read this one. Most failures are auth-layer mistakes, not tool bugs.
https://api.ayrshare.com/mcp, authenticated by the header Authorization: Bearer ${AYRSHARE_API_KEY}.mcp__ayrshare__<action> (e.g. mcp__ayrshare__create_post).references/install.md. The summary below is enough to get running.Auth has two parts. The API key is always a per-connection header configured in the MCP client (the plugin's .mcp.json), never a tool argument. The target profile is optional and can be set two equivalent ways, either a Profile-Key connection header (applies to every call on the connection) or a per-call profileKey tool argument (selects the profile for that one call):
Authorization: Bearer <API key> (required). Your account-level Ayrshare Business API key. The MCP server sends it on every call as the HTTP Bearer token. It is configured once via /ayrshare:setup (or the AYRSHARE_API_KEY env var), never passed as a per-call argument. The multi-profile features (Profiles) require a Business plan.
Target profile (optional): Profile-Key header or profileKey argument. Selects which client/customer profile a call acts on; a profileKey is returned by mcp__ayrshare__create_profile. Set it either as the Profile-Key connection header (the default for every call on that connection) or as an optional profileKey argument on the tool call (just that call). When both are present, the profileKey argument wins; with neither, calls act on the account's primary profile. The per-call argument lets an agent act as a client it learns at runtime (from chat, a database, or a CRM) without editing .mcp.json or restarting. It is accepted by the profile-scoped tools only; the account-level and no-social-account tools ignore it (see Which tools accept profileKey below). (generate_jwt_social_linking_url uses the same value to pick the sub-profile it mints a linking URL for, and requires it via either input.)
The rule in one line: the API key sets the account; the profile selection sets the identity. With only the API key set, every call acts on the primary/Business profile. To act as a client profile, either set that profile's Profile-Key header on the connection (applies to all calls) or pass its profileKey as a tool argument (per call, and it wins over the header). list_profiles and create_profile are account-level; the profile-scoped tools, including generate_jwt_social_linking_url, act on whichever profile the argument-or-header selects.
profileKey argumentMost tools are profile-scoped and accept the optional profileKey argument (equivalently, the Profile-Key header): the post, history, analytics, comments, messages, and webhook tools, plus generate_jwt_social_linking_url. Six tools do not take it:
create_profile, list_profiles.validate_media, explain_error, generate_post, recommend_hashtags. (recommend_hashtags still reads the Profile-Key header to pick whose linked TikTok account it uses; it just does not accept the per-call argument.)One exception: on get_platform_history and get_social_network_analytics, a userId/userName lookup (a specific X/Twitter user, not your linked account) must use the API key only. Supplying a profileKey (argument or Profile-Key header) together with userId/userName returns Error 400.
As a connection header (the default for every call). With the plugin, the bundled .mcp.json already carries the header with an empty default:
"headers": {
"Authorization": "Bearer ${AYRSHARE_API_KEY}",
"Profile-Key": "${AYRSHARE_PROFILE_KEY:-}" // empty when unset → primary profile
}
So you just set AYRSHARE_PROFILE_KEY (in your settings.json env block, same place as AYRSHARE_API_KEY, on any OS) and restart; every call on that connection then defaults to that profile. Leave it unset and the header goes out empty, which the server treats as "act on the primary profile." (For a non-plugin claude mcp add setup, add the Profile-Key header yourself alongside Authorization.)
As a per-call argument (no restart). Leave the header unset (or keep one as the default) and pass profileKey directly on a profile-scoped tool call to act as a specific client for that single call. The argument takes precedence over the header when both are set, so an agent can act as a client it discovers at runtime without touching .mcp.json or restarting:
// e.g. get this client's recent posts without changing the connection
{ "limit": 25, "profileKey": "<the client's profileKey>" }
Security note: the header keeps the key out of band; the argument does not. A Profile-Key connection header is sent by the transport and never enters the model context or the conversation transcript. A profileKey argument is, by design, part of the tool call the agent emits, so it appears in the conversation transcript and the payload sent to the model provider. Prefer the header for static, single-profile setups; use the per-call argument deliberately when you need runtime selection. The exposure is bounded: a profileKey is inert without the account API key (which is never an argument), so a key seen in a transcript is not usable on its own.
Each domain has its own skill with full parameters and gotchas:
../post/SKILL.md): create_post, validate_post, get_post, update_post, retry_post.../history/SKILL.md): get_post_history, get_platform_history.../analytics/SKILL.md): get_post_analytics, get_post_analytics_by_social_id, get_social_network_analytics.../comments/SKILL.md): get_comments, add_comment, reply_comment.../messages/SKILL.md): get_messages, send_message, get_auto_response, set_auto_response.../profiles/SKILL.md): list_profiles, create_profile, generate_jwt_social_linking_url.../media/SKILL.md): validate_media.../generate/SKILL.md): generate_post, recommend_hashtags.../webhooks/SKILL.md): register_webhook, unregister_webhook, list_webhooks.../errors/SKILL.md): explain_error.(There is no get_user, delete_post, delete_comment, delete_profile, or media upload/library/resize tool — if you reach for one of those, it does not exist.)
AYRSHARE_API_KEY is the account-level Business plan API key, obtained from the Ayrshare dashboard (app.ayrshare.com → Settings → API Key). The MCP server sends it as the HTTP Bearer token, loaded at session start — it is not passed per-call. A Business plan is required for the Profiles / multi-profile features (create profile, act as a client). If the key is missing or wrong, the server cannot authenticate any tool — see Missing credentials below.
Full, copy-paste instructions are in references/install.md. The essentials:
Claude Code plugin (recommended) — register the marketplace once, install (this brings commands, agents, and skills), then configure the key via setup:
claude plugin marketplace add ayrshare/ayrshare-social-media-api-claude-plugin # one time
claude plugin install ayrshare@ayrshare # default scope: user (all projects)
# or scope it:
claude plugin install ayrshare@ayrshare --scope local # this project, not committed
claude plugin install ayrshare@ayrshare --scope project # this project, committed with team
Then inside Claude Code, configure your key and restart:
/ayrshare:setup
After /ayrshare:setup writes the key, you MUST restart Claude Code — the MCP connection is initialized at session start, so the key isn't active until the next session.
MCP only (no plugin) — raw tools, no commands/agents/skills:
claude mcp add ayrshare --transport http \
https://api.ayrshare.com/mcp \
--header "Authorization: Bearer YOUR_API_KEY"
Env var / CI:
export AYRSHARE_API_KEY=your_key_here
claude plugin marketplace add ayrshare/ayrshare-social-media-api-claude-plugin
claude plugin install ayrshare@ayrshare
The plugin's .mcp.json substitutes ${AYRSHARE_API_KEY} at startup — no /ayrshare:setup needed.
Verification gotcha: do NOT verify the key by calling a tool in the same session where you set it. The key loads at session start, so a freshly-set key always returns 401/403 until you restart Claude Code. Restart first, then run
mcp__ayrshare__get_post_history(a plan-agnostic read —list_profilesneeds a Business plan) to confirm the connection works.
Onboarding a new client means creating a profile under your Business account, getting that client's social accounts linked, then acting as that profile.
mcp__ayrshare__create_profile (account-level, API key) — pass a title; returns the profileKey. Capture it (store it securely — it is sensitive).mcp__ayrshare__generate_jwt_social_linking_url, passing the profileKey from step 1 as the profileKey argument. No header change and no restart are needed; the argument selects the target profile for that call (the Profile-Key header still works as an alternative). It needs no private key or domain (the server derives those from your authenticated account) and returns a hosted linking url (valid 5 minutes by default, or expiresIn on the Max Pack). Hand the url to the client; they open it in a browser to OAuth their accounts. (The Ayrshare dashboard's linking page and the REST /profiles/generateJWT endpoint are equivalent alternatives.) Requires a provisioned social-linking domain (Business/Enterprise). Full schema in ../profiles/SKILL.md.profileKey as the tool argument on each call, or set the connection's Profile-Key header (and restart) to make that profile the default for the whole connection. create_profile/list_profiles ignore both and stay account-level.mcp__ayrshare__list_profiles shows the profile and its linked platforms; mcp__ayrshare__get_post_history (with the profileKey argument or the Profile-Key header set) confirms you are acting on the right profile.Don't over-railroad this. A client may already have a profileKey, in which case skip to step 2.
The server fails fast and surfaces errors. Your job is to not paper over them.
mcp__ayrshare__explain_error with the returned error code to translate the raw API error into plain language, then surface that explanation to the user. Do not silently retry.explain_error) instead. This applies to all writes: create_post, update_post, retry_post, add_comment, reply_comment, send_message, set_auto_response, create_profile, and the webhook writes. (Separately, the plugin's confirm-before-acting prompt covers the live-social publish/send actions plus create_profile; the webhook writes are still writes (no auto-retry on a 4xx), but are reversible config and are not behind that prompt.)retry_post is the ONLY correct way to re-attempt a failed post — and only when the original error says it is retryable, and only once. Never re-run create_post to "try again" (that double-posts on platforms that already succeeded).mcp__ayrshare__validate_post checks content for platform-specific issues before publishing, and mcp__ayrshare__validate_media checks a media URL is reachable. Use them ahead of create_post — detail in the Posts and Media skills.mcp__ayrshare__create_profile fails (wrong plan, invalid key, etc.) — STOP and explain (via explain_error) rather than pushing forward.When the user has no Ayrshare account or API key, when AYRSHARE_API_KEY is unset/wrong, or when the API returns 401/403, surface this signup link for a 28-day free trial of the Ayrshare Launch plan:
https://billing.ayrshare.com/b/9B6bJ15Oidr9fz615u1Nu0h?utm_source=claude
The ?utm_source=claude query parameter MUST be preserved exactly — it is signup attribution. Do not alter, shorten, URL-encode differently, or drop it. Note that the Launch trial does not include Profiles; the Profiles / multi-profile features still require a Business plan.
profileKey tool argument wins over the Profile-Key connection header; with neither set, calls act on the primary profile. To act as a client for one call, pass profileKey as the argument; to make a whole connection default to that client, set the header. The account-level tools (create_profile, list_profiles) and the no-social-account tools (validate_media, explain_error, generate_post, recommend_hashtags) accept neither. On get_platform_history / get_social_network_analytics, a userId/userName lookup must use the API key only (a profileKey there returns Error 400).get_user, delete_post, delete_comment, delete_profile, or media upload/list/resize tool. Deleting profiles is done in the dashboard / REST API; linking a client's accounts is done by the client opening a generate_jwt_social_linking_url URL in their browser (the MCP mints the link but does not run the OAuth)./ayrshare:setup won't activate until you restart Claude Code — verifying before restart returns 401/403. After restart, verify with mcp__ayrshare__get_post_history (works on any plan).explain_error and surface it. To re-attempt a failed post use retry_post (once, only if retryable), never a second create_post. 429 gets exactly one retry.utm_source=claude. The trial link's query param is attribution; keep it byte-for-byte.profileKey as a tool argument and that single call acts as them, with no header change and no restart. Change the Profile-Key header (and restart) only when you want every call on the connection to default to one client.