@affitor/mcp
A Model Context Protocol (MCP) stdio server for Affitor.
It exposes Affitor's affiliate-tracking capabilities as MCP tools so AI agents — Claude Desktop, Cursor, and any other MCP client — can report clicks, leads, sales and refunds, and poll integration readiness, directly as tool calls.
Under the hood it wraps the consolidated server client @affitor/sdk/server (the Affitor class). Authentication is your program API key, supplied via the AFFITOR_API_KEY environment variable.
Add it to your MCP client
Add this to your client's MCP server config (e.g. claude_desktop_config.json for Claude Desktop, or .cursor/mcp.json for Cursor):
Restart your client and the affitor tools will be available to the agent.
Environment variables
If AFFITOR_API_KEY is not set, the server prints a clear message to stderr and exits.
Tools
Every tool carries MCP annotations (readOnlyHint, destructiveHint, idempotentHint), so a client can ask before a write. affitor_track_sale and affitor_track_refund are marked destructive and only exist with AFFITOR_MCP_WRITE=1.
Inputs
affitor_readiness
forceRecheck?: boolean — force a fresh server-side recheck instead of the cached verdict.
affitor_track_lead (one of customerExternalId / clickId is required)
customerExternalId?: string — your own user id; binds this customer to the click.
clickId?: string — Affitor click id (from the affitor_click_id cookie).
email?: string
testMode?: boolean — record a test lead (is_test).
affitor_track_sale (one of customerExternalId / clickId is required)
customerExternalId?: string — your own user id; resolves attribution (no clickId needed once bound at lead time).
clickId?: string
amount: number — sale amount in integer cents (e.g. 4999 = $49.99).
invoiceId: string — idempotency key (your invoice / transaction id).
currency?: string — ISO currency code (default USD).
saleType?: "payment" | "subscription"
isRecurring?: boolean
subscriptionId?: string
subscriptionInterval?: "monthly" | "quarterly" | "annual"
testMode?: boolean — record a test sale (is_test, no commission), sent as transaction test_<invoiceId> so it never blocks the real sale with the same invoice.
affitor_track_refund
invoiceId: string — the sale's idempotency key (the invoiceId you passed to affitor_track_sale).
refundAmountCents?: number — integer cents. Omit (or 0) = full refund → commission reversed; partial → refunded.
refundReason?: string
testMode?: boolean — dry run: returns the refund that would be sent and calls nothing (the API has no test refunds).
affitor_track_click (all optional)
affiliateUrl?: string
pageUrl?: string
referrerUrl?: string
existingClickId?: string
affitor_get_integration_plan
framework: "next-app" | "next-pages" | "fastify" | "express" | "node" | "unknown" — the detected app framework; determines where trackSale is injected.
provider?: "stripe" | "polar" | "lemonsqueezy" | "paddle" | "unknown" — the detected payment provider (default stripe).
mode?: "stripe_connect" | "s2s" — payment-tracking mode (default stripe_connect). stripe_connect = Connect autocaptures the sale (metadata only, no trackSale); s2s = inject trackSale in your webhook. Returns { steps, recipe }.
affitor_run_verification (no input)
- Fires the synthetic verification chain and returns the parsed result. On a rate limit it returns
{ http_status: 429, retry_after_seconds, … } rather than throwing — back off and retry.
Each tool returns the Affitor API's JSON payload as text content. On a failed request (a thrown error or an { ok: false } envelope) the tool returns an MCP error result with the message.
License
MIT