# MCP server

> Connect Claude, ChatGPT, Claude Code or Cursor to your Affilyflow account – setup, sign-in, the 23 tools, prompts and limits.

The MCP server lets your AI assistant work directly with your Affilyflow account: find programs, read the store's rules, search products, create tracking links and fetch your clicks, sales, pages and balance – inside the conversation. The tools use the same functions as the dashboard and the [REST API](https://www.affilyflow.com/docs/en/affiliate/rest-api), so the numbers match.

The MCP server is for affiliates only.

## The address

```text title="MCP address"
https://app.affilyflow.com/api/mcp
```

The address is for an MCP client that sends POST requests. Opening it in a browser returns 405 Method Not Allowed – that is expected. Add the address as a connector in your assistant.

Before you start: you need an affiliate account, and you must have joined the programs you want links for. The assistant cannot join programs for you.

## Connect Claude

1. Open **Customize → Connectors** in Claude and choose **Add custom connector**.
2. Name the connector Affilyflow and paste the MCP address.
3. Choose **Connect**. Sign in to your Affilyflow account and approve the connection.
4. Enable Affilyflow under Connectors in the conversation. Ask the assistant to show your joined programs.

On a team account, an owner may need to add the connector to the organization first. See Anthropic's guide: [Get started with custom connectors](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp).

## Connect ChatGPT

1. Open ChatGPT on the web. Find **Developer mode** under Settings → Apps → Advanced Settings, if it is available for your account.
2. Create a custom app named Affilyflow. Paste the MCP address and choose OAuth as authentication.
3. Sign in to Affilyflow and approve the connection. On a work account, your administrator may need to grant access first.
4. Select Affilyflow in the conversation. Ask ChatGPT to show the programs you have joined.

> [!NOTE]
> ChatGPT connects through Developer mode. Access, and whether it can create links, depends on your plan, workspace and OpenAI's current features. See OpenAI's guide: [Developer mode and MCP apps in ChatGPT](https://help.openai.com/en/articles/12584461-developer-mode-and-mcp-apps-in-chatgpt).

## Connect Claude Code

Run the command in your terminal:

```bash title="Terminal"
claude mcp add --transport http affilyflow https://app.affilyflow.com/api/mcp
```

Then open Claude Code, type `/mcp`, choose Affilyflow and complete the sign-in in your browser. No API key is needed. Because Claude Code runs on your own computer, the approval page shows a warning – only allow it if you just started the connection yourself.

## Connect Cursor and other MCP clients

Clients that cannot sign in with OAuth use an API key. Create one under **AI og API** in the dashboard (see [REST API](https://www.affilyflow.com/docs/en/affiliate/rest-api#get-started)) and add it to the client's configuration:

```json title="mcp.json"
{
  "mcpServers": {
    "affilyflow": {
      "url": "https://app.affilyflow.com/api/mcp",
      "headers": { "Authorization": "Bearer afk_YOUR_KEY" }
    }
  }
}
```

## Sign-in and access

Claude, ChatGPT and Claude Code connect with a sign-in instead of a key (OAuth 2.1 with PKCE). The assistant sends you to Affilyflow's own sign-in and approval page. It shows the app's name and the address you will be sent back to, so you can check that it is the right app. The assistant gets access to the MCP server – it never gets your password.

| The assistant can | The assistant cannot |
|---|---|
| Read programs, rules, products, your links, sites, clicks, sales, balance and payouts | Join programs |
| Create, rename and archive links | Delete links or sites |
| Add and edit your sites | See or change bank, CPR, tax or address details or your profile |
| | Request a payout |

- An access token lasts one hour and is renewed automatically. The renewal lasts 60 days and rotates on every use.
- Access from a sign-in works only on the MCP server – not on the REST API.
- Under **AI og API** in the dashboard you see your connected apps and can disconnect them. API keys are revoked in the same place. A disconnected app stops working from its next request.

The data you fetch through the assistant becomes part of the AI service you use. Choose the account and workspace you want to use for your affiliate results.

## The tools

The server has 23 tools. Read tools change nothing. Write tools only create, edit or archive your own links and sites – no tool deletes anything. Tool descriptions are in English; data and error messages are in Danish.

### Programs and rules

| Tool | Does |
|---|---|
| `search_programs` | Searches all open programs – including ones you have not joined – with commission, cookie window, approval period, channels, rules, network EPC and join link. |
| `list_programs` | The programs you have joined, with the saved rules and the store guidelines. |
| `get_program` | One program in depth: description, guidelines verbatim, today's rules and upcoming tightenings with date, discount codes, creatives with ready banner HTML, top products, network stats and your own numbers. |
| `check_compliance` | Checks a planned promotion against the program's measurable rules: channel, coupon and cashback sites, paid search, landing page and advertising label. Returns ok, warning or not allowed per rule. |

### Products and links

| Tool | Does |
|---|---|
| `search_products` | Searches the stores' products with price, stock, estimated commission and – for joined programs – a ready link to the product. |
| `create_link` | Creates or reuses a link with landing page, sub-ID, campaign, channel, UTM, name, HTML snippet and QR code. Write. |
| `create_links_batch` | Up to 50 links in one call with a result per link. Write. |
| `list_links` | Your links, newest first, optionally with numbers per link. |
| `get_link` | One link with numbers, the pages it performs on, the program status and today's rules. |
| `update_link` | Renames a link or changes its landing page or site label. Write. |
| `archive_link` | Hides a link from the list – it keeps working. Write. |
| `restore_link` | Shows an archived link again. Write. |

### Sites

| Tool | Does |
|---|---|
| `get_sites` | Sites measured from clicks with earnings, page-tracking coverage and suggestions for sites to add (`suggest_add`). |
| `get_pages` | The pages on your sites with clicks, sales, commission and trend. |
| `list_websites` | Your registered sites. |
| `add_site` | Adds a site. The numbers from clicks that already came from it are included. Write. |
| `update_site` | Fixes domain, name, niche or traffic – e.g. a domain missing its .dk. Write. |

### Results

| Tool | Does |
|---|---|
| `get_stats` | Clicks, sales and commission for a period – in total or by sub-ID, program, link, day, site, page, source, device or country, optionally compared with the previous period. |
| `list_sales` | Individual sales with status, rejection reason, approval date, refunds and the click. |
| `list_clicks` | Individual clicks with page, source, device, country and the sales the click led to. |

### Account and payouts

| Tool | Does |
|---|---|
| `get_account` | Your account, quota for new links and shortcuts to the dashboard. |
| `get_balance` | Balance, next payout day and what is missing. Read-only. |
| `list_payouts` | Your payouts with self-billing invoices. Read-only. |

Parameters and responses are the same as in the [REST API](https://www.affilyflow.com/docs/en/affiliate/rest-api). Every tool returns structured content plus the same JSON as text. `create_link` and `get_link` with `include_qr` return the QR code as an image.

## Prompts

In Claude and Claude Code (and other clients that support prompts) there are four ready-made workflows. Their text is in Danish, as it becomes your message in the conversation.

| Prompt | Does | Arguments |
|---|---|---|
| `monthly_report` | A monthly report with key numbers, best programs and pages, rejected sales and the next payout. | `month` (YYYY-MM, default: last month) |
| `find_programs_for_my_niche` | Finds the best open programs for your niche and explains their rules. | `niche`, `channel` |
| `optimize_links` | Reviews links, pages and page tracking and suggests improvements. | – |
| `build_product_links` | Finds products and creates links for them in one call. | `query` (required), `store`, `sub_id`, `count` (default 10, max 50) |

ChatGPT does not use prompts – the tools work without them.

## What the assistant is told

The server gives the assistant short instructions: how Affilyflow works, a typical workflow, that the store's rules and guidelines must be followed, that a discount code alone gives no commission, that advertising must be labelled under Danish marketing law, that amounts are in DKK excluding VAT, and that dates are in Danish time. How the assistant uses this is up to the model – check important numbers in the dashboard.

## Try it

- "Find the 10 sofas I earn most on at Nordlys Bolig and create links for them with sub-ID article-sofas-oct. Check the program rules first and give me the HTML for my site."
- "I want to make a TikTok video and run Google Ads on generic keywords for one of my programs. Am I allowed to? Show the store's guidelines and tell me if the rules are about to change."
- "Make a report for last month compared with the month before: best programs, pages and sources, rejected sales with reason, and when my next payout is."
- "Add the sites that send me clicks."

## Limits

| Limit | Value |
|---|---|
| Requests per minute | 120 per API key or connection |
| Write requests per minute | 60 per API key or connection |
| New links | 500 per 24 hours per account. A reused identical link does not count. |
| Links per batch | 50 |

## Errors

A tool that fails returns an error with a code the assistant can act on, for example:

| Code | Meaning |
|---|---|
| `not_joined` | You have not joined the program. Join in the dashboard and try again. |
| `channel_not_allowed` | The channel is not allowed in the program. |
| `landing_page_other_host` | The landing page is not on the store's domain. |
| `immutable_field` | Sub-ID, campaign and channel cannot be changed on an existing link. Create a new one, or use `?sid=`. |
| `daily_link_limit` | 500 new links in the last 24 hours. |
| `invalid_domain`, `duplicate_domain` | The domain is invalid or already on one of your sites. |
| `rate_limited` | Too many requests. Wait a moment. |

The full list is under [REST API → Error codes](https://www.affilyflow.com/docs/en/affiliate/rest-api#error-codes).

A 401 means the access has expired or been disconnected: connect the assistant again, or check that the API key has not been revoked.

## For client builders

- **Transport:** Streamable HTTP without sessions. Every POST stands alone, and there is no SSE stream on GET.
- **Protocol:** the server speaks `2025-11-25`, `2025-06-18`, `2025-03-26` and `2024-11-05` (with `initialize`) as well as the stateless `2026-07-28` (with `server/discover`, version and client capabilities in `params._meta`, and the headers `MCP-Protocol-Version`, `Mcp-Method` and `Mcp-Name`).
- **Access:** `Authorization: Bearer afk_…` (API key) or an OAuth access token. Without valid access the server returns 401 with `WWW-Authenticate: Bearer resource_metadata="…"`, which starts the sign-in in the client.

OAuth endpoints (Affilyflow is its own authorization server):

| Path | Purpose |
|---|---|
| `/.well-known/oauth-protected-resource/api/mcp` | Protected resource metadata (RFC 9728). |
| `/.well-known/oauth-authorization-server` | Authorization server metadata (RFC 8414). |
| `/oauth/authorize` | Sign-in and approval. |
| `/oauth/token` | Code exchange and refresh (`authorization_code`, `refresh_token`). |
| `/oauth/register` | Dynamic client registration. |
| `/oauth/revoke` | Revoke a token. |

PKCE with `S256` is required, the scope is `affiliate` (plus `offline_access` for refresh), and the token is bound to the resource `https://app.affilyflow.com/api/mcp`. Clients can identify themselves with a Client ID Metadata Document (a URL as `client_id`) or with dynamic registration. Redirect URIs must be https or loopback.

```bash title="Call a tool with an API key"
curl -X POST https://app.affilyflow.com/api/mcp \
  -H "Authorization: Bearer $AFFILYFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_stats","arguments":{"group_by":"program","compare":true}}}'
```

Kilde: https://www.affilyflow.com/docs/en/affiliate/mcp
