Servidor MCP
Todo lo que hacen las pantallas de captación de socios, como herramientas que un asistente de IA puede llamar, mediante el Model Context Protocol y con su clave de API.
https://www.getaff.org/api/mcpStreamable HTTP · 2025-11-25Punto de acceso
Una URL, transporte Streamable HTTP (especificación MCP 2025-11-25; se aceptan clientes 2025-06-18, 2025-03-26 y 2024-11-05). Sin estado: cada petición lleva su propia clave, las respuestas son JSON simple y el servidor no abre ningún flujo hacia el cliente.
Autenticación y ámbitos
Envíe Authorization: Bearer gaff_live_…: las mismas claves, ámbitos y límites que la API REST. El descubrimiento (initialize, tools/list) responde sin clave para que un cliente pueda mostrar las herramientas; cada llamada a una herramienta la requiere. Una herramienta cuyo ámbito falta en la clave devuelve un error legible por el asistente. Cree una clave propia para cada asistente, solo con los ámbitos necesarios.
Conectar un cliente
Guarde la clave en una variable de entorno o en el almacén de secretos del cliente, nunca en un archivo de configuración compartido.
Claude Code
Un comando; la cabecera se envía en cada petición.
claude mcp add --transport http getaff https://www.getaff.org/api/mcp \
--header "Authorization: Bearer $GETAFF_API_KEY"Claude Desktop
Mediante el puente mcp-remote, que añade la cabecera. Edite claude_desktop_config.json (Ajustes › Desarrollador) y reinicie Claude.
{
"mcpServers": {
"getaff": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://www.getaff.org/api/mcp",
"--header",
"Authorization:${GETAFF_AUTH}"
],
"env": {
"GETAFF_AUTH": "Bearer gaff_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}Conectores personalizados de claude.ai
Los conectores personalizados añadidos en claude.ai inician sesión con OAuth, que GetAff aún no ofrece (véase más abajo). Mientras tanto, use Claude Desktop con la configuración anterior, o Claude Code.
Cursor
En ~/.cursor/mcp.json (o .cursor/mcp.json en un proyecto). La clave se lee de su entorno.
{
"mcpServers": {
"getaff": {
"url": "https://www.getaff.org/api/mcp",
"headers": {
"Authorization": "Bearer ${env:GETAFF_API_KEY}"
}
}
}
}VS Code
En .vscode/mcp.json; VS Code pide la clave una vez y la guarda en su almacén de secretos.
{
"inputs": [
{
"type": "promptString",
"id": "getaff-key",
"description": "GetAff API key",
"password": true
}
],
"servers": {
"getaff": {
"type": "http",
"url": "https://www.getaff.org/api/mcp",
"headers": {
"Authorization": "Bearer ${input:getaff-key}"
}
}
}
}ChatGPT y la API de OpenAI
Los conectores añadidos en la aplicación ChatGPT inician sesión con OAuth: no disponible hasta que GetAff lo admita. Desde la API de OpenAI (Responses API o Agents SDK), declare GetAff como herramienta MCP remota con la cabecera, manteniendo las aprobaciones activadas.
from openai import OpenAI
import os
client = OpenAI()
response = client.responses.create(
model="gpt-5",
tools=[{
"type": "mcp",
"server_label": "getaff",
"server_url": "https://www.getaff.org/api/mcp",
"headers": {"Authorization": f"Bearer {os.environ['GETAFF_API_KEY']}"},
"require_approval": "always",
}],
input="List my GetAff sites, then find wedding creators in France for the first one.",
)
print(response.output_text)Cualquier otro cliente
Funciona cualquier cliente que hable Streamable HTTP y pueda enviar una cabecera. Los SDK de MCP (TypeScript, Python) aceptan la cabecera como opción.
Confirmación del coste
Las herramientas que gastan créditos de proveedor — search_partners con includeLive, find_emails — nunca gastan en la primera llamada:
- La primera llamada no gasta nada. Devuelve la estimación (créditos, proveedor, lo que queda hoy) y un
confirmToken. - El asistente muestra el coste al usuario y espera un sí explícito.
- La misma llamada, con los mismos argumentos más
confirmToken, se ejecuta y gasta como máximo los créditos confirmados. El token está ligado a la clave, a la herramienta y a los argumentos, y caduca a los 15 minutos; repetir una llamada confirmada reproduce su primer resultado en lugar de pagar dos veces.
La misma regla en REST
Los clientes REST confirman con un número: sin un confirmCost al menos igual a la estimación, la llamada responde 402 cost_confirmation_required con la estimación en error.details.estimate, y no gasta nada.
const base = 'https://www.getaff.org/api';
const headers = {
Authorization: `Bearer ${process.env.GETAFF_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(), // a retry never pays twice
};
const url = `${base}/v1/sites/${siteId}/partner-search`;
let res = await fetch(url, { method: 'POST', headers, body: JSON.stringify({ includeLive: true }) });
if (res.status === 402) {
const { error } = await res.json(); // error.code === "cost_confirmation_required"
const credits = error.details.estimate.credits;
if (!(await askTheUser(`Spend about ${credits} credits?`))) return;
headers['Idempotency-Key'] = crypto.randomUUID();
res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ includeLive: true, confirmCost: credits }),
});
}
const { data } = await res.json();Herramientas
Cada herramienta llama a la misma operación que el punto de acceso REST correspondiente. Las indicaciones siguen la especificación MCP: los clientes las usan para decidir qué preguntar al usuario antes de ejecutar.
| Herramienta | Qué hace | Ámbitos | Indicaciones |
|---|---|---|---|
list_sites | List the GetAff sites of the account, with the affiliate programme each one runs. Call this first: every partner-search tool takes a siteId. | read | solo lectura |
get_site | One site: its programme, the criteria the next search will use, shortlist size, the last search, and what a live search would cost today. | read | solo lectura |
get_criteria | The partner-search criteria of a site (keywords, niches, platforms, countries, languages, audience bands, recency), those GetAff derives from the site, and the generated TOPIC TERMS the ranking matches (with the user corrections). Use correct_topic_term to fix a term. | read | solo lectura |
correct_topic_term | Correct one generated topic term of a site, as in the app "Terms used" panel: negative (off-topic, penalised), remove (no longer a match), restore (undo), dismiss (drop a suggestion). The next search ranks with it. | readwrite | escribe |
update_criteria | Change the partner-search criteria of a site. Each field given REPLACES the current one (send the full list you want); fields left out are kept. reset: true goes back to the derived criteria. Does not run a search: call search_partners next. | readwrite | escribe |
search_partners | Run ONE partner search for a site across every source: the GetAff creator index ranked for this programme, lookalikes of the shortlist, competitor findings and — with includeLive: true (Pro) — live creator-data providers. Returns merged, ranked creators with a fit score and per-source status. Free sources cost nothing. Live sources spend credits: the first call then returns only an estimate and a confirmToken; tell the user the cost, and only after they agree call again with the same arguments plus confirmToken. criteria changes apply to this run only. | readsearchspend* | escribe · de pago, confirmado · llama a servicios externos |
get_latest_results | The ranked results of the last partner search of a site (kept 30 days), paginated, optionally filtered by minimum fit score or source. No new search is run. | read | solo lectura |
explain_ranking | Why one creator of the latest search ranks where it does: rank, fit score (0-100) and its reasons (topic match, market, language, reach, recent activity, competitor evidence, similarity to the shortlist). | read | solo lectura |
shortlist_list | The creators selected for a site ("Ma sélection"), with their prospect status. | read | solo lectura |
shortlist_add | Add creators of the LATEST partner search to the site shortlist, by their key (e.g. "instagram:1784140"). Up to 50 per call; the shortlist holds 100. | readwrite | escribe |
shortlist_remove | Remove creators from the site shortlist by key. Prospects already created are kept. | readwrite | escribe · elimina datos |
shortlist_to_prospects | Turn shortlisted creators into private prospects (free: no credit spent; counts on the discovery quota). Without keys, every shortlisted creator not yet a prospect. To get e-mail addresses afterwards, use find_emails (paid). | readwrite | escribe |
find_emails | Paid e-mail lookups at the creator-data providers, for prospects still without an address (Pro). The first call returns only the estimate and a confirmToken: tell the user the cost, and only after they agree call again with the same ids plus confirmToken. Never replaces an existing address. | readspendspend* | escribe · de pago, confirmado · llama a servicios externos |
list_prospects | The private prospects of the account, most recently collected first, filtered by status, site, platform or whether they have an address. Paginated by cursor. | read | solo lectura |
get_prospect | One prospect: status, contact channel, address if known, provenance (where the data comes from). | read | solo lectura |
chat | Send one message to the GetAff partner-search assistant of a site (any language), e.g. "find wedding creators in Belgium with 10k-100k followers". It may change the criteria, run a free search, select creators or explain a rank. It never spends credits: a paid step comes back as pending — show the user its cost and, if they agree, call chat_confirm. One conversation per site; reset: true starts over. | readsearchwrite | escribe · llama a servicios externos |
chat_confirm | Run (decision "confirm") or drop (decision "cancel") the paid action a chat turn proposed. Confirming spends the credits shown in pending — only call it with "confirm" after the user explicitly agreed. Pending actions expire after 15 minutes. | readsearchwrite | escribe · llama a servicios externos |
competitors_get | The competitor list of a site, the last lookup summary, and where each competitor recruits in the GetAff directory. | read | solo lectura |
competitors_set | Replace the competitor list of a site (up to 5 domains, optional brand name). Then competitors_run finds who promotes them. | readwrite | escribe |
competitors_run | Look for public creators whose videos link to, or give a coupon for, the site competitors. Confirmed promoters become prospects (discovery quota). No credit of the user is spent; at most two runs an hour; takes up to two minutes. | readsearchwrite | escribe · llama a servicios externos |
competitors_latest | The last competitor lookup of a site with its findings and their public evidence (video links, coupons). | read | solo lectura |
creators_search | Search the GetAff index of public creator profiles with filters (text, platforms, countries, niches, languages, audience, engagement, activity). Counts one of the plan index pages per day. rank: "fit" ranks by fit for the user programme. For a programme-aware search across every source, prefer search_partners. | readsearch | solo lectura |
get_creator | One creator of the index, by platform and platform id or handle. | read | solo lectura |
lookalikes | Index creators similar to seed creators — given by key parts (creators), handles or profile URLs (handles), or the user accepted creator prospects (accepted: true). | readsearch | solo lectura |
list_found_creators | The private library of creators that live providers already returned to this account ("Found creators"): reusable without spending credits again, with the sites each was found for and its fit. Filter by platform, niche, country, language, audience band, text or site. | read | solo lectura |
found_to_prospects | Turn creators of the found library into private prospects, by key (free: no credit spent; counts on the discovery quota). | readwrite | escribe |
list_mailboxes | The mailboxes connected in GetAff that outreach sequences can send from (connecting one is done in the app). | read | solo lectura |
list_sequences | The outreach sequences of the account and the state of each of their three steps. Read-only. | read | solo lectura |
enrol_in_sequence | Schedule the three-step outreach sequence (opening + two follow-ups) for ONE prospect, from a connected mailbox, with every check GetAff makes: valid and unsuppressed address, the recipient country compliance regime (pass the attestations that apply), complete sender settings, a published programme. E-mails are then sent by GetAff at the scheduled times — confirm with the user before calling. Without draft, the draft saved in GetAff for this prospect is used. | readwrite | escribe · llama a servicios externos |
- Gastar créditos sin un token de confirmación emitido para esa llamada exacta.
- Enviar un correo:
enrol_in_sequenceprograma una secuencia con todos los controles de la aplicación (cumplimiento, lista de exclusión, ajustes del remitente); GetAff la envía después desde su buzón. - Aceptar una sesión de navegador: solo la clave de API autentica, un navegador con sesión iniciada no concede nada.
- Devolver una clave, un token o una credencial de plataforma, en ninguna herramienta.
- Hacer pasar el texto de un creador por instrucciones: nombres, usuarios y biografías proceden de perfiles públicos y se marcan como datos de terceros en cada resultado.
Ejemplos
Una llamada JSON-RPC en bruto con curl, y luego la misma con los SDK oficiales.
curl -s https://www.getaff.org/api/mcp \
-H "Authorization: Bearer $GETAFF_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":"search_partners",
"arguments":{"siteId":"Wq3b9ZK1","includeLive":true}}}'
# → structuredContent.status = "confirmation_required", with the estimate
# and a confirmToken. Nothing was spent. After the user agrees:
# same call, "arguments":{"siteId":"Wq3b9ZK1","includeLive":true,"confirmToken":"gcf_…"}import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
const transport = new StreamableHTTPClientTransport(new URL('https://www.getaff.org/api/mcp'), {
requestInit: { headers: { Authorization: `Bearer ${process.env.GETAFF_API_KEY}` } },
});
const client = new Client({ name: 'my-agent', version: '1.0.0' });
await client.connect(transport);
const { tools } = await client.listTools();
const sites = await client.callTool({ name: 'list_sites', arguments: {} });
console.log(tools.map((t) => t.name), sites.structuredContent);import asyncio, os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
headers = {"Authorization": f"Bearer {os.environ['GETAFF_API_KEY']}"}
async with streamablehttp_client("https://www.getaff.org/api/mcp", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
print([t.name for t in tools.tools])
sites = await session.call_tool("list_sites", {})
print(sites.structuredContent)
asyncio.run(main())OAuth: todavía no
La especificación de autorización de MCP (OAuth 2.1 con registro dinámico de clientes) es lo que usan los conectores de claude.ai y ChatGPT para iniciar sesión. GetAff aún no la implementa; cuando lo haga, las mismas herramientas estarán disponibles para esos conectores sin pegar una clave. Mientras tanto, las claves de API son el único acceso, revocables en cualquier momento desde /docs/keys.