Skip to main content
Glama
DanFrModa

TimelinesAI MCP Server

by DanFrModa

TimelinesAI MCP Server

MCP (Model Context Protocol) server that exposes the TimelinesAI public API β€”the WhatsApp inbox for teamsβ€” to Claude. Designed to be deployed on Railway in read-only mode.

πŸ‘‰ Deployment steps are in DEPLOY-RAILWAY.md.


What it does

Gives Claude 12 tools to read and operate the inbox: chats, messages, labels, assignees, connected numbers, and team β€” plus one generic tool, one discovery tool, and an aggregated inbox summary.

Tool

Endpoint

timelines_whoami

verifies the token, workspace, and gates

timelines_request

any endpoint, any method

timelines_discover

probes routes and reports which ones exist

timelines_list_chats

GET /chats with all filters

timelines_get_chat

GET /chats/{id}

timelines_list_messages

GET /chats/{id}/messages

timelines_send_message

POST /messages or /chats/{id}/messages

timelines_update_chat

PATCH /chats/{id}

timelines_manage_labels

GET/POST/PUT /chats/{id}/labels

timelines_list_whatsapp_accounts

GET /whatsapp_accounts

timelines_list_teammates

GET /workspace/teammates

timelines_activity_summary

pages through /chats and counts everything (50 per page)


Environment variables

Variable

Required

Default

Description

TIMELINES_API_TOKEN

yes

β€”

API token (tla_...)

TIMELINES_MCP_TRANSPORT

on Railway

stdio

http for remote server

MCP_AUTH_TOKEN

if http

β€”

Secret protecting the endpoint. Minimum 32 characters

TIMELINES_READ_ONLY

no

see below

1 blocks all writes

TIMELINES_ALLOW_SEND

no

0

Separate gate: sending WhatsApp messages

TIMELINES_API_BASE

no

https://app.timelines.ai/integrations/api

To point at another host

TIMELINES_MAX_CHARS

no

20000

Response truncation

TIMELINES_TIMEOUT

no

45

Timeout in seconds

PORT

no

8000

Railway injects it automatically


The three gates

This MCP talks to real people. A message sent over WhatsApp reaches someone's phone in seconds and cannot be undone. That's why there are three independent locks.

1. TIMELINES_READ_ONLY β€” the default depends on the transport

  • stdio (local): writes allowed by default.

  • http (remote): writes blocked by default.

Forgetting the variable on a public deployment leaves it in read-only mode.

2. TIMELINES_ALLOW_SEND β€” the sending gate

Off by default on both transports, even locally. Even if you enable writes, sending messages stays blocked until you set TIMELINES_ALLOW_SEND=1.

The reason is the asymmetry: changing a label, reassigning a chat, or closing it are internal, reversible actions. Sending a WhatsApp to a customer is not. It makes no sense for them to share the same switch.

3. confirm=true β€” the per-call gate

Every send requires confirm=true on top of the above, just like deleting a file, reconfiguring a webhook, or revoking a teammate's access. The tool's instruction is explicit: first show the user the exact recipient and the exact text, and only with their explicit approval is it confirmed.

Each rejection says which of the three gates stopped it.


Endpoint authentication

The MCP protocol has no built-in authentication. In http mode, this server requires Authorization: Bearer <MCP_AUTH_TOKEN> on every request, or the secret embedded in the path (/s/<secret>/mcp) for Claude connectors. /healthz is the only public route.

The server refuses to start if MCP_AUTH_TOKEN is missing or shorter than 32 characters.


Running locally

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.py

On startup it prints which mode it ended up in:

[timelines-mcp] streamable-http on 0.0.0.0:8000  token=set  read_only=True  allow_send=False  sending_enabled=False

Notes on the TimelinesAI API

Verified against the public reference (https://timelines.ai/docs/public-api-reference/overview):

  • Base: https://app.timelines.ai/integrations/api, auth Authorization: Bearer <tla_...>.

  • Bodies are JSON, not form-encoded.

  • Responses come wrapped: {"status":"ok","data":{...}}. And there are failures that arrive with HTTP 200 but status:"error" β€” this server treats them as errors, not successes, because otherwise a failed send would read as sent.

  • Errors carry per-field detail: {"status":"error","message":..., "error_code":...,"errors":[{"fields":["phone"],"msg":"..."}]}. They are shown as-is in the error message.

  • Multi-value filters are comma-separated in a single parameter (label=vip,enterprise), not repeated or bracketed. Passing a Python list produces that form.

  • The page size is fixed at 50 and cannot be changed. Verified against the live API on 2026-08-25: limit, per_page, page_size, size, count, take, and rows are all ignored, and each page arrives with 50 records. The only parameter that does anything is page, and has_more_pages in the response tells you whether there's another one. That's why the tools don't expose a per_page: it would be a parameter that pretends to adjust something and adjusts nothing.

  • To reduce the size of a response, then, the answer isn't a smaller page: you have to filter more, or use fields to keep only the keys you need. Messages are the case that most demands this β€” a chat with 50 messages blows past the character limit without breaking a sweat. fields=["uid","text", "from_me","timestamp"] reduces a conversation to its essentials in a fraction of the size.

  • Watch out for repeated field names: a message record carries its own data key (a metadata dict), in addition to the wrapper's data. That's why fields decides what to prune by position (whatever is inside a list is a record) rather than by key name.

  • Phone numbers use international format with +: +5215512345678. The model validates them before hitting the network and strips spaces and hyphens.

  • text has a 2000-character cap; labels 64, chat names 256.

  • If you omit whatsapp_account_phone, TimelinesAI sends from the most recently connected account β€” which is rarely the one the user has in mind. With more than one connected number, it's worth being explicit.

  • Sends are spaced ~2 seconds apart per WhatsApp policy, and each message consumes credits (1 for text, 2 with attachment; failed ones are refunded).

  • There are three distinct limits and it's worth not confusing them:

    Limit

    Value

    Applies to

    Request rate

    50 per minute per workspace

    Everything, reads included

    Monthly volume

    200,000 calls per month

    Everything

    Messaging quota

    depends on your plan (credits)

    Sends only

    The first one is the one that bites: exceeding it returns 429 rate_limit_exceeded mid-task, not at the start.

    The server defends itself on two levels, both in the request layer so that all tools are covered, not just the paging ones:

    1. Shared pacing. Calls are spaced 1.2 s apart (60Γ·50). A single call waits nothing; the delay only shows up in bursts, which is exactly the case that hits the limit. The limit is per workspace and all tools share one, so the pacemaker is also a single one.

    2. Retry with Retry-After. A 429 on a read is retried once, waiting exactly what the server asks. A send is never retried on its own: a message that may have gone out isn't repeated on a hunch.

    timelines_activity_summary additionally returns what it managed to count with a stopped_early note if it still gets cut off. For per-person questions it's better to filter (responsible=someone@...) rather than scan pages: one request instead of twenty. Higher limits can be requested by writing to hello@timelines.ai.

  • There is no aggregation endpoint. That's why timelines_activity_summary pages and counts on the MCP server side, and reports complete=false when the count didn't reach the end.


Security

  • Secrets go in environment variables, never in code. The .gitignore blocks .env files.

  • A TimelinesAI token grants access to the entire workspace: all of the team's WhatsApp conversations, with their phone numbers and content. That's real customer information β€” treat it as such.

  • A single shared token means zero per-person traceability.

  • To cut access at once: revoke the token in the TimelinesAI dashboard β€” the server becomes useless instantly.

-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

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

View all MCP Connectors

Latest Blog Posts

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