Fairplug (sandbox)

Servidor MCP en fase piloto temprana para ofertas patrocinadas con divulgación prioritaria. search_offers devuelve ofertas con términos; get_tracked_link devuelve un enlace rastreado más un texto de divulgación obligatorio. Sandbox gratuito sin registro con datos ficticios. Tarifa abierta del 10% sobre comisiones validadas.

Servidor MCP alojado

npx add-mcp 'https://fairplug-mcp.fairplughq.workers.dev/sandbox/mcp'

Se instala en Claude Code, Codex, Cursor y más

Documentación

Fairplug MCP

Un servidor MCP que permite a los asistentes de IA mostrar ofertas patrocinadas de forma honesta: datos de oferta tipados, un enlace rastreado y un texto de divulgación que el asistente debe mostrar. Los desarrolladores que muestran la oferta reciben pago; los usuarios siempre saben que es contenido patrocinado.

Piloto temprano. Fairplug está en una etapa inicial. Las ofertas son datos de ejemplo ficticios, aún no hay anunciantes reales y no se mueve dinero real a través de este servidor. El sandbox es para probar la integración, no para generar ingresos.

Pruébalo ahora (sin registro, sin clave)

Sandbox público, solo lectura, datos ficticios, nada se rastrea ni se paga, límite de 60 solicitudes/min por IP:

https://fairplug-mcp.fairplughq.workers.dev/sandbox/mcp

Configuración del cliente (HTTP transmisible):

{ "mcpServers": { "fairplug-sandbox": { "url": "https://fairplug-mcp.fairplughq.workers.dev/sandbox/mcp" } } }

Clientes solo-stdio: npx mcp-remote https://fairplug-mcp.fairplughq.workers.dev/sandbox/mcp

Tarjeta del servidor: https://fairplug-mcp.fairplughq.workers.dev/.well-known/mcp/server-card.json

Inicio rápido (ejecutar localmente)

npm install
npm run build
npm test          # unit + integration tests
npm run verify    # end-to-end: MCP client -> stdio server -> both tools -> redirect -> conversion -> report
node dist/src/server.js   # MCP over stdio

Requiere Node >= 18 (Node >= 22 solo para despliegues wrangler). Verifica un despliegue remoto: npm run remote-check -- <base-url> - (solo sandbox) o <base-url> <mcp-token> <admin-token> (completo).

Herramientas

  • search_offers(query, category?, region?): búsqueda por palabras clave; category = travel | saas | retail o una subcategoría; region = código de país ISO (filtro de elegibilidad estricto). Cada resultado tiene sponsored: true, una etiqueta de divulgación y el nombre del patrocinador.
  • get_tracked_link(offer_id, agent_id, context?): devuelve una URL rastreada (firmada con HMAC, TTL de 15 minutos) y un disclosure_text obligatorio. En el sandbox, la URL es un marcador de posición no funcional y no se registra nada.

Reglas

Divulgación primero. Cada oferta es patrocinada y debe etiquetarse como tal, en el mismo mensaje que el enlace, usando el disclosure_text que devolvemos. Muestra como máximo una oferta patrocinada, junto con alternativas orgánicas. Sin divulgación, sin pago. La salida de la herramienta son datos tipados, nunca instrucciones para el modelo.

Tarifas. Fairplug toma el 10% de una comisión validada, con un mínimo de US$0.50, nunca más del 15% de la comisión (el tope gana en comisiones pequeñas: una comisión de US$2.00 paga US$0.30). Las tarifas de red se transfieren al costo. Ves cada número en el informe de libros abiertos. Solo cuentan las conversiones validadas. Sin tarifa sobre nada pendiente o revertido.

Honestidad del piloto temprano. Las ofertas semilla son ficticias; las conversiones aquí son simuladas; aún no se realizan pagos. Lo diremos claramente hasta que eso cambie.

Notas de seguridad

  • /mcp (privado) requiere un token de portador; el sandbox en /sandbox/mcp es separado, no almacena nada y no expone datos de informes/administración.
  • Nunca comprometas secretos. Configura FAIRPLUG_SIGNING_SECRET, FAIRPLUG_MCP_TOKEN, FAIRPLUG_ADMIN_TOKEN como variables de entorno o wrangler secret put. El secreto de firma predeterminado es un valor de desarrollo público.

Licencia

MIT, ver LICENSE.


Almacenamiento

JSONL de solo anexión en var/events.jsonl (anula el directorio con FAIRPLUG_DATA_DIR). Registra cada llamada de herramienta (ok o error), emisión de enlaces, clics (incluidos rechazados/duplicados) y conversiones. Compartido de forma segura por los procesos MCP, redirección y CLI.

CLI

node dist/src/cli.js record_conversion --click-id clk_... [--order-value 189.00] [--status validated|pending|reversed] [--network-fee 0.25]
node dist/src/cli.js report

record_conversion es una simulación (sustituto de un postback de anunciante/red). Requiere que el clic se haya registrado (abre primero la URL rastreada, p. ej. curl -i '<tracked_url>'). Las ofertas cpa_percent necesitan --order-value; las fijas/CPL usan el monto de pago de la oferta. Re-registrar el mismo clic reemplaza su estado (p. ej. reversed).

Informe por agente: llamadas, enlaces, clics únicos, conversiones (validadas/pendientes/revertidas), comisión bruta, tarifa de Fairplug, tarifas de red, pago neto. Solo las conversiones validadas cuentan para el dinero. Tarifa = 10% de la comisión validada, mínimo US$0.50, tope del 15% de la comisión; tarifas de red al costo. Neto = bruto - tarifa - tarifas de red.

Regla de comisiones pequeñas: el tope del 15% anula el mínimo de US$0.50. El mínimo excedería el tope para cualquier comisión inferior a ~US$3.33 (0.50 / 0.15), por lo que allí la tarifa es floor(15% x commission). Ejemplos: comisión de US$2.00 -> tarifa US$0.30 (no 0.50); US$1.00 -> 0.15; US$3.00 -> 0.45; US$4.00 -> 0.50 (el mínimo aplica desde ~US$3.34 hasta US$5.00, donde el 10% toma el control). Implementado en src/fees.ts, cubierto por test/core.test.ts. Interpretación asumida; confirma.

Límites conocidos / no implementado

  • Caso límite de tarifa: ver "Regla de comisiones pequeñas" arriba (el tope supera al mínimo; asumido, confirma).
  • Sin FX: los pagos no USD en la semilla (NZD) se tratan como equivalentes a USD en el informe.
  • El secreto de firma predeterminado es un valor de desarrollo público; configura FAIRPLUG_SIGNING_SECRET para cualquier uso más allá de local.
  • No construido: recibos de divulgación_mostrada (D5), puntuaciones de subasta/clasificación, límites de tarifa, claves API, libro mayor/reservas, ventanas de validación, integración real de red/postback, libro mayor de dinero real; el endpoint de conversión alojado es una simulación registrada por administrador, no un postback de red real, filtros de bot/IP. La búsqueda es puntuación simple de palabras clave, no BM25/embeddings.
  • El servidor de redirección de la configuración stdio solo se vincula a 127.0.0.1; usa la compilación HTTP/remota a continuación para enlaces que funcionen fuera de la máquina.

Remoto (HTTP transmisible)

Un proceso/Worker sirve POST /mcp (MCP HTTP transmisible, sin estado, respuestas JSON), GET /r/clk_... (registrador de clics), GET /health y GET /admin/report (solo si FAIRPLUG_ADMIN_TOKEN está configurado). Código compartido: src/handler.ts (Web Request -> Response).

Env: FAIRPLUG_REDIRECT_BASE (URL base pública usada en enlaces rastreados), FAIRPLUG_SIGNING_SECRET, opcional FAIRPLUG_MCP_TOKEN (Bearer requerido en /mcp), FAIRPLUG_ADMIN_TOKEN.

Node (cualquier host/VM/contenedor): FAIRPLUG_REDIRECT_BASE=http://127.0.0.1:8788 npm run start:http (PORT / FAIRPLUG_PORT, predeterminado 8788). Los eventos van a var/events.jsonl.

Cloudflare Workers (host gratuito recomendado): worker/index.ts + wrangler.jsonc. El estado es un Durable Object respaldado por SQLite (compatible con plan gratuito), tabla events. Prueba local, sin cuenta necesaria (wrangler requiere Node >= 22):

printf 'FAIRPLUG_SIGNING_SECRET=dev\nFAIRPLUG_MCP_TOKEN=test-token\nFAIRPLUG_ADMIN_TOKEN=admin-token\n' > .dev.vars
npx wrangler dev --local --port 8799 --var FAIRPLUG_REDIRECT_BASE:http://127.0.0.1:8799
npm run build && npm run remote-check -- http://127.0.0.1:8799 test-token admin-token

Configuración del cliente para desarrolladores: { "mcpServers": { "fairplug": { "url": "https://<host>/mcp", "headers": { "Authorization": "Bearer <token>" } } } } (o npx mcp-remote https://<host>/mcp --header "Authorization: Bearer <token>" para clientes solo-stdio).

Endpoints de libros abiertos (alojado + compilación Node)

Todo el dinero está en USD, 2 decimales. ADMIN = Authorization: Bearer <FAIRPLUG_ADMIN_TOKEN>. Los endpoints de administración devuelven 404 a cualquier otra persona (y si no hay token de administrador configurado).

  • POST /admin/agent-token (ADMIN) cuerpo {"agent_id":"my_agent"} -> {agent_id, token}. Así es como un desarrollador obtiene un token de informe por agente: Fairplug (admin) lo emite y lo entrega una vez. Solo se almacena un hash SHA-256 (tabla Durable Object agent_tokens; var/agent_tokens.json en Node), por lo que un token perdido no se puede recuperar, solo re-emitir; re-emitir rota (el token anterior deja de funcionar). El token solo otorga GET /report para ese agent_id.
  • POST /admin/conversion (ADMIN) cuerpo {"click_id":"clk_...","status":"validated|pending|reversed","commission":20.00,"network_fee":0.25,"order_value":189.00} (status predeterminado a validated, network_fee/order_value opcional). El click_id debe tener un enlace emitido y un clic registrado. Re-publicar el mismo click_id reemplaza su estado (p. ej. validated -> reversed). Sustituto de simulación para un postback de red.
  • GET /report?agent_id=my_agent con Authorization: Bearer <that agent's token> o el token de administrador -> JSON: clicks (único), links_issued, conversions {validated, pending, reversed: count + commission}, gross_commission_usd, fairplug_fee_usd, network_fees_usd, net_payout_usd, fee_policy y por conversión items para que cada número pueda re-derivarse. Solo las conversiones validadas cuentan para bruto/tarifa/neto; la tarifa se calcula por conversión (10%, tope del 15%, mínimo US$0.50, el tope gana para comisiones pequeñas); tarifas de red al costo.
curl -X POST $HOST/admin/agent-token -H "Authorization: Bearer $ADMIN" -H 'content-type: application/json' -d '{"agent_id":"my_agent"}'
curl -X POST $HOST/admin/conversion  -H "Authorization: Bearer $ADMIN" -H 'content-type: application/json' -d '{"click_id":"clk_...","commission":20,"network_fee":0.25}'
curl "$HOST/report?agent_id=my_agent" -H "Authorization: Bearer $AGENT_TOKEN"

Pruebas: test/http.test.ts (auth, validación, matemática de tarifas, rotación, aislamiento de tokens); npm run remote-check también las ejecuta cuando se le da un token de administrador.

Despliegue (Cloudflare)

  1. Cuenta gratuita de Cloudflare (solo correo, sin tarjeta). npx wrangler login (Node >= 22).
  2. Edita FAIRPLUG_REDIRECT_BASE en wrangler.jsonc a https://fairplug-mcp.<your-subdomain>.workers.dev.
  3. npx wrangler secret put FAIRPLUG_SIGNING_SECRET (aleatorio largo), FAIRPLUG_MCP_TOKEN, FAIRPLUG_ADMIN_TOKEN.
  4. npx wrangler deploy, luego npm run remote-check -- https://<host> <mcp-token> <admin-token>.
  5. No agregues un método de pago / Workers Paid; en Free, exceder los límites solo falla solicitudes, nada se cobra. Límites gratuitos: 100k solicitudes/día, DO SQLite 100k escrituras de filas/día (~cada llamada de herramienta escribe 1-3 filas, cada clic 1), 5 GB; se restablece a las 00:00 UTC.