Affilio MCP: The Complete Tool Reference for AI Agents and IDEs
Affilio exposes a hosted, remote Model Context Protocol server at mcp.affilio.link. Once connected, any MCP-compatible client — Claude, Cursor, Windsurf, or your own agent — can shorten links, manage products, and update your storefront on your behalf, using natural language instead of REST calls.
MCP access is now available on every plan, not just Professional — what changes by tier is which tools you can call and whether you can write, not whether you can connect at all.
This guide is the technical reference: what each tool does, which plan it requires, how authentication works, and how to wire it into the client you're already using.
How mcp.affilio.link is different from a typical MCP server
No installation needed — connect any MCP-compatible client with just a URL and an Authorization header. There's no local process to spawn, no npx package to install, and nothing to run on your machine.
The tradeoff of a hosted server is that it can't lean on the implicit trust of "you installed this on your own laptop" — most of these tools need proof of who you're acting on behalf of, which is what the API key is for. Two tools are the exception; see below.
What each plan gets
| Plan | API key | Tools you can call | Notes |
|---|---|---|---|
| Free | None — fully unauthenticated, no account required | shorten_url, generate_qr only | Rate-limited to 100 calls/min per IP. Not tracked in your Affilio account. |
| Boost | Read-only key, generated in the app | All get_* / list_* tools | Write tools (create_*, update_*, archive_*, add_*, set_*) return a plan_restriction error telling you to upgrade. |
| Professional | Full read-write key, generated in the app | All 17 tools | No restrictions. |
Authentication: your API key
Boost and Professional tool calls to mcp.affilio.link require a Bearer token:
Authorization: Bearer <your-api-key>Boost and Professional users generate a key from within the Affilio app. Keys are per-user and per-scope — a Boost key is read-only at the server regardless of what the client sends; a Professional key can read and write.
shorten_url and generate_qr are the exception — they require no key and no account at all, at any tier. That's intentional: the goal is zero friction — any MCP-compatible agent can shorten a link or generate a QR code through Affilio without any setup. The tradeoff is that anything created this way is disconnected from your account — use a Boost or Professional key if you want the link tracked.
If a request to an auth.-prefixed tool arrives with no key, or an invalid/expired one, the server returns an auth_error envelope rather than a generic HTTP failure (see the Error Envelope Reference below).
Treat your MCP API key like a password. Anyone with it can act on your account through any MCP client, up to whatever your plan allows.
Tool Reference
All 17 tools are listed below, grouped by what they operate on, with the minimum plan required to call each. Tools prefixed auth. require your Bearer token to resolve a specific user/org context (link or product ownership, store membership, etc.); shorten_url and generate_qr are the two tools available at every tier.
Read/write classification is enforced at the backend for every endpoint, not just decided in the MCP layer — the same 403 that blocks a write call from a Boost-scoped API key in the dashboard blocks it here. MCP's only job is translating that 403 into a message an LLM client can act on (see the Error Envelope Reference).
Utility — Free, Boost, Professional
shorten_url
All plans — no keyShorten any HTTP/HTTPS URL (works with affiliate URLs from Amazon, eBay, AliExpress, etc.). Rate limit: 100 calls/min per IP on anonymous calls.
| Param | Type | Description |
|---|---|---|
| url | str | Full HTTP/HTTPS URL to shorten |
generate_qr
All plans — no keyGenerate a QR code PNG for any URL.
| Param | Type | Description | Default |
|---|---|---|---|
| url | str | Full URL to encode in the QR code | — |
| color | str | Foreground/dot color, CSS hex | #000000 |
| background_color | str | Background fill color, CSS hex | #FFFFFF |
| transparent | bool | Render background as transparent PNG alpha | true |
| rounded | bool | Rounded/circular dot style instead of square pixels | true |
Links
auth.create_link
Professional (write)| Param | Description | Default |
|---|---|---|
| url | Full affiliate destination URL | — |
| title | Human-readable label; Affilio auto-fetches the page title if omitted | null |
| destination | Override redirect target (for split-testing or geo-redirect setups) | null |
auth.get_link
Boost + Professional (read)| Param | Description |
|---|---|
| link_id | Link identifier, from a prior create_link or list_links call |
auth.list_links
Boost + Professional (read)| Param | Description | Default |
|---|---|---|
| skip | Pagination offset (≥0) | 0 |
| limit | Page size (1–200) | 50 |
auth.update_link
Professional (write)| Param | Description | Default |
|---|---|---|
| link_id | Link to update | — |
| title | New title; omit = unchanged | null |
| target | New destination URL; omit = unchanged | null |
| labels | Comma-separated labels — replaces existing labels entirely | null |
auth.archive_link
Professional (write)Archiving stops the redirect but preserves all historical analytics.
| Param | Description |
|---|---|
| link_id | Link to archive |
auth.get_link_stats
Boost + Professional (read)Returns click counts and performance data for one link.
| Param | Description |
|---|---|
| link_id | Link to fetch stats for |
auth.list_links_ranked
Boost + Professional (read)| Param | Description | Default |
|---|---|---|
| skip | Pagination offset | 0 |
| limit | Page size (1–200) | 50 |
Products
In-app, Products/Store features are available on Boost and Professional. Via MCP, reading product data follows the same Boost-read / Professional-write split as everything else.
auth.create_product
Professional (write)| Param | Description | Default |
|---|---|---|
| name | Product display name for the storefront | — |
| url | Canonical product page URL | — |
| platform | One of: amazon, aliexpress, ebay, awin, shareasale, impact, cj, rakuten, etsy, walmart, target, bestbuy | — |
| description | Storefront description (plain text) | null |
| image_url | Publicly accessible HTTPS image URL | null |
auth.get_product
Boost + Professional (read)| Param | Description |
|---|---|
| product_id | From a prior create_product or search_products call |
auth.add_product_link
Professional (write)| Param | Description |
|---|---|
| product_id | Product to attach the link to |
| link_id | Affiliate link to attach |
Attaching a link to a product is what makes it appear on your storefront — there's no separate "publish to store" step.
auth.set_link_visibility
Professional (write)| Param | Description |
|---|---|
| link_id | Link to update |
| visibility | "public" or "private" |
Stores
auth.get_store
Boost + Professional (read)Returns full storefront config (name, layout, branding).
auth.list_store_products
Boost + Professional (read)| Param | Description | Default |
|---|---|---|
| skip | Pagination offset | 0 |
| limit | Page size (1–200) | 50 |
auth.update_store
Professional (write)| Param | Description | Default |
|---|---|---|
| name | New display name; omit = unchanged | null |
| description | New description; omit = unchanged | null |
| layout | "grid" or "list"; omit = unchanged | null |
Integrations & Cross-Market Search
auth.list_integrations
Boost + Professional (read)No parameters. Returns the connection status of every affiliate platform integration on your account. Call this before search_products if you're not sure which platforms are connected.
auth.search_products
Professional only| Param | Description | Default |
|---|---|---|
| query | Natural-language product search query | — |
| platform | amazon, aliexpress, or ebay — must have an active integration | — |
| limit | Max results (1–50) | 10 |
Workflow example: link → product → storefront
A typical agent workflow chains three or four calls (Professional plan, since it involves writes):
- Shorten the affiliate URL.
shorten_url(url="https://amazon.com/dp/B0XXXXXX?tag=yourtag")→ returns a short URL andlink_id. - Create a product to hold it.
auth.create_product(name="Sony WH-1000XM5", url="https://amazon.com/dp/B0XXXXXX", platform="amazon")→ returnsproduct_id. - Attach the link to the product.
auth.add_product_link(product_id=..., link_id=...). - (Optional) Confirm it landed.
auth.list_store_products()— this step works on Boost too, since it's read-only.
Error Envelope Reference
Every tool returns one of these standard error shapes when something goes wrong, instead of a bare HTTP status:
| Envelope status | Meaning |
|---|---|
| auth_error | Missing, malformed, or invalid API key / Bearer token. Free-tier callers trying an auth.-prefixed tool will see this — there's no key to present, so the call fails before reaching the plan check. |
| plan_restriction | You have a valid key, but it doesn't cover this call. In practice this currently means: a Boost (read-only) key calling a write tool. |
| validation_error | A parameter failed validation — wrong type, out-of-range value, malformed ID. |
| no_integrations_connected | Returned by search_products (and other platform-specific calls) when no affiliate platform credentials are configured for your org. |
| rate_limited | Call volume exceeded the 100/min per-IP limit on the unauthenticated Free tools. |
plan_restriction carries enough detail for a human or an LLM client to know exactly what to do next. For example, a read-only (Boost) key attempting a write tool receives "Write access requires the Professional plan" with the suggestion "Upgrade to Professional to use write operations over API/MCP."
A rate_limited response follows the same envelope shape as everything else:
{
"ok": false,
"status": "rate_limited",
"message": "Slow down and retry after the rate-limit window resets."
}Connecting your client
mcp.affilio.link speaks standard HTTP MCP, so configuration is just a URL plus an Authorization header — no local process to install or run.
Cursor / Windsurf
Most current versions support remote HTTP MCP servers directly in their MCP config:
{
"mcpServers": {
"affilio": {
"url": "https://mcp.affilio.link",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}If your client version only supports local (stdio) servers, use the mcp-remote bridge instead (see below).
Claude Code / Claude Desktop
Claude Code currently has a known issue where custom headers declared in .mcp.json aren't reliably forwarded on tool-call POST requests — only on the initial handshake. If your connection authenticates but individual tool calls fail with auth_error, this is almost certainly why.
The reliable workaround is the mcp-remote npm bridge, which proxies your stdio client to the remote server and consistently attaches custom headers on every request:
{
"mcpServers": {
"affilio": {
"command": "npx",
"args": [
"mcp-remote",
"https://mcp.affilio.link",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer YOUR_API_KEY"
}
}
}
}(Note the env-var form has no spaces around the colon after Authorization — that's an mcp-remote quirk, not an Affilio one.)
A note on Claude.ai's web Connectors: the one-click "Connect" picker in Claude.ai's web interface uses OAuth, and a native Affilio listing there is on our roadmap but not live yet. For now, the supported path is Claude Code or Claude Desktop with the config above.
Discovery via glama.ai
Affilio is listed in the glama.ai MCP server registry — you can inspect the full tool schema, test calls, and find connection instructions there.
Questions or issues
If a tool call returns an envelope you don't recognize, or a client integration above doesn't match what you're seeing, reach out — this guide will be updated as the MCP surface grows.
Read the announcement on the Affilio blog.