> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gleap.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Sequences with AI agents (MCP)

> The Gleap MCP server's sequence tools: build multichannel sequences with emails, chat messages, surveys, push notifications and WhatsApp, check them, take them live and follow every contact.

Sequences (**Outreach → Sequences**) send a series of messages to one contact at a time: emails, chat messages, surveys, push notifications and WhatsApp messages, with waits, if/else checks and actions in between. Contacts join by hand, from a segment, a workflow, a pipeline or an event, and leave when the sequence ends, when its goal is reached or when one of its stop rules matches.

The Gleap MCP server lets AI agents such as Claude, ChatGPT, Cursor or Kai build and run sequences for you: draft a whole sequence from a one-line request, preview every message for a real contact, send test emails, take it live once you agree, and read the results.

## Connect

Add the Gleap MCP server as a custom connector in your AI client and sign in with Gleap (OAuth):

| Data region | MCP server URL |
| - | - |
| EU (default) | `https://mcp.gleap.io/mcp` |
| US | `https://mcp.us.gleap.ai/mcp` |

Clients that can't do OAuth send the headers `x-gleap-api-key` and `x-gleap-project-id` instead. The agent acts with your role in the project.

## Tools

| Tool | What it does | Access |
| - | - | - |
| `list_sequences` | Sequences with status (draft, live, paused), how contacts join, goal, step count, enrollment counts and summary (reply rate, goal rate), unpublished changes and the dashboard link. | Read |
| `get_sequence` | One sequence in full: who joins, when it stops, goal, sending settings, the steps as an outline with ids plus the editable steps JSON, unpublished changes and what still blocks going live. | Read |
| `get_sequence_templates` | The starter templates (`blank`, `onboarding`, `trial`, `reengage`) and the full reference for step types, settings, conditions and variables. Reads nothing from the project. | Read |
| `create_sequence` | New sequence from a template and/or a whole definition. Always a draft: nothing is sent until it goes live. | Draft only |
| `update_sequence` | Change the name, settings or steps (`steps` replaces the list, `stepChanges` edits steps by id). On a live or paused sequence the changes wait as unpublished changes; contacts keep getting the published version. | Draft only |
| `preview_sequence` | Renders every email and chat message as one contact would get it and lists variables that resolve empty. Saves and sends nothing. | Read |
| `send_sequence_test_email` | Sends one email step as a test to your own address or up to 5 addresses. A Kai-written step is written by Kai for a real contact and sent to you. Not counted in the results. | Write (to you) |
| `set_sequence_status` | `live`: starts enrolling and sending. `paused`: nothing is sent and nobody new joins; contacts wait where they are. The agent calls it once you agreed. | Write |
| `publish_sequence_changes` | Makes the unpublished changes of a live or paused sequence the version contacts get. | Write |
| `discard_sequence_changes` | Drops the unpublished changes; the published version stays. | Write |
| `enroll_in_sequence` | Adds up to 500 contacts by email, user id or contact id to a live sequence. Returns the skipped ones with a reason. | Write |
| `get_sequence_stats` | Results: enrollments by status, reply rate, goal rate, exit reasons and, per step, how many reached it, the yes/no split and, for emails, sent, opened, clicked and replied. | Read |
| `list_sequence_enrollments` | The contacts in a sequence with their current step, what they wait for and why they left. Filter by status or search a name or email. | Read |
| `get_sequence_enrollment` | One contact's timeline: every step done, skipped or failed, the paths taken and the exit reason. | Read |
| `manage_sequence_enrollment` | Pause, resume or end the sequence for one contact. | Write |

## Steps

Steps are read top to bottom. Every step has a unique `id` (up to 64 characters) and a `type`. A sequence holds up to 100 steps, and if/else paths nest up to 5 levels deep.

### Messages

| Step | Type | Fields | Notes |
| - | - | - | - |
| Email | `email` | `subject`, `content`, `preheader`, `look` (`plain`, `personal`, `company`), `threadWithPrevious`, `kai` | Content is plain text (a blank line starts a new paragraph) or a TipTap doc. Later emails reply in the thread of the first one ("Re: …") unless `threadWithPrevious: false`, then they need their own subject. |
| Chat message | `message` | `content`, `online` | Starts a conversation in your widget from the sender. |
| Survey | `survey` | `outboundId`, `online` | Shows one of your surveys in your app or website. A draft survey works: only the people this step sends it to see it, and the survey's own audience and schedule don't apply. |
| Push notification | `push` | `outboundId` | Sends one of your push notifications to the devices of people who use your mobile app. Skipped when push isn't set up for the project or the contact has no device. |
| WhatsApp | `whatsapp` | `outboundId` | Sends one of your approved WhatsApp templates to the contact's phone number. Skipped for contacts without a phone number. |

Survey, push and WhatsApp steps send something you already made under **Outreach**. The agent finds it with `list_surveys` or `list_outbound_messages` and puts its id in `outboundId`.

#### Emails written by Kai

Add `kai: { enabled: true, prompt: "…" }` to an email step and Kai writes each contact their own subject and message when the step is due, from their activity, company, conversations, your help center and website. Kai-written emails are billed as AI usage. The step's own `subject` and `content` become the fallback for people Kai knows nothing specific about; without a fallback the step is skipped for them.

#### When they're not online

Chat message and survey steps can wait for the contact to be active in your app instead of being shown the next time they open it:

```json theme={null}
{
  "id": "checkin",
  "type": "message",
  "content": "Need help setting up? I'm here.",
  "online": {
    "enabled": true,
    "amount": 3,
    "unit": "days",
    "fallback": "email",
    "subject": "Need a hand with the setup?",
    "content": "Hi {{session.firstName|there}},\n\nNeed help setting up? Just reply to this email."
  }
}
```

The step waits up to `amount` `unit` for the contact to come online. If they don't show up in time, they get the fallback email (its own `subject` and `content`) or, with `fallback: "skip"`, the step is skipped.

### Timing and logic

| Step | Type | Fields | Notes |
| - | - | - | - |
| Wait | `wait` | `amount`, `unit` | Units `minutes`, `hours`, `days`, `businessDays` (skip Saturday and Sunday), `weeks`. At most 365 days. |
| Wait until | `waitUntil` | `event`, `amount`, `unit`, `yes`, `no` | Waits until the contact tracks the event, up to the time limit. Did it: `yes` path. Timed out: `no` path. |
| If / else | `branch` | `name`, `conditions`, `yes`, `no` | Checks the contact's data when they reach the step (plan, tags, custom data, events). |
| If / else on email engagement | `branch` | `mode: "engagement"`, `engagement: { action, stepId }`, `yes`, `no` | Did they open, click a link in or reply to one email (`stepId`) or any email of the sequence so far (no `stepId`). `action` is `opened`, `clicked` or `replied`. |

Empty `yes` or `no` paths continue with the step after the if/else. Put a wait before an engagement check to give people time to open or reply. Opens and clicks are only tracked for emails with the `personal` or `company` look: `plain` emails (the default look) don't track them, so check `replied` for those. Opens are approximate: some email apps block them.

```json theme={null}
{
  "id": "replied_check",
  "type": "branch",
  "name": "Replied to the welcome email?",
  "mode": "engagement",
  "engagement": { "action": "replied", "stepId": "welcome" },
  "yes": [{ "id": "tag_replied", "type": "tag", "op": "add", "tag": "replied" }],
  "no": [{ "id": "nudge", "type": "email", "content": "Hi {{session.firstName|there}},\n\nJust checking in. Anything I can help with?" }]
}
```

### Actions

| Step | Type | Fields |
| - | - | - |
| Add or remove a tag | `tag` | `op` (`add`, `remove`), `tag` |
| Update contact data | `attribute` | `key`, `value` (variables allowed) |
| Add to pipeline | `pipeline` | `pipelineId`, `laneId` |
| Start another sequence | `sequence` | `sequenceId` |
| End here | `exit` | none |

Variables work in subjects, content and attribute values: `{{session.firstName|there}}`, `{{session.companyName}}`, `{{session.customData.role}}`, `{{project.name}}`. Give a fallback after `|` for anything a contact may lack; `preview_sequence` lists the variables that resolve empty.

## Settings

| Setting | What it controls |
| - | - |
| `enrollment` | How contacts join: `triggers` (`event`, `contactCreated`; adding by hand, from a segment, a workflow or a pipeline always works), `targetAudience` (`all`, `users`, `guests`), `conditions` and whether someone can join again (`reenroll`: `never`, `always`, `after` with `reenrollAfterDays`). |
| `exit` | When it stops early (see below). |
| `goal` | The conversion event (`event`), counted when tracked within `withinDays` (default 14) of joining. `exitOnGoal` (default true) stops the sequence once reached. |
| `sending` | `senderId`, `emailType` (`personal`: one-to-one, no unsubscribe link; `marketing`: with unsubscribe link), `emailLook`, `repliesTo` (the sender, a teammate, a team or nobody) and the sending hours `window` (days, start and end hour, time zone). Messages due outside the window wait for it. |

### When it stops

A sequence always stops when the contact unsubscribes or the address bounces, and an out-of-office reply always pauses it until the contact is back. On top of that, `exit` turns on more reasons:

| Field | Default | Effect |
| - | - | - |
| `onReply` | `false` | "They reply": a reply to one of the sequence's emails or to its chat message ends it. Off, replies keep the sequence going: the contact keeps getting the next steps. |
| `onNewConversation` | `false` | "They contact you about anything else": a message from them in any other conversation, like a new chat or email, ends it. |
| `events` | `[]` | Tracked events that end it, for example `["booked_demo"]`. |
| `conditions` | none | Contact data that ends it, checked before every step. |

Replies keep the sequence going by default, for every email type. They still count in the results (reply rate, replies per email), and an [engagement if/else](#timing-and-logic) can send people who replied down another path. The `reengage` (Win back) template turns `onReply` on; `blank`, `onboarding` and `trial` leave it off. Sequences created before this change keep the setting they have.

## How agents build a sequence

1. `get_targeting_options` for the event and attribute names your project really tracks.
2. `create_sequence` with a template or the whole definition. Invalid definitions are refused with the exact field that is wrong.
3. `preview_sequence` for a real contact, then `send_sequence_test_email` for the emails.
4. The agent shows you what the sequence sends and to whom (or you open the `reviewUrl` in the editor).
5. Once you say "go live", the agent calls `set_sequence_status` with `live`. Later edits go through `update_sequence` and `publish_sequence_changes`.

Example request to an agent:

> Build a trial sequence: a welcome email from me, a survey in the app after a week (email them the question if they don't come back within 3 days), and if they haven't opened the welcome email after 3 days, a WhatsApp reminder.

The agent creates a draft with a `welcome` email, a 3-day wait, an engagement if/else on `opened` for `welcome` with a `whatsapp` step on the No path, a wait, and a `survey` step with `online` and an email fallback. It asks before taking it live.

## Guardrails

* `create_sequence` always saves a draft, and `update_sequence` on a live sequence only saves unpublished changes. Nothing reaches contacts until `set_sequence_status` or `publish_sequence_changes`, which agents call only after you agreed.
* Going live is checked by the server: every email needs a subject and content (or a Kai prompt), survey, push and WhatsApp steps need the message they send, waits need a duration and if/else steps a condition or an engagement check.
* `enroll_in_sequence` contacts customers right away, so agents use it only for the contacts you asked for.
* `send_sequence_test_email` goes only to your own address or addresses you gave.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.