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 17 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

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

Read (10)Edit (7)

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

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

Errors

  • A tool that fails returns a normal result with isError: true and a text message saying what went wrong (for example "Error: text must be 10000 characters or fewer.").
  • Some refusals are ordinary answers, not errors: "This is available on a paid UniLink plan.", "Link limit for your plan reached.", "Profile not found or access denied."
  • There are no stable error codes. Read the message and relay it to the person.
  • 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.
  • 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."