Security
How the MCP connection is secured: OAuth with PKCE, scoped keys, short-lived tokens, and the boundaries that never move.
Connecting a language model to your revenue data deserves a clear answer to "what is the worst it could do". This page is that answer.
The connection
The server speaks streamable HTTP at https://mcp.affiliaterail.com/mcp and authenticates with OAuth 2.1:
- Dynamic client registration: assistants register themselves; redirect addresses must be
https(or localhost for local tools). - PKCE required, S256 only, so an intercepted authorization code is useless.
- Short lifetimes: authorization codes live five minutes, access tokens one hour, refresh tokens thirty days. Codes and refresh tokens are strictly one-time; a replay is refused.
- Discovery at
/.well-known/oauth-authorization-serverand/.well-known/oauth-protected-resource, so any client that implements the MCP authorization spec finds the sign-in flow on its own.
Tools that can send a header directly (Claude Code, command-line clients) can skip OAuth and present the API key as a bearer token. Same scopes, same revocation.
The key stays with you
The sign-in page runs on our domain, not inside the assistant. You paste the API key once; it is checked and never stored, and the assistant receives a token bound to that key. Revoke the key under Settings, API keys and every token minted from it dies with it, on the next request.
Scopes decide what the assistant may do
mcp:read(or a broader read key): the sixteen read tools. Nothing can change.mcp:write(or a broader write key): additionally the twelve write tools, which cover the commission and application review queues, partner invitations, risk-flag resolution, the resources shelf, and sending a campaign or pausing a sequence. The scope is checked when tools are registered and again on every call.
A read key is enough for questions and is the right default. Add write only if you want the assistant acting in the review queues, and keep the write tools on "needs approval" in the assistant's own permissions, so every change is confirmed by a human. Four of them carry a destructive hint so clients default them to a confirmation prompt: rejecting a commission, rejecting an application, deleting a resource, and sending a campaign, which puts real mail in real inboxes and cannot be recalled.
What is never exposed
Some capability is left out of the MCP surface on purpose, whatever the key's scopes:
- Moving money: executing payout batches, editing payout connections, changing anyone's bank details.
- Minting credentials: creating or revoking API keys, webhook secrets, domain settings. A compromised assistant must not be able to issue itself a better key.
- Destruction: deleting partners, customers or programs.
- Billing and team: plan changes, role changes.
The dashboard, with a signed-in human, is the only place for those. This is the standing shape of the server, not a configuration you could relax by accident.
Everything is attributed
Every write an assistant performs goes through the same ledger paths as a dashboard click and is written to the audit log as the assistant's key, with before and after state. A commission approved over MCP shows in its history like any other approval, marked as such. There is no anonymous path.
Practical hygiene
- Name keys after the assistant that holds them ("Claude", "ChatGPT"), one key per assistant, so revocation is surgical.
- Removing a connector inside the assistant does not revoke the key; revoke it in Settings too.
- Treat prompt content as untrusted when the assistant also browses the web: the write tools' approval prompts are your backstop, so read them before confirming.