TimelinesAI MCP Server
TimelinesAI MCP Server
Servidor MCP (Model Context Protocol) que expone la API pública de TimelinesAI —el inbox de WhatsApp para equipos— a Claude. Pensado para desplegarse en Railway en modo solo lectura.
👉 Los pasos de despliegue están en DEPLOY-RAILWAY.md.
Qué hace
Da a Claude 12 herramientas para leer y operar el inbox: chats, mensajes, etiquetas, responsables, números conectados y equipo — más una herramienta genérica, una de descubrimiento, y un resumen agregado del inbox.
Herramienta | Endpoint |
| verifica el token, el workspace y las rejas |
| cualquier endpoint, cualquier método |
| sondea rutas y reporta cuáles existen |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| pagina |
Variables de entorno
Variable | Requerida | Default | Descripción |
| sí | — | Token de la API ( |
| en Railway |
|
|
| si | — | Secreto que protege el endpoint. Mínimo 32 caracteres |
| no | ver abajo |
|
| no |
| Reja aparte: enviar mensajes de WhatsApp |
| no |
| Para apuntar a otro host |
| no |
| Truncado de respuestas |
| no |
| Timeout en segundos |
| no |
| Railway lo inyecta solo |
Las tres rejas
Este MCP habla con personas reales. Un mensaje enviado por WhatsApp llega al teléfono de alguien en segundos y no se puede deshacer. Por eso hay tres candados independientes.
1. TIMELINES_READ_ONLY — el default depende del transporte
stdio(local): escrituras permitidas por default.http(remoto): escrituras bloqueadas por default.
Olvidar la variable en un despliegue público lo deja en solo lectura.
2. TIMELINES_ALLOW_SEND — la reja de envío
Apagada por default en los dos transportes, incluso en local. Aunque
habilites las escrituras, enviar mensajes sigue bloqueado hasta que pongas
TIMELINES_ALLOW_SEND=1.
La razón es la asimetría: cambiar una etiqueta, reasignar un chat o cerrarlo son acciones internas y reversibles. Mandar un WhatsApp a un cliente no lo es. No tiene sentido que compartan el mismo interruptor.
3. confirm=true — la reja por llamada
Todo envío exige confirm=true además de lo anterior, igual que borrar un
archivo, reconfigurar un webhook o revocar el acceso de un compañero. La
instrucción de la herramienta es explícita: primero muéstrale al usuario el
destinatario exacto y el texto exacto, y solo con su visto bueno se confirma.
Cada rechazo dice cuál de las tres rejas lo detuvo.
Autenticación del endpoint
El protocolo MCP no trae autenticación propia. En modo http, este servidor
exige Authorization: Bearer <MCP_AUTH_TOKEN> en cada request, o el secreto
embebido en la ruta (/s/<secreto>/mcp) para los connectors de Claude.
/healthz es la única ruta pública.
El servidor se niega a arrancar si MCP_AUTH_TOKEN falta o tiene menos de
32 caracteres.
Correr en local
pip install -r requirements.txt
# stdio (para Claude Desktop)
TIMELINES_API_TOKEN=tla_xxx python timelines_mcp.py
# http (como en Railway)
TIMELINES_MCP_TRANSPORT=http \
TIMELINES_API_TOKEN=tla_xxx \
MCP_AUTH_TOKEN=$(python3 -c "import secrets;print(secrets.token_urlsafe(48))") \
PORT=8000 python timelines_mcp.pyAl arrancar imprime en qué modo quedó:
[timelines-mcp] streamable-http on 0.0.0.0:8000 token=set read_only=True allow_send=False sending_enabled=FalseNotas sobre la API de TimelinesAI
Verificado contra la referencia pública (https://timelines.ai/docs/public-api-reference/overview):
Base:
https://app.timelines.ai/integrations/api, authAuthorization: Bearer <tla_...>.Los cuerpos van en JSON, no form-encoded.
Las respuestas vienen envueltas:
{"status":"ok","data":{...}}. Y hay fallos que llegan con HTTP 200 perostatus:"error"— este servidor los trata como error, no como éxito, porque si no un envío fallido se leería como enviado.Los errores traen detalle por campo:
{"status":"error","message":..., "error_code":...,"errors":[{"fields":["phone"],"msg":"..."}]}. Se muestran tal cual en el mensaje de error.Los filtros de varios valores van separados por coma en un solo parámetro (
label=vip,enterprise), no repetidos ni con corchetes. Pasar una lista de Python produce esa forma.El tamaño de página es fijo en 50 y no se puede cambiar. Verificado contra la API en vivo el 2026-08-25:
limit,per_page,page_size,size,count,takeyrowsse ignoran todos, y cada página llega con 50 registros. El único parámetro que hace algo espage, yhas_more_pagesen la respuesta dice si hay otra. Por eso las herramientas no exponen unper_page: sería un parámetro que aparenta ajustar y no ajusta nada.Para reducir el tamaño de una respuesta, entonces, no queda bajar la página: hay que filtrar más, o usar
fieldspara quedarte solo con las claves que necesitas. Los mensajes son el caso que más lo pide — un chat con 50 mensajes se pasa del límite de caracteres sin problema.fields=["uid","text", "from_me","timestamp"]deja lo esencial de una conversación en una fracción del tamaño.Ojo con los nombres de campo repetidos: un registro de mensaje trae su propia clave
data(un dict de metadatos), además deldatade la envoltura. Por esofieldsdecide qué podar por posición (lo que está dentro de una lista es un registro) y no por el nombre de la clave.Los teléfonos van en formato internacional con
+:+5215512345678. El modelo lo valida antes de salir a la red y limpia espacios y guiones.texttiene tope de 2000 caracteres; las etiquetas 64, los nombres de chat 256.Si omites
whatsapp_account_phone, TimelinesAI manda desde la cuenta conectada más recientemente — que rara vez es la que el usuario tiene en mente. Con más de un número conectado, conviene ser explícito.Los envíos se espacian ~2 segundos entre uno y otro por política de WhatsApp, y cada mensaje consume créditos (1 texto, 2 con adjunto; los fallidos se reembolsan).
Hay tres límites distintos y conviene no confundirlos:
Límite
Valor
Aplica a
Tasa de peticiones
50 por minuto por workspace
Todo, lecturas incluidas
Volumen mensual
200,000 llamadas al mes
Todo
Cuota de mensajería
según tu plan (créditos)
Solo envíos
El primero es el que muerde: pasarse devuelve 429
rate_limit_exceededa media faena, no al principio.El servidor se defiende en dos niveles, ambos en la capa de peticiones para que todas las herramientas queden cubiertas, no solo las que paginan:
Ritmo compartido. Las llamadas se espacian 1.2 s entre sí (60÷50). Una llamada suelta no espera nada; el retraso solo aparece en ráfagas, que es justo el caso que topa el límite. El límite es por workspace y todas las herramientas comparten uno, así que el marcapasos también es único.
Reintento con
Retry-After. Un 429 en una lectura se reintenta una vez, esperando exactamente lo que pide el servidor. Un envío nunca se reintenta solo: un mensaje que quizá salió no se repite por corazonada.
timelines_activity_summaryademás devuelve lo que alcanzó a contar con una notastopped_earlysi aun así lo cortan. Para preguntas por persona conviene filtrar (responsible=alguien@...) en lugar de escanear páginas: una petición en vez de veinte. Se pueden pedir límites mayores escribiendo a hello@timelines.ai.No hay endpoint de agregación. Por eso
timelines_activity_summarypagina y cuenta del lado del servidor MCP, y avisa concomplete=falsecuando el conteo no llegó al final.
Seguridad
Los secretos van en variables de entorno, nunca en el código. El
.gitignorebloquea archivos.env.Un token de TimelinesAI da acceso a todo el workspace: todas las conversaciones de WhatsApp del equipo, con sus teléfonos y su contenido. Es información de clientes reales — trátala como tal.
Un solo token compartido significa cero trazabilidad por persona.
Para cortar el acceso de golpe: revoca el token en el dashboard de TimelinesAI — el servidor queda inútil al instante.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Drive your real WhatsApp inbox from Claude — send, reply, label, assign, and triage via TimelinesAI.
233 tools for Google, Microsoft, TikTok, LinkedIn Ads in Claude or ChatGPT. Writes need approval.
Connect your team's living knowledge base — docs, data, issues, CRM — to Claude and ChatGPT.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/DanFrModa/Timelines-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server