Are you an AI agent? Machine-readable entry points:/llms.txt/llms-full.txt/catalog.json

MCP server

One URL for every assistant. You sign in on UniLink and approve; the assistant gets 22 tools on your own account.

https://unilink.us/mcp

Connect your assistant

Claude (claude.ai and Claude Desktop)

  1. Open Settings → Connectors → Add custom connector.
  2. Paste https://unilink.us/mcp and add it.
  3. Sign in to UniLink and click Allow.

ChatGPT

  1. Turn on developer mode, then add a custom connector.
  2. Use the same URL: https://unilink.us/mcp.
  3. Sign in to UniLink and click Allow.

Claude Code

claude mcp add --transport http unilink https://unilink.us/mcp
  1. Run the command above.
  2. In Claude Code, run /mcp, pick unilink and sign in to UniLink.
  3. Click Allow.

Cursor

Not supported

Cursor needs Dynamic Client Registration, which UniLink doesn’t offer.

Sign-in and security

  • OAuth 2.1, authorization code with PKCE (S256 only).
  • You approve on a UniLink screen; nothing happens until you click Allow.
  • Access tokens last 1 hour. Refresh tokens rotate: each one works once.
  • Changing your password, logging out everywhere or changing MFA ends the grant.
  • Disconnect any time in Account settings → Connected apps.
  • Discovery: https://unilink.us/.well-known/oauth-protected-resource/mcp and https://unilink.us/.well-known/oauth-authorization-server.
  • Client registration: Client ID Metadata Documents from claude.ai and chatgpt.com. Dynamic Client Registration is not supported.

Transport

Endpoint
POST https://unilink.us/mcp
Transport
Streamable HTTP, JSON-RPC 2.0
Responses
application/json, one per request (no SSE stream)
Sessions
Stateless — no Mcp-Session-Id
Protocol versions
2025-06-18, 2025-03-26
Batching
Not supported
Request body
Up to 1 MB
Resource metadata
https://unilink.us/.well-known/oauth-protected-resource/mcp
Authorization server
https://unilink.us/.well-known/oauth-authorization-server
Client registration
Client ID Metadata Documents (claude.ai, chatgpt.com); Dynamic Client Registration not supported

First call

For people building an MCP client: what the server answers before sign-in, and what to do next.

curl -i -X POST https://unilink.us/mcp
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://unilink.us/.well-known/oauth-protected-resource/mcp", Bearer
  1. Read resource_metadata: it names the authorization server, https://unilink.us.
  2. Fetch https://unilink.us/.well-known/oauth-authorization-server for the authorize and token endpoints.
  3. Run the authorization code flow with PKCE (S256); the person signs in and clicks Allow.
  4. Send the access token as Authorization: Bearer on every POST.

Only client IDs on claude.ai and chatgpt.com are accepted. Building your own client? Use the REST API with an API key.

Tool reference

22 tools. 10 need a paid plan. Names, descriptions and arguments are exactly what tools/list returns.

Read (13)Edit (9)

Read

get_account_info

Read-only

Get account and profiles

Get current user account info including list of profiles, plan info. Call this first to discover available profileId values.

Arguments

No arguments.

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

get_profile_analytics

Read-onlyPaid plan

Get profile analytics

Get analytics for a profile: views, unique visitors, clicks, signups, top referrers and countries.

Arguments

  • profileIdintegerrequired

    Profile ID (get from get_account_info)

  • periodintegeroptionaldefault: 5

    1=Today, 2=Yesterday, 3=Week, 4=Month, 5=AllTime, 6=Custom

  • startDatestringoptional

    Start date ISO 8601 (only for period=6)

  • endDatestringoptional

    End date ISO 8601 (only for period=6)

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

list_blocks

Read-only

List blocks

List all blocks on a profile. Shows type, title, visibility, position, and for link blocks each link's ID (the itemId update_link_item takes), title and URL.

Arguments

  • profileIdintegerrequired

    Profile ID

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

list_orders

Read-onlyPaid plan

List orders

List orders for a profile with pagination.

Arguments

  • profileIdintegerrequired

    Profile ID

  • takeintegeroptionaldefault: 20

    Number of orders (default 20)

  • skipintegeroptionaldefault: 0

    Offset (default 0)

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

list_audience

Read-onlyPaid plan

List audience

List audience members (contacts). Supports search and pagination.

Arguments

  • profileIdintegerrequired

    Profile ID

  • searchstringoptional

    Search by name, email, phone

  • takeintegeroptionaldefault: 50

    Limit (default 50)

  • skipintegeroptionaldefault: 0

    Offset (default 0)

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

get_audience_stats

Read-onlyPaid plan

Get audience stats

Get audience stats: contacts, forms, subscribers, customers counts.

Arguments

  • profileIdintegerrequired

    Profile ID

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

list_products

Read-onlyPaid plan

List products

List products for a profile store with pagination.

Arguments

  • profileIdintegerrequired

    Profile ID

  • takeintegeroptionaldefault: 20

    Limit (default 20)

  • skipintegeroptionaldefault: 0

    Offset (default 0)

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

get_product_details

Read-onlyPaid plan

Get product details

Get detailed info about a product: price, description, media, status.

Arguments

  • profileIdintegerrequired

    Profile ID

  • productIdintegerrequired

    Product ID (from list_products)

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

get_revenue_summary

Read-onlyPaid plan

Get revenue summary

Get revenue from paid orders, grouped by currency, optionally within a date range on the order's creation time (UTC). A paid order is one with status paid, confirmed, processing, in-progress, packed, shipped, delivered or completed. Not included: orders not yet paid, failed, cancelled, refunded or on hold. This differs from the Revenue figure on the UniLink Analytics screen, which counts only orders still in status 'paid'.

Arguments

  • profileIdintegerrequired

    Profile ID

  • startDatestringoptional

    Start date ISO 8601, UTC (optional)

  • endDatestringoptional

    End date ISO 8601, UTC (optional). A date alone (2026-01-31) includes that whole day; a full timestamp is inclusive of that exact instant.

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

list_repeat_customers

Read-onlyPaid plan

List repeat customers

List customers (audience contacts) who bought at least minOrders times, most purchases first, with order count, total spent per currency, and first/last purchase dates. A purchase is a paid order (status paid, confirmed, processing, in-progress, packed, shipped, delivered or completed) - the same definition as get_revenue_summary, and wider than the UniLink Analytics screen, which counts only 'paid'. Orders not linked to a contact cannot be attributed and are reported as a count only.

Arguments

  • profileIdintegerrequired

    Profile ID

  • minOrdersintegeroptionaldefault: 2

    Minimum number of purchases (default 2, at least 2)

  • takeintegeroptionaldefault: 20

    Number of customers (default 20, max 100)

  • skipintegeroptionaldefault: 0

    Offset (default 0)

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

smm_list_connected_accounts

Read-only

List connected social accounts

List the social media accounts connected to a profile, per platform (facebook, instagram, twitter, linkedin, telegram, pinterest, threads, discord, youtube), marking the account publish_to_social and schedule_social_post post to. Accounts are connected in the UniLink Dashboard, not here. Call this before publishing. Not paginated.

Arguments

  • profileIdintegerrequired

    Profile ID

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

list_smm_campaigns

Read-only

List social campaigns

List the profile's social media campaigns, newest first, with each campaign's status and platforms and each platform's post status and link. Paginated with take/skip: the text ends with a line Pagination: {"hasMore":true|false,"nextSkip":n|null}; while hasMore is true, call again with skip = nextSkip.

Arguments

  • profileIdintegerrequired

    Profile ID

  • takeintegeroptionaldefault: 20

    Number of campaigns (default 20, max 100)

  • skipintegeroptionaldefault: 0

    Offset (default 0)

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

get_campaign_details

Read-only

Get social campaign details

Get one social media campaign: status, schedule, text, and per platform the post status, link, error and engagement metrics. campaignId comes from list_smm_campaigns or from publish_to_social's result.

Arguments

  • profileIdintegerrequired

    Profile ID

  • campaignIdintegerrequired

    Campaign ID (from list_smm_campaigns)

readOnlyHint: truedestructiveHint: falseidempotentHint: trueopenWorldHint: false

Edit

create_block

Changes your page

Create a block

Create a new block on a profile page. Common types: link, text, faq, contact, html, video, map, timer, gallery, banner, shop, digital, appointment, event, course, donation, tip. A new link block starts with no links; add them with add_link_item. A new text block starts with placeholder text under a "Text" heading; replace both with update_text_block. Call list_blocks to get the new block's UID.

Arguments

  • profileIdintegerrequired

    Profile ID

  • pageIdintegeroptional

    Page ID (the Page shown by list_blocks). Omit or 0 for the profile's main page.

  • typestringrequired

    Block type (e.g. link, text, faq, shop, video)

  • positionintegeroptionaldefault: 0

    Position index (0 = top)

readOnlyHint: falsedestructiveHint: falseidempotentHint: falseopenWorldHint: true

update_block

Overwrites content

Rename a block

Rename a block (its name/title). It changes nothing else: to change a block's content use add_link_item / update_link_item (link blocks) or update_text_block (text blocks).

Arguments

  • profileIdintegerrequired

    Profile ID

  • blockUIDstringrequired

    Block UID (from list_blocks)

  • namestringrequired

    New block name/title

readOnlyHint: falsedestructiveHint: trueidempotentHint: trueopenWorldHint: true

toggle_block_visibility

Changes your page

Show or hide a block

Show or hide a block on the profile page.

Arguments

  • profileIdintegerrequired

    Profile ID

  • blockUIDstringrequired

    Block UID (from list_blocks)

  • isActivebooleanrequired

    true=visible, false=hidden

readOnlyHint: falsedestructiveHint: falseidempotentHint: trueopenWorldHint: true

reorder_blocks

Changes your page

Reorder blocks

Change the order of blocks on a profile page. Pass block UIDs in the desired order.

Arguments

  • profileIdintegerrequired

    Profile ID

  • blockUIDsarray of stringrequired

    Array of block UIDs in desired order

readOnlyHint: falsedestructiveHint: falseidempotentHint: trueopenWorldHint: true

update_text_block

Overwrites content

Set the text of a text block

Set the text of an existing TEXT block (type 'text' in list_blocks), replacing what is there. A text block shows one tab unless its owner turned tabs on; this always writes the first tab. text is plain text; line breaks become paragraphs. HTML or other markup is not interpreted: it shows as typed.

Arguments

  • profileIdintegerrequired

    Profile ID

  • blockUIDstringrequired

    UID of a text block (from list_blocks)

  • textstringrequired

    The new text, at most 10000 characters

  • titlestringoptional

    Heading shown above the text (optional), at most 512 characters

readOnlyHint: falsedestructiveHint: trueidempotentHint: trueopenWorldHint: true

publish_to_social

Posts to social mediaPaid plan

Publish a social post

Publish a post now to one or more of the profile's connected social accounts: one account per platform, the one smm_list_connected_accounts marks. It creates a campaign (see list_smm_campaigns) and sends it to each platform. Platforms that are not connected are skipped; if none is connected the call fails with NOT_CONNECTED. The text lists each platform as SUCCESS, FAILED or SKIPPED; for Instagram, SUCCESS means accepted and still processing, not yet live. Each platform applies its own rules (e.g. X allows 280 characters, Instagram needs an image or video, YouTube needs a video). Paid UniLink plans only, up to the profile's daily social post limit (10 by default) per 24 hours.

Arguments

  • profileIdintegerrequired

    Profile ID

  • contentstringrequired

    Post text, at most 5000 characters

  • platformsarray of stringrequired

    Platforms to post to, each at most once: facebook, instagram, twitter, linkedin, telegram, pinterest, threads, discord, youtube

  • mediaUrlsarray of stringoptional

    Optional public https:// image or video URLs to attach, at most 10, each at most 2048 characters. A URL whose path ends in .mp4, .mov, .avi or .webm is sent as a video, any other as an image.

  • titlestringoptional

    Optional campaign title shown in list_smm_campaigns, at most 512 characters (default: the start of content)

readOnlyHint: falsedestructiveHint: falseidempotentHint: falseopenWorldHint: true

schedule_social_post

Posts to social mediaPaid plan

Schedule a social post

Schedule a post to go out later to one or more of the profile's connected social accounts. Same as publish_to_social, but nothing is sent now: at scheduleAt UniLink publishes to each platform; follow it with list_smm_campaigns. Platforms that are not connected are skipped; if none is connected the call fails with NOT_CONNECTED. Paid UniLink plans only, up to the profile's daily social post limit (10 by default) per 24 hours, counted when the post is scheduled.

Arguments

  • profileIdintegerrequired

    Profile ID

  • contentstringrequired

    Post text, at most 5000 characters

  • platformsarray of stringrequired

    Platforms to post to, each at most once: facebook, instagram, twitter, linkedin, telegram, pinterest, threads, discord, youtube

  • scheduleAtstringrequired

    When to publish: ISO 8601 in UTC, e.g. 2026-03-01T10:00:00Z (a time without an offset is taken as UTC). Must be in the future.

  • mediaUrlsarray of stringoptional

    Optional public https:// image or video URLs to attach, at most 10, each at most 2048 characters. A URL whose path ends in .mp4, .mov, .avi or .webm is sent as a video, any other as an image.

  • titlestringoptional

    Optional campaign title shown in list_smm_campaigns, at most 512 characters (default: the start of content)

readOnlyHint: falsedestructiveHint: falseidempotentHint: falseopenWorldHint: true

Errors

  • Every tool error comes back with isError: true and the text {"success":false,"errorCode":…,"message":…,"retryable":…} (plus "field" when one argument is at fault). errorCode is one of INVALID_ARGUMENT, NOT_FOUND, PAID_PLAN_REQUIRED, LIMIT_REACHED, NOT_ALLOWED, NOT_CONNECTED, INTERNAL. Only INTERNAL can be retryable. Relay the message to the person.
  • publish_to_social and schedule_social_post skip platforms that are not connected and return NOT_CONNECTED when none of them is (connect the account in the UniLink Dashboard first; a Facebook login without a Page or a Discord connection without a channel counts as not connected). They return LIMIT_REACHED at the daily social post limit.
  • An unknown tool or method gets a JSON-RPC error.

Pagination

These tools take take and skip. The others return everything in one call.

Limits

  • add_link_item counts the profile’s live links against your plan’s link limit; at the limit it answers "Link limit for your plan reached."
  • Links to onlyfans.com, fansly.com and fanvue.com need a paid plan.
  • Link URL: at most 511 characters. Link title: at most 512.
  • Text block text: at most 10 000 characters, plain text. Heading: at most 512.
  • list_repeat_customers returns at most 100 per page.
  • publish_to_social and schedule_social_post: text at most 5000 characters, up to 10 media URLs (public https, at most 2048 characters each), and the profile’s daily social post limit (10 by default) per 24 hours.
  • Request body: up to 1 MB.

How labels work

No label
Works today. You can call it now.
Coming soon
Designed, not yet callable. Don’t build on it yet.
Not supported
UniLink doesn’t offer it. The reason is given next to it.
Paid plan
Works today on a paid plan. On Free it answers "This is available on a paid UniLink plan."