Appearance
Build and operate outreach with Claude or Codex
Describe the audience, message, timing, and acceptable effect in plain language. Claude or Codex inspects your real Sales setup, builds a reviewable definition, and pauses before any operation that can contact customers.
- What you'll build — A postponed silence-triggered sequence, a one-time immediate campaign, or a single message/call through the account-scoped Sales-Management MCP.
- Who it's for — An owner or operator who wants Claude or Codex to configure outreach without manually constructing the internal follow-up graph.
- Time & plan — About 15–30 minutes. You need an active Sales plan and at least one suitable connected channel for customer contact.
The Sales Platform remains the customer-conversation runtime. Claude or Codex is the configuration and inspection workspace: it can prepare a disabled postponed draft and perform read-only audience previews, but customer contact is always a distinct effect.
What the coding agent can and cannot do
| Operation | Available through MCP | Customer-contact effect |
|---|---|---|
| List and inspect follow-ups | Yes | None |
| Create or edit a postponed sequence | Yes; it is created as draft | None while it remains draft |
| Publish or unpublish a postponed sequence | Yes, through follow_up_update | Publishing lets future matching conversations enter it |
| Attach a postponed sequence to a sales assistant | No; use the assistant's Toolkit → Follow ups in the app | A published sequence only runs for an assistant to which it is attached |
| Target a postponed sequence by pipeline | No in the current MCP schema | Use target_status_name and target_labels; do not invent pipeline_ids for postponed follow-ups |
| Preview an immediate audience | Yes | Read-only selection; nothing is scheduled or sent |
| Create an immediate campaign | Yes | Creates a real scheduled campaign; now may begin in about three minutes |
| Pause, resume, or reset an immediate campaign | Yes | Changes a real campaign's lifecycle; reset clears its progress and statistics |
| Send one message or place one call | Yes | Real and immediate; there is currently no no-effect preview call |
There is no universal dry-run switch yet
immediate_outreach_preview_audience previews selection only. It does not simulate channel delivery, message composition, calls, or queue execution. send_one_off_message and outbound_call are the effect when invoked. Keep the client approval prompt enabled and require a separate confirmation containing the exact recipient or audience, channel, content, and timing.
1. Connect the focused Sales areas
Open Agents → Connectors, find the relevant From your sales platform card, and use Connect AI tools to copy the account-specific URL and access key. The key authorizes the account; the domain query parameter narrows the visible tools.
Connect these areas:
| MCP area | Why it is needed |
|---|---|
sales_outreach | Follow-up CRUD, immediate campaigns, one-off messages, and outbound calls |
sales_channels | list_channels and its immediate_outreach_capable signal |
sales_clients | Real client IDs, labels, statuses, managers, pipelines, and custom-field values used for targeting |
For Claude Code, repeat the generated command with a different local name and domain:
bash
claude mcp add sales-outreach \
"https://api.mychatbot.app/api/mcp/sales-management?account_id=ACCOUNT_ID&domain=sales_outreach" \
--transport http \
--header "Authorization: Bearer mcp_YOUR_ACCESS_KEY"
claude mcp add sales-channels \
"https://api.mychatbot.app/api/mcp/sales-management?account_id=ACCOUNT_ID&domain=sales_channels" \
--transport http \
--header "Authorization: Bearer mcp_YOUR_ACCESS_KEY"
claude mcp add sales-clients \
"https://api.mychatbot.app/api/mcp/sales-management?account_id=ACCOUNT_ID&domain=sales_clients" \
--transport http \
--header "Authorization: Bearer mcp_YOUR_ACCESS_KEY"Use the URLs generated by your account instead of typing IDs by hand. The corresponding Codex and Cursor snippets are in MCP & connectors. Never put the access key in a prompt, repository, routine, skill, document, or screenshot.
2. State the operating boundary first
Give Claude or Codex an explicit policy before asking it to design anything:
text
Use my MyChatBot Sales MCP connections to build this outreach.
You may inspect assistants, clients, statuses, labels, pipelines, channels, and existing
follow-ups. You may create or edit a postponed follow-up only while it remains draft.
Do not publish a postponed follow-up, create an immediate campaign, send a message,
or place a call until you show me the exact target, content, channel, schedule, pacing,
and resulting effect and I explicitly approve that one operation.
Never guess an ID or channel identifier. Read it from the account first. Preview every
immediate audience and show the count plus sample before asking for approval.This policy complements the MCP client's write confirmation. It does not replace careful review: a client can be configured to auto-approve writes, and a successful tool call can contact real people.
3. Inspect before authoring
Ask the coding agent to perform these reads:
list_follow_ups— find duplicate or already-running campaigns. Follownext_offsetuntil it is absent when the account has multiple pages.list_channels— use only enabled rows and, for immediate campaigns, only rows whereimmediate_outreach_capable=true. Build the ID exactly as<communication_channel>__<assistant_id>.- Use the
sales_clientstools to resolve real status, label, manager, pipeline, assistant, and lead IDs. Do not copy a display name into an ID field. - For one-lead actions, call
get_clientimmediately before proposing the send or call so the recipient and available contact details are current.
A useful inspection request is:
text
Inspect existing follow-ups and enabled outreach-capable channels. Then inspect the
status, labels, pipelines, and custom fields available for targeting. Report the exact
IDs and values you would use, but do not write anything yet.4. Build a postponed sequence as a draft
Claude supplies a plain ordered steps array. The API creates safe node IDs, edges, silence conditions, and editor positions. A complete draft creation can look like:
json
{
"name": "Proposal follow-up",
"target_status_name": "Proposal sent",
"target_labels": ["warm lead"],
"target_labels_operator": "and",
"steps": [
{
"name": "Gentle reminder",
"delay_seconds": 7200,
"chat_depth": 10,
"instructions": "Briefly remind the client about the proposal and offer to answer questions."
},
{
"name": "Final check-in",
"delay_seconds": 86400,
"use_custom_message": true,
"custom_message": "Just checking in one last time. Reply whenever you would like to continue."
}
],
"schedule": {
"timezone": "Europe/Kyiv",
"days": {
"Monday": {"start": "09:00", "end": "18:00"},
"Tuesday": {"start": "09:00", "end": "18:00"},
"Wednesday": {"start": "09:00", "end": "18:00"},
"Thursday": {"start": "09:00", "end": "18:00"},
"Friday": {"start": "09:00", "end": "18:00"},
"Saturday": {"start": "", "end": ""},
"Sunday": {"start": "", "end": ""}
}
}
}Call follow_up_create, then immediately call get_follow_up with the returned ID. Ask Claude to summarize:
- stored status—it must be
draft; - targeting and working hours;
- every step in order, including delay and message mode;
- generated canonical graph fields;
- anything it could not configure through MCP.
Revise without manipulating the graph
follow_up_update.steps is a complete atomic replacement. To add, edit, delete, or reorder one step, read the stored record, construct the entire intended ordered list, and send that list back:
json
{
"follow_up_id": "42",
"steps": [
{
"name": "Gentle reminder",
"delay_seconds": 10800,
"instructions": "Briefly remind the client about the proposal and offer to answer questions."
},
{
"name": "Final check-in",
"delay_seconds": 172800,
"use_custom_message": true,
"custom_message": "Just checking in one last time. Reply whenever you would like to continue."
}
]
}Never send a partial steps array expecting it to patch one element. An empty array clears a draft sequence.
Attach and publish separately
The current Sales MCP cannot attach the new sequence to an assistant. In the app:
- Open the sales assistant that should execute it.
- Open Toolkit → Follow ups and attach the reviewed sequence.
- Return to Outreach and inspect the draft once more.
Only after that review, publish with a separate call:
json
{
"follow_up_id": "42",
"status": "live"
}To unpublish and disable the sequence, call follow_up_update with status: "draft". A live configuration change must move it to draft in the same call or in a prior call. Use follow_up_delete only after reading the record and confirming that permanent deletion—not disabling the sequence—is intended.
5. Preview an immediate campaign
Immediate outreach is a one-time campaign. Start with exactly the audience fields you intend to use for creation:
json
{
"client_source": "allClients",
"statuses": ["Qualified"],
"labels": ["annual plan"],
"labels_operator": "and",
"pipeline_ids": [7],
"created_date_from": "2026-08-01",
"has_email": true,
"audience_limit": 100,
"metadata_filters": [
{
"field": "country",
"operator": "in",
"values": ["Ukraine", "Poland"]
}
]
}Call immediate_outreach_preview_audience. It returns:
matched_count—the audience size after the optional limit;missing_count—the selector's aggregate missing-data count; this is not a delivery-readiness check;sample_clients—up to five{client_id, client_name}rows;- the resolved activity cutoff range, where applicable.
Preview is read-only, but it reads the real customer database. Ask Claude to show the payload and result unchanged, then spot-check the sample leads in the app. A preview does not prove that a channel can deliver to every recipient, and it does not reserve the matched set. Re-preview immediately before approval; account data can change between the preview and campaign creation.
6. Create the immediate campaign only after approval
Resolve the delivery channel with list_channels. For example, an Email row with communication_channel: "Email", assistant_id: 15, is_on: true, and immediate_outreach_capable: true becomes Email__15.
Reuse the previewed audience fields exactly and add content, channel, schedule, and pacing:
json
{
"name": "Annual-plan check-in",
"client_source": "allClients",
"statuses": ["Qualified"],
"labels": ["annual plan"],
"labels_operator": "and",
"pipeline_ids": [7],
"created_date_from": "2026-08-01",
"has_email": true,
"audience_limit": 100,
"metadata_filters": [
{
"field": "country",
"operator": "in",
"values": ["Ukraine", "Poland"]
}
],
"outreach_channels": ["Email__15"],
"instructions": "Write a concise, personal check-in about renewing the annual plan. Ask one clear question and do not invent discounts.",
"email_subject": "A quick annual-plan check-in",
"schedule_mode": "later",
"schedule_run_at": "2099-08-25T09:00:00Z",
"send_window_start": "09:00",
"send_window_end": "17:00",
"send_timezone": "Europe/Kyiv",
"interval_seconds": 3600,
"chats_per_interval": 50,
"send_delay_seconds": 7,
"dynamic_audience": false
}Before Claude calls immediate_outreach_create, require it to show a final approval summary containing:
- matched count and five-lead sample from the preview;
- the unchanged audience payload;
- exact ordered channel IDs;
- exact instruction or custom message and email subject/attachments;
- UTC or per-lead run time, daily window, and timezone;
- pacing, total upper bound, and whether the audience is static or dynamic.
Creation returns {follow_up_id, status, stats: {matched}}. A successful response means the real campaign has been stored as scheduled; it is not a dry run.
Replace the deliberately distant example date with the reviewed future run time. Keeping an example far in the future makes an accidental copy less likely to contact customers immediately, but invoking the tool still creates a real campaign.
Static is the safer default
With dynamic_audience=false, creation resolves and freezes the recipient set. A dynamic campaign re-runs filters at send time and may include clients who did not appear in the preview. Use it only when that changing membership is intentional.
Per-lead local time
For a per-lead wall time, set schedule_run_at without Z or an offset and provide the custom-field name holding each lead's IANA timezone or numeric UTC offset:
json
{
"schedule_mode": "later",
"schedule_run_at": "2099-08-25T10:00:00",
"timezone_field": "timezone"
}Those fields belong inside the otherwise complete create payload. Static campaigns validate the resolved instant for every matched lead before storage. Dynamic campaigns must remain in the future even at UTC+14 because their eventual recipients are unknown.
7. Pause, resume, reset, or inspect
Read the campaign with get_follow_up before every lifecycle change, then use immediate_outreach_update_status for the approved transition.
Pause a scheduled or active campaign:
json
{"follow_up_id": "84", "status": "user_paused"}Resume only a user_paused campaign:
json
{"follow_up_id": "84", "status": "scheduled"}Reset a non-running campaign to draft and clear all progress and statistics:
json
{"follow_up_id": "84", "status": "draft"}An active running, recovering, or system-paused campaign must first move to user_paused before reset. Status changes use optimistic matching; if someone changes the campaign concurrently, read it again instead of repeating the stale request.
8. Handle one-recipient actions deliberately
For one message, resolve the lead with get_client, resolve the channel with list_channels, show the exact recipient/channel/text, and ask for separate approval:
json
{
"client_id": "CLIENT_UUID_FROM_GET_CLIENT",
"assistant_id": "15",
"communication_channel": "Email",
"message": "Hi Sam, this is a reminder that your appointment is tomorrow at 10:00.",
"subject": "Appointment reminder"
}With a messaging channel, calling send_one_off_message sends the real message and writes it to chat history.
Do not select Ringostat, UniTalk, or Binotel when the intended effect is a text message. Those channel values are legacy call-provider paths: invoking send_one_off_message with one of them initiates a real operator callback/direct call, and its message value is not delivered or spoken to the lead.
For one call, resolve a lead with a phone number and an outbound-capable Twilio- or SIP-trunk Calls channel. Confirm the literal opening line—the customer will hear it:
json
{
"client_id": "CLIENT_UUID_FROM_GET_CLIENT",
"assistant_id": "15",
"first_message": "Hi Sam, this is Alex calling about the demo you requested. Is now a good time?"
}Calling outbound_call initiates the real call. WebSDK Calls channels cannot dial out.
9. Ask Claude for a final handoff
A useful completion request is:
text
Summarize what you inspected and changed. Include every created follow_up_id, current
status, target definition, assigned channel/assistant, schedule, pacing, and whether any
customer contact is now possible. List manual app steps still required. Do not perform
another write while producing the handoff.Keep the returned IDs. They let another operator call get_follow_up, pause/unpublish, or diagnose the same record without searching by a potentially duplicated name.
See also
- Follow-ups & Outreach — how postponed and immediate outreach execute in the Sales Platform
- Sales tools reference — complete tool parameters, constraints, and result shapes
- MCP & connectors — generated Claude, Codex, and Cursor setup
- Configure a sales assistant with Claude or Codex — configure and test the assistant that handles replies
- Labels and statuses — prepare reliable targeting values
