# Integraciones: MCP, API y webhooks

> Cómo conecta un negocio su Atenta con Claude, ChatGPT, Zapier, Make, n8n o su propio sistema: tokens con permisos, servidor MCP, API REST con OpenAPI y webhooks firmados.

Atenta es **abierta**: con **un token** el negocio conecta su Atenta a Claude, ChatGPT, Zapier, Make, n8n o a su propio código. Todo lo que se hace desde ahí es lo mismo que se haría en la app: mismos datos, mismas reglas, mismos límites.

- **Servidor MCP:** `https://mcp.atenta.mx` (Claude Code, Claude Desktop, Cursor, n8n y cualquier cliente MCP que mande una cabecera `Authorization`).
- **API REST:** `https://api.atenta.mx/v1` · OpenAPI 3.1 en `https://api.atenta.mx/v1/openapi.json` · documentación en `https://api.atenta.mx/v1/docs`.
- **Webhooks salientes:** Atenta avisa a tu URL cuando pasa algo (mensaje, escalación, pedido, cita, pago, llamada).

Las páginas por integración, en el lenguaje del dueño, están en [/integraciones](https://atenta.mx/integraciones).

## 1. El token

Se crea en la app → **Ajustes → Integraciones** («Conectar» en la tarjeta que quieras, con los permisos sugeridos). Tiene la forma `atk_<negocio>_<32 caracteres>` y **se enseña una sola vez**: guárdalo en un gestor de contraseñas o en una variable de entorno, nunca en un chat ni en un repositorio. Atenta guarda solo su hash y un prefijo para reconocerlo.

Permisos (elige solo los que necesite la integración):

| Permiso | Qué deja hacer |
|---|---|
| `leer_chats` | leer conversaciones, mensajes, respuestas rápidas y equipo |
| `escribir_chats` | contestar en un chat, tomar o devolver el control, fijar/archivar |
| `pedidos` | ver, crear y actualizar pedidos |
| `citas` | ver disponibilidad, agendar, mover y cancelar citas; fechas |
| `clientes` | buscar clientes, ficha, notas, etiquetas, seguimientos, segmentos, importar/exportar |
| `finanzas` | monedero, créditos y abonos, cobranza, links de pago, cobrar pedidos |
| `reportes` | reporte del mes, PDF, historial y métricas de llamadas |
| `base` | leer la base de respuestas, el menú, el menú del día, el catálogo y los ajustes; **proponer** correcciones (aprobarlas es del dueño, en la app) |
| `integraciones` | ver los tokens y administrar los webhooks |

Reglas que aplican siempre: **120 llamadas por minuto** por token; cada escritura queda en la bitácora del negocio con el nombre del token; lo que solo se hace desde la app (aprobar la base, encender, cobrar el plan, campañas, borrar) responde `403 solo_desde_la_app`; los teléfonos de los clientes llegan redactados; un token solo ve su negocio. **Revocar** un token corta la integración en el acto; «Revocar todo» (rojo, con la confirmación `REVOCAR TODO`) corta todas.

## 2. Claude Code y Claude Desktop

**Claude Code** (terminal). Guarda el token en una variable de entorno; la configuración lo referencia, no lo contiene:

```bash
export ATENTA_TOKEN="atk_..."   # el token que te dio la app
claude mcp add --transport http atenta https://mcp.atenta.mx --header 'Authorization: Bearer ${ATENTA_TOKEN}'
claude mcp list                 # atenta: https://mcp.atenta.mx (HTTP) - ✓ Connected
```

Luego, dentro de Claude Code: *«¿Qué conversaciones me necesitan hoy?»*, *«Agenda a Laura el jueves a las 5»*, *«Hazme el resumen del día»*. Las herramientas se llaman `atenta_chats_listar`, `atenta_pedidos_crear`, `atenta_citas_disponibles`… (solo aparecen las que tu token permite; `atenta_yo` dice cuáles).

**Claude Desktop** se conecta por archivo (`claude_desktop_config.json`) con el puente `mcp-remote`, que manda el token como cabecera. Los «conectores personalizados» de claude.ai autentican por OAuth y Atenta autentica por token, así que ese camino no aplica.

```json
{
  "mcpServers": {
    "atenta": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.atenta.mx", "--header", "Authorization: Bearer ${ATENTA_TOKEN}"],
      "env": { "ATENTA_TOKEN": "atk_..." }
    }
  }
}
```

Bloque genérico `mcpServers` para cualquier cliente que hable Streamable HTTP (Cursor, Windsurf, VS Code…):

```json
{
  "mcpServers": {
    "atenta": {
      "type": "http",
      "url": "https://mcp.atenta.mx",
      "headers": { "Authorization": "Bearer atk_..." }
    }
  }
}
```

### Lo que expone el servidor MCP

Solo aparecen las herramientas que el token permite (más `atenta_yo`, siempre).

| Herramientas | Permiso |
|---|---|
| `atenta_chats_listar` · `atenta_chats_leer` | `leer_chats` |
| `atenta_chats_escribir` · `atenta_chats_tomar_control` · `atenta_chats_devolver` | `escribir_chats` |
| `atenta_pedidos_listar` · `atenta_pedidos_crear` · `atenta_pedidos_actualizar` | `pedidos` |
| `atenta_pedidos_cobrar` · `atenta_finanzas_saldo` · `atenta_finanzas_recargar` · `atenta_finanzas_abonar` · `atenta_finanzas_cobranza` · `atenta_finanzas_link` | `finanzas` |
| `atenta_citas_listar` · `atenta_citas_disponibles` · `atenta_citas_crear` · `atenta_citas_mover` · `atenta_citas_cancelar` | `citas` |
| `atenta_clientes_buscar` · `atenta_clientes_ficha` · `atenta_clientes_nota` · `atenta_clientes_seguimiento` · `atenta_clientes_etiquetar` | `clientes` |
| `atenta_reporte_mes` · `atenta_llamadas_historial` | `reportes` |
| `atenta_base_leer` · `atenta_base_proponer` (queda como corrección propuesta; **aprobar es del dueño, en la app**) · `atenta_menu_leer` · `atenta_menu_dia_hoy` | `base` |

Recursos (con `base`): `atenta://base`, `atenta://menu-dia`, `atenta://catalogo`, `atenta://menu`, `atenta://horario`, `atenta://plan`. Prompts: `resumen_del_dia`, `que_contesto_a_los_escalados` (propone, no manda), `cobranza_de_hoy`.

## 3. ChatGPT

El camino que funciona con un token es un **GPT personalizado con Actions**: en «Acciones» importa el esquema desde `https://api.atenta.mx/v1/openapi.json`, autenticación **API Key**, tipo **Bearer**, valor `atk_...`. El esquema ya trae `servers`, `securitySchemes` y una operación por acción (`chats_listar`, `pedidos_crear`, `citas_disponibles`…). Instrucción sugerida para el GPT: *«Usa las acciones de Atenta para contestar con datos reales del negocio; nunca inventes precios ni horarios; si una acción falla, di el motivo que devuelve».*

Los conectores MCP personalizados de ChatGPT autentican por OAuth o sin autenticación; Atenta autentica por token, así que para ChatGPT se usa la vía de Actions.

## 4. Zapier, Make y n8n

Dos direcciones.

**a) Atenta → tu flujo (webhooks).** Se crean en **Ajustes → Integraciones → Webhooks** (URL `https` pública + eventos) o por la API con el permiso `integraciones`:

```bash
curl -X POST https://api.atenta.mx/v1/webhooks \
  -H "Authorization: Bearer $ATENTA_TOKEN" -H "Content-Type: application/json" \
  -d '{"url":"https://hooks.zapier.com/hooks/catch/123/abc","eventos":["pedido","cita","escalacion"]}'
```

La respuesta trae `secreto` (`whsec_…`, **una sola vez**). Cada evento llega como `POST` JSON:

```json
{ "evento": "pedido", "tenant": "mi-negocio", "ts": "2026-09-21T18:03:11.000Z",
  "datos": { "id": 812, "cliente_id": 41, "estado": "nuevo", "total": 250, "moneda": "MXN", "canal": "whatsapp", "nuevo": true } }
```

con las cabeceras `X-Atenta-Evento`, `X-Atenta-Entrega` (id único: sirve para no procesar dos veces) y `X-Atenta-Firma: t=<unix>,v1=<hmac>`. Para verificar: `v1 == HMAC_SHA256(secreto, t + "." + cuerpo_crudo)` y `|ahora − t| ≤ 300 s`. En Node:

```js
import { createHmac, timingSafeEqual } from "node:crypto";
export function firmaValida(secreto, cuerpoCrudo, firma) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(firma ?? ""); if (!m) return false;
  if (Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false;
  const esperado = createHmac("sha256", secreto).update(`${m[1]}.`).update(cuerpoCrudo).digest("hex");
  return esperado.length === m[2].length && timingSafeEqual(Buffer.from(esperado), Buffer.from(m[2]));
}
```

Eventos: `mensaje` (cada mensaje que entra o sale, con el mensaje completo), `escalacion` (Atenta pidió a una persona), `pedido` (nuevo o cambio de estado), `cita` (nueva, movida o cancelada), `pago` (link pagado o abono registrado), `llamada` (llamada con IA terminada). Reintentos: si tu URL no contesta 2xx, Atenta reintenta 3 veces (1 s, 5 s, 25 s); tras 20 fallos seguidos el webhook se apaga solo y lo ves en la app (con sus últimas entregas). Botón «Probar» = evento `ping`. Máximo 5 webhooks por negocio; solo URLs `https`.

En Zapier: *Webhooks by Zapier → Catch Hook* te da la URL; en Make: *Webhooks → Custom webhook*; en n8n: nodo *Webhook* (POST) y un nodo *Crypto* o *Code* para validar `X-Atenta-Firma`.

**b) Tu flujo → Atenta (API REST).** Cualquier ruta del negocio funciona en `https://api.atenta.mx/v1/…` con `Authorization: Bearer atk_...` (módulos *HTTP Request* / *Webhooks by Zapier → Custom Request*). Ejemplos:

```bash
# quién soy y qué puedo hacer
curl https://api.atenta.mx/v1/yo -H "Authorization: Bearer $ATENTA_TOKEN"
# pedidos nuevos
curl "https://api.atenta.mx/v1/crm/pedidos?estado=nuevo&limite=20" -H "Authorization: Bearer $ATENTA_TOKEN"
# huecos libres para agendar
curl "https://api.atenta.mx/v1/citas/disponibles?n=5" -H "Authorization: Bearer $ATENTA_TOKEN"
# agendar
curl -X POST https://api.atenta.mx/v1/citas -H "Authorization: Bearer $ATENTA_TOKEN" -H "Content-Type: application/json" \
  -d '{"inicio":"2026-09-25T17:00:00-06:00","nombre":"Laura","motivo":"corte","estado":"confirmada"}'
# contestar en un chat como persona del negocio
curl -X POST https://api.atenta.mx/v1/conversaciones/5214421234567/mensajes -H "Authorization: Bearer $ATENTA_TOKEN" -H "Content-Type: application/json" \
  -d '{"texto":"Ya salió tu pedido, llega en 20 minutos."}'
# reporte del mes
curl "https://api.atenta.mx/v1/reporte?mes=2026-09" -H "Authorization: Bearer $ATENTA_TOKEN"
```

Errores, siempre con `error` corto y `motivo` en humano: `401` token inválido o revocado · `403 sin_permiso` (dice qué permiso falta) · `403 solo_desde_la_app` · `404` no existe en este negocio · `409` estado que no lo permite (`fuera_de_ventana`, `saldo_insuficiente`…) · `422` datos incompletos (`campos`) · `429` más de 120 llamadas en un minuto (`Retry-After`). Cabeceras `X-RateLimit-Limit` y `X-RateLimit-Remaining` en cada respuesta.

## 5. Integradores (agencias)

Un token de integrador (`atp_…`, lo emite Kalia Code) da de alta negocios como lo hace el formulario de atenta.mx y lee su estado; nunca entra a los datos de un negocio (para eso está el token del dueño).

```bash
curl -X POST https://api.atenta.mx/v1/alta -H "Authorization: Bearer $ATENTA_INTEGRADOR" -H "Content-Type: application/json" \
  -d '{"negocio":"Taquería El Güero","giro":"fonda","whatsapp":"5214421234567","pais":"MX"}'
curl https://api.atenta.mx/v1/tenants -H "Authorization: Bearer $ATENTA_INTEGRADOR"
curl https://api.atenta.mx/v1/tenants/taqueria-el-guero/base -H "Authorization: Bearer $ATENTA_INTEGRADOR"
```

## 6. Seguridad, en corto

- El token solo existe en tu lado: Atenta guarda un hash. Si se filtra, revócalo en la app y crea otro.
- Todo viaja por HTTPS; las respuestas nunca traen secretos ni números completos de clientes.
- Cada escritura hecha con un token queda en la bitácora del negocio con el nombre del token.
- Las IA externas leen datos del negocio **solo** con un token que el dueño creó a propósito, con los permisos que eligió y mientras no lo revoque. El proveedor de esa IA es un subprocesador elegido por el propio negocio, como dice el [aviso de privacidad](https://atenta.mx/privacidad).
