Using Saava from an AI assistant
How Claude, ChatGPT, Codex or Cursor connect to Saava over MCP, the rules to follow, the common workflows, and every tool the connector offers.
These instructions live at https://docs.saava.io (plain text: https://docs.saava.io/mcp.md). Saava finds people showing buying signals, scores them against the user's targeting, and reaches them on LinkedIn and email. An assistant connected through MCP Connect can do almost everything the app does, from the chat: read leads and replies, build lists, watch for signals, write each person's messages, and reply.
Connect
The connector URL is https://www.saava.io/api/mcp. Add it as a custom connector (remote MCP server) in the assistant; the user signs in to Saava and approves one workspace. The connection sees only that workspace, and the user can remove it at any time from Integrations, MCP Connect, which stops access immediately.
- Claude: Settings, Connectors, Add custom connector, paste the URL. Needs a paid Claude plan.
- ChatGPT: Settings, Connectors (developer mode), add a custom connector with the URL.
- Codex and Cursor: add a remote MCP server with the URL in the MCP settings.
Rules for the assistant
- Ask before anything reaches a real person. Queuing messages, approving drafts, adding a lead to a campaign and sending a reply all go out under the user's name. Show the user the exact text or the people, and wait for a clear yes.
- Preview, then confirm. A tool that spends credits or takes something away (a search, deleting a monitor, removing a tracked profile or a campaign step) first returns a preview and a
confirm_tokenand does nothing. Show the user the preview, and only after they say yes call the same tool again with the same arguments plus thatconfirm_token. Changing any argument needs a new preview; a token lasts 15 minutes. - Check the account first.
get_account_statussays the plan, the credits left and whether sending is paused. A trial is free to use; a paid plan spends credits. - Targeting and the business profile are the user's. Suggest changes; change them only when the user asks.
- Write from the person, not a template. Use what
get_leadreturns about someone (their role, company, and what they posted or did) and keep messages short.
Common workflows
See what is happening
get_account_status for the plan and credits, list_campaigns and get_campaign_performance for results, and list_inbox then get_conversation for replies.
Find and organise leads
list_leads with filters (fit, stage, source, date), get_lead for one person, create_lead_list and add_leads_to_list to group them, and update_lead to record a stage or an outcome.
Find new leads
search_leads finds people in the database who match targeting filters (titles, industries, company sizes, places, optionally only people recently active on LinkedIn); search_intent_leads finds people showing a buying moment right now, described in plain English. Both need a lead count, a credit cap (max_credits) and the list the results go into (list_id, or new_list_name). Called without confirm_token they are the cost estimate: they start nothing and return the leads, the price per lead, the most the search can draw, the credits available and the searches left today. If the count could cost more than the cap, the preview lowers it and says what cap the full count needs. Show that to the user, and only after they agree call again with the same arguments plus the confirm_token. A search runs in the background: get_search_status says how it's going and why it stopped short, list_leads with the list_id shows the people, and list_searches lists past runs.
Write each person's messages yourself
Saava can send messages the assistant writes, one per lead, instead of a shared template. No add-on is needed: queuing them costs 0.5 credits per message (free on a trial).
list_campaignsand pick a campaign whosemessages_written_byisyour_aiorsaava_ai. A campaign that sends one template to everyone can't carry per-lead text. If there is none, create one withcreate_campaign: confirm its name, the LinkedIn accounts it sends from (list_linkedin_senders) and its steps with the user. It starts empty, so creating it sends nothing.get_campaign_message_shapefor that campaign: whether it sends a connection note, how many follow-ups, and the limits for each.- Write one message set per lead from their own details, show them to the user, then
queue_custom_messages(up to 50 leads per call). - The messages wait in AI Messages for the user's approval, or send straight away if the campaign approves automatically.
list_message_drafts,approve_message_draftsanddismiss_message_draftswork that queue from the chat.
Rename a campaign or change its wording
rename_campaign changes only the name. To change what a campaign says, get_campaign_messages shows each step's words and wait, and update_campaign_messages changes just the steps you pass. It works on a live campaign: the campaign keeps its id, its people and its stats, and new sends use the new text. Show the user the exact new wording and wait for a clear yes before calling it. To add, remove or switch off steps, or switch the connection note on or off, use update_campaign_steps: it returns the steps before and after and, for a campaign that has already started, what happens to the people already in it. Show the user that preview, then confirm with its confirm_token.
Control how AI messages are written and sent
get_campaign_settings shows whether a campaign's messages wait for approval, its guidance to the writer, its maximum note and follow-up lengths, and which business-profile fields the writer reads. update_campaign_settings changes them: auto_approve: false makes every new message wait for approval, guidance sets the campaign's notes to the writer, and max_note_chars / max_followup_chars set shorter limits (a message over its limit loses whole sentences, never half of one). Turning auto-approve on needs the user's explicit OK and confirm_auto_send: true.
export_message_history returns every message written for a campaign with ids, timestamps, status, any review hold and what it was written from, a page at a time. stop_lead_outreach stops all remaining automated messages to one person, including follow-ups already scheduled, without deleting anything; confirm with the user first.
Watch for buying signals
create_intent_monitor from a plain-English description of what to watch for (for example: companies hiring their first SDR), list_intent_monitors to see them, and list_sources or add_sources for the LinkedIn profiles whose audience Saava follows.
Reply to people
list_inbox, then get_conversation, then draft a reply, show it to the user, and send_linkedin_reply once they approve.
Keep the pitch current
get_business_profile and update_business_profile hold what the user sells, to whom, and the proof. Every message Saava writes is built from it, so keep it accurate. get_targeting shows who they sell to.
Change who Saava looks for
get_targeting shows each targeting profile: job titles, industries, company sizes, locations, exclusions and the description Lead Search reads. When the user asks for a change, update_targeting makes it: add or remove single entries with add_* / remove_* (or replace_* for a whole new list), and leave the rest alone. It first returns the before and after, and what the change sets off (leads re-scored, a first search, an immediate lead search); show that to the user and confirm with the confirm_token. Seniority and departments are changed in the app.
Tool reference
Every tool the connector offers, as the assistant sees it.
Leads, lists, campaigns and inbox
get_account_status: Snapshot of this Saava workspace: plan, billing state, credits, connected channels (LinkedIn outreach / email), and totals for leads, lead lists and campaigns. Call this first to orient.list_leads: Search and filter this workspace's leads. Returns compact rows sorted by newest or by ICP match. Statuses: active, snoozed, bad_fit, client. Outcomes: qualified, booked, won, not_a_fit.get_lead: Full detail for one lead by id: contact info, ICP score and reasoning, engagement, outreach status and which campaign it went to.update_lead: Update one lead: set status (active/snoozed/bad_fit/client), set outcome (qualified/booked/won/not_a_fit), or mark good_fit / bad_fit (mutually exclusive; marking one clears the other). Provide only the fields to change.list_lead_lists: All lead lists in this workspace with member counts and type.create_lead_list: Create a new lead list. Returns the new list's id.typeis optional and defaults to 'standard' — the kind you want for a list you fill yourself.add_leads_to_list: Add up to 200 leads (by id) to a lead list. Already-present leads are skipped.remove_leads_from_list: Remove leads (by id) from a lead list. The leads themselves are kept.list_campaigns: All outreach campaigns in this workspace (LinkedIn via the connected sender network, plus email campaigns if connected), with status and launch state.get_campaign_performance: Outreach funnel for a time window: per-campaign and per-sender invites sent, accepted, and replies. Defaults to the last 30 days.pause_campaign: Pause a LinkedIn campaign. Sticks until resumed: Saava also stops feeding it leads.resume_campaign: Resume a paused LinkedIn campaign so sending and lead routing restart.push_lead_to_campaign: Add one lead to a LinkedIn campaign so outreach actually goes to them. The lead needs a LinkedIn URL. This queues a REAL message sequence to a REAL person — confirm with the user before calling.list_inbox: Recent LinkedIn outreach conversations: who they're with, the last message, and unread state. Use unread_only to fetch just threads awaiting a reply.get_conversation: Full message history of one LinkedIn conversation by conversation_id.send_linkedin_reply: Send a reply into an existing LinkedIn conversation, as the user. This DELIVERS A REAL MESSAGE immediately — always show the user the exact text and get their go-ahead first.get_business_profile: The workspace's business profile (what they sell, to whom, proof points) — the grounding every AI-written message uses.update_business_profile: Update fields of the business profile. Only the fields provided are changed; everything else is kept. This grounds all AI-written outreach, so keep it factual.get_targeting: The workspace's saved targeting (ICP), one entry per targeting profile, the primary one first: titles, industries, locations, seniority, company sizes, exclusions and the free-text description. Each entry'sprofilekey is what update_targeting takes to change that profile; change targeting only when the user asks.update_targeting: Change a targeting profile: who Saava finds and how it scores them. Covers job titles, industries, company sizes, locations, exclusions and the description Lead Search reads. Lists change with add_ / remove_ (or replace_ for a whole new list); anything left out stays as it is. Change targeting only when the user asks. Returns a before-and-after preview plus what the change sets off (re-scoring, a first search, an immediate lead search) and changes nothing; call again with the same arguments plus the confirm_token once the user agrees. Seniority and departments are changed on the Targeting page.get_plans: What each Saava plan costs and includes, and what the current plan allows. Call this before suggesting an upgrade — upgrade_plan requires the price from here.upgrade_plan: Move this workspace UP to a higher plan and charge the card on file immediately: a full month of the new plan, minus the unused part of the current one. The billing date moves to today. Confirm the price with the customer first: this spends their money.confirm_monthly_usdmust match the plan's monthly price from get_plans. Downgrades and cancellations are not available here — those are done in Saava.rename_campaign: Rename a LinkedIn campaign. Only the name changes: the campaign, its id, its people and its stats stay as they are. Names are up to 120 characters.get_campaign_messages: The words a LinkedIn campaign sends, step by step: the connection note, each follow-up with its wait (days after the step before) and whether it's on, and the InMail if it has one. Read this before update_campaign_messages or update_campaign_steps; steps are numbered from 1.update_campaign_messages: Change the words or waits of a LinkedIn campaign, including a live one: it keeps its id, its people and its stats, and carries on sending with the new text (it pauses for a moment while the change is made, then resumes). Pass only what changes: the connection note, and/or follow-up steps by number (get_campaign_messages) with a new message and/or delay_days, and/or the InMail subject and message. To add, remove or switch off a step, use update_campaign_steps. These are real messages to real people under the user's name: show the user the exact new text and get explicit confirmation before calling. Personalize with {{firstName}}, {{lastName}}, {{companyName}} or {{position}}; other spellings of those ([First name], {{first_name}}) are corrected automatically, and any other variable is refused.update_campaign_steps: Add, remove, or switch off/on the follow-up steps of a LinkedIn campaign, and switch its connection note on or off, as one change. Step numbers are the ones get_campaign_messages shows now (1 = the first message after they accept), and every number in one call refers to the campaign as it is before the call. Called without confirm_token it changes nothing and returns a preview: the steps before and after, and, if the campaign has already started, what happens to the people already in it. Show the user that preview, including any new step's exact words, and only after they say yes call again with the same arguments plus the confirm_token. A switched-off step is kept and can be switched back on; a removed one is gone. On a campaign whose words are written for each person (messages_written_by your_ai or saava_ai) a new step takes only a wait, and the messages queued for it must then match the new steps (get_campaign_message_shape). To change an existing step's words or wait, use update_campaign_messages.get_campaign_settings: How Saava writes and sends for one AI-messages LinkedIn campaign: whether messages send without review (auto_approve), the campaign's guidance to the writer, the maximum note and follow-up lengths, the allowed ranges, and which business-profile fields the writer reads.update_campaign_settings: Change how Saava writes and sends for one AI-messages LinkedIn campaign. Only what you pass changes. auto_approve false makes every new message wait in the AI Messages queue for approval. auto_approve true sends future messages without review: it needs confirm_auto_send true and the user's explicit OK, and it does not release messages already waiting. guidance: the campaign's notes to the writer, up to 400 characters ("" clears it). max_note_chars (100-270) and max_followup_chars (150-500) cap new messages; a message over its cap is shortened by whole sentences, never cut mid-sentence. Voice is set in the business profile with update_business_profile.export_message_history: The full record of messages for audit, newest first, with ids and timestamps: per lead, the connection note, each follow-up and the InMail as written, the status (draft, approved, sent = handed to LinkedIn sending, dismissed, failed), created/approved/sent times, whether it was held for review and why, and what it was written from (how they engaged, the post's URL and author, whether the post is theirs, the role and company used). Follow-ups after the first are sent by LinkedIn's sequence on their waits once the person accepts; replies and delivered messages are in get_conversation. Page withbefore(the next_before value).stop_lead_outreach: Stop every remaining automated message to one person in one LinkedIn campaign, including follow-ups LinkedIn's sequence would send on its own, and dismiss any unsent messages for them. Nothing is deleted: the conversation and the message history stay, and the user can still message them by hand. Use it for anyone who shouldn't hear from the campaign again. It can't be undone from here, so confirm with the user first.pause_intent_monitor: Pause an intent monitor: it stops scanning LinkedIn (and spending) until resumed. Its leads, lists and scan history stay. Pausing doesn't free a plan slot; delete_intent_monitor does.resume_intent_monitor: Resume a paused intent monitor. It picks up scanning on its next scheduled check.update_intent_monitor: Change what an intent monitor watches for, in plain English (3-600 chars). Saava rebuilds its search keywords from the new description and starts a fresh scan. Leads it already found stay.delete_intent_monitor: Delete an intent monitor and free its plan slot. Returns a preview first; call again with the confirm_token after the user agrees. Its leads stay, and lists it fed keep their people. Recreating the same monitor later re-scans posts it had already read.remove_source: Stop tracking a LinkedIn profile or company page (from list_sources) and free its plan slot. Returns a preview first; call again with the confirm_token after the user agrees. Leads it already brought in stay.search_leads: Warm database search: find new people who match targeting filters and file them into a lead list. This is also how to get a cost estimate: called without confirm_token it spends nothing, makes no list and starts nothing, and returns a preview (leads, price per lead, the most it can draw, credits available, searches left today and any extra-search charge, the list it will fill) with a confirm_token. Show the preview to the user; once they agree, call again with the same arguments plus confirm_token to start it. Leads are charged only as they're delivered (1.5 credits each, 2 with recently_active), never more than max_credits in total. Tell the user the recently_active price before they confirm. Any filter left out comes from the saved targeting, as on the search page; pass [] to drop one. The search runs in the background: follow it with get_search_status.search_intent_leads: Intent search: find people showing a buying moment right now (posting about it, researching it, hiring for it) who fit the targeting, and file them into a lead list. Describe the moment in plain English; name topics, keywords or competitors in it and Saava turns it into its own search phrases. It reads recent activity only (posts from about the last six weeks); there is no date-range setting. This is also how to get a cost estimate: called without confirm_token it spends nothing and starts nothing, and returns a preview (leads, price per lead, the most it can draw, credits available, searches left today, the list it will fill) with a confirm_token. Show it to the user; once they agree, call again with the same arguments plus confirm_token. Charged per lead delivered (8 credits; more at a stronger research level), nothing for looking, never more than max_credits. Often finds fewer than asked. Follow it with get_search_status.get_search_status: How a search started with search_leads or search_intent_leads is doing: queued, running, done or failed, how many leads it has delivered of how many asked, the list they're in, and why it stopped short if it did. The people themselves: list_leads with the list_id.list_searches: Past and running searches in this workspace, newest first: when each ran, warm database or intent, status, leads delivered of how many asked, and the list they went into. Use a search_id with get_search_status for details.
Messages
get_campaign_message_shape: What one message for a campaign must contain before you write it: whether it sends a connection note, how many follow-ups (in order), whether it sends an InMail to open profiles, the character limits, and the personalisation tokens allowed. Call this before queue_custom_messages.queue_custom_messages: Queue messages YOU wrote, one per lead, for a per-lead campaign (messages_written_by your_ai or saava_ai; up to 50 leads per call). Each lead's text must match the campaign's shape from get_campaign_message_shape. Costs 0.5 credits per message queued (free on a trial). Messages land in the AI Messages review queue — or send straight away if the campaign auto-approves. These are real messages to real people under the user's name: show the user the exact text and get explicit confirmation before calling. A lead that already has a sent or approved draft in this campaign is skipped; an unsent draft is replaced at no charge.list_people_waiting: People waiting for YOU to write their messages in a your_ai campaign: everyone a lead list attached to it brought in who has nothing queued yet (attach_lists_to_campaign adds lists; new list members keep arriving). Write each one's messages to the campaign's shape (get_campaign_message_shape) and queue_custom_messages; they leave this list as you queue. Paged by offset.list_message_drafts: Messages waiting in the AI Messages queue (or recently sent/failed): who they're for, the text, the status, and who wrote them. Filter by campaign and status.approve_message_drafts: Approve queued messages so they send: either specific draft ids, or everything waiting in one campaign. Sending happens in the background, one lead at a time. This sends real messages to real people — confirm with the user first. Drafts flagged sensitive_context are skipped unless include_sensitive is true.dismiss_message_drafts: Dismiss queued messages so they never send. The lead stays in the workspace; only the pending message is withdrawn.
Setup
list_linkedin_senders: The LinkedIn accounts this workspace sends from, with their ids. Use an id in create_campaign's sender_ids.create_campaign: Create a LinkedIn campaign whose messages YOU write, one set per lead (messages_written_by: your_ai). No add-on is needed; each message costs the same as queue_custom_messages when you queue it (free on a trial). The campaign starts with nobody in it: people join only when you queue their messages with queue_custom_messages, so creating it sends nothing. Confirm the name, the sending accounts and the steps with the user first. Steps: an optional connection note, then up to 4 follow-up messages, each sent a number of days after the one before.list_campaign_lists: Which lead lists feed a campaign (a campaign sends to the people in its attached lists, continuously). Shows attached and previously-detached lists with sync counts.attach_lists_to_campaign: Plug lead lists into a LinkedIn campaign so it keeps sending to everyone in them, now and as the lists grow. Leads start going out within minutes, subject to the campaign's fit floor and daily limits. On a your_ai campaign nothing is sent: the lists' people wait for you to write their messages (list_people_waiting, then queue_custom_messages). This causes real outreach — confirm with the user first.detach_list_from_campaign: Stop a lead list feeding a campaign. Only FUTURE sends stop — people already in the sequence keep receiving it. Re-attaching later resumes where it left off.list_sources: The LinkedIn profiles and company pages this workspace watches. Everyone who likes or comments on their posts is pulled in as a lead and scored against the targeting.add_sources: Watch LinkedIn profiles or company pages (up to 20 URLs per call). Their engagers start arriving as leads within minutes. Counts against the plan's source limit; re-adding one already watched just refreshes it.list_intent_monitors: The intent monitors in this workspace — each watches LinkedIn posts for a buying signal described in plain English and turns matching posters into leads.create_intent_monitor: Create an intent monitor from a plain-English description of the buying signal to watch for (e.g. "companies hiring their first SDR"). Saava turns it into search keywords and starts scanning right away. Optionally send its leads to an existing lead list. Counts against the plan's monitor limit.