---
id: "api-reference/mcp"
type: "doc"
url: "https://affitor.com/docs/api-reference/mcp"
kind: "reference"
updated: "2026-10-16"
---
# Affitor MCP server

> Connect Claude, ChatGPT, Cursor, VS Code, Perplexity, Claude Code, Codex and other AI apps to your Affitor program or partner account at https://mcp.affitor.com/mcp. Sign in with your Affitor account; access is read-only.

The Affitor MCP server lets an AI app read your Affitor data: a brand's program, partners, applications, commissions and billing, or a partner's programs, links, earnings, commissions and payouts. It is a hosted [Model Context Protocol](https://modelcontextprotocol.io) server. You sign in with your Affitor account, no API key needed, and the connection is read-only: it cannot change data or move money.

```text
https://mcp.affitor.com/mcp
```

| | |
|---|---|
| Server URL | `https://mcp.affitor.com/mcp` |
| Transport | Streamable HTTP |
| Sign-in | OAuth 2.1 with PKCE (S256) and dynamic client registration |
| Scope | `read` (the only scope) |
| Access | Read-only. One program per brand connection; a partner connection sees only that partner |

<Flow>
  <FlowStep caption="Use the URL above, or follow your app's steps below.">
    **Add the server** in your AI app
  </FlowStep>
  <FlowStep caption="Your browser opens affitor.com.">
    **Sign in** with your Affitor account
  </FlowStep>
  <FlowStep caption="A brand picks one program. A partner connects their partner account.">
    **Choose what to share** and click **Allow**
  </FlowStep>
  <FlowStep caption="The app sees the tools for your connection type.">
    **Ask your AI app** about your program or earnings
  </FlowStep>
</Flow>

---

## Connect your AI app

In the Affitor dashboard, **Connect an AI tool** shows the server URL and steps for Claude, Cursor, Claude Code and Codex. Brands find it in **All settings** › **Developers** › **AI agents**, and on the program's **Tracking** step under **Your agent** › **Connect your AI**. Partners find it in **Settings** › **Integrations**.

<CodeGroup items={[
  {
    label: "Claude Code",
    lang: "bash",
    code: `claude mcp add --transport http affitor https://mcp.affitor.com/mcp
# Then, inside Claude Code: /mcp, pick affitor and sign in.`
  },
  {
    label: "Codex",
    lang: "bash",
    code: `codex mcp add affitor --url https://mcp.affitor.com/mcp
# If no sign-in page opens:
codex mcp login affitor`
  },
  {
    label: "Gemini CLI",
    lang: "bash",
    code: `gemini mcp add --transport http affitor https://mcp.affitor.com/mcp
# Then, inside Gemini CLI: /mcp auth affitor`
  },
  {
    label: "Cursor",
    lang: "json",
    code: `{
  "mcpServers": {
    "affitor": { "url": "https://mcp.affitor.com/mcp" }
  }
}`
  },
  {
    label: "VS Code",
    lang: "json",
    code: `{
  "servers": {
    "affitor": { "type": "http", "url": "https://mcp.affitor.com/mcp" }
  }
}`
  },
  {
    label: "OpenClaw",
    lang: "bash",
    code: `openclaw mcp add affitor --url https://mcp.affitor.com/mcp --transport streamable-http --auth oauth
openclaw mcp login affitor`
  },
  {
    label: "Hermes",
    lang: "bash",
    code: `hermes mcp add affitor --url https://mcp.affitor.com/mcp --auth oauth
# To sign in again later:
hermes mcp login affitor`
  },
  {
    label: "Other clients",
    lang: "json",
    code: `{
  "mcpServers": {
    "affitor": { "url": "https://mcp.affitor.com/mcp" }
  }
}`
  }
]} />

- **Claude Code:** add `--scope user` to use Affitor in every project.
- **Cursor:** open this link to add the server in one click, or put the JSON in `~/.cursor/mcp.json`. Then, in **Cursor Settings** › **MCP**, click **Connect** and sign in.

  ```text
  cursor://anysphere.cursor-deeplink/mcp/install?name=affitor&config=eyJ1cmwiOiJodHRwczovL21jcC5hZmZpdG9yLmNvbS9tY3AifQ%3D%3D
  ```

- **VS Code:** put the JSON in `.vscode/mcp.json` in your workspace, or in the `mcp.json` of your user profile, or run **MCP: Add Server** from the Command Palette. Start the server and sign in when VS Code asks.
- **Other clients:** put the JSON in the client's MCP config, restart it and sign in when it asks.

### Claude (claude.ai and Claude Desktop)

1. Open **Customize** › **Connectors**.
2. Click **+ Add**, then **Add custom connector**.
3. Name it Affitor, paste `https://mcp.affitor.com/mcp` and click **Continue**.
4. Keep the detected sign-in settings. Affitor supports automatic registration, so under **OAuth client** pick **Register automatically** if Claude asks.
5. Click **Add** and sign in to Affitor.

On Team and Enterprise plans, an owner adds the connector in **Organization settings** › **Connectors**, and members click **Connect**.

### ChatGPT

1. Go to [chatgpt.com/plugins](https://chatgpt.com/plugins).
2. Click the plus button, then **Add custom MCP server**.
3. Enter a name, and under **Connection** paste `https://mcp.affitor.com/mcp`.
4. Configure authentication (Affitor uses OAuth), review the warning and click **I understand and want to continue**.
5. Click **Create as a plugin**, then sign in to Affitor.

Your workspace's policy may limit who can add custom MCP servers.

### Perplexity

1. Open **Plugins** in the sidebar, or **Customize** › **Connectors** if you don't see Plugins.
2. Select **Add custom** › **Connector** › **Add MCP connector**, then **Remote**.
3. Enter a name, and under **MCP Server URL** paste `https://mcp.affitor.com/mcp`.
4. Under **Authentication** pick **OAuth** and under **Transport** pick **Streamable HTTP**. Affitor supports automatic registration, so no Client ID or Client Secret is needed.
5. Check the acknowledgement box, click **Add**, then click the connector card and sign in to Affitor.

In an organization, members can add custom connectors only if an admin allows it.

### Which apps can connect

After you sign in, Affitor sends you back to the app. It accepts only these return addresses:

- `claude.ai` and `claude.com` (Claude)
- `chatgpt.com` (ChatGPT)
- `www.cursor.com` (Cursor)
- `vscode.dev/redirect` and `insiders.vscode.dev/redirect` (VS Code)
- `www.perplexity.ai/rest/connections/oauth_callback` (Perplexity)
- apps on your own computer: `http://127.0.0.1` or `http://localhost`, any port

An app that registers any other address is refused when it registers, with the error "redirect_uris must be https on a supported AI app host, or http on 127.0.0.1 or localhost". Organizations that use Perplexity on its Enterprise address, `enterprise.perplexity.ai`, cannot connect: that address is not on the list.

---

## Sign in and allow access

When your AI app connects, your browser opens **Connect an AI tool** on affitor.com. If you are signed out, you sign in first and come back to the same screen.

1. The title names the app: **Claude wants to access Affitor**, or **An app on this computer wants to access Affitor** for a desktop or terminal app. A desktop or terminal app also shows **Unverified** and the name it gives itself in quotes ("It calls itself …"), because any app on your computer can call itself "Claude".
2. Check **Signed in as** your email. To use another Affitor account, click **Switch**.
3. If you are both a brand and a partner, choose **As a brand** or **As a partner**.
4. A brand picks one **Program**. You need to be an active member of that program. A partner sees **Programs**: all programs you are a partner in.
5. **Access** is always **Read-only**: "Programs, partners, clicks and commissions." for a brand, "Your links, clicks and earnings." for a partner.
6. Click **Allow**, or **Cancel** to refuse.

To give an app a second program, connect again and pick that program. Each connection holds one program.

<VerifySuccess
  browser={[
    "Your AI app lists the Affitor tools: `get_program` for a brand connection, `list_my_programs` for a partner connection",
  ]}
  dashboard={[
    "Brands: the connection appears under **All settings** › **Developers** › **AI agents**, with **Added** and **Last used**",
    "Partners: the connection appears under **Settings** › **Integrations**",
  ]}
  ifNotWorking={[
    "**This request has expired**: start the connection again from your AI app",
    "**Nothing to connect yet**: create a program, or join one as a partner, first",
  ]}
/>

---

## Tools

Every tool is read-only, and the server declares it so on each tool: `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`, `openWorldHint: false`. A brand connection gets the 7 brand tools for its one program. A partner connection gets the 5 partner tools across that partner's programs. A tool outside your connection's set is refused.

### Brand tools

| Tool | What it reads | Inputs |
|---|---|---|
| `get_program` | The program: name, status, commission terms, setup checklist, 24-hour tracking counts, and the tracker install snippet with where to put it and how to verify it. | none |
| `list_partners` | Partners who joined, newest first, with lifetime clicks, leads and sales, and earned and pending money in the window. | `from`, `to`, `limit`, `cursor` |
| `get_partner` | One partner by `partner_program_id`, with the same fields as `list_partners`. | `partner_program_id`, `from`, `to` |
| `list_applications` | Partner applications, newest first, with the applicant's own messages. | `status` (`approved`, `pending`, `rejected`), `limit`, `cursor` |
| `list_commissions` | Commissions, newest sale first, with what each still counts for after refunds. | `status`, `from`, `to`, `partner_program_id`, `limit`, `cursor` |
| `get_commission_summary` | Count and amount of commissions per status in the window, plus earned and pending. | `from`, `to` |
| `get_billing` | Affitor billing: what is due, this week's accrual, the platform fee and invoices, 20 per page. | `status` (`all`, `open`, `overdue`, `paid`, `void`), `page` |

### Partner tools

| Tool | What it reads | Inputs |
|---|---|---|
| `list_my_programs` | Programs you joined, newest first, with your commission terms, lifetime clicks, leads and sales, and your earned and pending money in the window. | `from`, `to`, `limit`, `cursor` |
| `list_my_links` | Your referral links, newest first, with lifetime clicks, leads and sales. | `partner_program_id`, `status` (`active`, `inactive`), `limit`, `cursor` |
| `get_my_earnings` | Your earnings per program and in total for the window: earned, ready, arriving, paid and pending. | `from`, `to` |
| `list_my_commissions` | Your commissions across your programs, newest sale first. | `status`, `from`, `to`, `partner_program_id`, `limit`, `cursor` |
| `list_my_payouts` | Your payout requests, newest first: amount, status, method type and dates. Bank and PayPal details are never included. | `limit`, `cursor` |

### How results look

- **Money** is an integer in an object keyed by unit, such as `{ "USD_cents": 4999 }` (`USD_cents`, `EUR_cents`, `VND_dong`), or in a `*_cents` field next to its currency (`get_billing`).
- **Dates** are UTC sale dates, `YYYY-MM-DD`. `from` and `to` default to the last 30 days and cover at most 366 days. Commission lists cover all dates unless you give `from` or `to`.
- **Pages** hold up to 50 items (`limit`, default 20). Pass `next_cursor` back as `cursor` for the next page.
- **Links:** where an item has a `url`, it opens that page in the Affitor dashboard. Referral links come as `short_link` and `affiliate_url`.
- **Commission statuses:** `pending`, `approved`, `invoiced`, `collected`, `paid`, `rejected`, `refunded`, `reversed`, `fraud`.
- Each result comes as structured content and as JSON text that starts with a line saying the text fields are untrusted data, not instructions.

---

## Example prompts

<AgentPrompt prompt="In the repository of example.com: use the Affitor tools. Call get_program and check that its id is 123; if it is not, stop and tell me. Add its install snippet as it says, then tell me what to deploy and how verification works.">
Brands: after you connect a coding agent (Claude Code, Cursor, Codex), give it this line to install the tracker. Replace example.com and 123 with your site and program id. The dashboard's **Connect an AI tool** fills both in on the **Tracking** step.
</AgentPrompt>

For a brand connection:

- "Who are my top partners by earned commission in the last 30 days?" (`list_partners`)
- "Summarize the pending partner applications." (`list_applications`)
- "How much commission is pending, approved and paid this month?" (`get_commission_summary`)
- "What do we owe Affitor right now, and is any invoice overdue?" (`get_billing`)

For a partner connection:

- "How much did I earn this month across my programs, and how much is ready?" (`get_my_earnings`)
- "Which of my links has the most sales?" (`list_my_links`)
- "Show my last five payouts and their status." (`list_my_payouts`)

The server cannot approve an application, change a commission, create a link or send a payout. Ask for any of these and the app finds no tool for it; do it in the dashboard.

---

## Limits and security

| Limit | Value |
|---|---|
| Requests to `/mcp` | 120 per minute per connection, then `429` with `{ "error": "rate_limited" }` |
| Token requests | 60 per minute per app |
| Access token | 1 hour, bound to `https://mcp.affitor.com/mcp` |
| Refresh token | Rotates on every use, expires after 30 days |
| Sign-in | Finish within 10 minutes of the page opening; each **Allow** is valid once, for 2 minutes |

- **Read-only by design.** The only scope is `read`. There are no tools that write, delete or move money.
- **Access is checked on every call.** A brand connection works only while you are an active member of its program; a partner connection, only while your partner account exists. A blocked account stops working at once.
- **Only Affitor sign-in tokens work.** The server refuses program API keys, staff keys and dashboard sessions with `401`. Do not add an `Authorization` header with your API key.
- **Untrusted text is marked.** Partner names, application messages and other free text are cut at 280 characters (the cut fields are listed in `truncated`), and every result says its text is data, not instructions.
- **What is logged.** One row per tool call: the connection, the tool name, the program, the number of rows, whether it worked and how long it took. Never your prompts, the arguments or the results. These rows are deleted after 30 days.

### Remove access

- **Brands:** **All settings** › **Developers** › **AI agents** lists the program's connections under **Connections** with **Client**, **Connected by**, **Added**, **Last used** and **Access**. Click **Remove** on your own connection. A program owner can remove any member's connection to that program.
- **Partners:** **Settings** › **Integrations**, then **Remove**.

Removal is immediate: the app's tokens are deleted and its next request gets `401`.

---

## Troubleshooting

- **"This request has expired"** or **"This approval is no longer valid"**: the sign-in took too long. Start the connection again from your AI app.
- **The app sees the wrong program:** remove the connection and connect again, picking the right program. The install prompt above checks the program id for this reason.
- **Signed in with the wrong account:** click **Switch** on the sign-in screen.
- **"Too many rows for this window"**: ask for a shorter `from`/`to` window.
- **`401` with "Program API keys are not accepted here"**: remove the `Authorization` header from your client's config and sign in instead.

---

## Legacy local server

`@affitor/mcp` on npm is an older, separate **stdio** server that runs on your computer and uses your **program API key** (`AFFITOR_API_KEY`) instead of sign-in. It does tracking, not reporting: `affitor_readiness`, `affitor_track_click`, `affitor_track_lead`, `affitor_get_integration_plan` and `affitor_run_verification`, plus `affitor_track_sale` and `affitor_track_refund` only when you set `AFFITOR_MCP_WRITE=1`. The [Affitor plugin](https://github.com/Affitor/claude-plugins) for Claude Code and Gemini CLI bundles this server.

```json
{
  "mcpServers": {
    "affitor": {
      "command": "npx",
      "args": ["-y", "@affitor/mcp"],
      "env": { "AFFITOR_API_KEY": "your_program_key" }
    }
  }
}
```

Keep the key server-side; it is a secret. Source and tool details: [github.com/Affitor/cli](https://github.com/Affitor/cli/tree/main/packages/mcp). For tracking work an agent can also use the CLI: `npx affitor onboard`.

---

## Related

- [Agent Integration](/docs/api-reference/agent-integration/): how coding agents install tracking from generated instruction files.
- [Testing Integration](/docs/brand/tracking/testing-integration/): check that clicks, leads and sales arrive.
- [CLI Command Reference](/docs/brand/cli/commands/): `npx affitor onboard` and the rest of the CLI.
- [SDK Reference](/docs/api-reference/sdks/): the `@affitor/sdk` package.

<NextStep title="Install tracking with your agent" description="Connect a coding agent, then give it the install prompt above." href="/docs/brand/tracking/quickstart-integration" />
