Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
setup_profileA

Set up HeyLead by connecting your LinkedIn account and analyzing your writing style.

REQUIRED for first-time users — must be called before any other tool.

This analyzes your LinkedIn profile, posts, and writing style to create
a "voice signature" so every outreach message sounds like YOU, not a bot.
Handles LinkedIn automation setup, SDR onboarding, account connection,
and voice analysis for personalized outreach.

First-time setup: sign in at https://heylead.dev/auth/login-url, click
'Connect' on the LinkedIn row, copy the setup message ('Copy' under
'Get Started'), then call this tool with the eyJ... token from it as
backend_jwt. No API keys needed on the hosted backend.

Args:
    llm_api_key: Optional — only if you want to use your own AI key instead of the backend's.
    llm_provider: Which AI to use if providing your own key: "gemini", "claude", or "openai".
    backend_url: HeyLead Backend API URL. Leave empty — defaults to production server.
    backend_jwt: Your authentication token from HeyLead.
accountA

Manage your LinkedIn accounts — list, switch, or disconnect.

Args:
    action: What to do:
        "list"          — Show all connected LinkedIn accounts (default)
        "switch"        — List accounts and pick one to switch to
        "switch_to"     — Switch to a specific account by ID
        "unlink"        — Disconnect the current LinkedIn account
        "connect_email" — Connect Gmail/Outlook via Unipile hosted auth.
                          Never use Mail.app.
        "refresh_tier"  — Re-check Sales Navigator on your accounts and heal the stored tier flags
    account_id: The Unipile account ID (required for "switch_to").
organizationA

List, switch, or manage hosted HeyLead organizations.

Use this to work across client workspaces. The person stays signed in;
only the active organization changes.

Args:
    action: list | switch | members | invite | remove_member | create
    org_id: Organization id (required for switch; optional if already switched).
    email: Invitee email (invite), or the new org name (create).
    role: editor or viewer (invite).
    user_id: Member to remove (remove_member).
generate_icpA

Generate a rich Ideal Customer Profile with buyer personas.

The same profile describes whoever the user needs to reach: buyers,
candidates to recruit, research or user-interview participants, hiring
managers for a job search, investors or partners.

Creates 2-4 ICP personas with pain points, fears, barriers,
LinkedIn search parameters, and confidence scores. The result
is saved and can be reused with create_campaign(icp_id=...).
Supports target audience analysis, customer segmentation, buyer persona
creation, ideal customer profiling, and B2B market research.

Args:
    target_description: Who to target (e.g., "CTOs at fintech startups",
        "freelance UX designers in London", "yoga studio owners in California")
    company_context: Optional URL or text about your company/product.
        Providing this makes the ICP more precise and evidence-backed.
    focus_query: Optional focus (e.g., "enterprise segment only",
        "focus on pain points around compliance")
    decision_makers_only: Keep every persona's seniority to people who
        hold budget authority — owner, cxo, vp, director. Default True.
        Pass False only when the target really is individual contributors
        (developers, designers, analysts); the ICP then keeps whatever
        levels the description implies.
profile_signalsA

Compile a targeting request into LinkedIn recall + profile evidence.

Use this to see how HeyLead looks for country ties (school, language,
worked-in) or interests (car lovers, esoteric) on a full LinkedIn
profile. Campaigns still go through generate_icp / create_campaign.

Args:
    action: compile (default), preview, or schools (exact LinkedIn school names).
    request: e.g. "Ukrainians in the US" or "classic car lovers".
    titles: Optional comma-separated titles for recall queries.
    location_codes: Optional comma-separated LinkedIn location codes.
    profiles_json: preview only — JSON list of full profiles to score.
icpA

Preview a saved ICP against LinkedIn, or audit it against a campaign goal, without creating anything.

Runs the search create_campaign would run from the ICP's enriched LinkedIn
codes and shows what comes back, how each filter is shaping the result, and
how the profiles score against the persona. It creates no campaign, no
outreach records and no contacts, so an ICP can be checked and rejected
without cleanup. Use it when the targeting is unproven or when someone asks
for example profiles for an ICP.

Args:
    action: "preview" shows matched profiles, the exact filters sent to
        LinkedIn with their resolved code names, a per-filter contribution
        readout, and the fit scores. "goal_match" runs no search at all:
        it asks whether the ICP's personas actually hold budget authority
        for the campaign's goal, grounded in the shipped sales-methodology
        knowledge base, and returns match / partial / mismatch with the
        decision-maker coverage and concrete fixes.
    icp_id: ID of a saved ICP from generate_icp (a truncated id works).
        Leave empty to list your saved ICPs.
    persona: Which persona of the ICP to search with, 1-based (default 1).
        An ICP usually holds 2-4; each has its own filters.
    limit: How many matched profiles to list, 1-50 (default 10). The search
        itself always fetches one full page regardless.
    campaign_id: goal_match only — take the goal and the offer from this
        campaign's config/context instead of typing them.
    target_description: goal_match only — the goal to audit against when
        there is no campaign yet. Falls back to the ICP's own target.
create_campaignA

Create a LinkedIn outreach campaign from a natural language description.

Finds people on LinkedIn who match the description and saves a draft;
nothing is sent until campaign(action='launch'). Use it for sales
prospecting, recruiting and candidate sourcing, research and
user-interview recruitment, job-search networking, investor and partner
outreach, vendor scouting and event invitations.

Describe your ideal customers and HeyLead will find them on LinkedIn.
Supports lead generation, prospect discovery, SDR automation, cold outreach,
and targeted B2B sales campaigns with AI-powered ICP-based targeting.
On first campaign, project_brief is asked explicitly (what you are building,
go-live, volume, what a vendor must confirm) — a homepage alone is not enough.

Args:
    target_description: Who to target (e.g., "CTOs at fintech startups",
        "freelance UX designers in London", "yoga studio owners in California")
    campaign_name: Optional name for the campaign.
    icp_id: Optional ID of a saved ICP from generate_icp. If provided,
        uses the saved ICP's enriched LinkedIn codes for precise targeting
        instead of generating a new one.
    company_context: Optional. Your website URL or 1-2 sentences about your
        product/company. Copied into project_brief when project_brief is omitted.
    project_brief: Optional. Full project paste the model sees: what you are
        building, go-live, volume, what a vendor must confirm. Required before
        launch, resume, or auto-send.
    mode: Always autopilot. Copilot mode removed.
    company_url: Optional LinkedIn company URL for account-based targeting.
        Searches for employees at that specific company matching the ICP.
        Example: "https://www.linkedin.com/company/google"
    voice_mode: Voice memo mode for follow-ups and replies. "text_only"
        (default), "mixed" (alternates text and voice), "voice_only", or "ab_test".
    connections_only: "on" to create a DM-only campaign targeting existing
        LinkedIn connections. Skips invitations and warm-up — sends DMs
        directly to people you're already connected with. Use when user says
        "existing connections", "DM my network", "message my connections".
    exclude_connections: ON BY DEFAULT for a new campaign: nobody who was
        already a 1st-degree connection before this campaign started is
        reached — refused at enrolment and skipped at send time rather than
        DMed. People who accept this campaign's own invitation still get
        the opener. Pass "off" to include existing connections (or turn it
        off later in the campaign settings). Defaults off only for a
        connections_only campaign. Use "off" when the user says
        "include my existing connections"; the old "on" is still accepted
        for "don't message my existing connections", "cold only",
        "skip people I already know". Cannot be combined with
        connections_only, which is its exact inverse.
    campaign_type: Prompt family: "outbound" (default) or "job_search".
        job_search writes a job-search campaign: the invitation note and
        the first DM may name the recipient's company and the role, use
        one credible proof point at most and never list a CV. InMail is
        not routed by this switch. Pair with connections_only="on" to
        write to people the sender is already connected to.
    force: True to create the campaign even when the goal <-> ICP audit
        returns `mismatch` (the ICP holds no plausible buyer for the goal).
        Leave False; a `partial` verdict never blocks, it only warns.
generate_and_sendA

Generate a personalized LinkedIn message and send it (or queue for review).

Creates and sends cold outreach, connection requests, and personalized
LinkedIn invitations using voice-matched AI messaging.
Sends automatically after validation. A message that fails validation is
never sent.

Args:
    campaign_id: Which campaign to send from. Uses active campaign if empty.
book_meetingA

Book a meeting on your Google Calendar and invite a prospect.

Use this when a reply agrees to a call. Creates the event on the calendar
you connected, attaches a Google Meet link, and emails the attendee an
invitation.

Args:
    attendee_email: Who to invite — the prospect who replied.
    start: When it starts, ISO 8601, e.g. 2026-09-01T10:00:00.
    duration_minutes: How long the meeting runs. Defaults to 30.
    summary: Event title. Defaults to naming the attendee.
    description: Optional agenda or notes included in the invitation.
check_repliesB

Check for new LinkedIn replies across all campaigns.

Fetches new messages, classifies sentiment (positive/negative/question), and surfaces hot leads that need your attention. Handles inbox monitoring, lead response tracking, and conversation management.

show_statusA

Show your outreach dashboard — campaigns, stats, hot leads, account health.

The chat is the front door to your dashboard. View pipeline metrics, prospect
funnel, engagement rates, and campaign performance. Ask "how's my outreach?" anytime.

Hosted accounts get a dashboard link and a snapshot card; relay the link,
because some clients show the image only to the model.

Args:
    campaign_id: Show stats for a specific campaign. Shows all if empty.
campaignA

Control campaign lifecycle — launch, monitor, pause, resume, archive, delete, emergency stop, or retry failed.

Hosted accounts get a dashboard link and a snapshot card; relay the link,
because some clients show the image only to the model.

Args:
    action: What to do:
        "launch"         — Start outreach for a draft campaign (create_campaign
                           leaves it as a draft; nothing sends until this runs).
                           On a hosted account this also commissions the cloud
                           scheduler, so the campaign keeps sending with the
                           laptop closed
        "monitor"        — Activate a campaign for signal collection only. Sends
                           nothing; requires scheduler(action='observe')
        "pause"          — Pause an active campaign
        "resume"         — Resume a paused campaign
        "archive"        — Archive a completed campaign
        "delete"         — Permanently delete a campaign (requires confirm=True)
        "emergency_stop" — Immediately pause ALL active campaigns (kill switch)
        "retry_failed"   — Reset error outreaches to pending
        "repair_queue"   — Drop never-contacted rows below min_fit_score
        "status_history" — View campaign status change audit log (who stopped/started and when)
        "clear_coordinator_hold" — Release a campaign-wide coordinator hold
    campaign_id: Which campaign to act on. Auto-selects if empty.
    confirm: Must be True for delete action. Safety guard.
send_messageA

Send follow-ups, replies, voice memos, or InMail to prospects.

Args:
    action: What to do:
        "followup" — Send a follow-up DM after connection accepted
        "reply"    — Reply to a prospect who has messaged you
        "voice"    — Send a voice memo on LinkedIn
        "delete"   — Delete a recently sent message (within 60 min on LinkedIn)
        "inmail"   — Send an InMail to a NON-connection. Preconditions
                     (each fails closed with no send): prospect has a
                     provider_id; they are NOT a 1st-degree connection
                     (use followup/DM for those); no InMail already sent
                     on this outreach; InMail credits remaining > 0.
                     A pending invitation to the same person is allowed
                     — that is the escalation path. Requires outreach_id.
    campaign_id: Which campaign to send from. Uses active if empty.
    outreach_id: Specific outreach to target. Required for inmail.
    format: 'text' (default) or 'voice' (audio via Hume TTS). For followup/reply.
    text: Custom text for voice memo. Auto-generates if empty.
        For delete: optionally pass a Unipile message_id directly.
send_emailA

Send an email through the connected Unipile mailbox (Gmail/Outlook).

This is the only supported way to send email. Never use Mail.app, osascript,
mailto: handlers, or a local SMTP client.

If no mailbox is connected, the result includes a hosted-auth link.
Have the user open it, then retry. Or call account(action='connect_email')
first.

Args:
    to: Recipient email address.
    subject: Subject line.
    body: Body text (HTML is fine).
    to_name: Optional display name for the recipient.
engage_prospectA

Comment on, react to, follow, or endorse a prospect on LinkedIn to build trust.

Finds a prospect's recent posts, generates a voice-matched comment
(or reacts with a Like), and sends it. Use action="follow" to follow
a prospect's profile — this triggers a "X started following you"
notification and warms them up before connecting. Use action="endorse"
to endorse their skills — triggers a high-visibility notification.
Great for social selling, warm-up engagement, and building familiarity
before cold outreach.

Args:
    campaign_id: Which campaign to engage from. Uses active campaign if empty.
    outreach_id: Specific outreach to engage with. Auto-picks next if empty.
    action: "auto" (comment if post has text, react otherwise),
        "comment" (always comment), "react" or "like" (just like the post),
        "view" (view their LinkedIn profile — lightest warm-up signal),
        "follow" (follow their LinkedIn profile as a warm-up signal),
        "endorse" (endorse their skills — highest visibility warm-up),
        "reply_comment" (reply to prospect's response on your comment thread).
suggest_next_actionA

Suggest the best next action for your outreach.

Hosted accounts get a dashboard link and a snapshot card; relay the link,
because some clients show the image only to the model.

Analyzes all active campaigns and recommends what to do next,
prioritized by impact: hot leads first, then pending approvals,
follow-ups, engagement warm-ups, and new invitations.

Args:
    campaign_id: Focus on a specific campaign. Analyzes all active if empty.
edit_campaignA

Edit a campaign's name, mode, booking link, or context fields.

Change the campaign name or configure campaign settings
modes, set a booking link, or configure campaign context for
better message personalization.

Args:
    campaign_id: Which campaign to edit. Edits the first active campaign if empty.
    name: New campaign name. Leave empty to keep current name.
    mode: Only "autopilot" supported. Copilot mode removed.
    booking_link: Calendar/booking URL (e.g., "https://cal.com/you/15min").
        Used in reply_to_prospect() for positive replies to suggest meetings.
    offerings: What you offer (products, services, value props). Used in follow-up messages.
    case_studies: Brief case studies or success stories. Used for social proof in messages.
    social_proofs: Social proof (logos, metrics, testimonials). Used in follow-up messages.
    campaign_preferences: Custom messaging preferences (tone, topics to avoid, etc.).
    campaign_intent: Message stance: "sell", "buy", "partner", or "recruit".
    campaign_type: Prompt family: "outbound" (default) or "job_search".
        job_search replaces the intent-specific invitation note and first
        DM with ones that may name the company and the role, use one
        credible proof point at most and never list a CV. InMail is not
        routed by this switch, and campaign_intent still selects the
        system prompt. Empty keeps the current value.
    project_brief: Full project paste the model sees. Required before launch,
        resume, or auto-send.
    product: Optional structured fact: product / what you buy or sell.
    go_live: Optional structured fact: go-live date.
    volume: Optional structured fact: volume model.
    must_confirm: Optional comma-separated questions a vendor must confirm.
    voice_mode: Voice memo mode: "text_only", "voice_only", "mixed", or "ab_test".
        Leave empty to keep current value.
    voice_noise: Ambient noise type for voice memos: "office", "cafe", "street",
        "quiet", "none", "auto". Leave empty to keep current value.
    voice_humanize: Voice text humanization: "on" or "off".
        Leave empty to keep current value.
    enable_profile_views: View prospect profiles before following: "on" or "off".
    enable_follows: Follow prospects before inviting: "on" or "off".
    enable_endorsements: Endorse skills before inviting: "on" or "off".
    enable_engagements: Comment/react on posts before inviting: "on" or "off".
    enable_followups: Send follow-up DMs after connection: "on" or "off".
    enable_auto_replies: Auto-reply to prospect messages: "on" or "off".
    enable_invitations: Send connection invitations: "on" or "off".
        When off, campaign only DMs existing connections (no invitations sent).
    enable_discovery: Auto-find and enrol new prospects: "on" or "off".
    exclude_connections: "on" to never message anyone who was already a
        1st-degree connection before this campaign started — they are
        refused at enrolment and skipped at send time instead of being
        DMed. People who accept this campaign's own invitation still get
        the opener. Turning it on turns connections_only off.
    connections_only: "on" to target only your existing 1st-degree
        connections (DM-only, no invitations). Turning it on turns
        exclude_connections off.
        Turn off for curated campaigns with a fixed, hand-picked list.
    exclude_competitors: "on" to never first-touch people who work at
        competing companies. Default on. Empty list excludes nobody
        until research or competitor_companies names them.
    competitor_companies: Comma-separated employer names to skip.
    enable_reply_agent: Reply exception agent: "on" (act), "off", or
        "observe". Empty keeps the current value. Unset defaults to act.
    enable_strategist_replan_agent: Strategist replan: "on", "off", or
        "observe". Empty keeps the current value.
    enable_hot_lead_closer: Hot-lead closer: "on", "off", or "observe".
        Empty keeps the current value.
    enable_coordinator_agent: Coordinator digest/hold: "on", "off", or
        "observe". Empty keeps the current value.
    engagement_mode: Engagement style: "auto" (30% react / 70% comment),
        "comment_only", or "react_only".
    max_followups: Max follow-up messages (1-5). 0 to keep current.
    weekly_meeting_target: Meetings this campaign should book per week.
        The daily report reads it as the Key Result and says whether the
        campaign is on track. 0 means no goal this week; -1 keeps current.
    followup_delay_days: Custom day intervals as comma-separated list
        (e.g., "1,3,7,14"). Leave empty to keep current.
    withdraw_stale_invites: Auto-withdraw stale invites: "on" or "off".
    stale_invite_days: Days before withdrawing stale invites (7-60). 0 to keep current.
    inmail_fallback: Escalate quiet invitations with one InMail: "on" or "off".
        Free tier sends only to Open Profile members (zero credits).
    inmail_fallback_days: Quiet days before the InMail (1-60). 0 to keep current.
    inmail_first_touch: InMail as first touch: "on" or "off". Unset follows inmail_fallback.
    send_in_business_hours: Respect prospect's business hours: "on" or "off".
    active_days: Active send days as comma-separated numbers (0=Mon, 6=Sun).
        E.g., "0,1,2,3,4" for weekdays. Leave empty to keep current.
prospectA

Manage prospects — skip, close, dismiss, view conversation, or timeline.

Skip and Stop are different decisions:
  Skip — leave this person out of THIS campaign. No other effect.
  Stop — close(outcome='opt_out'): stop all outreach to this person
         across the workspace, and say why. That feedback improves
         targeting.

Args:
    action: What to do:
        "skip"         — Leave the prospect out of this campaign only
        "close"        — Record outcome (won/lost/opt_out) for an outreach
        "dismiss"      — Clear a lead off the Needs attention strip.
                         Closes it as lost, so it also leaves the Hot
                         Leads count. Needs confirm=True; the first call
                         previews who would be dismissed.
        "conversation" — View the full message thread with a prospect
        "timeline"     — View chronological journey of all actions for a prospect
    outreach_id: The outreach ID. Auto-selects if empty (except 'conversation'/'timeline').
    campaign_id: Which campaign (for 'skip'). Uses active if empty.
    outcome: 'won', 'lost', or 'opt_out' (for 'close').
    reason: Optional notes for the outcome (for 'close').
    meeting_link: Meeting/calendar URL if outcome is 'won' (for 'close').
        This is the URL where the meeting was booked — could be
        the user's booking page or the prospect's shared calendar.
    confirm: Must be True to actually dismiss (for 'dismiss').
    reason_code: Why, for 'skip' and 'close'. One of 'not_a_fit',
        'negative_reply', 'asked_to_stop', 'handled_elsewhere', 'other'.
        Only the first two are evidence about targeting; the rest are
        facts about that one person and never move a segment's ranking.
    reason_note: Free text alongside the code.
analyticsA

Campaign analytics — reports, comparisons, and exports.

Hosted accounts get a dashboard link and a snapshot card; relay the link,
because some clients show the image only to the model.

Args:
    action: What to do:
        "report"  — Detailed analytics with outcomes, conversion rates, stale leads
        "compare" — Compare 2+ campaigns side by side
        "export"  — Export campaign results as table, CSV, or JSON
    campaign_id: Which campaign. Uses active if empty.
    campaign_ids: Comma-separated IDs (for 'compare'). Compares all if empty.
    format: Output format for 'export': 'table', 'csv', or 'json'.
inspectA

Read-only digest of what the in-process agents decided — never writes.

Surfaces operator holds, today's strategist replans, hot-lead closer
decisions, recent reply skips, and gated scheduler jobs from the local
log. Use it when someone asks what the agents did, who is held, why a
reply was skipped, or why a campaign is not sending.
It does not send, book, replan, or change outreach state.

Args:
    action: What to show:
        "agents"  — one-screen digest of holds, replans, closer, skips, jobs (default)
        "holds"   — fresh hold_for_operator rows and coordinator campaign holds
        "replans" — today's strategist_replan_decision rows
        "closer"  — today's hot_lead_closer_decision rows
        "skips"   — recent reply skips (hard gates, cap, dedup, agent skip)
        "jobs"    — pending scheduler jobs and recent gated-job refusals
        "commons" — digest, beats (including product), live notes, coordinator hold, stale liveness
        "journal" — hosted agent diary (cloud workers). Self-hosted: use the other actions.
    campaign_id: Optional campaign filter (full id or prefix).
    outreach_id: Optional outreach filter (full id or prefix).
    limit: Max rows per slice, 1-100 (default 20).
knowledgeA

Curate the knowledge base that grounds generated messages. Hosted only.

Four kinds of source live in it: "upload" (documents added here),
"website" (crawled pages from your own site), "campaign" (campaign
context and offerings) and "reply_exemplar" (replies that worked).
Message generation quotes them, so what is in here decides what the
agent may claim.

Args:
    action: What to do:
        "list"    — Show every source with kind, chunk count, and embed status
        "add"     — Upload one document (needs title and text)
        "remove"  — Delete one source (needs source_id)
        "refresh" — Re-ingest the derived corpus (website, campaigns, exemplars)
        "search"  — Retrieve grounded evidence for a query
    title: Document title, for 'add'.
    text: Document body, for 'add'. Required.
    source_uri: Where the document came from, for 'add'. Optional.
    source_id: Which source to delete, for 'remove'. From 'list'.
    scope: What to re-ingest, for 'refresh': "all" (default), "website",
        "campaigns", or "exemplars".
    campaign_id: Restrict 'refresh' or 'search' to one campaign.
    query: What to retrieve, for 'search'. Required.
    kinds: Comma-separated source kinds — "upload,website,campaign,
        reply_exemplar". Filters 'search'; 'list' uses the first one.
    top_k: Max evidence chunks for 'search' (default 6, clamped to 1-50).
    sync: For 'refresh'. False (default) queues a background job and
        returns immediately — re-run knowledge(action='list') in a
        minute to watch the chunk counts land. True blocks until the
        re-ingest finishes and reports a summary; it can take minutes,
        and the backend only allows it for scope "campaigns" or
        "exemplars" (scope "all" is refused with the reason).
productA

Local-only product agent — patch this HeyLead git checkout or open a PR.

Does not send LinkedIn, email, or calendar. Cloud workers and installs
without a HeyLead .git checkout refuse. The coordinator never starts this
loop; call it explicitly.

Args:
    action: "status" (default) or "tick".
    request: What to change. Required for action='tick'.
schedulerA

Manage the autonomous scheduler — view status or toggle on/off.

Args:
    action: What to do:
        "status" — Show scheduler status, pending jobs, and recent activity
        "toggle" — Enable or disable the scheduler
        "observe" — Collect and classify signals, and check replies, while this
            machine sends nothing: no invitations, DMs, engagements, or
            enrolments. Local only — it does not stop 24/7 cloud scheduling,
            which must be disabled separately with
            scheduler(action='toggle', enabled=False, cloud=True)
        "always_on" — Enable/disable always-on mode (auto-re-enable + immediate email alerts)
        "logs" — Event log with job metrics and recent failures
        "activity" — Real action results from DB: what happened, what didn't, and why
        "diagnostics" — Full system diagnostics: rate limits, timers, blockers
        "report" — Configure periodic email campaign reports
        "backfill_cloud" — One-shot push of ALL local history (every campaign,
            any mode/status) to the hosted dashboard (backend mode only)
        "send_from" — Move all campaign outbound to the cloud or this machine.
            Pass host="cloud" (default for hosted accounts) or host="local".
            Local turns the cloud scheduler off so both never send.
    enabled: True to enable, False to disable (for 'toggle').
        For 'report': True to enable email reports, False to disable.
    cloud: If True, toggle the cloud scheduler for 24/7 operation (for 'toggle').
        Launching or resuming a campaign already switches it on for hosted
        accounts; pass cloud=True, enabled=False to stop the backend sending
        while leaving this machine's scheduler alone.
    hours: Lookback window in hours for 'logs' and 'activity' (default 24).
        For 'report': report interval in hours (1, 2, 4, 8, or 24).
        Omitted, 'report' leaves the stored interval unchanged.
    event_type: Filter events by type for 'logs'.
        For 'report': recipient email (empty = use login email).
    campaign_id: Filter by campaign for 'logs', 'activity', and 'diagnostics'.
    host: For 'send_from': "cloud" or "local".
create_postA

Generate and publish a voice-matched post to LinkedIn, X/Twitter, or both.

Creates posts using your voice signature for social selling.
Builds authority and drives inbound connections across platforms.

Args:
    topic: What to post about (e.g., "share a tip about cold outreach",
        "comment on AI in sales", "share a success story").
    tone: Post tone: "professional", "casual", "thought-leader", "storytelling".
    platforms: Comma-separated platforms: "linkedin", "x", or "linkedin,x".
    image: Path to a photo to attach. LinkedIn only — a tweet is posted
        without it. png, jpg, gif or webp, up to 10MB.
    mode: "autopilot" (publishes immediately).
brand_strategyA

Analyze and improve your LinkedIn personal brand to drive more leads.

Audits your profile, generates a personal brand strategy, executes
actions (post topics, headline rewrites, engagement targets), and
tracks improvement over time.

Args:
    action: What to do:
        "analyze" — Full profile audit with scored areas and issues
        "plan"    — Generate a 4-week brand strategy with content calendar
        "execute" — Execute the next recommended action from your plan
        "progress" — Show before/after metrics and completed actions
        "upload_photo" — Upload a profile photo (provide file_path or base64 data)
        "upload_cover" — Upload a cover/banner photo (same input as upload_photo)
        "set_link" — Set custom CTA link on profile (pass URL via focus param)
        "set_headline" — Set the headline to exact text (pass the headline via focus)
        "set_summary" — Set the About section to exact text (pass the text via focus).
            Use these two when the user has already decided the wording; "execute"
            and "makeover" write model-generated copy instead.
        "set_photo_library" — Folder of the user's own photos that brand-calendar
            posts may attach (pass the folder path via focus; "off" clears it).
            Files named "NNN - what it shows.jpeg"; personal or family subfolders
            are never used. Local posting only: a cloud-owned seat posts text only.
    focus: Focus area for analyze/plan ("headline", "summary", "content", "engagement", ""),
        URL string for set_link, the literal text for set_headline / set_summary,
        or the folder path for set_photo_library.
    photo: File path or base64-encoded image for upload_photo / upload_cover actions.
profileA

View and restore LinkedIn profile change history.

Every profile edit is tracked so you can see what changed and roll back
if needed.  Supported fields: headline, summary, photo, cover_photo,
custom_link, location, skills, experience.

Args:
    action: What to do:
        "history"  — List recent profile changes (default)
        "restore"  — Revert a specific change by its ID
        "current"  — Show current cached profile snapshot
    field: Filter history by field name (e.g. "headline", "summary", "photo",
        "cover_photo", "custom_link", "location", "skills", "experience"). Optional.
    change_id: The change ID to restore (required for "restore" action).
    limit: Max number of history entries to show (default 20).
import_prospectsA

Import prospects from a CSV/XLSX file into a campaign.

Point HeyLead at a .csv or .xlsx file (or paste CSV text) and it will parse
it, deduplicate against existing contacts and LinkedIn connections, score
each prospect, and add them to the campaign for outreach. Every row of the
file gets a disposition — imported, skipped:<reason>, or deduped-against a
specific earlier row — and the totals are reconciled against the file's row
count, so a partial import can never be reported as a success.

Supports CSV import, XLSX/spreadsheet import, bulk prospect upload, lead
list import, and contact list management for LinkedIn outreach campaigns.

Args:
    campaign_id: Campaign to import into. Leave empty for the most recent.
    csv_data: CSV text with headers. Only use for a handful of rows —
        prefer file_path, which has no size limit. Ignored if file_path
        is given.
    linkedin_enrich: If true, fetch full LinkedIn profiles for imported
        prospects (slower but better personalization). Default: false.
    file_path: Path to a .csv or .xlsx file on disk. Preferred over
        csv_data — a large lead list must never be pasted through this
        argument, since anything that does not fit is silently lost.
    sheet: Worksheet name for .xlsx files. Defaults to the first sheet.
    dry_run: If true, report the full per-row disposition without creating
        any contacts or outreaches and without fetching any LinkedIn
        profiles — linkedin_enrich is not run. Your own connection list is
        still read, so the preview matches the real import. Default: false.

Columns are auto-detected (case-insensitive): Name, Title, Company,
LinkedIn URL, Email, Location. Each row needs Name + at least one of
Title, Company, or LinkedIn URL.
crm_syncA

Sync campaign contacts and deals to HubSpot CRM.

Pushes won deals, hot leads, or all contacts to HubSpot as contacts + deals.
Tracks sync status to avoid duplicates. Includes conversation history as notes.
Supports CRM integration, deal pipeline sync, and lead handoff to sales teams.

First-time setup: create a HubSpot Private App with CRM scopes
(contacts, deals, notes), then pass the access token here.
The key is saved for future syncs.

Args:
    campaign_id: Campaign to sync. Uses the most recent if empty.
    filter: Which contacts to sync: "won" (default), "hot_leads", or "all".
    hubspot_api_key: Optional — your HubSpot Private App access token.
        Only needed on first use; saved for future syncs.
manage_watchlistA

Add, remove, and list signal keyword watchlists.

Watchlists define keywords that HeyLead monitors on LinkedIn
to detect buying signals from prospect posts. Watchlists are
also auto-created when you generate an ICP.

Args:
    action: What to do: 'list', 'add', 'remove', 'pause', 'resume'.
    name: Watchlist name (for 'add').
    watch_type: 'keyword', 'competitor', 'company', 'person', or 'industry' (for 'add').
    keywords: Comma-separated keywords (for 'add'). E.g., "cold outreach, SDR automation".
    watchlist_id: Watchlist ID (for 'remove', 'pause', 'resume').
    campaign_id: Optional campaign to link the watchlist to.
signalsA

View and analyze buying signals from LinkedIn.

Args:
    action: What to do:
        "show"     — Display detected buying signals (keyword mentions, job changes, etc.)
        "report"   — Signal analytics report with trends and ROI
        "strategy" — Show strategy engine insights, patterns, and autonomous actions
        "feedback" — Mark a signal as 'useful' or 'not_useful' (improves future classification)
        "website_setup" — Set up website visitor tracking (generates JS snippet to embed)
        "website_stats" — View website tracking analytics (visits, companies, high-intent)
        "optimize" — Run signal self-optimization (weights, keywords, warmup, thresholds)
        "optimize_history" — View optimization change log with rollback IDs
        "optimize_rollback" — Rollback a specific optimization change by entry ID
        "optimize_weights" — Show all signal weights (default vs effective overrides)
    campaign_id: Filter by campaign. Shows all if empty.
    signal_type: Filter by signal type, e.g. 'keyword_mention', 'job_change' (for 'show').
        For 'optimize_history': filter by optimization type (weight, keyword_added, warmup, threshold).
    status: Filter by status: 'new', 'classified', 'actioned' (for 'show').
    limit: Max signals to show (for 'show'). Default 20.
    days: Lookback window in days (for 'report'). Default 30.
    signal_id: Signal ID (for 'feedback' action). Entry ID (for 'optimize_rollback').
    feedback: 'useful' or 'not_useful' (for 'feedback' action).
partnerA

Track follow-ups with business partners, vendors, and investors.

Manages a CRM-style pipeline for non-prospect relationships (e.g., API
vendors, investors, co-founders). Auto-sends email reminders when
follow-ups are due using an escalating cadence (1, 3, 7, 14, 21 days).

Args:
    action: What to do:
        "add"      — Add a new partner to track (auto-schedules follow-ups)
        "list"     — Show all active partner follow-ups with due dates
        "update"   — Update partner info or add a note
        "complete" — Mark a partner follow-up as done (got what you needed)
        "snooze"   — Push the next follow-up by N days
        "cancel"   — Stop tracking this partner
    name: Partner's name (for 'add'). E.g., "Julien Crépieux".
    company: Company name (for 'add'). E.g., "Unipile".
    email: Partner's email (for 'add'). E.g., "partner@example.com".
    context: What you're following up about (for 'add').
    next_followup: Next follow-up date as YYYY-MM-DD (for 'add'). Defaults to tomorrow.
    partner_id: Partner ID (for 'update', 'complete', 'snooze', 'cancel').
    note: Add a note to the partner record (for 'update').
    days: Number of days to snooze (for 'snooze'). Default 7.
contactsA

Search, browse, and manage your global contact base.

One master record per person across all campaigns. View full interaction
history, add tags/notes, track lifecycle stages, and build reusable
prospect pools for future campaigns. Also search LinkedIn directly
for people without creating a campaign.

Args:
    action: What to do:
        "list"    — List contacts with optional filters (default)
        "search"  — Search contacts by name, company, or title
        "view"    — View full cross-campaign history for one contact
        "tag"     — Add a tag (or remove with '-tag_name')
        "note"    — Add a note to a contact
        "stage"   — Update lifecycle stage
        "stats"   — Contact base dashboard stats
        "export"  — Export contacts as table, CSV, or JSON
        "linkedin_search" — Search LinkedIn directly by name/company/title
        "link"    — Resolve a campaign's contact rows against the contact base
                    by name, so rows imported without a LinkedIn id pick one
                    up. Dry run unless dry_run=False.
        "enrich" — Enrich contacts with full LinkedIn profiles + posts
        "my_connections" — Search your 1st-degree LinkedIn connections (locally synced, guaranteed 1st degree)
    query: Search text for 'search', 'linkedin_search', and 'my_connections' actions.
        For 'enrich': search query to find contacts to enrich.
        For 'linkedin_search' the query is passed to LinkedIn as KEYWORDS,
        matched literally — a company name, a job title, a person's name, or a
        combination such as 'Acme Corp CTO' or 'Jane Doe'. A natural-language
        question ('who is the CTO of Acme?') is sent through unchanged and
        usually comes back empty, so prefer keywords. Nothing is filtered out
        locally. An empty result and a failed search are reported in different
        words, so a "no matches" line means LinkedIn really returned nobody
        rather than "the search broke".
        The profile and posts fetches this triggers are paced: they used to go
        out back to back and LinkedIn rate-limited them, so the call now spends
        up to a fixed wall-clock budget waiting between fetches and prints how
        much of it went on waiting. Expect tens of seconds.
    contact_id: Global contact ID for view/tag/note/stage actions.
    lifecycle_stage: Filter by stage (prospect/contacted/connected/engaged/customer/lost)
        or target stage for 'stage' action.
    tag: Tag to add/remove for 'tag' action, or filter for 'list'/'search'.
    note: Note text for 'note' action.
    min_fit_score: Minimum fit score filter (0.0-1.0).
    limit: Max results to return (default 25). For 'linkedin_search' this is
        capped at 25 per call because every result costs a profile fetch and a
        posts fetch; a result list says so when your limit was capped.
    format: Output format for 'export': 'table', 'csv', or 'json'.
    campaign_id: Campaign whose contact rows to resolve, for the 'link' action.
    match: How 'link' pairs campaign rows with contact base records. Only
        'name' is supported (exact, ignoring case and extra spaces).
    dry_run: For 'link' — True (the default) lists every row it would change
        and writes nothing. Pass False to apply.
    connected_since: For 'my_connections' — only people who became a
        1st-degree connection on or after this date (YYYY-MM-DD).
    connected_before: For 'my_connections' — only people who became a
        1st-degree connection before this date (YYYY-MM-DD). Connections
        synced before dates were recorded have no date and match neither
        filter; the result line says how many those are.
networkA

Network Intelligence — a reciprocal pool of members' connected accounts.

Pool members lend each other their LinkedIn accounts as "network sensors"
for enrichment, search, network analysis, and anonymized message insights.

The pool is reciprocal: it lends other members' connections and seats only
to a workspace whose own LinkedIn seat is an active member. The nine
consuming actions below are marked "members only" and are refused until
you join; joining is free and takes two calls — `opt_in`, then `sync`.
`status` reports whether you are opted in. The same is true of pooled
Premium/Sales Navigator seats used for search elsewhere in HeyLead: a
non-member is not lent one and quietly falls back to its own seat.

Args:
    action: What to do:
        "status"     — Pool health, member accounts, your participation
        "opt_in"     — Join the network pool (share your connections; this is what unlocks the members-only actions)
        "opt_out"    — Leave the network pool (also ends your access to it)
        "sync"       — Refresh your connection graph snapshot
        "opt_in_all" — Admin: opt in all connected LinkedIn accounts
        "sync_all"   — Admin: sync connections for all pool accounts
        "enrich"     — Members only: smart profile lookup via closest-connected pool account
        "contact"    — Members only: get email/phone via a 1st-degree connected pool account
        "parallel"   — Members only: enrich up to 100 profiles in parallel across pool
        "search"     — Members only: distributed search across pool (merged, deduplicated)
        "reach"      — Members only: show which pool accounts can reach a prospect
        "intros"     — Members only: find warm introduction paths to a prospect
        "insights"   — Members only: query aggregated message insights (objections, trends, patterns)
        "trends"     — Members only: industry trend analysis from cross-account conversations
        "patterns"   — Members only: objection and response patterns with timing data
    linkedin_id: Target prospect's LinkedIn provider_id (for enrich/contact/reach/intros).
    linkedin_ids: Comma-separated LinkedIn IDs (for parallel action).
    query: Search keywords (for search action).
    title: Job title filter (for search action).
    max_accounts: Max pool accounts to use for search (default 5).
    force_refresh: Ignore cache for enrich (default False).
    insight_type: Filter insights by type (for insights/patterns actions).
    segment: Filter by industry:seniority segment (for insights/trends actions).
    min_confidence: Minimum confidence threshold 0.0-1.0 (for insights action).
inboxB

Browse and read LinkedIn inbox messages directly.

Read any conversation in your LinkedIn inbox, not just campaign contacts.

Args:
    action: What to do:
        "list" — List recent conversations with last message preview
        "read" — Read full conversation thread
        "reply" — Send a message to any inbox conversation
        "comment_drafts" — Replies drafted for comments on your own posts,
            waiting for your approval. Nothing is sent until you approve.
        "approve_draft" — Send one drafted reply (chat_id = draft id).
            Pass text= to send an edited version instead.
        "discard_draft" — Throw a draft away without sending (chat_id = draft id)
    chat_id: Chat ID to read (from list output). For 'read' and 'reply' actions.
        For 'approve_draft' and 'discard_draft', the draft id.
    name: Contact name to search for (partial match). For 'read' and 'reply' actions.
    limit: Max conversations (list) or messages (read) to show. Default 30.
    text: Message text to send. Required for 'reply' action.
backfill_inboxA

Process unreplied LinkedIn inbox messages through the inbound pipeline.

Scans your inbox for conversations where prospects messaged you but
never got a reply. Classifies each message and sends discovery DMs.

Args:
    limit: Max conversations to scan (default 50).
    dry_run: If True (default), only classify — don't send DMs. Set False to send.
    min_confidence: Only send DMs for signals >= this confidence (0.0-1.0).
    send_only: If True, skip inbox scan — process already-classified signals
        directly. Use after a dry_run to avoid re-scanning.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
capabilitiesHeyLead server capabilities and tool inventory.
changelogRelease notes and changelog for recent HeyLead versions

TDQS

A3.6/5.0

Scored across 35 tools

Disambiguation2/5

Several tools have unclear boundaries: check_replies, inbox, and backfill_inbox all deal with reading/responding to LinkedIn messages, while generate_and_send and send_message both send prospect-facing messages. icp, generate_icp, and profile_signals also overlap in targeting analysis. The detailed descriptions help, but an agent could easily select the wrong tool for reply handling or outreach sending.

Naming Consistency3/5

Tool names are consistently lowercase snake_case, but the pattern is mixed: some use verb_noun (create_campaign, send_message, import_prospects) while many are bare nouns representing resource managers (scheduler, campaign, prospect, analytics, inbox, contacts, network). This is readable and mostly predictable, but not a uniform verb_noun convention throughout.

Tool Count2/5

35 tools is a heavy surface for a single MCP server, well above the 15-tool threshold that typically indicates a well-scoped set. While the server covers many subdomains (campaigns, inbox, signals, CRM, brand, network), so many top-level tools create navigation and selection burden. Several tools also collapse many actions into single entries, making the count feel inflated rather than appropriately granular.

Completeness4/5

The tool surface covers the full outreach lifecycle: setup, ICP generation, campaign creation/editing/launch/control, message sending, engagement, replies, meeting booking, prospect management, analytics, imports, CRM sync, and signals. Minor gaps exist—such as no dedicated campaign-template editor or calendar availability checker—but agents can work around these.

Maintenance

ActivityMaintained
ResponsivenessNo issues