Leadbay

AI lead discovery, qualification, and outreach prep on your Leadbay account.

От сообщества: Добавлен пользователем или импортирован; проверьте владельца перед подключениемРаботаетБез входаГлобальныйБесплатноТолько чтение

Что умеет

  • Leadbay Lead Job Status: ## WHAT IT DOES Poll a running leadbay_find_new_leads / leadbay_qualify_leads job by job_id — cumulative results and funnel. Use when a delivery tool returned still_running:tr
  • Leadbay Pull Leads: ## WHAT IT DOES Pull today's NEW leads from the user's Discover wishlist — fresh prospects the AI has scored for fit, not the known pipeline. Records each one as seen. ## WHEN TO U
  • Leadbay Pull Followups: ## WHAT IT DOES Pull the KNOWN leads that are due a follow-up (the Monitor view), filtered by city, sector, recency or last action. ## WHEN TO USE Trigger phrases: "what should

Какие данные видит

Нужен ли аккаунт

Не нужен: сервер работает без входа

AI lead discovery, qualification, and outreach prep on your Leadbay account.

Leadbay finds lookalikes of your best customers and reasons like your best sales rep, at scale. Connect it to Claude, ChatGPT, Cursor or any MCP client to pull leads, qualify them, draft outreach and log activity in plain language, on your real Leadbay data and with your permissions.

Sign in once with your Leadbay account (OAuth), no API token needed. US accounts use https://mcp.leadbay.app/mcp, France / EU accounts use https://mcp.leadbay.app/fr/mcp.

Docs: https://docs.leadbay.app/doc/leadbay-mcp/what-is-leadbay-mcp

Как подключить

Как подключить Leadbay к Claude

Адрес сервера, который нужно вставить в настройках Claude:

https://leadbay--leadbay.run.tools

  1. Откройте Claude (сайт claude.ai или приложение для компьютера).
  2. Перейдите в Настройки → Коннекторы (в английском интерфейсе: Settings → Connectors).
  3. Нажмите Добавить пользовательский коннектор (Add custom connector).
  4. Вставьте адрес сервера, скопированный ниже, в поле URL удалённого MCP-сервера и нажмите Добавить.
  5. В чате нажмите + → Коннекторы и включите новый коннектор.

Пользовательские коннекторы доступны на тарифах Free, Pro, Max, Team и Enterprise. На Free можно добавить только один. В Team и Enterprise коннектор сначала добавляет владелец организации в Настройки организации → Коннекторы.

Авторизация

После нажатия Добавить откроется окно входа в сервис. Войдите под своим аккаунтом и подтвердите доступ. Пароль Claude не видит.

Как подключить Leadbay к ChatGPT

Адрес сервера, который нужно вставить в настройках ChatGPT:

https://leadbay--leadbay.run.tools

  1. Откройте ChatGPT в браузере (chatgpt.com). Нужен тариф Plus, Pro, Business, Enterprise или Edu.
  2. Один раз включите режим разработчика: Настройки → Приложения → Дополнительные настройки → Режим разработчика (Settings → Apps → Advanced settings → Developer mode).
  3. Откройте Настройки → Коннекторы и нажмите Создать (Create).
  4. Заполните форму: Название (любое), Описание (одна фраза, что делает сервис), URL MCP-сервера (скопируйте ниже).
  5. В поле Аутентификация выберите OAuth, если сервис требует вход, иначе Нет. Нажмите Создать.
  6. В новом чате откройте + → Приложения/Коннекторы и включите коннектор.

Название раздела у OpenAI менялось (Connectors → Apps/Plugins). Если пункт называется иначе, ищите «режим разработчика» в настройках. В рабочих пространствах Business/Enterprise администратор должен разрешить пользовательские коннекторы.

Авторизация

При первом использовании ChatGPT откроет окно входа в сервис. Войдите и подтвердите доступ.

Как подключить Leadbay к Cursor

Адрес сервера, который нужно вставить в настройках Cursor:

https://leadbay--leadbay.run.tools

Быстрый способ: нажмите кнопку Открыть в Cursor ниже, Cursor сам предложит добавить сервер.

Вручную:

  1. В Cursor откройте Settings → Cursor Settings → MCP и нажмите Add new global MCP server.
  2. Вставьте JSON, скопированный ниже, в открывшийся файл ~/.cursor/mcp.json (для одного проекта: .cursor/mcp.json в корне проекта).
  3. Сохраните файл. Сервер появится в списке MCP; при необходимости пройдите авторизацию по кнопке рядом с ним.

Авторизация

Если сервис требует вход, рядом с сервером в списке MCP появится кнопка авторизации.

Список инструментов сервера (60)

Технические названия из tools/list. Нужны только разработчикам.

leadbay_lead_job_status## WHAT IT DOES Poll a running leadbay_find_new_leads / leadbay_qualify_leads job by job_id — cumulative results and funnel. Use when a delivery tool returned still_running:true or the user asks "is it done / any results yet". Don't use it for enrichment jobs (leadbay_bulk_enrich_status) or imports (leadbay_import_status). ## WHEN TO USE Trigger phrases: "is the lead search done", "any results yet on that job", "check on the delivery". Do NOT use for: "is the enrichment done" → `leadbay_bulk_enrich_status`; "is my import done" → `leadbay_import_status`; "is the top-N qualification done" → `leadbay_qualify_status`. Use this when: a find_new_leads / qualify_leads result carried next_poll — pass its job_id, and wait_seconds 45 while the user waits on the result. Examples that SHOULD invoke this tool: - "Any leads yet from that search you started?" - "Wait for the qualification job to finish and show me everything." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Is the email enrichment finished?" - "Is my CSV import done?" ## RENDER (quick) Terminal job -> render the full delivery per the lead-delivery table + honest funnel line. Still running -> one progress line (examined / delivered so far), then check again in this turn. Never render UUIDs or cursors. --- Cumulative snapshot of a lead-delivery job: state, funnel counters, every item emitted so far (compact lead payloads for delivered/degraded, with one reason and the freshest signals; full evidence via `leadbay_research_lead_by_id`; honest status_reason for skipped), internal usage counters (never render them), and the `explain` block (basis, seed strategy, scope notes). Items are immutable once emitted — polling never re-reads live data, so numbers only ever grow. `wait_seconds: 0` (default) answers instantly; 45 (the maximum) waits for completion — use it while the user waits on the result. `since` (from a prior poll's `next_since`) pages only the new items. Jobs termina
leadbay_pull_leads## WHAT IT DOES Pull today's NEW leads from the user's Discover wishlist — fresh prospects the AI has scored for fit, not the known pipeline. Records each one as seen. ## WHEN TO USE Trigger phrases: "show me leads", "show me new leads", "show me today's leads", "today's prospects", "best new leads", "fresh leads", "what's new today". Do NOT use for: "find me N companies that <specific profile>", "new prospects like <company> with their emails" → `leadbay_find_new_leads`; "leads I should follow up with", "leads I should reach out to", "leads to get back to", "leads to contact today", "should I contact", "reconnect with", "re-engage" → `leadbay_pull_followups`; "I'm going to <city>", "I'm in <city> next week — who's worth meeting", "who should I meet in <city>", "visiting <city> — who's worth meeting / seeing" → `leadbay_tour_plan`. Use this when: fresh Discover leads; if a lens is named, pass `lensId` and pin it Examples that SHOULD invoke this tool: - "Show me today's leads." - "Pull my best new prospects." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Find me 10 gyms around Dallas that would buy our flooring." - "Which leads should I follow up with this week?" - "I'm flying to Berlin Thursday — who should I meet?" - "I'm in San Francisco next Tuesday — who's worth meeting?" - "Show me leads I should reach out to today." - "Who should I get back to today?" - "Leads I should contact today." ## RENDER (quick) 3-col markdown table in the order the tool returns them (the Discover-tab order — do NOT re-sort by score) — DO NOT print the numeric score. Col 1 = inline-code 10-segment bar (`▰` firmographic, `❖` AI booster cap at the right end of the filled run, `▱` empty; filled=round(score/10), ai=round(avg_boost/3.3)) + `<br>` + linked company · location · size. Col 2 = why-fits ≤20 words. Col 3 = linked contact + title. Full algorithm + linking rules below. --- **Side effect.** Leads returned here are recorded as seen in the us
leadbay_pull_followups## WHAT IT DOES Pull the KNOWN leads that are due a follow-up (the Monitor view), filtered by city, sector, recency or last action. ## WHEN TO USE Trigger phrases: "what should I follow up on", "leads I've already worked", "what's overdue", "stale leads", "leads in <city / state / region>", "reach out to today", "should reach out to", "get back to", "contact today", "reconnect with", "re-engage", "leads to contact", "who should I ping". Do NOT use for: "new leads / today's prospects" → `leadbay_pull_leads`; "map / trip / in person" → `leadbay_followups_map`. Use this when: known Monitor leads; pass `city` or `set_filter` for geo/sector/recency; NEVER a country name — a whole-country ask means NO geo filter Examples that SHOULD invoke this tool: - "What should I follow up on this week?" - "What's overdue in my pipeline?" - "Show me leads I should reach out to today." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me today's new leads." - "Draft an email to Sarah at Acme." ## RENDER (quick) 4-col markdown table sorted by `last_monitor_action_at` desc, NO score bar (status badges instead). Col 1 = status (🎯⚡🟢💤✨🔥❄) + company link + location/size. Col 2 = AI take (3 lines from `split_ai_summary`). Col 3 = history + notes. Col 4 = contacts (★ recommended, ☎ 📧 pills). Active-filters chip line ABOVE the table. Detail + status priority below. --- Wraps `GET /1.6/monitor`, preceded by `POST /1.6/monitor/filter` when `set_filter` is supplied. The Monitor filter is one `FilterItem` per user, server-persisted across sessions; `set_filter` overwrites it. **Filter mechanism — store-then-apply.** `set_filter: { criteria: FilterCriterion[] }` overwrites the stored filter, then the composite re-fetches with `filtered:true`. Every `FilterCriterion` MUST carry a `type` discriminator — `{sector_ids: [...]}` is silently dropped, `{type: "sector_ids", sectors: [...]}` is not. Types: `size`, `keywords`, `sector_ids`, `location_ids`, `cu
leadbay_followups_map## WHAT IT DOES Plot follow-up leads on a map for travel / in-person / "I'm going to <city>" intent. Same backend as pull_followups; pass `city` (NYC / SF / LA aliases auto-expand) and route into either `places_map_display_v0` (Claude native widget) or per-lead place-card prose blocks (host's auto-detected carousel). ## WHEN TO USE Trigger phrases: "I'm going to <city>", "visit in person", "map of leads", "plan my itinerary". Do NOT use for: "default follow-up table" → `leadbay_pull_followups`; "new prospects" → `leadbay_pull_leads`. Use this when: geographic, travel, in-person, itinerary, or map intent; NEVER a country name — a whole-country ask means NO geo filter Examples that SHOULD invoke this tool: - "I'm flying to New York Thursday — who should I meet in person?" - "Who can I visit while I'm in Chicago next week?" Examples that should NOT invoke this tool (sound similar, route elsewhere): - "What should I follow up on this week?" - "Tell me about Acme Corp." ## RENDER (quick) Two render surfaces — host picks. Primary: route to Claude's `places_map_display_v0` widget with `{name, address (lead.location.full), latitude+longitude (lead.location.pos[0/1]), notes (short prose with bare phone+email)}` per lead. Fallback: per-lead markdown blocks `### **Company** · City, ST` + one-sentence note + bare phone/email — chat hosts auto-detect into place-card carousel. Detail below. --- Plot the user's follow-up leads on an interactive map for travel / in-person / "I'm going to <city>" intent. Wraps `leadbay_pull_followups` (same params, response, store-then-apply geo filter); named separately so the agent has an explicit entry-point for travel intent and can route to `places_map_display_v0` (when the host exposes it) or emit place-card prose blocks (which most chat hosts auto-detect into Google Place cards). **Common city aliases resolve automatically** — `NYC` / `New York` → City of New York, `SF` / `S.F.` → San Francisco, `LA` / `L.A.` → Los Angeles, `DC` /
leadbay_tour_plan## WHAT IT DOES Build a mixed-mode field-sales itinerary for a city — Monitor follow-ups (known accounts) + fresh Discover leads (new prospects) in one call. The single entry point for "I'm visiting <city> in N days — who should I meet". Pairs with the `leadbay_plan_tour_in_city` prompt and renders via `places_map_display_v0`. ## WHEN TO USE Trigger phrases: "visiting <city> in <N> days", "I'm in <city> next week / Tuesday — who's worth meeting", "I'm going to <city> — who should I see", "who's worth meeting in <city>", "field tour in <city>", "plan a tour in <city>", "who should I meet in <city>", "prospects within <N> km of <city>", "<city> and the surrounding area", "customers plus prospects in <city>", "tour itinerary". Do NOT use for: "follow-ups only, no new prospects" → `leadbay_followups_map`; "new leads only" → `leadbay_pull_leads`; "research one account" → `leadbay_research_lead_by_id`. Use this when: known accounts plus new discoveries in one itinerary; pass `radius_km` when they name a radius; NEVER a country name, and do NOT omit `city`: a city-less tour is arbitrary nationwide leads, so ask which city or region Examples that SHOULD invoke this tool: - "I'm flying to Limoges in 4 days — give me 3 customers, 3 qualified prospects, and 3 new high-potential." - "I'm in San Francisco next Tuesday. Who's worth meeting?" - "Plan my tour next Tuesday in Lyon: known accounts plus discoveries." - "Build a mixed itinerary for Berlin — I want both follow-ups and fresh leads." - "J'ai un rdv le 19 août à Colmar — trouve-moi les prospects dans un rayon de 10km." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me my follow-ups for the SF trip." - "What's new in today's batch?" - "Tell me about Acme Corp." ## RENDER (quick) Present the leads grouped by mode (★ Customer / ★ Qualified / ✦ New), then ALWAYS offer to plot them on a map ("Want me to put these on a map?"). On yes (or if the user asked for a map up front), render
leadbay_list_campaigns## WHAT IT DOES List the caller's campaigns with roll-up stats (lead count, contact count, contacted / meeting-booked / declined counts). The manager's "what's in flight" view. Scoped to the calling user — teammates' campaigns are not surfaced (backend filters by `created_by`). ## WHEN TO USE Trigger phrases: "what campaigns do I have", "list my campaigns", "show me my active campaigns", "campaign overview", "what's in flight", "pulse on my campaigns". Do NOT use for: "create a new campaign", "prepare campaigns to re-engage my prospects" → `leadbay_create_campaign`; "drill into one specific campaign's progression" → `leadbay_campaign_progression`. Use this when: user wants the pulse / overview view across all their campaigns. Use campaign_progression to drill into one Examples that SHOULD invoke this tool: - "What campaigns am I running?" - "Show me my active campaigns and how they're doing." - "Quick pulse on my campaigns." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Create a 'Q2 Push' campaign." - "How are leads progressing in my Limoges Tour?" - "Today's fresh leads." - "Prepare 3 email campaigns to re-engage my prospects." ## RENDER (quick) Render as a compact markdown table sorted by `updated_at` desc: | Campaign | Leads | Contacted | Meetings | Declined | Updated | Each row links to "View progression" via a NEXT STEPS chip that passes the campaign_id back into `leadbay_campaign_progression`. Suppress archived rows unless `archived: true` was passed. --- List the caller's campaigns with roll-up stats. Wraps `GET /campaigns` (with `?archived=true` to surface archived ones). Each entry is `CampaignWithStatsPayload`: the campaign object + `lead_count`, `contact_count`, `contacted` (leads with any logged outreach), `meeting_booked` (leads with a recorded meeting outcome), `declined` (leads with a recorded decline). **Scope warning**: this list is filtered server-side to campaigns the calling user CREATED. Other users i
leadbay_campaign_progression## WHAT IT DOES Per-lead progression inside one campaign. For each lead: contact counts (total / in-progress / declined), the most recent interaction headline, and affiliation overlap (which OTHER campaigns this lead is also in, plus a teammate-overlap count). The drill-down view for managerial follow-up. ## WHEN TO USE Trigger phrases: "how is my <name> campaign doing", "campaign progression", "lead-by-lead status on <campaign>", "who in <campaign> have I contacted", "what's stuck in my campaign". Do NOT use for: "pulse across all campaigns (not one)" → `leadbay_list_campaigns`; "log an outreach event" → `leadbay_report_outreach`. Use this when: user named (or just selected from list_campaigns) ONE campaign and wants per-lead status. Use list_campaigns for the cross-campaign overview Examples that SHOULD invoke this tool: - "Walk me through the Limoges Tour campaign — who have I touched?" - "Show progression on campaign 1f12...?" - "What's stuck in my Q2 Push?" Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me all my campaigns." - "Create a new campaign." - "Log that I emailed Acme." ## RENDER (quick) Two-tier render. Top: one-line summary ("Limoges Tour: 9 leads · 4 contacted · 1 meeting · 0 declined"). Then a markdown table per lead: | Lead | Score | Contacts | Last action | Also in | Each row's "Also in" column lists `affiliation.own_campaigns[]` names (with a ⚠ suffix if `other_users_campaign_count > 0`, indicating teammates also have it). Sort by progress.headline recency or by score desc — pick whichever surfaces "needs attention" leads first. --- Per-lead progression view for one campaign. Wraps `GET /campaigns/{id}/leads` (paginated). For every lead in the campaign: - **lead** — full `LeadPayload` (same shape `pull_leads` / `pull_followups` return), so the agent has score, contacts, ai_summary, location, etc. without an extra round trip. - **progress** — `{total_contacts, in_progress, declined, headline}`. `t
leadbay_campaign_call_sheet## WHAT IT DOES Cold-calling cheat sheet for a campaign — joins `/campaigns/{id}/contacts` + `/campaigns/{id}/leads` into one call-ready payload. Each lead block carries the AI next-step + every reachable contact (name, phone with `tel:` URL, LinkedIn, role). Optional `map_locations` is ready to pass into `places_map_display_v0` for a geographic call route. ## WHEN TO USE Trigger phrases: "campaign call sheet", "people to call in <campaign>", "cold-calling cheat sheet", "work this campaign", "calling session for <campaign>". Do NOT use for: "campaign pulse only" → `leadbay_campaign_progression`; "create campaign" → `leadbay_create_campaign`; "list campaigns" → `leadbay_list_campaigns`. Use this when: user wants one campaign with phone + LinkedIn contacts ready to call Examples that SHOULD invoke this tool: - "Show me my Limoges Tour campaign as a call sheet." - "I'm about to do a calling session — render the Q2 Push campaign." - "Give me phones + LinkedIn for everyone in my OK Sweep campaign." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Quick pulse on how my campaigns are doing." - "Save these 9 leads as a new campaign." - "Tell me about Acme Corp." ## RENDER (quick) Per-lead CARD sorted by AI score desc. Heading `### ⚡ **<Company>** — <City>, <State>`; one-line "★ Next step: …" from split_ai_summary; then a 4-col table of contacts: Contact / Phone / Role / Recent. Cell 1 stacks linked name + email + (if constructed) LinkedIn marker °. Phone is `[bare](tel:URL)`. Recent stacks last note + lead headline. Top of page = summary chip from `summary` + readiness flags. --- Build a cold-calling cheat sheet for one campaign. The composite joins two backend reads — `/campaigns/{id}/contacts` (per-contact phones, LinkedIn URLs, emails, job titles, recent notes) and `/campaigns/{id}/leads` (per-lead AI next-step, location, score, progress) — into a single call-ready payload aligned to the lead's page order. **Per-lead block** carr
leadbay_research_lead_by_id## WHAT IT DOES Return everything decision-relevant about one lead identified by its Leadbay UUID: qualification answers, web-research signals, firmographics, contacts and recent activity in one call. Use leadbay_research_lead_by_name_fuzzy when only the company name is known. ## WHEN TO USE Trigger phrases: "tell me about this lead", "deep dive on the lead I just picked", "everything you know about lead <UUID>". Do NOT use for: "company name without lead id" → `leadbay_research_lead_by_name_fuzzy`; "draft outreach for <Contact>" → `leadbay_prepare_outreach`; "add a contact to this company" → `leadbay_add_contact`. Use this when: user picked a row and you have its UUID; pass `leadId` Examples that SHOULD invoke this tool: - "Tell me everything about that lead I just picked." - "Is this one actually a fit — what does the AI think?" Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Look up Acme Corp for me." - "Show me today's leads." --- Payload order is deliberate: qualification, signals, firmographics, contacts, recent activity. Contacts arrive in two tiers (`enriched` + `org`), web-research signals carry hot flags + sources, and `_meta.has_reachable_contact` drives NEXT STEPS. **Side effect.** Leads returned here are recorded as seen in the user's own Leadbay account, which rotates them out of tomorrow's Discover list. Scoring has two layers: the basic `score` (firmographic, always present) and the AI qualification layer (`ai_agent_lead_score` + per-question answers + web_fetch signals). The AI layer is pre-populated for roughly the top 10 of each daily batch, and on-demand (via leadbay_bulk_qualify_leads) below that. Combine both when judging a lead. **leadbay_research_lead_by_name_fuzzy** wraps this tool when the user names a company without a UUID: same shape, plus `_meta.resolved_from` / `_meta.match_candidates`. WHEN TO USE: when picking up a single lead from leadbay_pull_leads (or any list that exposed a leadId) to
leadbay_research_lead_by_name_fuzzy## WHAT IT DOES Resolve a company name, domain, or contact across the user's own leads and the Leadbay company registry, then return its research card. Use when there is no lead_id; use leadbay_research_lead_by_id when the UUID is known. ## WHEN TO USE Trigger phrases: "look up <Company>", "research <Company>", "what do we know about <Company>". Do NOT use for: "picked row with leadId" → `leadbay_research_lead_by_id`; "draft outreach for <Contact>" → `leadbay_prepare_outreach`; "for each of these companies…" → `leadbay_qualify_leads`. Use this when: ONE company name or domain in prose, no Leadbay id yet — always pass `website` if a domain was mentioned Examples that SHOULD invoke this tool: - "Look up Acme Corp for me." - "Find Initech in my pipeline." - "Who is Wink Lab? Their email is at @wink-lab.com." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Tell me about that lead I just picked." - "Draft outreach to Acme's CTO." - "Websites and LinkedIn for these 200 companies." --- **Side effect.** Leads returned here are recorded as seen in the user's own Leadbay account, which rotates them out of tomorrow's Discover list. **Pass `website` whenever the user mentioned a domain.** It survives a misspelled name and turns "not in your list" into an answer. With only a contact email, pass `email`: the domain is derived from it, consumer mailboxes ignored. Both `resolution` answers below are successes, not cards. `"ambiguous"` carries `candidates[]`: ask which one, never guess from `score`. `"not_found"` carries `summary` + `next_step`: say nobody has it, then do what `next_step` says. --- ## RENDERING — single-record research card, mode-adaptive Present as a single-record card, not a table. This tool gets invoked in two distinct user contexts — detect which and adapt the body density accordingly. **MODE A — Discovery.** The user is evaluating whether to pursue this company as a target. Signals: "tell me about", "what do they
leadbay_get_qualification_questions## WHAT IT DOES Retrieve the org's qualification questions, its ideal buyer profile and its targeting prompt — everything that decides which leads Leadbay surfaces. Use when the user wants to know HOW their leads are qualified, and ALWAYS before changing any of it. Don't use it for one lead's qualification ANSWERS (that's leadbay_research_lead_by_id). ## WHEN TO USE Trigger phrases: "what are my qualification questions", "what questions does Leadbay ask about each lead", "show me the org qualification questions", "how are my leads being qualified", "what's the qualification criteria", "(before any settings change) what is configured today", "why am I getting these leads", "the leads aren't relevant — what are my settings". Do NOT use for: "how did this lead score on the qualification questions" → `leadbay_research_lead_by_id`; "change / add / remove a qualification question" → `leadbay_set_qualification_questions`; "answer a pending clarification" → `leadbay_answer_clarification`. Use this when: user wants the ORG-level qualification settings, or you are about to change any of them — read this FIRST to see whether their rule is already covered Examples that SHOULD invoke this tool: - "What qualification questions does Leadbay use to score my leads?" - "Show me my org's qualification questions." - "Why do I keep getting these companies? What are my settings?" Examples that should NOT invoke this tool (sound similar, route elsewhere): - "How did Acme Corp answer the qualification questions?" - "Add a question about install crews." ## RENDER (quick) Numbered list of the questions (chat-native markdown), each one line, verbatim. Below it, the ideal buyer profile summary + anti-patterns and the targeting prompt when set. When `is_admin` is true, append the `hint` as a footnote (points at leadbay_set_qualification_questions). When the question list is empty, say so explicitly and render the `hint` instead. --- Retrieve the organization's **qualification questio
leadbay_getting_started## WHAT IT DOES Returns the guided first-run walkthrough script — four one-forward-option gates (check the account → pull leads → draft a first email to the top one → reveal who to send it to). Use when the user is new or asks to be SHOWN how Leadbay works. Don't use it to answer a data question or orientation prose. ## WHEN TO USE Trigger phrases: "walk me through leadbay", "I'm new", "how do I use this", "getting started", "show me how this works", "give me a tour", "help me get started", "I just installed this". Do NOT use for: "show me today's leads" → `leadbay_pull_leads`; "which audiences do I have" → `leadbay_manage_lenses`; "where am I / what's my plan and quota" → `leadbay_account_status`. Use this when: the user has never used Leadbay, or asks to be SHOWN rather than told — the walkthrough runs real calls on their own account Examples that SHOULD invoke this tool: - "Walk me through Leadbay." - "I'm new here — how do I use this?" - "Can you show me how this works?" Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me today's leads." - "Explain the difference between discovery and follow-up." - "Which of my lenses is active right now?" ## RENDER (quick) Not a data table. Run the walkthrough ONE gate at a time: fire your host's choice widget with that step's forward option + exit, wait for the click, make that step's tool call, then advance. Never dump all four steps at once, and never render a gate as a prose question. --- Returns the **guided first-run walkthrough** — a short script the agent drives so a brand-new user learns Leadbay by *doing*, not by reading. Makes no backend call and mutates nothing; the content is static and version-locked. Every click in the walkthrough runs a real Leadbay call against the user's own account. By the end they have confirmed which account they're on, pulled today's leads, had a first email drafted to the best of them, and revealed the person to send it to. Every gate calls a
leadbay_get_lead_custom_fields## WHAT IT DOES Retrieve the CRM custom-field VALUES stored on one lead. Use when the user asks what custom fields a specific company/lead has, or for the value of a named custom field on a lead. Don't use it for the custom-field DEFINITIONS / catalog (that's leadbay_list_mappable_fields) or for a lead's full research dossier (that's leadbay_research_lead_by_id). ## WHEN TO USE Trigger phrases: "what custom fields are on this lead", "show the CRM custom field values for <Company>", "what's the <custom field name> on this lead", "get lead <UUID>'s custom fields", "does this lead have any custom field values". Do NOT use for: "what custom fields exist on my account" → `leadbay_list_mappable_fields`; "give me the full research dossier on this lead" → `leadbay_research_lead_by_id`. Use this when: user wants the custom-field VALUES on ONE lead; pass `leadId` Examples that SHOULD invoke this tool: - "What custom field values are stored on this lead?" - "Show me the CRM custom fields for that company." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "What custom fields are defined on my account?" - "Give me the full research breakdown on Acme Corp." ## RENDER (quick) 3-column markdown table: Field | Type | Value, one row per entry. When `custom_fields` is empty, render the `hint` sentence instead of an empty table. --- Retrieve the CRM custom-field **values** stored on a single lead — the actual data (`value`) per custom field, not the field definitions. **Side effect.** Leads returned here are recorded as seen in the user's own Leadbay account, which rotates them out of tomorrow's Discover list. This is distinct from **leadbay_list_mappable_fields**, which returns the org's custom-field *catalog* (the definitions: id/name/type, used for import mapping). This tool answers "what does *this* lead hold for each custom field". Params: `leadId` (required UUID); `lensId` (optional escape hatch — normally omit; auto-resolves to the ac
leadbay_account_history## WHAT IT DOES Give me ONE account's full back-story in a single call — current AI signals PLUS the historical notes logged on the record PLUS the full interaction timeline. Use when the user wants to know why a dormant or half-forgotten account is worth revisiting. Don't use it for the live-signals-only deep dive (that's leadbay_research_lead_by_id) or for a list of accounts to follow up (that's leadbay_pull_followups). ## WHEN TO USE Trigger phrases: "what's the history on this account", "why should I revisit this account", "summarize everything we've done with <Company>", "has this account gone cold", "give me the back-story on lead <UUID>". Do NOT use for: "live signals only, no history" → `leadbay_research_lead_by_id`; "which accounts should I follow up with" → `leadbay_pull_followups`. Use this when: user wants ONE account's full back-story — notes + past activity + current signals together; pass `leadId` Examples that SHOULD invoke this tool: - "What's the full history on this account — why did it resurface?" - "Summarize everything we've logged on that lead and whether it's worth another visit." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Tell me the current AI take on this lead." - "Which accounts should I follow up with this week?" ## RENDER (quick) Single resurfaced-account card. Lead the card with the current signal/trigger line (from `signals`), then a "History" section: notes digest (chronological) + the activity timeline. Close with a one-line "why revisit now" synthesis and a suggested outreach angle tied to the freshest signal. --- Give me one account's full back-story in a single call. This is the tool for the **reprioritize-a-neglected-account** workflow: the user has an account that was contacted or quoted long ago and wants to know, in one shot, whether a fresh signal makes it worth another visit. **Side effect.** Leads returned here are recorded as seen in the user's own Leadbay account, which rot
leadbay_scan_portfolio_signals## WHAT IT DOES Scan a KNOWN portfolio (Monitor view, or an explicit lead-id list) for a specific web-research signal in bulk — e.g. "which of my leads acquired a company since 2025". Reads CACHED signals across many leads in one call and returns only the matches, campaign-ready. Use instead of looping leadbay_research_lead_by_id per lead. Don't use it to research one named company (that's leadbay_research_lead_by_name_fuzzy) or to qualify unresearched leads (that's leadbay_bulk_qualify_leads). ## WHEN TO USE Trigger phrases: "which of my leads <did X>", "find leads that <raised / acquired / hired / moved / changed CEO>", "scan my portfolio for <signal>", "identify all the ones that <event> since <date>", "who in Monitor has a <funding / M&A / hiring> signal", "build a campaign from leads with <signal>". Do NOT use for: "research one named company" → `leadbay_research_lead_by_name_fuzzy`; "everything about lead <UUID>" → `leadbay_research_lead_by_id`; "qualify my next N leads (they aren't researched yet)" → `leadbay_bulk_qualify_leads`; "just list my follow-ups" → `leadbay_pull_followups`. Use this when: user wants to FILTER a known portfolio by a web-research signal in bulk — pass `query`, optionally `since`, `city`/`set_filter`, or `leadIds`; NEVER a country name in `city` — a whole-country ask means NO geo filter Examples that SHOULD invoke this tool: - "Which of my leads acquired a company since 2025?" - "Scan my Lyon portfolio for funding signals." - "Find everyone in Monitor who changed CEO and build a campaign." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Look up Acme Corp for me." - "Show me my follow-ups." - "Qualify my next 10 leads." ## RENDER (quick) Cohort grouped by lead: one block per matched lead (name · location + its matched signal entries, hot first, source-linked). Open with "N match <query> (M scanned)"; ALWAYS close with an honesty footer — "scanned N · matched M · K not yet researched". Never present
leadbay_team_activity## WHAT IT DOES Manager view: per-rep activity leaderboard + team activity-over-time, for a look-back window. Use when a manager asks how the team is doing / who's most active / top performers. Don't use it to list leads or one rep's pipeline. ## WHEN TO USE Trigger phrases: "how is my team doing", "team activity", "top performers", "rep leaderboard", "manager dashboard", "who's most active this week", "activity by rep". Do NOT use for: "show me leads" → `leadbay_pull_leads`; "leads I should follow up with" → `leadbay_pull_followups`; "how is this campaign progressing" → `leadbay_campaign_progression`. Use this when: a manager wants team-wide / per-rep activity aggregates, not a lead list Examples that SHOULD invoke this tool: - "How is my team doing this month?" - "Who are my top performers in the last two weeks?" - "Show me activity by rep." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me today's leads." - "How is the Q3 Outbound campaign progressing?" - "Which leads should I follow up with?" ## RENDER (quick) Per-rep leaderboard table (sort by total_activities desc) + an activity time-series. Columns worth showing: name, total_activities, notes, contacts_added, meetings_or_interest, lost. Feeds a manager dashboard artifact (table + Chart.js line of `trend`). --- Manager / team KPIs — the data behind the web app's Dashboard-Manager screen, exposed so an agent (or an artifact) can render a team dashboard. Returns `{ range, reps, trend }`: - `range` — `{ from, to, periodicity }` (the resolved look-back window). - `reps` — per-rep activity, sorted by `total_activities` desc (the leaderboard). Each: `{ user_id, name, email, total_activities, likes, saves, website_clicks, exported, profile_views, contacts_added, contacts_purchased, notes, meetings_or_interest, could_not_reach, lost, still_chasing }`. The `epilogue_*`-derived fields (`meetings_or_interest`, `lost`, …) are the outcome signal. - `trend` — `[{ date, count
leadbay_list_previously_enriched_titlesShow job titles the org has previously enriched, so the agent can repeat the same titles for new leads (or skip already-saturated ones). Two implementation paths: (1) PRIMARY — a selection-scoped preview call that reads `previously_enriched_titles` from the backend (newer prod field). (2) FALLBACK — live aggregation across each lead's enriched contacts. The composite picks transparently. WHEN TO USE: before leadbay_enrich_titles, to plan which titles to order. WHEN NOT TO USE: when you already know the exact titles you want to enrich.
leadbay_account_status## WHAT IT DOES Show the user's account state — admin rights, language, last-active lens, what the account is set up to find, and quota usage shown like the web app: a percentage-used + dollar-spend gauge for each daily/weekly/monthly window, with a per-resource breakdown, plus regeneration flags. ## WHEN TO USE Trigger phrases: "what's my account status", "how much quota do I have", "what lens am I on", "I topped up / I bought credits / I added credits", "what version of Leadbay am I running". Do NOT use for: "show me leads" → `leadbay_pull_leads`. Use this when: meta question about account, quota, active lens, or top-up recovery Examples that SHOULD invoke this tool: - "What's my account status?" - "How much quota do I have left this week?" - "Which version of the Leadbay connector is this?" Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me today's leads." - "What should I follow up on?" ## RENDER (quick) Report user + org + one line on what the account targets (`search_configuration`). Show quota only when asked (quota/account status) or a window is exhausted. NEVER mention the lens unless asked (use `last_requested_lens_name`, never the id). SILENT on quota when `quota_error` set, `unlimited_credits` true, or quota null. Else render Daily/Weekly/Monthly from `quota.user` (else `quota.org`) as `$used / $cap (N% used) · resets` (resource-count table if `spend[]` empty). Never say raw "credits". --- Show the user's account state — admin rights, language, last-active lens, quota usage across daily/weekly/monthly windows, and whether the org's intelligence is mid-regeneration. **When you show quota, show it the way the web app does — a percentage-used + dollar-spend gauge per window, never raw "credits".** Each window in `quota.<group>.spend[]` carries `current_units` / `max_units` in dollar_cents (% used = the ratio, $ = `/100`); the `quota.<group>.resources[]` list gives the per-resource usage breakdown (`count`, plus
leadbay_bulk_enrich_statusCheck status + per-lead contacts for a bulk enrichment you previously launched via leadbay_enrich_titles. Pass the `notification_id`, and/or the `lead_ids` + `titles` + `email` / `phone` the launch returned. Either one alone is a valid call: with `notification_id` the tool reads the job's lead set back from the backend, so an id kept from an earlier conversation still answers with per-lead progress. Pass `lead_ids` as well whenever you still have them — the job lookup is a scan of your recent notifications, so an archived job may not be found, but the leads always answer. `titles` / `email` / `phone` scope the count to the roles and channel THIS run asked for. When `include_contacts=true` (opt-in), includes each contact's email/phone_number/job_title/enrichment.done. WHEN TO USE: after leadbay_enrich_titles returns a `notification_id`, checking until the job is done. "Done" = `all_done:true`, OR `overall_progress.done` has held steady across several SPACED polls (~15–30s apart) over at least ~90s–2 min of elapsed time (a reservation the provider never answers stays `done:false`, so `all_done` can stay false forever — don't spin indefinitely; a contact with nothing found does flip, to `done:true` with `credits_used:0`). Do NOT declare a plateau from the first few back-to-back reads: right after launch, `overall_progress.done` can sit flat while the backend is still spinning the job up, so space your polls out and give it real elapsed time before treating a flat count as terminal. Also do NOT declare a plateau while the result carries `partial_failures` — a flat `done` there means a transient per-lead fetch error (e.g. a 429), NOT an unresolvable contact; keep polling (respecting any `retry_after`) or surface it as a temporary status failure, rather than reporting those leads as permanently unresolved. Default `include_contacts=false` for the cheap interim polls; set `include_contacts=true` on the read you report from to pull each lead's enriched contacts for the com
leadbay_qualify_statusRetrieve the current state of a bulk_qualify_leads or import_and_qualify launch. Which ids to pass depends on which tool launched it, because only one of them creates a qualification job on the backend: - **`leadbay_bulk_qualify_leads`** returns a `notification_id`. Pass it for progress in ONE call, and add the `lead_ids` + `lens_id` it also returned for per-lead detail (which settled, which are still running). - **`leadbay_import_and_qualify`** returns NO qualification `notification_id` — its qualify phase runs per-lead, so no job notification exists. Pass the `lead_ids` + `lens_id` it returned. Its `notification_ids[]` are the FILE-IMPORT notifications; handing one of those to this tool is rejected as the wrong kind, and `leadbay_import_status({importIds})` is where the import half is polled. **When it is finished:** `status` is always `"launched"` — it is not a progress field. On the `notification_id` path the job is done when `in_progress` is false (or `bulk_progress.success_count + failure_count` reaches `total_count`); `still_running[]` is empty on that path from the very first poll and must NOT be read as "done". On the `lead_ids` path the job is done when `still_running[]` is empty. Pass both and you get both signals in one call. Everything comes straight out of the launch response — nothing is stored on the MCP side. A backend job is scoped to the user who launched it, so a `notification_id` resolves from a later message, a later conversation, or the next day. WHEN TO USE: after leadbay_bulk_qualify_leads or leadbay_import_and_qualify came back with a non-empty `still_running[]` or `status:'running'`: call it with those ids until finished, in the same turn or a later one, to read the qualifications without re-running the import or re-spending qualify quota. WHEN NOT TO USE: as a substitute for leadbay_research_lead_by_id — that's a deeper per-lead profile and includes contacts. This tool is purely the qualification answers + signals_count. ## A launch
leadbay_import_statusRetrieve the current **status/progress** of a lead import, and its leadIds once it finishes. Pass the `importIds` the launch returned — `leadbay_import_leads` returns `importIds`, `leadbay_import_and_qualify` returns `import_ids`. These are the backend's own import ids, so they resolve from a later message, a later conversation, or the next day; nothing is stored on the MCP side. Also pass the `dry_run` the import was launched with, so completion is judged against the right phase (a dry run finishes at preprocess, a real import at processing). This status call performs a single refresh pass and never polls in a loop. WHEN TO USE: after an async import returns its ids — `leadbay_import_leads` as `{status:'running', importIds}`, `leadbay_import_and_qualify` as `import_ids` — check with those until `complete`; OR to check whether a finished import is still processing. This tool does NOT surface the leads Leadbay adds later for pending-crawl (`uncrawled`) rows — those populate in the user's Leadbay account as the crawl completes; no tool here fetches them on demand (re-run the import to pull them back through the MCP). WHEN NOT TO USE: for the qualification half — use leadbay_qualify_status, with the `lead_ids` + `lens_id` an `leadbay_import_and_qualify` launch returned (it has no qualification `notification_id`; its `notification_ids[]` are these same file imports); or when you still want the legacy blocking behavior from leadbay_import_leads with `wait_for_completion=true`. ## A launched job cannot be stopped Leadbay has no cancel. A job started by `leadbay_enrich_titles`, `leadbay_bulk_qualify_leads`, `leadbay_import_leads` or `leadbay_import_and_qualify` runs to completion on Leadbay. The user cancelling in the chat, a request timeout, or a closed stream stops YOUR waiting, never the job, and `cancelled: true` on an earlier result means we stopped watching, not that the work stopped. **This tool only reads.** Calling it again launches nothing and spends no quot
leadbay_resolve_import_rowsResolve messy CSV-shaped lead rows against Leadbay before file import. The tool sends each row's available identity signals to `POST /leads/resolve`, returns matched lead IDs or ambiguous candidate IDs, and produces `records_for_import` plus a SAFE identity-only `mappings_for_import` starting point for leadbay_import_leads / leadbay_import_and_qualify. This tool deliberately does not try to understand every CSV dialect; the agent should inspect the file, derive clean helper columns when useful, pass explicit `identity_mappings`, and build the final CRM mapping from `mapping_guidance`. WHEN TO USE: before importing user-supplied files when domains, names, CRM IDs, registry numbers, or Leadbay IDs may be inconsistently formatted; when the agent needs to pre-resolve messy rows, inspect ambiguous candidates, or prepare LEADBAY_ID values for the import composites. For contact-only files, first derive company website/domain from business contact emails where possible, while ignoring consumer mailbox domains. Deterministic matches get a LEADBAY_ID column inserted so the standard import commits immediately. Ambiguous rows are deliberately left without LEADBAY_ID; inspect candidates and choose one only when the evidence is good. Rows with websites but no match can still be imported; Leadbay may crawl and match them later (a late import), and those leads then populate in the user's Leadbay account as the crawl completes (no tool here fetches them on demand — re-run the import later to pull them back through the MCP). WHEN NOT TO USE: for prospect discovery from scratch (use leadbay_pull_leads); for one known company profile (use leadbay_research_lead_by_name_fuzzy / leadbay_research_lead_by_id); or when the file already has clean, final LEADBAY_ID/CRM_ID/SIREN mappings and no row-level identity disambiguation is needed. --- ## RENDERING Present as a markdown table of resolution outcomes per row. ``` | Source row | Match status | Resolved leadId / candidates | ``` Statu
leadbay_list_lens_seed_candidates## WHAT IT DOES INTERNAL scaffolding for `leadbay_extend_lens` — fetch ranked candidate leads currently in the lens so the agent can pick 3–5 seeds itself, silently, and chain to the extend call. Do NOT surface the candidate list to the user; the user asked for "more leads", not "pick seeds". ## WHEN TO USE Trigger phrases: "(internal) agent decided to extend the lens — fetch seed candidates". Do NOT use for: "show me today's leads" → `leadbay_pull_leads`; "leads I should follow up with" → `leadbay_pull_followups`; "narrow the audience" → `leadbay_adjust_audience`; "stop showing me X" → `leadbay_refine_lead_targeting`. Use this when: agent is mid-`leadbay_extend_my_lens` flow and needs to pick seeds before calling `leadbay_extend_lens` Examples that SHOULD invoke this tool: - "(agent-internal) user asked for more leads — fetch seeds before calling extend_lens" Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me today's leads." - "Restrict the audience to fintech only." - "Which leads should I follow up with this week?" ## RENDER (quick) DO NOT RENDER TO THE USER. This is internal data the agent reasons over before calling `leadbay_extend_lens`. No table, no list of company names, no "here are your candidates". The user asked for more leads; surface the *outcome* of extend_lens, not the picking step. --- **INTERNAL TOOL — do not surface candidates to the user.** The user asked for more leads on the lens (a higher daily appetite than the standard fill delivers), not to manually review candidates. This tool exists so the agent can pick seeds *silently*, then chain to `leadbay_extend_lens`. Picking is an agent decision; the user only sees the extend confirmation. Backed by `GET /lenses/{lensId}/seed_candidates`. By construction every lead returned is a valid input to `extra_refill` (same eligibility query). Defaults to the user's last-active lens. **Pick 3–5 seeds that represent the *kind* of leads the user wants more of**
leadbay_list_mappable_fieldsList every CRM field the agent can target when calling leadbay_import_leads or leadbay_import_and_qualify. Returns two arrays: `standard_fields` (Leadbay's built-in StandardCrmFieldType enum — LEAD_NAME, LEAD_WEBSITE, LEAD_STATUS, contact + location + sector fields) and `custom_fields` (this org's user-defined fields — id, name, type, and the literal `mapping_value` you pass in `mappings.fields`). For custom fields, `mapping_value` is the wire-format string `CUSTOM.<id>` — pass it verbatim. For contact exports, map person data to CONTACT_* fields and still provide parent-company identity via LEADBAY_ID/LEAD_WEBSITE/LEAD_NAME/CRM_ID/SIREN. When contact emails contain business domains, agents may derive a clean company-domain column for LEAD_WEBSITE only when the domain agrees with the row's company/deal/brand context, while preserving the original email as CONTACT_EMAIL. For import files, audit every meaningful source column. If no standard/contact field fits, preserve the data by creating or reusing a custom field unless the column is blank, duplicate plumbing, raw unparsed noise after useful extraction, or harmful to data quality. For HubSpot or other source-system deep links, create or reuse an EXTERNAL_ID/TEXT custom field with leadbay_create_custom_field, then map the source id/link to the returned `mapping_value`. Backend mapping_hints are advisory only; for contact files, do not accept hints such as first_name -> LEAD_NAME when the column is clearly a person field. Optional `for_records` param: pass a sample of CSV-shaped rows and the tool also runs the wizard's preprocess on them, attaching `mapping_hints` (per-column AI-confidence suggestions) and `custom_field_candidates` (custom fields that match unmapped columns by exact / case-insensitive / fuzzy name). Saves a separate preview round-trip. WHEN TO USE: before authoring an import mapping, especially when the CSV has columns that aren't obvious matches for standard fields. WHEN NOT TO USE: when you alr
leadbay_list_sectorsList the sector taxonomy (id + display name in the requested language). Default: `lang` follows the caller's language; `includeInvisible=false` returns ~1,091 visible sectors. WHEN TO USE: to resolve a free-text sector name (e.g. "Healthcare") into the sector ids that leadbay_adjust_audience needs. WHEN NOT TO USE: when you already have sector ids — pass them directly.
leadbay_list_locationsSearch the geo / admin-area taxonomy by free-text name and return the matching admin_area ids. This is the primary way to turn a user's "leads in Berlin" / "filter to Lyon" intent into the `{type: "location_ids", locations: [<id>]}` shape that the backend filter expects. The response has two arrays: `results` (top-10 prefix matches ranked by relevance) and `parents` (the admin-area chain referenced by `results[].parent_ids`, useful for disambiguation breadcrumbs). Each entry: `{id, country, level, name, parent_ids}`. The `level` is the admin depth — **5** = region, **6** = county, **7** = township-area, **8** = city/town. Country nodes are NOT in this index, so searching a country name cannot return that country — it returns whatever same-named town the trigram matcher finds (measured: `France` → the commune of Francs, `United States` → Statesboro). Passing such an id onward fences the caller to one village, so this tool refuses a country query outright and returns `status: "country_level_location"` with an empty `results`. **One workspace = one country — a country name is NEVER a location filter.** The admin-area index holds no country nodes, so `"France"` matches the *commune of Francs* and `"United States"` matches *Statesboro*: the call is silently fenced to one village and every conclusion from it is wrong. City AND country named? Keep the city, drop the country. **On `code: "COUNTRY_LEVEL_LOCATION"` read `country_locations[].axis` and `[].kind` — the recovery differs per case and they are NOT interchangeable, and do NOT retry with another spelling or a nearby city.** `axis: "include"`: - `home_country`, or "nationwide" / "everywhere" → drop that ONE value. Omit the geo argument (`city` / `locations` / `location_ids`) only if nothing else was on it — then the result covers the whole workspace. If other values remain, keep them and describe the result as those places. - `foreign_country` ("leads in France" on a US workspace) → **unsupported, not unfiltered.
leadbay_create_topup_linkGenerate a one-shot Stripe checkout session for an AI-credits top-up. Wraps `POST /1.6/stripe/topup_checkout` → `{url}`. Returns a fresh Stripe-hosted URL (~1 hour TTL); creating one does NOT charge the user — payment happens only after the user opens the URL and completes checkout in their browser. **When a quota window is hit, offer top-up as the FIRST option.** A top-up clears the throttle immediately (no need to wait for the daily/weekly/monthly window reset). The flow: 1. Operation returns QUOTA_EXCEEDED / 429. 2. Tell the user which window was hit (from `leadbay_account_status` / `leadbay_get_quota`) and offer BOTH options: "wait until `<resets_at>`" OR "top up at app.leadbay.ai (I can generate the link)". 3. If the user accepts top-up, call `leadbay_create_topup_link` and surface the returned `url` as a clickable link. 4. Tell the user to complete checkout in their browser. After they return saying "I topped up" / "bought credits" / "added credits", call `leadbay_account_status` to confirm the refreshed state, then RETRY the originally failed call. Do NOT call this tool defensively before any quota error — only after a real 429 or in response to the user's explicit "I want to top up" / "I'll buy credits". The URL is single-use and rotating it without the user asking just clutters the conversation. `leadbay_open_billing_portal` is the companion tool for ongoing subscription management (upgrade / downgrade / payment methods) via the Stripe customer portal. WHEN TO USE: when a quota error has blocked the user's intent and they want to keep working today rather than wait for the window reset; OR when the user explicitly asks for a top-up link. WHEN NOT TO USE: pre-flight (the agent is not paying — the user is); for subscription / plan changes use `leadbay_open_billing_portal` instead; for read-only quota diagnostics use `leadbay_account_status` / `leadbay_get_quota`.
leadbay_open_billing_portalGenerate a one-shot Stripe customer-portal URL. Wraps `GET /1.6/stripe/portal` → `{url}`. Returns a fresh Stripe-hosted URL the user can open to manage their existing Leadbay subscription: change plan tier, swap payment method, view invoices. The agent does NOT make subscription changes itself — it surfaces the URL and lets the user act. Sibling of `leadbay_create_topup_link`. Use cases differ: - **Top-up** (`leadbay_create_topup_link`) = one-shot purchase of AI credits to clear an immediate quota throttle. Doesn't change the plan. - **Billing portal** (this tool) = ongoing subscription management. Plan upgrades persist; they raise the recurring window caps (daily/weekly/monthly) rather than buying a one-time bucket. WHEN TO USE: when the user asks to upgrade / downgrade / change plan; manage payment methods; view invoices; or "open my billing". WHEN NOT TO USE: for one-off credit top-ups (use `leadbay_create_topup_link`); for read-only quota state (use `leadbay_account_status` / `leadbay_get_quota`).
leadbay_prepare_outreach## WHAT IT DOES Prepare an outreach brief for one lead: lead block, recommended contact, channel readiness and AI angles in one call. `enrich: true` also orders the contact's details. ## WHEN TO USE Trigger phrases: "draft outreach for <Contact>", "write an email to <Contact>", "outreach package for <Company>". Do NOT use for: "research a lead, no draft" → `leadbay_research_lead_by_id`; "log sent outreach" → `leadbay_report_outreach`; "bulk enrich contacts" → `leadbay_enrich_titles`. Use this when: single picked lead/contact; action-imminent drafting context Examples that SHOULD invoke this tool: - "Draft an email to Sarah at Acme." - "I'm about to call Acme's CTO — prep me." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "I just sent that email — log it." - "Research the Acme lead before I commit." ## RENDER (quick) Route the draft through `message_compose_v1` (Claude's email composer) with 2–3 strategic variants — labels describe STRATEGY, not tone ("Push for alignment", "Reference M&A signal", "Soft intro — peer reference"). Above the composer, emit ONE short markdown paragraph with score callout + sector fit + linked contact name + bare phone / email. Do NOT paste the email body into chat prose alongside. --- Payload: the full `lead` block (score, `split_ai_summary`, `location`, `size`, `phone_numbers`, `website`, `description`, `social_urls`, `social_presence`); `recommended_contact` in post-enrichment shape (`contact_id`, names, `job_title`, `email`, `phone_number`, `linkedin_page`, `is_org_contact`, null where not enriched); `additional_contacts_count`; an `enrichment` block; the lead's `qualification` answers and web-research `signals`; and its `history` (`notes` on the lead and on each of its people, plus the `activities` timeline). `enrich:true` orders contact details (async, ~1 min). Re-call without `enrich` until `enrichment.complete: true`; the recommended contact then carries `email` and/or `phone_number`. ##
leadbay_report_friction## WHAT IT DOES Reports a specific problem with Leadbay to the team — a search that came back empty, a wrong result, a missing capability. Use when the user asks to report something, or when they accept your offer to report a problem you hit. The user's own words, confirmed with them before sending, and the send is always visible. Don't use it for routine acknowledgements. ## WHEN TO USE Trigger phrases: "report this problem", "tell the Leadbay team this didn't work", "this is broken, let them know", "file a report about this", "flag this to Leadbay". Do NOT use for: "user vents about follow-ups but has not asked to report anything — keep solving the ask they actually made" → `leadbay_pull_followups`; "user vents about a company or result but has not asked to report anything — answer the underlying question" → `leadbay_research_lead_by_name_fuzzy`; "general feedback, praise, or a feature request the user wants sent" → `leadbay_send_feedback`; "log outreach" → `leadbay_report_outreach`; "thumbs up / down" → `leadbay_like_lead`; "snooze / pushback" → `leadbay_set_pushback`. Use this when: the user has asked for a specific Leadbay problem to be reported, or has said yes to your offer to report one. Frustration on its own is NOT a trigger — offer first, and only call this if they agree. Examples that SHOULD invoke this tool: - "Report this to the Leadbay team — searching Wisconsin returns nothing." - "Yes, please let them know the enrichment came back empty." - "Can you flag to Leadbay that the region filter is wrong?" Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Ugh, this never finds what I'm looking for." - "I sent the intro email to Acme — log it." - "Thumbs down on this lead, wrong industry." ## RENDER (quick) Ask the user before calling — never fire this on your own. Show the one-line confirmation from the result's `message` (e.g. "✓ Shared with the Leadbay team"). If `reported` is false the report was NOT delivered — tell
leadbay_acknowledge_notificationAcknowledge a Leadbay notification — i.e. tell the MCP and the backend "I've seen this and acted on it." Wraps `POST /1.6/notifications/{id}/seen` (default) or `/archive` (when `archive:true`) and drops the entry from the local inbox so subsequent `_meta.notifications` payloads stop carrying it. **When to call.** After you read an entry from `_meta.notifications` or `account_status.notifications` and have revised whatever prior output the just-finished background work might have made stale (outreach drafts, lead lists, "available leads" claims, followup plans). Mark-seen tells the human team's pipeline you handled this and prevents the notification from re-surfacing on every subsequent tool response. If nothing you produced for the user is affected, ack anyway with `archive:false` — the entry should still clear so the inbox stays focused on what's actually pending. Use `archive:true` only when you want the row gone from the FE notification dropdown too (e.g. a non-actionable system notification that's already handled). Default behaviour is `seen` — same as the FE dropdown's "click to read" semantics. WHEN TO USE: immediately after you finish reviewing / revising in response to a `_meta.notifications[]` entry. Idempotent — calling twice with the same id is safe. WHEN NOT TO USE: before doing the revision work; for general "mark all read" sweeps (call once per notification id you've actually consumed). This tool MUTATES state. The caller (agent or human-in-the-loop) is responsible for confirming intent before invocation; the MCP server does not soft-prompt for confirmation. See `annotations.destructiveHint`.
leadbay_get_artifact_runtime## WHAT IT DOES Serves Leadbay's finished boards — a route planner and a lead triage board — to publish as they are, and the headless runtime + usage guide to BUILD any other interactive HTML artifact whose controls call Leadbay tools. Use when the user wants a clickable artifact. Don't use it to answer a data question. ## WHEN TO USE Trigger phrases: "build me a dashboard", "build a call sheet", "interactive artifact", "make a page with buttons", "build an artifact to work my leads", "interactive lead triage board", "route planner board", "a map of my follow-ups I can work from", "a page with buttons that log my calls", "relance board", "campagne de relance", "board de relance", "follow-up table", "a table with emails and phone numbers to call my leads", "a table where I can set status and log what happened". Do NOT use for: "show me today's leads" → `leadbay_pull_leads`; "leads I should follow up with" → `leadbay_pull_followups`; "log that I emailed" → `leadbay_report_outreach`. Use this when: the user wants a clickable/interactive HTML artifact whose controls call Leadbay tools — not a one-off data answer Examples that SHOULD invoke this tool: - "Build me an interactive call sheet for these leads." - "Make an artifact with buttons to log call outcomes per lead." - "I want a clickable lead-triage board I can work down." - "Build me a relance table with each lead's email and phone, where I can set the status and log what happened." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me today's leads." - "Which leads should I follow up with this week?" - "Log that I emailed Acme's CTO." ## RENDER (quick) With `template`: publish the returned `html` AS IT IS, with its `capabilities`, `icon` and `description`; never restyle it. Without: do NOT render the result as prose. Inline `runtime` as ONE `<script>`, READ `usage_guide` first, build with `lb.*`, and pass the tools you call as the artifact's `mcp_tools`. The artifact is the
leadbay_get_basemap**Do not call this tool.** The route planner template that `leadbay_get_artifact_runtime` serves calls it from inside the published page, to draw the grey country shape under its pins. It returns `{region, geojson}` for the workspace's region (`fr` or `us`) — a large GeoJSON document that is useless in a conversation. A board needs it because an artifact can only load its own published files, and an agent building a board for another user has no outline file to publish. With this tool every board gets the same outline, for the right country.
leadbay_report_artifact_error**Do not call this tool.** It is the ingest endpoint for the `@leadbay/components` runtime that `leadbay_get_artifact_runtime` ships, and the only legitimate caller is that runtime's own `lb.report()` — running inside an artifact page, in the browser, with no human in the loop. An artifact runs in a chat-hosted page whose only channel out is `window.cowork.callMcpTool`. When one of its controls fails — a picker that loaded zero options, a button blocked by validation, a call that timed out or came back as a failure envelope — there is no other way for that fact to reach the Leadbay team. This tool is that way. The runtime calls it automatically, deduped and capped; you do not need to do anything to make it work, and calling it yourself would inject a failure that never happened. If a user tells you an artifact is broken and asks you to report it, that is `leadbay_report_friction`, not this. That tool carries the user's own words and requires their consent. This one is automatic, carries only bounded enum values and error codes, and never carries user text. Parameters (supplied by the runtime): `kind` — one of `bridge_unavailable`, `call_timeout`, `call_failed`, `parse_failed` (exceptions) or `options_empty`, `action_blocked`, `result_rejected` (outcomes, where nothing threw and the call reported success). `surface` — which view-model surfaced it: `call`, `field`, `action`, `resource`, `list`. Optional `kit_version`, `tool`, `code`. Returns `{ recorded, kind }`. `recorded: true` means the event was accepted, not that it was delivered — a user who has opted out via `leadbay_set_telemetry` sends nothing, by design. The artifact ignores the result either way. WHEN NOT TO USE: always — this is not a tool you call. The artifact runtime calls it for you. To report a problem a USER raised, use `leadbay_report_friction` instead.
leadbay_find_new_leads## WHAT IT DOES Search for NET-NEW companies matching an ideal-customer profile the user describes, scored for fit and optionally AI-qualified with contacts. Use it when the user describes who they want. ## WHEN TO USE Trigger phrases: "find me N companies that <profile>", "get me new prospects like <company>", "I need leads in <place> that <do X>", "search for companies that would buy <product>", "net-new leads outside my current pipeline", "we're entering <market> — who should we target". Do NOT use for: "show me today's leads / what's new today", "find me new leads (no profile, no count named)" → `leadbay_pull_leads`; "more leads like the ones in my lens" → `leadbay_extend_lens`; "qualify / vet these companies I have" → `leadbay_qualify_leads`; "qualify the top N of my batch" → `leadbay_bulk_qualify_leads`; "leads I should follow up with" → `leadbay_pull_followups`; "tell me about <one company>" → `leadbay_research_lead_by_name_fuzzy`. Use this when: the user describes a target profile or names a count of NEW companies — craft the example_lead per the seed rules below BEFORE calling; never pass the user's raw sentence as query. Examples that SHOULD invoke this tool: - "Find me 10 gyms around Dallas that would buy our flooring, with a contact." - "Get me 20 new US SaaS companies, 50-2000 employees, with the VP People's email." - "We're launching in Lyon — find 15 hotels that fit our ICP." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Show me today's leads." - "Which leads should I follow up with this week?" - "Qualify these 40 websites from my spreadsheet." ## RENDER (quick) 3-col table of delivered leads in returned order: col 1 = 10-segment fit bar + linked company · location · size; col 2 = why-fits ≤20 words; col 3 = contact + found channels. ALWAYS close with the honest funnel line, even at 0 delivered. --- The backend matches the ICP seed against the full company universe, applies hard filters, skips what the org a
leadbay_qualify_leads## WHAT IT DOES Run one server-side batch (up to 500) over companies the user already named — a pasted list, a file, CRM rows. Identity pass returns website and LinkedIn; the qualified pass adds fit verdicts with evidence and a contact. Use leadbay_find_new_leads to discover companies instead. ## WHEN TO USE Trigger phrases: "for each of these companies, give me the website / LinkedIn", "qualify these companies", "vet this list", "which of these fit our ICP", "score these websites / accounts", "get me the right contact at these companies", "re-qualify what you delivered last week". Do NOT use for: "find me new leads / companies that <profile>" → `leadbay_find_new_leads`; "qualify the top N of my lens batch" → `leadbay_bulk_qualify_leads`; "import this CSV file" → `leadbay_import_leads`; "tell me about <one company> in depth" → `leadbay_research_lead_by_name_fuzzy`; "add emails to the contacts I selected" → `leadbay_enrich_titles`. Use this when: the user points at SPECIFIC companies (ids, websites, names, a pasted list, "what you found yesterday") and wants fit verdicts and/or the right person to talk to. Examples that SHOULD invoke this tool: - "For each of these 300 brokers, give me the website and LinkedIn, nothing else." - "Here are 60 restaurant websites from my Austin sweep — which fit, and who's the owner?" - "Re-qualify last week's delivery and get phone numbers for the good ones." - "Vet these 12 accounts from my spreadsheet against our criteria." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Find me 10 new gyms in Texas." - "Qualify the top 10 leads in my batch." - "I have a CSV of 400 attendees to import." ## RENDER (quick) Identity pass (`rows[]`): one table Company / Website / LinkedIn, then the coverage line. Otherwise a 3-col table for delivered items (fit bar + company / why-fits ≤20 words / contact + channels) in returned order, then a compact Ref → Outcome table for skipped refs (not_in_universe, low_confid
leadbay_bulk_qualify_leadsPick the next N unqualified leads in the active lens and qualify them (run AI rescore + web fetch). Pass `wait_for_completion:false` to return quickly with `{status:'running', notification_id}`; poll leadbay_qualify_status with that id. With `wait_for_completion` omitted/true, the legacy behavior polls until the answers are populated or a budget is exhausted. Already-qualified leads (those with a non-null `ai_agent_lead_score`) are silently no-ops on the backend, so this composite paginates past them to find fresh candidates. On 429 mid-fanout, stops launching but keeps polling already-launched leads. **Default to `wait_for_completion:false`** for any `count > 5` or when chained inside a multi-phase workflow — the blocking default can hit the MCP per-call timeout and surface as `"Request timed out"` even when the server is still working fine. The async pattern (capture `notification_id`, check `leadbay_qualify_status` until `in_progress: false`, usually 2–10 min) is timeout-proof. Reserve the blocking form for tiny single-digit counts in interactive use. Context: Leadbay auto-qualifies roughly the top 10 of each daily batch. Leads below the top ~10 are NOT worse — the system is saving resources. This tool is how the agent spends more resources to go deeper on promising-looking leads the user hasn't had time to surface yet. WHEN TO USE: when the user wants more qualified leads than what's currently shown, or when a lead looks promising in leadbay_pull_leads but has an empty `qualification_summary`. WHEN NOT TO USE: to qualify a single specific lead — that's leadbay_qualify_lead (granular, advanced). And NOT for companies the user names or lists themselves (CRM rows, websites, prior deliveries) — that's leadbay_qualify_leads (server-side batch with per-item verdicts and contact matching); this tool only walks the ACTIVE LENS top-down. ## A launched job cannot be stopped Leadbay has no cancel. Once `leadbay_enrich_titles`, `leadbay_bulk_qualify_leads`, `leadbay_i
leadbay_enrich_titlesOrder contact enrichments by job title across many leads. Contacts are NOT returned by default with a lead (Leadbay keeps enrichment out-of-band); the agent requests them on demand via this tool when it's ready to actually reach out. Two modes: (A) NO `titles` param — returns the available titles + Leadbay's `title_suggestions` + `auto_included_titles` + a count of enrichable contacts, so the agent can ask the user which titles to enrich. (B) `titles` given — calls preview, then launches if there's anything enrichable. On 429 returns `{status:'quota_exceeded'}` cleanly. Selection lifecycle is wrapped in a try/finally so the user's selection is left clean even on error. WHEN TO USE: as the agent's go-to enrichment entry point, immediately before proposing outreach. WHEN NOT TO USE: to enrich a single named contact — that's leadbay_enrich_contacts. Speculatively, before the user has committed to outreaching — enrichment consumes quota. **NOT to add "titles" or "LinkedIn" to a list** — a contact's `job_title` and `linkedin_page` already ride on the contact record; they are FREE and need no enrichment. If the user asks for "title and LinkedIn only", read those fields directly (e.g. leadbay_get_contacts / leadbay_research_lead_by_id); do NOT launch a job here. This tool is strictly the email / phone reveal, which consumes quota. ## A launched job cannot be stopped Leadbay has no cancel. Once `leadbay_enrich_titles`, `leadbay_bulk_qualify_leads`, `leadbay_import_leads` or `leadbay_import_and_qualify` has returned a launched or running result, that work is queued on Leadbay and runs to completion, and the quota it uses is already committed. A discovery, preview or `dry_run` result launched nothing and is not covered here. The user cancelling in the chat, a request timeout, or a closed stream stops YOUR waiting, never the job. `cancelled: true` means we stopped watching, not that the work stopped. What to do next depends on what you are holding: - **A handle.** Poll t
leadbay_adjust_audience## WHAT IT DOES Edit an EXISTING lens's audience by sector / size / geography. Free-text sectors and locations auto-resolve; ambiguous matches are surfaced rather than guessed. Filter MERGES with existing criteria. Pass `lensName` to edit a lens by name; otherwise edits the active lens. ## WHEN TO USE Trigger phrases: "narrow the audience to <sector>", "add <sector> to my <name> lens", "remove <sector> from this lens", "only show me companies of <size>", "stop including <sector>", "broaden this lens to also include <sector>", "restrict this lens to <city/département/région/state>", "only companies in <place>", "exclude <region> from this lens". Do NOT use for: "companies anywhere in this workspace's OWN country / nationwide (a foreign country is unsupported, not unfiltered — call nothing)" → `leadbay_pull_leads`; "create a new lens called X", "make a new audience for Y" → `leadbay_new_lens`; "show me / list / switch my lenses" → `leadbay_manage_lenses`; "focus on a kind of company beyond sector/size (e.g. 'hospitals running their own IT')" → `leadbay_refine_lead_targeting`. Use this when: user wants to change an EXISTING lens's sectors/sizes. If the user NAMES a lens ('my Joinery lens'), you MUST pass lensName with that name — do NOT edit the active lens. To create a brand-new lens use leadbay_new_lens instead. Examples that SHOULD invoke this tool: - "Add fintech to my Joinery lens." - "Narrow my audience to manufacturing companies, 50–500 people." - "Restrict my rep's lens to Indre-et-Loire." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Create a lens called Joinery for fintech." - "Show me my lenses." - "Focus on hospitals that run their own IT." - "Show me companies anywhere in the US." ## RENDER (quick) On `applied`: confirm the lens edited (name) + the sectors/sizes/locations added as chips. On `ambiguous_sectors` / `ambiguous_locations` / `ambiguous_lens` / `lens_not_found`: surface the candidates and ask the user to
leadbay_refine_lead_targeting## WHAT IT DOES Refine the kind of leads Leadbay surfaces, beyond firmographics (qualitative intent, not sector/size). Sets the org's user_prompt and may raise a clarification question the composite polls for. Admin-only. ## WHEN TO USE Trigger phrases: "focus on companies that <qualitative trait>", "I prefer leads that <behavior/characteristic>", "prioritize companies running their own IT", "deprioritize companies that just raised", "stop showing me <kind of company>", "we only sell to the private sector, not the public one", "harden the exclusion on <business model>, not the keyword", "competitors / resellers are never prospects for us". Do NOT use for: "create a new lens / a lens specialized into <X>" → `leadbay_new_lens`; "add/remove <sector> to/from my <name> lens", "narrow the audience to <sector> / <size>" → `leadbay_adjust_audience`; "show me / list / switch my lenses" → `leadbay_manage_lenses`; "a company trait one yes/no question could estimate from their website" → `leadbay_set_qualification_questions`; "exclude <named company>" → `leadbay_dislike_lead`. Use this when: ADMIN-ONLY. A qualitative ORIENTATION too broad for one yes/no — a segment to avoid, a business model to rule out. One estimable company trait goes to set_qualification_questions; a named company to dislike_lead. Examples that SHOULD invoke this tool: - "Focus on hospitals that run their own IT in-house." - "Prioritize companies that have recently expanded headcount." - "On ne vend qu'au privé — arrête de me remonter des hôpitaux publics." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Create a lens specialized in automobile." - "Add fintech to my Joinery lens." - "Show me my lenses." - "Exclude Groupe Solidum, we had an unpaid invoice with them." ## RENDER (quick) On success: confirm the refinement applied to the active lens. If a clarification was raised, surface its question (route via ask_user_input_v0). --- Refine the kind of leads Leadbay sur
leadbay_answer_clarificationAnswer the pending clarification question Leadbay raised after a leadbay_refine_lead_targeting call. The answer is stored as the new `user_prompt` and triggers regeneration. Pass `option_id` (preferred — pick from the offered options) or `text_answer` (free-text). Admin-only. WHEN TO USE: after leadbay_refine_lead_targeting returns `status='clarification_pending'`. WHEN NOT TO USE: to set a brand-new prompt — use leadbay_refine_lead_targeting. This tool MUTATES state. The caller (agent or human-in-the-loop) is responsible for confirming intent before invocation; the MCP server does not soft-prompt for confirmation. See `annotations.destructiveHint`. The regeneration is a job: before pulling leads that should reflect it, check `leadbay_account_status` until `computing_intelligence` reads false (a few minutes). ## A LAUNCHED JOB — its first result is a receipt, not the answer A result saying the job is still working (`still_running`, `next_poll`, a `running` status) holds only ids to check it with. If the user's request needs the output: 1. Say in one line what is running and roughly how long it takes, so the wait does not look broken. 2. In this same turn, check it with the tool named here until it reports finished: `wait_seconds: 45` where accepted, else every 15–30 s. A `stop_reason` or an early flat count is not finished. 3. Answer from the finished result. Calling the launcher again is not a check: it can charge twice. Stop early only if the user said not to wait or the check tool says the job stalled. Then say it is not ready, show what landed, and that asking again fetches the rest.
leadbay_report_outreachLog an outreach action (email, call, message, meeting) on a lead so the human team using Leadbay sees the progress in their UI. Writes a NOTE on the lead and (optionally) sets an EPILOGUE status (still chasing, meeting booked, etc.). Bulk variant: pass `lead_ids=[uuid,...]` instead of `lead_id` (epilogue is bulk-native; notes fan out per-lead). VERIFICATION REQUIRED: every call must include `verification={source: 'gmail_message_id'|'calendar_event_id'|'user_confirmed', ref: '<id-or-confirmation>'}` to prevent hallucinated outreach poisoning the pipeline. The verification is appended to the note body. Skipping or fabricating verification poisons the human team's pipeline. For an email, pass the Gmail message id of the sent message whenever you have it: `leadbay_pull_followups` hands it back so the contact's reply can be found in that thread. WHEN TO USE: AFTER actually emailing/calling/meeting/messaging a contact, OR after a substantive decision the user wants logged (skip, save, hand off). WHEN NOT TO USE: BEFORE doing the outreach (use `dry_run:true` to validate args first); without verification (call will be rejected); from a flow where the user did not consent to having actions logged automatically. To log on the person the outreach went to, pass their org contact id as `contact_id` with a single `lead_id`. The note and the status then go on that person, and the lead's Monitor row still shows the action and the status. Logging the same Gmail message id or calendar event id twice writes nothing the second time: the lead or person comes back in `already_logged`. This tool MUTATES state. The caller (agent or human-in-the-loop) is responsible for confirming intent before invocation; the MCP server does not soft-prompt for confirmation. See `annotations.destructiveHint`. ### Logging outreach from the user's mailbox and calendar The `leadbay_sync_outreach` prompt runs the block below once, over the last 14 days instead of 2. It then schedules a daily task named
leadbay_set_prospecting_action## WHAT IT DOES Turns one of a lead's prospecting actions for today on or off (Still chasing, Couldn't reach, Meeting planned, Not interested), exactly as the web app's Prospection cell does. Writes no note. ## WHEN TO USE Trigger phrases: "mark it as still chasing", "set the prospecting action", "untick meeting planned", "remove the couldn't reach", "clear the prospecting action", "that was a mistake, unset it". Do NOT use for: "I called them / I emailed them / we met" → `leadbay_report_outreach`; "mark it as won / lost" → `leadbay_set_lead_status`. Use this when: the user sets or clears the action flag itself, with no outreach to record; when an outreach happened, log it with leadbay_report_outreach instead Examples that SHOULD invoke this tool: - "Untick Meeting planned on Solimac, I clicked it by mistake." - "Set Bachelard to Still chasing." - "Clear the Couldn't reach on the Courthézon lead." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "I just called Solimac, they want a demo — log it." - "Mark Bachelard as won." - "Draft a follow-up email to Magali." ## RENDER (quick) One line: ✅ "<Action>" on / off for <Company>. No table. When turning an action ON after a real call or visit, suggest logging it with leadbay_report_outreach so the note carries what happened. --- Sets or clears one prospecting action for **today** on one lead. `selected: true` wraps `POST /leads/epilogue`; `selected: false` wraps `DELETE /leads/{id}/epilogue?type=`. Both return 204; the tool echoes `{lead_id, action, selected}`. **What "selected" means.** A lead's actions for today live in `epilogue_today_statuses`, and several can be on at once — the web app shows them as a multi-select. Turning one on appends it there and moves `epilogue_status`; turning one off removes that type from today's list and leaves `epilogue_status` alone. So read the current state from `epilogue_today_statuses`, never from `epilogue_status`, which is only the last value
leadbay_send_feedback## WHAT IT DOES Send the user's feedback to the Leadbay team's inbox — the SAME place the Leadbay web app's "Send feedback" form delivers to. Use when the user wants to tell the team something (a bug, a request, praise, "let Leadbay know…"), OR when a tool errored and the user accepts your offer to report it. The user writes the message; you confirm the wording, then send. Use leadbay_report_friction instead when the user is reporting one specific tool result that disappointed them. ## WHEN TO USE Trigger phrases: "send feedback", "I want to report a bug", "tell the Leadbay team", "let Leadbay know", "give feedback", "report this to support", "I have a feature request". Do NOT use for: "report this specific empty/wrong result to the team" → `leadbay_report_friction`; "log the email I sent" → `leadbay_report_outreach`. Use this when: the user explicitly wants the Leadbay TEAM to receive a message they authored — or accepts your offer to report an error. When the report is about one specific tool result that disappointed them, use leadbay_report_friction instead. Examples that SHOULD invoke this tool: - "Send feedback to the team: the lead scores feel off this week." - "Can you tell Leadbay the onboarding was confusing?" - "Tell Leadbay I'd love a way to schedule my morning check-in." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Pulling leads in Lyon returns nothing — report that." - "Ugh, this never finds what I'm looking for. Show me today's leads." - "I emailed Acme — log that outreach." ## RENDER (quick) Confirm the exact wording with the user BEFORE calling (this is sent to the team). After sending, show a one-line confirmation from the result's `message` (e.g. "✓ Sent to the Leadbay team"). If `sent` is false, tell the user it could NOT be delivered — never imply it was sent. --- Deliver a user-authored message to the Leadbay team's feedback inbox — the same destination as the web app's feedback form. **You do not wri
leadbay_import_leadsImport leads into Leadbay's CRM via the file-import wizard. Returns stable Leadbay leadIds for downstream chaining into leadbay_bulk_qualify_leads / leadbay_research_lead_by_id. For MCP clients with short transport timeouts, pass `wait_for_completion:false` to return quickly with `{status:'running', importIds}`; poll leadbay_import_status with that handle. For end-to-end import+qualify in one call, prefer leadbay_import_and_qualify. For messy files, prefer the `leadbay_import_file` prompt which walks an agent through scan → resolve → preserve → commit phases. SLOW BACKEND ⇒ `{status:'running', timed_out:true, importIds}`. The wizard is sometimes slow; when the poll budget runs out this tool returns that SUCCESS result, not an error. The import is still running server-side. **Do NOT call leadbay_import_leads again** — that re-uploads the file and leaves a duplicate CRM-imports row. Leadbay has no cancel, so a Cancel or timeout is no reason to call it either. Sole exception: a `wait_for_completion:false` call that returned NOTHING — and even that can re-upload, so check CRM-imports. Check `leadbay_import_status({importIds})` — plus `dry_run:true` if the result carried it — until `complete` (usually 1–5 min), which returns `result.leads` with the leadIds; `phase:"committing"` means keep checking. Exception: `rows_pending_upload` rows never reached the backend and DO need a fresh call for that subset only. In records mode the result also carries `row_ids` — the synthetic id of each input row, in your `records[]` order — because `leadbay_import_status` reports recovered leads by that id; keep it to map them back to your source rows. ## A LAUNCHED JOB — its first result is a receipt, not the answer A result saying the job is still working (`still_running`, `next_poll`, a `running` status) holds only ids to check it with. If the user's request needs the output: 1. Say in one line what is running and roughly how long it takes, so the wait does not look broken. 2. In
leadbay_import_and_qualifyImport + qualify leads in one call. Pass either `domains: [{domain, name?}]` (Mode A) OR `records[]` with `mappings` (Mode B). At least one mapped field must be LEADBAY_ID, CRM_ID, SIREN, LEAD_NAME, or LEAD_WEBSITE. Discover the org's mappable surface via `leadbay_list_mappable_fields`. For messy files, prefer the `leadbay_import_file` prompt which walks an agent through scan → resolve → preserve → commit phases. WHEN TO USE: agent has a list of companies (domains, or CSV-shaped rows from the user's CRM) and wants the full AI qualification — qualification answers, web-research signals — without orchestrating import + bulk_qualify_leads + lead_profile chains by hand. WHEN NOT TO USE: discovery (use leadbay_pull_leads); single-lead deep dive (use leadbay_research_lead_by_id); high-cadence or untrusted automation — this mutates user state and consumes ai_rescore + web_fetch quota. ## A launched job cannot be stopped Leadbay has no cancel. Once `leadbay_enrich_titles`, `leadbay_bulk_qualify_leads`, `leadbay_import_leads` or `leadbay_import_and_qualify` has returned a launched or running result, that work is queued on Leadbay and runs to completion, and the quota it uses is already committed. A discovery, preview or `dry_run` result launched nothing and is not covered here. The user cancelling in the chat, a request timeout, or a closed stream stops YOUR waiting, never the job. `cancelled: true` means we stopped watching, not that the work stopped. What to do next depends on what you are holding: - **A handle.** Poll the status tool with it, and do not launch the work that handle covers a second time — that uses the quota again on the same rows. `leadbay_import_status` takes `importIds`, so pass the values of `import_ids` under that name. A qualification started by `leadbay_import_and_qualify` has no notification of its own: resume it with `leadbay_qualify_status({lead_ids, lens_id})`. - **A handle AND a subset the result says never started** — `failed[]`
leadbay_add_contact## WHAT IT DOES Add a single contact (a person) to a known company in one call — name plus optional title, LinkedIn URL, email, phone. Use when a rep found someone (often just a LinkedIn URL) and wants them on an already-identified lead. Don't use it to import a list of companies, or to enrich an existing contact's email/phone. ## WHEN TO USE Trigger phrases: "add a contact to this company", "add this person to <company>", "create a contact from this LinkedIn URL", "this company has no contacts — add one", "I found someone on LinkedIn, add them to <lead>". Do NOT use for: "import these companies / a CSV of leads and qualify them" → `leadbay_import_and_qualify`; "get email/phone for a contact already on the company" → `leadbay_enrich_titles`; "remove / delete this contact" → `leadbay_remove_contact`. Use this when: user wants to attach ONE known person to an already-identified company — pass the company's `lead_id` plus the person's name (+ optional linkedin_page/title/email/phone) Examples that SHOULD invoke this tool: - "Acme has no suggested contacts — add Jane Doe, VP Eng, here's her LinkedIn." - "Add this person I found on LinkedIn to that company." - "Create a contact for John Smith, CFO, on this lead." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Import these 40 domains from my CRM and qualify them." - "Get me the email for the contact already on this company." - "Remove that contact, it's the wrong person." ## RENDER (quick) One-line confirmation: the contact's name + title now sits on the company. No table. If the contact has no email/phone yet, note it can be enriched. --- Add a single contact (a person) to a known company — the in-conversation "create a contact" path. Use it when a rep has found someone (often just a LinkedIn URL) and wants them on an already-identified Leadbay company without leaving the chat. Pass the parent company's `lead_id` plus the person's `first_name` + `last_name`. Everything else is
leadbay_remove_contact## WHAT IT DOES Remove (archive) a single contact from a company — the undo for the add-a-contact path. Use when the user wants to delete a person off a lead. Don't use it to remove a whole lead, or to skip/dislike a lead. ## WHEN TO USE Trigger phrases: "remove this contact", "delete this contact", "take this person off the company", "that contact is wrong — get rid of it", "undo the contact I just added". Do NOT use for: "add a contact to this company" → `leadbay_add_contact`; "stop showing me this lead / not interested" → `leadbay_dislike_lead`. Use this when: user wants a specific PERSON gone from a company — pass that contact's own `contact_id` (from a contacts list), not the lead id Examples that SHOULD invoke this tool: - "Remove Jane Doe from that company — I added her by mistake." - "Delete this contact, it's the wrong person." - "Undo the contact I just added to Acme." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Stop showing me this lead." - "Add a contact to this company." - "Show me today's leads." ## RENDER (quick) One-line confirmation: name the contact (or id) and that it was removed from the company. No table. --- Remove a single contact from a company by archiving it. This is the **undo** for the add-a-contact path (`leadbay_add_contact`) — when a rep adds the wrong person, or finds a stale contact, this takes them off the company. Pass the contact's **own** `contact_id` — the `id` field on a contact object returned by `leadbay_research_lead_by_id` or the contacts list. **Not** the parent lead id; the archive endpoint is keyed by the contact directly. Backend: `POST /contacts/{contact_id}/archive` → 204. Archive is a **soft-delete** — the contact leaves the company's active contact list (the same action the Leadbay web UI's contact "delete" fires). Idempotent: archiving an already-archived contact is a no-op. Returns `{ archived: true, contact_id, action: "archived" }`. Requires: LEADBAY_MCP_WRITE=1
leadbay_pin_contact## WHAT IT DOES Pin a contact on a company so it surfaces first as a priority/favourite. Use when the user wants to mark a specific person as the one to focus on. Don't use it to add a contact, remove one, or skip a whole lead. ## WHEN TO USE Trigger phrases: "pin this contact", "mark this person as priority", "make this the main contact", "favourite this contact". Do NOT use for: "unpin / remove the pin" → `leadbay_unpin_contact`; "add a contact to this company" → `leadbay_add_contact`; "remove / delete this contact" → `leadbay_remove_contact`. Use this when: user wants ONE person flagged as the priority on a company — pass that contact's own `contact_id`, and ONLY a `source:"org"` contact can be pinned (a `source:"paid"` candidate returns 'contact not found') Examples that SHOULD invoke this tool: - "Pin Jane Doe as the main contact on this company." - "Mark this person as the priority contact." - "Favourite that contact so it shows first." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Add a contact to this company." - "Remove that contact, wrong person." - "Stop showing me this lead." ## RENDER (quick) One-line confirmation that the named contact (or id) is now pinned. No table. --- Pin a single contact on a company so it surfaces first as a priority / favourite. Use when the user wants to flag a specific person as the one to focus on. Pass the contact's **own** `contact_id` (the `id` field on a contact object from `leadbay_research_lead_by_id` or a contacts list) — **not** the parent lead id. **Only `source: "org"` contacts are pinnable.** Every contact returned by `leadbay_research_lead_by_id` carries a `source` field, and the two sources are separate id namespaces on the backend: - `source: "org"` — a row in your organization's own contact directory. Pinnable. Also carries `pinned` (true when someone has pinned it) and `pinned_by_ai` (true when Leadbay's AI pinned it rather than a human). - `source: "paid"` — an e
leadbay_unpin_contact## WHAT IT DOES Unpin a contact on a company — the inverse of pinning. Use when the user wants to clear a contact's priority/favourite flag. Don't use it to remove the contact entirely (that's leadbay_remove_contact). ## WHEN TO USE Trigger phrases: "unpin this contact", "remove the pin from this contact", "this person isn't the priority anymore", "unfavourite this contact". Do NOT use for: "pin / mark as priority" → `leadbay_pin_contact`; "remove / delete this contact" → `leadbay_remove_contact`. Use this when: user wants to clear the pinned flag on a contact (but keep the contact) — pass that contact's own `contact_id`, and ONLY a `source:"org"` contact can be unpinned (a `source:"paid"` candidate returns 'contact not found') Examples that SHOULD invoke this tool: - "Unpin Jane Doe — she's not the priority anymore." - "Remove the pin from that contact." - "Unfavourite this person." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Pin this contact as priority." - "Remove that contact entirely." - "Add a new contact to this company." ## RENDER (quick) One-line confirmation that the named contact (or id) is no longer pinned. No table. --- Unpin a single contact on a company — clears its priority / favourite flag. The contact stays on the company; only the pin is removed (to remove the contact entirely, use `leadbay_remove_contact`). Pass the contact's **own** `contact_id` — not the parent lead id. **Only `source: "org"` contacts are pinnable.** Every contact returned by `leadbay_research_lead_by_id` carries a `source` field, and the two sources are separate id namespaces on the backend: - `source: "org"` — a row in your organization's own contact directory. Pinnable. Also carries `pinned` (true when someone has pinned it) and `pinned_by_ai` (true when Leadbay's AI pinned it rather than a human). - `source: "paid"` — an enrichment *candidate* (the `candidates` bucket): a person Leadbay suggests but has not yet resolved into
leadbay_update_contact## WHAT IT DOES Edit an existing contact in place — change their title, LinkedIn, email, phone, or name. Send only the fields you are changing; the rest keep their values. Pass a field as null to erase it. Use when the user wants to fix or update a contact's details. Don't use it to add a new contact or remove one. ## WHEN TO USE Trigger phrases: "update this contact", "fix this contact's title", "change their email / phone / LinkedIn", "edit this person's details", "correct the contact's name". Do NOT use for: "add a new contact to this company", "fix an enriched contact's details" → `leadbay_add_contact`; "remove / delete this contact" → `leadbay_remove_contact`; "get email/phone for a contact (enrichment)" → `leadbay_enrich_titles`. Use this when: user wants to change details on a contact that is in their own directory (`source: "org"`) — pass its `contact_id`, first_name, last_name and only the fields being changed Examples that SHOULD invoke this tool: - "Update Jane's title to SVP Engineering." - "Fix this contact's LinkedIn URL." - "Change John's email to john@acme.com." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Add a new contact to this company." - "Remove that contact, wrong person." - "Get me the email for this contact." ## RENDER (quick) One-line confirmation naming the contact and what changed. No table. --- Edit an existing contact in place — change their `job_title`, `linkedin_page`, `email`, `phone_number`, or name. Pass the contact's **own** `contact_id` — **not** the parent lead id. **Only your organization's own directory contacts can be edited.** Leadbay holds contacts in two separate id namespaces and this endpoint resolves one of them: | `source` on the contact | What it is | Editable here | |---|---|---| | `"org"` | A row in your organization's contact directory — added by you or your team, or promoted from an import | **yes** | | `"paid"` | An enrichment result bought from a data provider | **
leadbay_enrich_contacts## WHAT IT DOES Order email and/or phone enrichment for ONE specific contact on a lead — the person the user named, not a job title. Use when the user has already picked who they want. Don't use it to enrich a title across many leads. ## WHEN TO USE Trigger phrases: "enrich this contact", "get this person's email", "find <name>'s phone number", "reveal the email of <name> at <company>", "enrich the managing director, not the president", "enrichir le DG à la place du président". Do NOT use for: "enrich the CEOs / a job title across my leads" → `leadbay_enrich_titles`; "pin / mark this person as the priority contact" → `leadbay_pin_contact`; "draft an email / prepare outreach for this lead" → `leadbay_prepare_outreach`. Use this when: the user names ONE person on ONE company — pass the lead id + that contact's own id. A `source:"paid"` candidate id from leadbay_research_lead_by_id is valid input. Pinning does not enrich anyone. Examples that SHOULD invoke this tool: - "Get me Jane Doe's email at Acme." - "Enrich the managing director at Cromology, not the president." - "Reveal the phone number for this contact." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Enrich the CEOs across my top 10 leads." - "Pin Jane Doe as the main contact on Acme." - "Draft an outreach email for Acme." ## RENDER (quick) One line: "Enrichment started for <name> (<email / phone>)". Then re-read the lead's contacts every ~30s via leadbay_research_lead_by_id and report when the requested channel has landed. Never print a credits figure. --- Order email and/or phone enrichment for a specific contact. Tries the paid-contact path and falls back to the org-contact path on NOT_FOUND. Each email reveal and each phone reveal consumes QUOTA. Both `email` and `phone` default to `true` — a bare call enriches both channels. WHEN TO USE: when the user has already picked WHO they want on a company and you hold that person's `contact_id` — from `leadbay_research_l
leadbay_create_custom_fieldCreate an org-level CRM custom field for imports, then use the returned `mapping_value` in leadbay_import_leads / leadbay_import_and_qualify mappings. Use when the user's file contains valuable columns that do not fit Leadbay's standard fields, such as source-system deep links, source record IDs, campaign provenance, or user-requested enrichment attributes. For HubSpot record links, prefer `type:'EXTERNAL_ID'` with `config.url_template` and import only the stable HubSpot id as the CSV value. Example: create field name 'HubSpot Contact', type 'EXTERNAL_ID', config `{url_template:'https://app.hubspot.com/contacts/<portal-id>/record/0-1/{value}'}`; then map `hubspot_id` to the returned `mapping_value`. If only a full URL column exists and the id cannot be safely extracted, use a TEXT field instead. WHEN TO USE: after leadbay_list_mappable_fields shows no suitable existing custom field and preserving the column matters to the user's goal. WHEN NOT TO USE: for standard company/contact data that maps to LEAD_WEBSITE, LEAD_NAME, CONTACT_EMAIL, etc.; do not create custom fields for noisy scraper notes unless the user explicitly asks to preserve them.
leadbay_update_custom_fieldUpdate an org-level CRM custom field in place. Use when the user wants to rename a custom field or change its type/config — e.g. "rename the 'Tier' field to 'Account Tier'" or "make the ARR field a PRICE in USD". Pass `id` (the numeric custom-field id from `leadbay_list_mappable_fields` — NOT the `CUSTOM.<id>` mapping value) plus any of `name`, `type`, `config`. The update is a partial merge over the current definition: a rename-only call keeps the existing type; a retype-only call keeps the name. At least one of `name` / `type` / `config` is required. Type + config rules mirror creation: `EXTERNAL_ID` requires `config.url_template` containing `{value}`; `PRICE` requires `config.currency`; `DATE`/`DATETIME` may set `config.format`. Returns the updated `{id, name, type, config, mapping_value}`. WHEN TO USE: the user wants to change an existing custom field's name or type. WHEN NOT TO USE: to CREATE a new field (use leadbay_create_custom_field) or to DELETE one (use leadbay_delete_custom_field). To read a lead's custom-field values use leadbay_get_lead_custom_fields; to list the catalog use leadbay_list_mappable_fields. ### RENDERING Confirm the change in one line naming the field and what changed, e.g. **"Renamed custom field #12 → 'Account Tier' (TEXT)."** or **"Updated #13 'ARR' → PRICE (USD)."** Don't dump the raw payload.
leadbay_delete_custom_fieldDelete an org-level CRM custom field. Use when the user explicitly wants to remove a custom field from their account — e.g. "delete the old 'Legacy Source' field". **This is destructive.** Removing the field drops its stored values from every lead and breaks any import mapping that targets `CUSTOM.<id>`. For that reason the tool has a safety gate: - Call with `id` only → the tool returns the field that WOULD be deleted (`{id, name, type, deleted:false, hint}`) and changes nothing. Surface the hint to the user and ask them to confirm. - Call with `id` + `confirm:true` → the field is deleted (`{id, name, type, deleted:true}`). `id` is the numeric custom-field id from `leadbay_list_mappable_fields` — NOT the `CUSTOM.<id>` mapping value. WHEN TO USE: the user explicitly asks to delete/remove a custom field — and only fire with confirm:true after they confirm. WHEN NOT TO USE: to rename or retype a field (use leadbay_update_custom_field) or to create one (use leadbay_create_custom_field). ### RENDERING Before deleting (no confirm), render the `hint` and ask the user to confirm — do NOT auto-confirm on the user's behalf. After a confirmed delete, acknowledge in one line: **"Deleted custom field #12 'Legacy Source'."**
leadbay_set_qualification_questions## WHAT IT DOES Modify the org's qualification questions — the AI-agent questions every lead is scored against — or add negative criteria to its ideal buyer profile. Use when the user states what makes a lead good or bad and no existing question or anti-pattern covers it. Don't use it for a sector/size/territory rule (leadbay_adjust_audience), a named company, or a delivery requirement like "email and phone required". ## WHEN TO USE Trigger phrases: "add / remove / replace a qualification question", "update my qualification so Leadbay looks for <trait>", "my best customers are <trait> — target those", "I don't want <kind of company> at all", "the leads aren't relevant, fix my criteria". Do NOT use for: "what are my qualification questions" → `leadbay_get_qualification_questions`; "narrow to <sector> / <headcount> / <territory>" → `leadbay_adjust_audience`; "a qualitative orientation one yes/no can't express" → `leadbay_refine_lead_targeting`; "exclude <named company>" → `leadbay_dislike_lead`; "only leads that already have an email and a phone" → `leadbay_enrich_titles`. Use this when: the user stated a durable company TRAIT a stranger could estimate from that company's public material, and get_qualification_questions shows nothing covering it. Read first, propose the text, write only on a yes. Examples that SHOULD invoke this tool: - "Our best customers are cold-storage plants that run their own maintenance crews — update my qualification for that." - "Écarte les sociétés en liquidation, je ne veux plus les voir." - "Remove the flooring question and add one about install crews." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "What qualification questions does Leadbay use?" - "Add fintech to my Joinery lens." - "Exclude Groupe Solidum, we had an unpaid invoice with them." ## RENDER (quick) Before writing: show the exact question text you propose, say what it changes, and ask for a yes (route via ask_user_input_v0). After writi
leadbay_add_noteAdd a note to a lead. Notes are visible to the whole organization in Leadbay. WHEN TO USE: low-level — for free-form notes not tied to outreach actions, including meaningful per-lead notes/context preserved from an imported file after the import returns lead IDs. Also to record why a company was set aside when a CRM status change carries no reason, or when the user tells you something about one company that only they know (their own sales agent, already a client) without excluding it. A dislike saves its own reason: do not add a second note for it. WHEN NOT TO USE: to log an outreach action — use leadbay_report_outreach, which requires verification (gmail/calendar/user_confirmed) to prevent hallucinated outreach poisoning the SDR pipeline. This tool MUTATES state. The caller (agent or human-in-the-loop) is responsible for confirming intent before invocation; the MCP server does not soft-prompt for confirmation. See `annotations.destructiveHint`.
leadbay_like_lead## WHAT IT DOES Mark a lead as liked — signals positive interest to the Leadbay scoring engine, influencing future batch composition. Use when the user explicitly approves a lead ("thumbs up", "save this one", "I like this"). Don't use it for snoozing — that's `leadbay_set_pushback`. ## WHEN TO USE Trigger phrases: "I like this lead", "thumbs up", "this one looks good", "save this one", "this is a good fit", "more like this", "yes to this one". Do NOT use for: "remind me about this lead later / snooze it" → `leadbay_set_pushback`; "not relevant / wrong fit / thumbs down" → `leadbay_dislike_lead`. Use this when: user expresses durable positive interest in a specific lead; pass the lead's UUID as `lead_id` Examples that SHOULD invoke this tool: - "I like this lead — show me more like it." - "Thumbs up on Acme Corp, save it." - "This one's a perfect fit, keep them in the rotation." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Skip this for now, I'll look at it next week." - "Not relevant — wrong industry." - "Just show me the top leads today." ## RENDER (quick) One short confirmation line after the call returns ("👍 Liked **{company_name}** — positive signal sent."), then continue the current flow (don't dump the full lead card again). --- Mark a lead as liked. This is the same action as clicking the thumbs-up on the Leadbay website. The signal is fed back into the scoring engine: liked leads improve the quality of future batches by teaching Leadbay what the user finds relevant. Pass the lead's UUID as `lead_id`. WHEN TO USE: the user explicitly approves of a lead ("this one looks good", "I like this", "thumbs up", "save this one", "this is a good fit"). Also use after `leadbay_research_lead_by_id` reveals strong signals. WHEN NOT TO USE: the user is just reading or researching a lead without expressing approval. Use `leadbay_dislike_lead` for negative signals; use `leadbay_set_pushback` for "remind me later" / temporary
leadbay_dislike_lead## WHAT IT DOES Mark a lead as disliked, hiding it from this user, and save the user's reason as a note on the lead. Use when the user rejects a lead ("not relevant", "thumbs down", "wrong industry"). Distinct from `leadbay_set_pushback`, which is a temporary deferral the user expects to revisit. ## WHEN TO USE Trigger phrases: "I don't like this lead", "thumbs down", "not relevant", "wrong industry", "too small", "skip permanently", "not a fit", "no to this one". Do NOT use for: "remind me later / snooze / not now" → `leadbay_set_pushback`; "thumbs up / save this one" → `leadbay_like_lead`. Use this when: durable rejection of a specific lead; pass `lead_id`, and the user's words as `reason`. For temporary deferral, route to `leadbay_set_pushback`. Examples that SHOULD invoke this tool: - "Thumbs down — wrong industry." - "Dislike this one, never show me leads like this again." - "Not a fit at all, remove it." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "Skip this for now, ask me again next month." - "I'll look at this one later." - "I like this lead — save it." ## RENDER (quick) One short confirmation line after the call returns ("👎 Disliked **{company_name}** — reason saved as a note." when `reason_saved`). If the reason names a kind of company, add one line proposing the setting change (see `targeting`). Then continue the current flow (don't dump the full lead card again). --- Mark a lead as disliked. This is the same action as clicking the thumbs-down on the Leadbay website: the lead stops appearing for this user. The dislike itself carries no reason and changes no lens filter, qualification question or targeting prompt. Leadbay only avoids a sector on the lens's next refresh after two of the lens's leads in it are disliked and none liked, and a city after two. Pass the lead's UUID as `lead_id`, and the user's reason as `reason` whenever they gave one. The reason is saved as a note on the lead, so the team and later
leadbay_set_lead_status## WHAT IT DOES Set the org-wide CRM status on one or more leads — WANTED, WON, LOST, or UNWANTED — optionally stamping the date the status was reached. Use when the user states a commercial outcome ("we won Acme", "mark these as lost"). Don't use it for post-outreach disposition — that's `leadbay_report_outreach`'s `epilogue_status`. ## WHEN TO USE Trigger phrases: "we won this deal", "mark this lead as won", "we lost them", "mark as lost", "this one is a target", "add them to my wanted list", "set the status on these leads", "closed the deal with", "they signed", "not a target anymore". Do NOT use for: "I sent the email / left a voicemail — log the outcome" → `leadbay_report_outreach`; "thumbs up, I like this lead" → `leadbay_like_lead`; "remind me about this lead next week / snooze it" → `leadbay_set_pushback`. Use this when: user states a COMMERCIAL outcome or pipeline stage, not an outreach event; pass `lead_ids` + the uppercase `status`, and `status_date` when they name a close date Examples that SHOULD invoke this tool: - "We just signed Acme Corp — mark them as won." - "Mark these three as lost, they went with a competitor." - "Add Northwind to my wanted list, they're a priority target." Examples that should NOT invoke this tool (sound similar, route elsewhere): - "I emailed the CTO this morning, log it." - "Thumbs up on this one, show me more like it." - "Snooze this lead until next quarter." ## RENDER (quick) One short confirmation line per status applied ("✅ **Acme Corp** → WON (closed 2026-03-14)"). If `failed` is non-empty, list those leads with their error underneath. Don't re-render the full lead card. --- Set the **org-wide CRM lead status** — the same field the Leadbay website's status selector writes, and the one a CSV import maps via `mappings.statuses`. It is shared across the whole organization: every rep sees the value this call sets. Two distinct status systems exist in Leadbay. Do not confuse them: | System | Values | Written by