MCP server

Reply.io's full sales platform as 70 MCP tools — sequences, contacts, inbox, tasks, and the Jason AI SDR autopilot. Live at mcp2.reply.io. Verified overview — auth, contract rules, envelopes, error model, recipes — with the full 70-tool reference at /mcp/tools.

Status — available today, verified live

Reply MCP is an official, live, remote Streamable HTTP MCP server exposing Reply.io’s sales-engagement, inbox, AI SDR (Jason), task, account, and help workflows as 70 tools for any MCP-compatible client — Claude, Cursor, Make, n8n, and custom agents.

Everything below was read off the running server. Tool names, signatures, per-argument documentation, enum values, MCP annotations, response envelopes, and error codes come from an authenticated initialize + tools/list handshake and safe validation probes on 2026-07-05 — not from published docs. This page is the overview; the full per-tool reference lives at /mcp/tools. This is the current next-generation surface. If any other documentation disagrees, trust this page or re-probe the server yourself (see §10, Reproduce this, at the end of this page).

On this page: 1. Server overview · 2. Contract rules the schemas enforce · 3. Response envelopes and error model · 4. Design principles for agents · 5. Tool index (70 tools) · 6. Workflow recipes · 7. High-stakes tools · 8. Relationship to the REST API (v3) · 9. Agent prompt guidance · 10. Reproduce this — full tool reference: /mcp/tools

1. Server overview

Endpointhttps://mcp2.reply.io/
TransportStreamable HTTP (responses are SSE text/event-stream frames carrying JSON-RPC)
Wire formatJSON-RPC 2.0 over HTTP
MCP protocol2025-06-18
ServerReply.Mcp v1.0.0.0
Capabilitiestools, logging (no prompts or resources advertised)
Tools70 — 31 annotated readOnlyHint, 39 annotated destructiveHint
SessionsNone required — initialize and tools/list work without Mcp-Session-Id
Authx-api-key: <key> or Authorization: Bearer <key>
Rate limitHourly window, ~3000/hour (X-Rate-Limit-Limit: 1h, -Remaining, -Reset on every response)

Unauthenticated behavior. A call with no credentials returns 401 Unauthorized with:

WWW-Authenticate: Bearer resource_metadata="https://mcp2.reply.io/.well-known/oauth-protected-resource/"
X-Rate-Limit-Limit: 1h
X-Rate-Limit-Remaining: 2997
X-Rate-Limit-Reset: 2026-07-05T00:00:00.0000000Z

OAuth protected-resource metadata (GET /.well-known/oauth-protected-resource/):

{
  "resource": "https://mcp2.reply.io",
  "authorization_servers": ["https://oauth.sandbox.replyapp.io"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["reply-web-api", "mcp:tools"]
}

For most agents the simplest path is an API-key header; the OAuth metadata exists for clients (e.g. Claude custom connectors) that prefer a discovery-based OAuth flow.

Client initialization flow

  1. Open an HTTP connection to https://mcp2.reply.io/.
  2. Send JSON-RPC initialize with your protocol version and client info.
  3. Send the notifications/initialized notification if your client library requires it.
  4. Call tools/list to discover tools, their JSON schemas, and their annotations.
  5. Call tools/call with a tool name and an argument object.

initialize payload

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {},
    "clientInfo": { "name": "your-client", "version": "1.0.0" }
  }
}

MCP client config

Header form (recommended):

{
  "mcpServers": {
    "reply": {
      "type": "http",
      "url": "https://mcp2.reply.io/",
      "headers": { "x-api-key": "YOUR_REPLY_API_KEY" }
    }
  }
}

Bearer form (equivalent):

{
  "mcpServers": {
    "reply": {
      "type": "http",
      "url": "https://mcp2.reply.io/",
      "headers": { "Authorization": "Bearer YOUR_REPLY_API_KEY" }
    }
  }
}

Claude Code, one line:

claude mcp add --transport http reply https://mcp2.reply.io/ \
  --header "x-api-key: YOUR_REPLY_API_KEY"

2. Contract rules the schemas enforce

These apply to every one of the 70 tools — verified against the served JSON schemas and live validation probes:

  • Unknown arguments are invalid. Every inputSchema sets additionalProperties: false. Don’t pass extra keys “just in case” — the call fails validation.
  • Required means non-empty. Required string and array fields reject null, "", and [] alike. The server’s own words: “null, empty strings, and empty arrays are not accepted for required fields.”
  • Every tool is annotated. readOnlyHint: true (31 tools) or destructiveHint: true (39 tools) arrives in tools/list. Agents can — and should — auto-gate on these before adding their own confirmation UX for the ⚠️ subset.
  • Pagination is uniform. List/search tools take top (default 20, max 100) and skip; responses return Data.Items plus HasMore. Iterate with skip += top until HasMore is false.
  • Patch semantics on updates. Every update_* tool changes only the fields you pass; omitted/null fields keep their current value. A passed list field replaces the whole list.
  • IDs come from resolvers. Mutating tools require exact numeric IDs from prior search_* / list_* / filter_* output. The descriptions repeat one rule verbatim: “Never invent, estimate, default, or ask the user.”
  • Approvals are addressed by pair. Approve/reject/regenerate identify a Jason draft by sequenceId + contactId — there is no separate draft/message ID.
  • Batches are bounded and explicit. Bulk tools cap at 100 items. reply_bulk_approve_messages is atomic (any stale reference rejects the whole batch; nothing is sent). Contact batches return per-item results (Affected / AffectedContactIds / NotProcessed) — the authoritative record of what actually happened; report exact counts (“reassigned 48 of 50”).

Enum quick reference

Every closed value set the server declares (in schemas or tool descriptions), in one place. All are case-insensitive unless noted:

FieldValuesUsed by
channelEmail, LinkedInsend_inbox_reply, list_pending_approvals filter
Per-sequence contact statusActive, Paused, Finished, Inactive, OutOfOfficechange_status_in_sequence
Sequence search statusNew, Active, Pausedsearch_sequences
Reply modeReview, Autonomous (+ sendExistingDrafts boolean)set_sequence_reply_mode
toneOfVoiceConfident, Persuasive, Witty, Straightforward, Empatheticreply handlers, reengagement cards
responseLengthSuperShort, Short, Medium, Longreply handlers, reengagement cards
taskTypeToDo, Call, Meeting, LinkedIn, ManualEmail, Sms, WhatsAppcreate_task, list_my_tasks
linkedInTaskTypeMessage, Connect, InMail, ViewProfilecreate_task (required when taskType=LinkedIn)
callResolutionPositive, ToCall, Negativecomplete_task (recommended for Call tasks)
Playbook visibilityTeam (default), Organizationcreate_playbook, duplicate_playbook
category (schema enum)integrations, reporting, sequences, contacts, email, linkedIn, ai, otherreport_unsupported_request
sortModeNewestFirst (default), OldestFirstlist_pending_approvals

3. Response envelopes and error model

Transport. Responses are SSE frames (text/event-stream) whose data: lines carry ordinary JSON-RPC payloads. Read the last data: frame for the result.

Success envelope. A successful tools/call returns result.isError = false, and the actual payload is a JSON string inside result.content[0].text:

{ "Success": true, "Data": { "Items": [ ... ], "HasMore": false } }

Error envelope. Tool failures are not HTTP errors — they come back as HTTP 200, JSON-RPC success, with result.isError = true and the error as a JSON string in result.content[0].text:

{ "Success": false, "ErrorCode": "InvalidArguments", "ErrorMessage": "..." }

Parse the inner JSON; branch on Success, then on ErrorCode. Real captured examples:

{"Success":false,"ErrorCode":"InvalidArguments","ErrorMessage":"Tool 'reply_get_sequence_steps' arguments failed validation: SequenceId: 'Sequence Id' must be greater than '0'."}
{"Success":false,"ErrorCode":"InvalidArguments","ErrorMessage":"Tool 'reply_send_inbox_reply' is missing required argument(s): message. Supply a real value for each; null, empty strings, and empty arrays are not accepted for required fields."}
{"Success":false,"ErrorCode":"InvalidArguments","ErrorMessage":"Tool 'reply_search_contacts' arguments failed validation: : At least one of Email or LinkedIn must be provided. If the user gave only a name or company, ask them for an email address or LinkedIn URL instead."}

Error layers to handle:

  • Transport / auth. 401 (missing/invalid key), 403 (valid key, missing scope or plan feature), 429 (rate limit — back off using X-Rate-Limit-Reset), 5xx (transient).
  • Tool-level ErrorCodes (inside the envelope): InvalidArguments, NotFound, Forbidden, Conflict, InvalidInput, InvalidParameter, UpstreamFailure, ServiceUnavailable, plus domain-specific codes named per tool in the reference below (NoEmailAccounts, NoContacts, ContactLimitExceeded, ChannelMismatch, ContactOptedOut, ThreadSendFailed, InvalidStatusTransition, ArticleNotFound, PERMISSION_DENIED, …). Each tool’s description states which codes it can return and what to do about each.
  • Per-item partial results. Batch tools report per-contact skips in NotProcessed (e.g. ContactAlreadyInSequence, ContactInBlackList, NotFound) while the call as a whole succeeds. Read them; never claim an item succeeded unless it appears in the affected list.

Safe-retry matrix.

  • Auto-retry once on transient ServiceUnavailable/UpstreamFailure/timeout: all 📖 read tools — search_*, list_*, get_*, filter_*, *_stats, compare_*, get_app_map, search_knowledge_base.
  • Retry only after a verifying read: create_*, update_*, add_contact_to_sequence, change_status_in_sequence, assign_*, attach_*, complete_task, mark_contacts_as_replied.
  • Never auto-retry — confirm with the user first: send_inbox_reply, approve_message, bulk_approve_messages, reject_message, start_sequence, blacklist_contact, change_contact_owner, and switching to Autonomous. A timed-out send may already have succeeded server-side; verify with a read before retrying.

4. Design principles for agents

Resolve before you mutate. Almost every mutating tool takes exact numeric IDs (sequence, contact, task, thread, user, email-account, LinkedIn-account, schedule, offer, playbook, knowledge-base). Never invent an ID, and never ask the user for one — users don’t know internal IDs. Search → confirm the match → act → verify:

User: "Add John from Acme to the Q3 outbound sequence."
1. reply_search_contacts(email or LinkedIn URL) — note: this tool needs an email/LinkedIn,
   not a name; if you only have a name, ask the user for an email first.
2. reply_search_sequences(name: "Q3 outbound")
3. If exactly one contact and one sequence match, confirm and call
   reply_add_contact_to_sequence(sequenceId, [contactId]).
4. Read NotProcessed in the result; verify with reply_get_contact_activity(contactId).

Gate high-stakes actions. The server executes a successful call immediately — there is no undo. Confirm with the user before anything that sends to a prospect, starts outreach, enrolls contacts, changes ownership, blacklists, bulk-approves, or switches Jason to Autonomous. Two traps worth naming: reply_reject_message doesn’t just discard a draft — it removes the contact from the sequence entirely (to merely revise a draft, use reply_regenerate_message); and reply_send_inbox_reply supports only threadId + channel + message in v1 — no Cc/Bcc, attachments, or scheduling, 32,000-char max, channel must match the thread’s.

Separate discovery, configuration, and execution. Discover objects and IDs (search_* / list_* / get_*), configure the sequence (mailboxes, schedules, offers, knowledge bases, playbooks, reply mode), then execute (start, approve, send, complete). reply_start_sequence fails with NoEmailAccounts or NoContacts if you skip configuration.

MCP is the interactive surface; REST is the exhaustive one. These 70 tools cover most day-to-day operations. Drop to the REST API (api.reply.io/v3) for bulk imports and updates, background jobs, deep report exports, and anything absent from tools/list.

5. Tool index (70 tools)

One line per tool. Full signatures, per-argument documentation, enum values, and per-tool failure modes live on the dedicated reference page: /mcp/tools (markdown twin: /mcp/tools.md). Badges: 📖 read-only (readOnlyHint) · ✏️ mutation (destructiveHint) · ⚠️ prospect-visible or irreversible — confirm with the user first.

Sequences — discover & inspect

ToolWhat it does
reply_search_sequences📖Returns a paginated list of sequences (campaigns) the user owns or has access to, optionally filtered by name substring, status, and archive flag.
reply_get_sequence_steps📖Returns the ordered steps of a sequence: each step’s type, delay, position in the flow, and how many message content variants it has.
reply_get_sequence_step_variants📖Returns the content variants (A/B variations) of a single sequence step: subject, message body, enabled flag, and attachment flag.
reply_get_sequence_stats📖Returns email and LinkedIn performance metrics for one sequence: contact volume, delivered/opened/replied/bounced rates, LinkedIn connection and message stat…
reply_compare_sequence_performance📖Returns side-by-side email + LinkedIn performance metrics for multiple sequences in a single call.

Sequences — control & configuration

ToolWhat it does
reply_start_sequence✏️⚠️Starts (or resumes) a sequence so it begins sending outreach.
reply_pause_sequence✏️Pauses a sequence so it stops sending outreach.
reply_add_contact_to_sequence✏️⚠️Adds one or more existing contacts to a sequence so they begin receiving its steps.
reply_change_status_in_sequence✏️Sets the per-sequence status of a single contact inside one sequence.
reply_assign_email_account_to_sequence✏️Links an email account (mailbox) to a sequence so the sequence can send from it.
reply_assign_linkedin_account_to_sequence✏️Links a LinkedIn account to a sequence so the sequence can run LinkedIn steps from it.
reply_assign_schedule_to_sequence✏️Sets the sending schedule (business-hours window) on a sequence.
reply_attach_offer_to_sequence✏️Attaches an offer to an AI SDR sequence so Jason pitches it for that sequence’s outreach.
reply_attach_playbook_to_sequence✏️Attaches a playbook to an AI SDR sequence so Jason follows it for that sequence’s outreach.
reply_attach_knowledge_base_to_sequence✏️Attaches a knowledge base to an AI SDR sequence so Jason uses it when answering prospects in that sequence.
reply_set_sequence_reply_mode✏️⚠️Sets how the AI SDR (Jason) handles outgoing messages for one sequence.

Contacts

ToolWhat it does
reply_search_contacts📖Looks up contacts by exact email address or LinkedIn URL.
reply_filter_contacts📖Lists contacts narrowed by list membership, sequence membership and/or a free-text search term applied to name/email/company.
reply_create_contact✏️Creates a new contact in the workspace.
reply_update_contact✏️Updates fields on an existing contact.
reply_get_contact_activity📖Returns the activity history for one contact: emails sent / opened / replied, LinkedIn actions, calls, manual events, ordered newest first.
reply_mark_contacts_as_replied✏️Marks one or more contacts as having replied (or clears that flag), the same action as manually flagging a reply in Reply.io.
reply_change_contact_owner✏️⚠️Reassigns one or more contacts to a different Reply.io user.
reply_blacklist_contact✏️⚠️Adds the contact’s email (or the contact’s whole email domain) to the workspace blacklist so future outreach to that address (or any address on that domain)…

Inbox & conversations

ToolWhat it does
reply_get_inbox_emails📖Returns inbox threads (email + LinkedIn replies), typically newest first by LastActivityDate as ordered by the underlying service, with a short body preview,…
reply_send_inbox_reply✏️⚠️Sends a reply on an existing inbox thread.
reply_change_inbox_category✏️Assigns (or clears) the workspace-defined category on one inbox thread.

Jason AI SDR — approvals & autopilot

ToolWhat it does
reply_list_pending_approvals📖Returns the queue of AI SDR (Jason) draft messages waiting for the user’s approval before they are sent, newest first by default.
reply_approve_message✏️⚠️Approves a single AI SDR draft and sends it to the contact immediately.
reply_bulk_approve_messages✏️⚠️Approves multiple AI SDR drafts at once and sends them all immediately.
reply_reject_message✏️⚠️Rejects a single AI SDR draft.
reply_regenerate_message✏️Asks the AI SDR to rewrite a single pending draft, optionally guided by the user’s feedback.

Jason AI SDR — knowledge bases

ToolWhat it does
reply_list_knowledge_bases📖Lists the AI SDR (Jason) knowledge bases in the workspace: the bundles of company information Jason uses to answer prospects, which can be attached to sequen…
reply_get_knowledge_base📖Returns one AI SDR (Jason) knowledge base in full: its name, its free-text Instructions, the web-page URL sources it contains (with their source ids), and ho…
reply_create_knowledge_base✏️Creates a new AI SDR (Jason) knowledge base.
reply_update_knowledge_base✏️Updates an existing AI SDR (Jason) knowledge base.
reply_add_knowledge_base_source✏️Adds a web-page URL as a source to an AI SDR (Jason) knowledge base, so Jason can use that page’s content when answering prospects.
reply_delete_knowledge_base_source✏️Removes a URL source from an AI SDR (Jason) knowledge base.

Jason AI SDR — reply handlers

ToolWhat it does
reply_list_reply_handlers📖Lists the reply handlers in an AI SDR (Jason) knowledge base.
reply_get_reply_handler📖Returns one reply handler from an AI SDR (Jason) knowledge base in full: its question type, instructions, sample answer, tone of voice, response length, link…
reply_create_reply_handler✏️Adds a reply handler to an AI SDR (Jason) knowledge base so Jason knows how to answer a specific kind of prospect question.
reply_update_reply_handler✏️Updates a reply handler in an AI SDR (Jason) knowledge base.
reply_delete_reply_handler✏️Removes a reply handler from an AI SDR (Jason) knowledge base.

Jason AI SDR — reengagement cards

ToolWhat it does
reply_list_reengagement_cards📖Lists the reengagement cards in an AI SDR (Jason) knowledge base.
reply_get_reengagement_card📖Returns one reengagement card from an AI SDR (Jason) knowledge base in full: its name, instructions, sample answer, send-after days, tone of voice, response…
reply_create_reengagement_card✏️Adds a reengagement card to an AI SDR (Jason) knowledge base so Jason knows how to win back a prospect who went quiet.
reply_update_reengagement_card✏️Updates a reengagement card in an AI SDR (Jason) knowledge base.
reply_delete_reengagement_card✏️Removes a reengagement card from an AI SDR (Jason) knowledge base.

Jason AI SDR — offers

ToolWhat it does
reply_list_offers📖Lists AI SDR (Jason) offers: what Jason can pitch to prospects.
reply_get_offer📖Returns one AI SDR (Jason) offer in full: company name and description, ideal customer profile (ICP), reason for outreach, and the lists of case studies, pai…
reply_create_offer✏️Creates a new AI SDR (Jason) offer that Jason can pitch.
reply_update_offer✏️Updates an existing AI SDR (Jason) offer.
reply_generate_offer_from_website📖Asks Jason to draft offer content from a company website URL (and optional extra notes).

Jason AI SDR — playbooks

ToolWhat it does
reply_list_playbooks📖Lists AI SDR (Jason) playbooks: the named sets of selling instructions Jason can follow.
reply_get_playbook📖Returns one AI SDR (Jason) playbook in full, including its instruction Body (the prompt that tells Jason how to sell), visibility type, and the names of any…
reply_create_playbook✏️Creates a new AI SDR (Jason) playbook: a named set of selling instructions.
reply_update_playbook✏️Updates an existing AI SDR (Jason) playbook.
reply_duplicate_playbook✏️Duplicates an existing AI SDR (Jason) playbook into a new one with the same description and instruction Body.

Tasks

ToolWhat it does
reply_list_my_tasks📖Returns the user’s tasks (To Do, Call, Meeting, LinkedIn, Manual Email, Sms, WhatsApp), filterable by status, type, due window, and contact.
reply_create_task✏️Creates a new task (ToDo / Call / Meeting / LinkedIn / ManualEmail / Sms / WhatsApp) for the user.
reply_complete_task✏️Marks an existing task as completed.

Workspace resolvers & accounts

ToolWhat it does
reply_list_email_accounts📖Returns the email accounts (mailboxes) configured in the workspace, with their connection status, daily send limit, default flag, and tags.
reply_list_linkedin_accounts📖Returns the LinkedIn accounts connected to the workspace, with status, cookie health, account tier, and ownership.
reply_list_schedules📖Returns all sending schedules (business-hours / sending-window configurations) in the workspace, with timezone, default flag, and counts of main + follow-up…
reply_search_lists📖Resolves contact lists (a.k.a.
reply_search_team_members📖Resolves teammates in the current workspace to their numeric UserId by name or email substring.

Help & meta

ToolWhat it does
reply_search_knowledge_base📖Searches the Reply.io Help Center for articles that answer product how-to and support questions (for example ‘how do I add an account’, ‘what does autopilot…
reply_get_knowledge_base_article📖Returns the full text and source URL of a single Reply.io Help Center article identified by its slug (obtained from reply_search_knowledge_base).
reply_get_app_map📖Returns the catalog of Reply.io app areas: each entry has a title, a short description, the exact in-app navigation steps, and a relative URL.
reply_report_unsupported_request📖Records, for the product team, that the user asked for a capability Reply.io does not currently have.

6. Workflow recipes

Concrete call graphs an agent can follow. Each resolves IDs first, configures where needed, confirms before high-stakes steps, and verifies after.

Launch a sequence safely

  1. reply_search_sequences by name → resolve the exact sequenceId (ask the user if ambiguous).
  2. reply_get_sequence_steps → see which channels the sequence uses.
  3. If it has email steps: reply_list_email_accounts, then reply_assign_email_account_to_sequence if none is attached.
  4. If it has LinkedIn steps: reply_list_linkedin_accounts, then reply_assign_linkedin_account_to_sequence; warn if the account is unhealthy.
  5. reply_list_schedules, then reply_assign_schedule_to_sequence if none is set.
  6. Optional AI SDR: reply_attach_offer_to_sequence / reply_attach_playbook_to_sequence / reply_attach_knowledge_base_to_sequence, then reply_set_sequence_reply_mode.
  7. Confirm with the user: “Start sequence X? This begins outreach to its contacts.”
  8. reply_start_sequence — expect NoContacts / NoEmailAccounts / Archived if configuration was skipped.
  9. reply_get_sequence_stats or reply_search_sequences to confirm it is Active.

Add a contact to a sequence

  1. reply_search_contacts by email or LinkedIn URL (the tool does not accept names — ask the user for an email if that’s all you have).
  2. If missing and the user confirms details, reply_create_contact (needs a name plus at least one of email/LinkedIn URL).
  3. reply_search_sequences for the target sequence.
  4. Confirm, then reply_add_contact_to_sequence (up to 100 IDs; per-contact skips arrive in NotProcessed, e.g. ContactAlreadyInSequence, ContactInBlackList).
  5. reply_get_contact_activity to verify enrollment.

Supervise Jason in Review mode

  1. reply_set_sequence_reply_mode → Review (if not already).
  2. reply_list_pending_approvals — filter by sequence, owner, or channel.
  3. For each draft (addressed by sequenceId + contactId):
    • inspect the contact and context, compare against the attached playbook/knowledge base;
    • reply_approve_message (optionally overriding body/subject) — sends immediately;
    • reply_regenerate_message with specific feedback to revise the draft;
    • reply_reject_message only if the contact should leave the sequence entirely — rejection is irreversible and removes them from the sequence.
  4. reply_bulk_approve_messages only after every draft in the batch was reviewed — the batch is atomic: one stale reference rejects the whole batch and nothing is sent.

Switch Jason to Autonomous

  1. Verify the sequence has an offer, playbook, and knowledge base attached and reviewed.
  2. Confirm explicitly: Autonomous mode sends replies without per-message approval.
  3. reply_set_sequence_reply_mode → Autonomous.
  4. Keep watching reply_get_inbox_emails and reply_get_sequence_stats.

Reply to an inbox thread

  1. reply_get_inbox_emails (pagination only in v1 — no filters; previews only, not full bodies) → resolve the exact threadId and note its channel.
  2. Draft the reply and show it to the user for approval.
  3. reply_send_inbox_reply with the matching channel (‘Email’ or ‘LinkedIn’) — v1 supports message body only (max 32,000 chars); no Cc/Bcc, attachments, or scheduling. Expect ChannelMismatch, ContactOptedOut, or ThreadSendFailed as the named failure modes.
  4. Optionally reply_change_inbox_category to reflect the new state.

Handle an unsupported request

  1. Confirm no tool in tools/list can do it.
  2. reply_get_app_map — the action may be a UI-only setting; return the exact in-app link.
  3. reply_search_knowledge_base + reply_get_knowledge_base_article — answer a how-to and cite the source.
  4. Only if genuinely missing, reply_report_unsupported_request with a stable kebab-case requestKey and a category from its enum (integrations, reporting, sequences, contacts, email, linkedIn, ai, other) — then tell the user plainly you cannot do it. Offer the REST API if it covers the gap.

7. High-stakes tools

Require explicit confirmation in almost any agent UX — each reaches a prospect or changes ownership/state the instant it succeeds:

  • reply_start_sequence — begins outreach processing.
  • reply_add_contact_to_sequence — enrolls people into outreach.
  • reply_send_inbox_reply — sends a real message to a contact.
  • reply_approve_message / reply_bulk_approve_messages — send Jason’s drafts (bulk is atomic, ≤100).
  • reply_reject_messageirreversible: discards the draft AND removes the contact from the sequence. Use reply_regenerate_message if the user merely dislikes the draft.
  • reply_blacklist_contact — suppresses an email (or, with blockEntireDomain, a whole company domain — including future contacts) from all outreach.
  • reply_change_contact_owner — changes visibility and responsibility; trust only AffectedContactIds when reporting what changed.
  • reply_set_sequence_reply_modeAutonomous — Jason sends without per-message review.

Usually worth confirming too (production-affecting, but not prospect-visible): reply_pause_sequence, reply_change_status_in_sequence, the reply_assign_* / reply_attach_* configuration tools, reply_complete_task, and any create/update/delete on knowledge bases, reply handlers, reengagement cards, offers, or playbooks. The server’s destructiveHint annotation marks all 39 mutations — use it as the machine-readable gate.

8. Relationship to the REST API (v3)

MCP and the REST API are the same platform and the same account — two surfaces over one product. Base REST URL https://api.reply.io/v3, Authorization: Bearer auth, 100 req/min and 3000 req/hour.

  • MCP — interactive agent actions and natural-language workflows; 70 curated, annotated tools.
  • REST — bulk imports/updates, background jobs, report exports, webhooks, and template/schedule/mailbox management not exposed as tools.

Rough mapping of MCP tool areas to the REST modules in the API catalog:

MCP areaREST module
Sequence discover/controlSequence API
Contact search/CRUDContact Data API
Inbox toolsConversations & Inbox API
Jason KB / offers / playbooks / approvalsAI SDR API (Jason)
TasksTasks API
Email/LinkedIn account resolversMailbox Management · LinkedIn Accounts
Sequence/contact statsAnalytics API
reply_blacklist_contactSuppression & Blacklist API

9. Agent prompt guidance

Drop this into an agent’s system prompt when it has Reply MCP tools:

You have access to Reply.io MCP tools. For every request:
1. Classify it: read-only, configuration, outreach-changing, or prospect-visible send.
   The server annotates every tool (readOnlyHint / destructiveHint) — honor them.
2. For any mutation, resolve exact numeric IDs first with search/list/filter tools.
   Never guess an ID and never ask the user for one.
3. For high-stakes actions (send, approve, reject, start, enroll, blacklist, change owner,
   go Autonomous), summarize the target and side effect, then ask the user to confirm.
   Remember: reject_message removes the contact from the sequence — it is not "discard draft".
4. Parse results from result.content[0].text: {"Success":true,"Data":...} or
   {"Success":false,"ErrorCode":...,"ErrorMessage":...}. Branch on ErrorCode.
   Read per-item results (NotProcessed / AffectedContactIds) and report exact counts.
5. Do not pass unknown arguments (schemas are additionalProperties:false) and never send
   empty strings/arrays for required fields.
6. Paginate with top/skip until HasMore is false.
7. On failure, follow the tool's own failure-mode guidance. Do not blindly retry sends,
   approvals, starts, or enrollments — a timeout may already have succeeded; verify first.
8. If no tool fits, try reply_get_app_map and reply_search_knowledge_base before saying
   you can't; then reply_report_unsupported_request if it is truly missing.

10. Reproduce this

The reference on this page is not hand-maintained trust — regenerate it in seconds:

curl -s -X POST https://mcp2.reply.io/ \
  -H "x-api-key: YOUR_REPLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize",
       "params":{"protocolVersion":"2025-06-18","capabilities":{},
                 "clientInfo":{"name":"probe","version":"0.1"}}}'

# then:
curl -s -X POST https://mcp2.reply.io/ \
  -H "x-api-key: YOUR_REPLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

Responses are SSE — take the JSON after the last data: line. If the returned tool set differs from this page, the server is newer — trust the server. This reference was captured 2026-07-05.

Frequently asked questions

Is the MCP server real, and how current is this page?

Real and live. Endpoint https://mcp2.reply.io/, server Reply.Mcp v1.0.0.0, MCP protocol 2025-06-18. Every tool, parameter, enum value, annotation, envelope shape, and error mode on this page and the full tool reference (/mcp/tools) was read from the running server via authenticated initialize + tools/list and safe validation probes on 2026-07-05 — not from documentation. Re-probe any time; the surface grows.

How does authentication work?

Send your Reply.io API key as an x-api-key header or an Authorization Bearer token — this server accepts either. The endpoint also advertises OAuth 2.0 protected-resource metadata (authorization server oauth.sandbox.replyapp.io, scopes reply-web-api and mcp:tools) for clients that prefer an OAuth flow. Get an API key in the Reply.io app under Settings → API Key. No session header is required — initialize and tools/list work without Mcp-Session-Id.

How do I know which tools are safe to call?

The server tells you, machine-readably. Every tool carries MCP annotations — readOnlyHint (31 tools) or destructiveHint (39 tools). Agents can auto-gate on them; anything destructive that reaches a prospect or changes ownership (start, enroll, send, approve, reject, blacklist, change owner, go Autonomous) should also get explicit user confirmation. Note reply_reject_message is irreversible — it removes the contact from the sequence entirely.

What do responses look like?

Responses arrive as SSE (text/event-stream) frames carrying JSON-RPC payloads. The tool result is a JSON string inside result.content[0].text — {"Success":true,"Data":{...}} on success, {"Success":false,"ErrorCode":"...","ErrorMessage":"..."} on failure (with result.isError=true, HTTP still 200). Parse the inner JSON; branch on Success and ErrorCode.

When should an agent use MCP instead of the REST API?

Use MCP for interactive, natural-language work — 70 tools cover most day-to-day operations including the full Jason AI SDR autopilot. Use REST (api.reply.io/v3) for bulk imports, scheduled backend syncs, deep report exports, and anything tools/list does not expose.

Is the Jason autopilot really callable here?

Yes. The approval queue, the Review↔Autonomous switch, and the whole knowledge base / offer / playbook / reply-handler / reengagement-card surface are live MCP tools — even where the equivalent REST v3 autopilot endpoints are still rolling out.