HeyLead
HeyLead is an MCP server that gives AI assistants a complete LinkedIn sales development workflow: profile setup, lead generation, personalized outreach, follow-ups, reply handling, meeting booking, and analytics.
Account & setup: connect LinkedIn, analyze writing style into a voice signature, manage/switch/disconnect accounts, connect Gmail/Outlook email, and manage hosted workspaces/orgs.
Lead targeting & ICPs: generate ideal customer profiles with buyer personas, preview saved ICPs against LinkedIn, compile targeting evidence from profile signals, and create draft campaigns from natural-language descriptions.
Outreach automation: generate and send personalized LinkedIn messages/invitations, send follow-ups, replies, voice memos, and InMail, and send email via connected Gmail/Outlook.
Engagement & warm-up: comment on, react to, follow, endorse, or view prospects, and publish voice-matched posts to LinkedIn or X.
Inbox management: list/read LinkedIn inbox conversations, reply, approve/discard drafted replies, and backfill unreplied inbound messages through the pipeline.
Campaign management: launch, pause, resume, archive, delete, emergency-stop, retry failed, edit campaign settings, import prospects from CSV/XLSX, and manage individual prospects (skip, close, dismiss, view conversations/timelines).
Reply handling & meetings: check and classify replies by sentiment, surface hot leads, book meetings on Google Calendar with Meet links and attendee invitations.
Autonomous scheduling: control the background scheduler (status, on/off, observe mode, cloud vs local sending), monitor activity/logs/diagnostics, and configure email reports.
Signals & intelligence: view buying signals, manage keyword watchlists, analyze signal trends, and review autonomous agent decisions via a read-only inspect tool.
CRM & integrations: sync contacts/deals to HubSpot, search and manage a global contact base, enrich profiles, and use a reciprocal network pool for enrichment, search, warm intros, and insights.
Growth & branding: audit and improve LinkedIn personal brand, view/restore profile change history, and create/execute brand strategies.
Analytics & reporting: generate campaign reports, compare campaigns, export data, view status dashboards, and get prioritized next-action suggestions.
Knowledge & product tools: curate the knowledge base grounding messages (hosted), and patch the local HeyLead checkout/PR for developers.
Allows sending outreach emails through a connected Gmail mailbox via Unipile.
Allows booking meetings by placing agreed calls on Google Calendar and sending the prospect an invite.
Syncs campaign contacts and deals to HubSpot CRM.
HeyLead
Your AI sales rep. One command to fill your pipeline.
HeyLead is an MCP-native autonomous LinkedIn SDR that runs inside Cursor, Claude Code, or any MCP-compatible editor. Sign in on the web, then talk to your AI and say "find me leads."
Getting Started
MCP (Model Context Protocol) lets AI assistants use external tools. HeyLead gives your AI the ability to do LinkedIn outreach for you.
You need: Cursor or Claude Code — any MCP-compatible AI editor.
Step 1: Install HeyLead
HeyLead runs locally over stdio. You need uv:
Claude Code:
claude mcp add heylead -- uvx heyleadCursor: Settings > MCP > "Add new MCP server" > Name: heylead, Command: uvx heylead
Any MCP client:
{
"heylead": {
"command": "uvx",
"args": ["heylead"]
}
}Update with uvx --refresh heylead.
Step 2: Set up your account
Option A — Hosted (easiest): take the 90-second quiz or sign in at heylead.dev/dashboard/login. Your quiz personas become a draft campaign. Connect LinkedIn in Settings → Connected accounts, then launch from the dashboard — or copy your setup message from Settings → Integrations → Chat client into your AI chat. Nothing sends before you launch. Hosted users share a professional directory; campaigns and inboxes stay private.
Option B — Self-hosted: run everything against your own accounts. You need two things first:
A Unipile account — this is what talks to LinkedIn. Sign up at unipile.com, then put the DSN and API key from the Access Tokens page into
~/.heylead/config.jsonasunipile_api_urlandunipile_api_key.An LLM API key — AI calls are billed to you. A free Gemini key is enough to start.
Then open your AI chat and say:
"Set up my HeyLead profile with this Gemini key: YOUR_KEY"
You'll get a LinkedIn authentication link. Open it, connect LinkedIn, then say "finish setup". HeyLead fetches your profile and analyses your writing style.
Step 3: Find leads
"Find me CTOs at fintech startups in New York"
"Send outreach to the campaign"
"Check my replies"
"How's my outreach doing?"Related MCP server: LinkedIn Outreach MCP Server
How It Works
Define your ICP — "Generate an ICP for AI SaaS founders" → RAG-powered personas with pain points, barriers, and LinkedIn targeting
Create a campaign — "Find me fintech CTOs" → searches LinkedIn, scores prospects by fit
Warm up prospects — Engages with their posts (comments, likes) before reaching out
Send personalized invitations — Voice-matched messages that sound like you, not a bot
Follow up automatically — Multi-touch sequences after connections are accepted
Handle replies — Detects sentiment, advances positive leads toward meetings, answers questions
Track outcomes — Won/lost/opted-out tracking with conversion analytics
Safety model: campaigns are created as drafts and only start when you
explicitly launch them. Every send passes rate limits, working-hours checks,
and a 1st-degree connection guard before it goes out. Launching is also what
commissions 24/7 cloud sending — in observe mode nothing is commissioned and
nothing is sent, from either machine.
Tools
HeyLead gives your AI 22 tools:
Core Workflow
Tool | What it does |
| Connects LinkedIn and analyzes your writing style into a voice signature |
| Generates a rich Ideal Customer Profile with buyer personas |
| Previews which LinkedIn profiles a saved ICP matches, without creating a campaign |
| Compiles a targeting request (country ties, interests) into LinkedIn recall queries and profile-evidence scoring |
| Creates an outreach campaign (as a draft) from a natural language description |
| Generates a personalized LinkedIn message and sends it |
| Checks for new replies across campaigns, classifies sentiment, surfaces hot leads |
| Puts an agreed call on your Google Calendar and sends the prospect an invite |
| Your dashboard — campaigns, stats, hot leads, account health. Links to the matching heylead.dev/dashboard page and, on hosted accounts, attaches a snapshot card |
Outreach & Engagement
Tool | What it does |
| Sends follow-ups and replies to prospects |
| Sends email via a connected Unipile mailbox (Gmail/Outlook). Never Mail.app. |
| Comments on, reacts to, follows, or endorses a prospect to build trust |
| Browses and reads LinkedIn inbox messages directly |
| Processes unreplied inbox messages through the inbound pipeline |
| Generates and publishes a voice-matched post to LinkedIn, X/Twitter, or both |
Campaign Management
Tool | What it does |
| Campaign lifecycle — launch, pause, resume, archive, delete, emergency stop, retry failed |
| Edits a campaign's name, mode, booking link, or context fields |
| Manages prospects — skip, close with outcome, view conversation or timeline |
| Imports prospects from CSV data into a campaign |
Insights & Analytics
Tool | What it does |
| Campaign analytics — reports, comparisons, and exports |
| Read-only digest of operator holds, strategist replans, closer decisions, reply skips, and gated jobs |
| Curates the knowledge base that grounds messages — lists, adds, removes, refreshes, and searches sources. Hosted only |
| Recommends the best next action, prioritized by impact |
| Views and analyzes buying signals — news, company engagement, website visits, profile viewers |
| Adds, removes, and lists signal keyword watchlists |
| Network intelligence — a reciprocal pool of members' connected accounts; join to use it |
Growth & Relationships
Tool | What it does |
| Analyzes and improves your LinkedIn personal brand |
| Views and restores LinkedIn profile change history |
| Tracks follow-ups with business partners, vendors, and investors |
| Searches, browses, and manages your global contact base |
| Syncs campaign contacts and deals to HubSpot CRM |
Automation & Account
Tool | What it does |
| Manages the autonomous scheduler — status, on/off, send_from (cloud default / local opt-in) |
| Local git checkout only — patch this repo and/or open a PR |
| Manages LinkedIn accounts — list, switch, or disconnect |
| Hosted orgs — list, switch, invite editor/viewer, create a client workspace |
Key Features
Voice Matching — Analyzes your LinkedIn profile and posts to capture your writing style. Every message sounds like you wrote it.
ICP Generation — RAG-powered pipeline that crawls company context, generates buyer personas with pain points, fears, barriers, and maps them to LinkedIn search parameters.
Autonomous Scheduler — Runs in the background, respects working hours and rate limits. On a hosted account, cloud is the default sender for every campaign. Launching commissions the cloud, so outreach continues 24/7 with your laptop closed: invitations, opening DMs, first-touch InMail, follow-ups, engagements, follows, endorsements, email fallbacks, prospect top-ups, brand posts, auto-replies, inbound, warmup, signal collectors, and post-intel. This machine does not start a local scheduler engine for that work. Move the whole account here with scheduler(action='send_from', host='local'), which turns the cloud scheduler off. Observe still means nobody sends. Direct / self-hosted installs send from this machine only.
Engagement Warm-ups — Automatically engages with prospect posts before sending connection requests, building familiarity.
Adaptive Rate Limiting — Starts conservative, ramps up when acceptance rate is high, pulls back when it drops. Respects LinkedIn safety limits.
Outcome Tracking — Mark deals as won/lost, track conversion rates, identify stale leads, measure engagement ROI.
Pricing
Plan | Price | What you get |
Free | $0 | Up to 2 follow-ups per prospect |
Pro | $29 per connected LinkedIn account per month | Up to 5 follow-ups per prospect |
Invitation limits follow the LinkedIn account (free, Premium or Sales Navigator), not the HeyLead plan. Self-hosted free installs have monthly quotas: 50 invitations, 20 messages, 30 engagements, 1 active campaign.
Privacy
AI calls — routed through HeyLead's backend or your own key
Cloud MCP — your data is processed server-side but never shared with third parties
Local mode — contacts and messages stay on your machine in a local SQLite database
Power users: Pass your own LLM key (Gemini/Claude/OpenAI) during setup to use your own AI. Completely optional.
Backend mode & env
When the MCP client talks to a HeyLead backend (e.g. heylead-api), the backend uses these environment variables. Operators running their own backend should set them as required.
Purpose | Example env vars |
LLM |
|
Search / crawl |
|
Auth / storage |
|
Optional | Feature flags, rate limits, logging — see backend repo |
For full backend configuration and deployment, see the heylead-api (or backend) repo and its docs.
Optional Dependencies
The base install covers all core features. For advanced ICP generation:
pip install heylead[icp] # Embeddings for RAG-powered ICP generation
pip install heylead[crawl] # Web crawling for company context ingestion
pip install heylead[all] # BothTroubleshooting
"uvx: command not found"
Install uv first: curl -LsSf https://astral.sh/uv/install.sh | sh (or brew install uv on Mac)
"MCP server not connecting" Restart your editor after adding the MCP server. In Cursor, check Settings > MCP — the server should show a green dot.
"Setup failed" or "LinkedIn not connected" Make sure you clicked "Connect" on the LinkedIn row of the sign-in page (dashboard: Settings → Connected accounts) and completed the LinkedIn login. Then run setup again.
Need help? Open an issue.
Publishing to PyPI (maintainers)
To make HeyLead available on PyPI (or to publish a new version):
Option A: Publish via GitHub Release (recommended)
One-time: Create a PyPI account and an API token. In your repo: Settings → Secrets and variables → Actions → add secret
PYPI_TOKENwith the token value.Bump version in
pyproject.toml(version = "0.2.4").Commit, push, then create a GitHub Release (tag e.g.
v0.2.4, release title optional). The workflow.github/workflows/publish.ymlruns on release and publishes to PyPI.
Option B: Publish manually
pip install build twine
python -m build # creates dist/
twine check dist/* # optional: validate
twine upload dist/* # prompts for PyPI username + password (use __token__ and your API token)After publishing, anyone can add it with claude mcp add heylead -- uvx heylead (Cursor: command uvx heylead).
For AI Agents
HeyLead is designed as an MCP-native tool — built for AI agents, not humans clicking buttons.
Install as MCP server (stdio):
{
"heylead": {
"command": "uvx",
"args": ["heylead"]
}
}OpenClaw: Add the same entry to your openclaw.json under mcp.servers.
Also available on ClawHub — search "HeyLead".
Sign in at heylead.dev (hosted), or bring your own Unipile account and LLM API key (self-hosted).
Capabilities: LinkedIn lead generation, cold outreach automation, ICP generation with buyer personas, voice-matched personalized messaging, multi-touch drip sequences, reply sentiment classification, engagement warm-ups, campaign analytics, and autonomous 24/7 scheduling.
22 tools covering the full SDR workflow: prospect discovery → outreach → follow-up → reply handling → deal closing.
See AGENTS.md for the full agent integration guide.
Links
ClawHub (OpenClaw skill store)
License
MIT (code) — see LICENSE
Knowledge base and prompt configurations are proprietary.
Available Tools
22 toolsaccountADestructiveInspect
Switch the active LinkedIn account, unlink it, or connect an email account.
Which account is active decides who outreach is sent as. Listing them is
the accounts tool.
Args:
action: "switch", "switch_to", "unlink", "connect_email" or "refresh_tier".
account_id: The account id (switch_to).
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| account_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive and open-world behavior; the description adds the meaningful consequence that switching accounts changes outreach identity. It does not elaborate on side effects of unlink or refresh_tier, but the annotation coverage lowers the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Tight and front-loaded: the main purpose is stated first, the accounts-vs-account distinction takes one sentence, and the args are compactly listed. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers core usage, the key sibling distinction, and relies on an existing output schema. However, action semantics are under-specified: what 'switch' versus 'switch_to' means, what 'refresh_tier' does, and which actions require account_id are left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides no descriptions or enum values, but the description lists the allowed action values and notes account_id is used for switch_to. This meaningfully compensates for the schema, though the difference between 'switch' and 'switch_to' and the meaning of 'refresh_tier' remain unclear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses specific verbs ('switch', 'unlink', 'connect') and names the resource (active LinkedIn account). It also explicitly distinguishes itself from the 'accounts' sibling by noting listing is the accounts tool, so an agent can tell which tool handles mutation vs listing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States that the active account determines who outreach is sent as and points to the accounts tool for listing, giving clear context for when to use this tool. It does not spell out exclusions or conditions, but the main alternative is named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
accountsARead-onlyInspect
List the LinkedIn accounts connected to this HeyLead. Changes nothing.
Args:
action: "list" (switching, unlinking and connecting email are the account tool).
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | list |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already covers the 'Changes nothing' aspect, so the description adds no new behavioral disclosure beyond that. It does not mention rate limits, response size, or other side effects, but for a simple list operation the annotation suffices.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences plus a minimal Args block. The purpose is front-loaded, and every sentence earns its place, with no redundant words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is very simple (one optional parameter, no required fields) and has an output schema, so the description doesn't need to explain return values. The combination of the purpose statement, the Args hint, and the annotations fully equips an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only a title and default for the action parameter, with zero description. The description compensates by specifying action="list" and clarifying that other account actions belong to the account tool, giving the agent enough context to invoke it correctly. It doesn't explicitly state the parameter is optional, but the schema default covers that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb+resource: 'List the LinkedIn accounts connected to this HeyLead.' It immediately clarifies the tool's scope and read-only nature with 'Changes nothing.' This distinguishes it from the singular 'account' sibling by pointing out that account management actions belong elsewhere.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names the alternative tool 'account' for switching, unlinking, and connecting email, telling the agent when not to use this tool. The instruction in the Args block reinforces that only the 'list' action is intended here, leaving no ambiguity about which operations belong to this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analyticsARead-onlyInspect
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'.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | report | |
| format | No | table | |
| campaign_id | No | ||
| campaign_ids | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only and open-world, and the description adds useful behavior beyond that: hosted accounts receive a dashboard link and snapshot card, the link should be relayed, and some clients show the image only to the model. It also documents default behavior for empty parameters without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a one-line summary and then an organized Args block. The hosted-account image nuance is a valuable caveat that earns its place. It is slightly longer than strictly needed but contains no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still explains what each mode returns, export formats, parameter defaults, and the hosted-account rendering caveat. It omits error handling and permission notes, but for a read-only analytics tool the provided context is sufficient for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden. It documents all four parameters: action values, campaign_id defaulting to active, campaign_ids for compare mode, and format choices for export. This fully compensates for the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as campaign analytics with reports, comparisons, and exports, which distinguishes it from sibling tools like campaign or show_status. It lacks a direct action verb, but the resource and available modes are specific enough to avoid tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The Args section gives mode-specific usage context: report, compare, and export, along with defaults for empty campaign_id and campaign_ids. However, it never explicitly states when not to use this tool or names alternatives among the large sibling set, leaving some routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
answer_inboxADestructiveInspect
Reply in a LinkedIn conversation, or approve or discard a drafted reply.
"reply" and "approve_draft" SEND a LinkedIn message and cannot be undone.
Reading the inbox is the inbox tool.
Args:
action: "reply", "approve_draft" or "discard_draft".
chat_id: Which conversation, or which draft.
text: What to send, or an edited version of the draft.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | ||
| action | Yes | ||
| chat_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and readOnlyHint=false, and the description adds meaningful behavioral detail: 'reply' and 'approve_draft' SEND a LinkedIn message and cannot be undone. It does not explicitly state whether discard_draft is also irreversible, which is the only small gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact: a one-line purpose, a warning about irreversibility, a sibling routing note, and a clean args list. It front-loads the most important facts and has no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, not explaining return values is acceptable. The description covers actions, target, content, and irreversibility, but it leaves the send_message sibling unaddressed and does not clarify whether text is required for reply/approve_draft, so an agent may need to infer those preconditions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, yet the description documents all three parameters: action values ('reply', 'approve_draft', 'discard_draft'), chat_id as the conversation/draft, and text as the message or edited draft. This fully compensates for the sparse schema and adds allowed values via prose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a concrete verb+object: 'Reply in a LinkedIn conversation, or approve or discard a drafted reply.' It clearly delimits three actions and distinguishes it from the inbox read tool ('Reading the inbox is the inbox tool'), so an agent can tell it apart from siblings like inbox.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit routing away from reading ('Reading the inbox is the inbox tool') and warns that reply/approve_draft send a message and cannot be undone. However, it does not address the sibling send_message tool, so the boundary between sending a fresh message and answering an inbox conversation is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
book_meetingADestructiveInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| start | Yes | ||
| summary | No | ||
| description | No | ||
| attendee_email | Yes | ||
| duration_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=true, so the description doesn't need to restate that. It adds useful behavioral context: creates the event on the connected calendar, attaches a Google Meet link, and emails the attendee an invitation. It doesn't mention side effects like overwriting existing events or permission requirements, but the core behavior is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening sentence, a usage trigger, and a compact Args list. Every sentence earns its place. It could be slightly tighter, but it's appropriately sized for a 5-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema and annotations, the description covers the essential behavioral context: what happens (event created, Meet link attached, invitation emailed) and when to use it. It doesn't mention failure modes or prerequisites (e.g., calendar must be connected), but the connected-calendar detail is implied. This is adequate for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden. It explains attendee_email ('Who to invite — the prospect who replied'), start ('When it starts, ISO 8601'), duration_minutes ('How long the meeting runs. Defaults to 30'), summary ('Event title. Defaults to naming the attendee'), and description ('Optional agenda or notes'). This adds meaning beyond the bare schema property names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Book'), a resource ('a meeting on your Google Calendar'), and the action's purpose ('invite a prospect'). It clearly distinguishes itself from siblings like send_email or send_message by specifying calendar event creation with a Google Meet link and attendee invitation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this when a reply agrees to a call,' giving a clear trigger condition. It doesn't explicitly name alternatives or exclusions, but the context is clear enough for an agent to select this tool over generic messaging tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
campaignADestructiveInspect
Launch, pause, resume, archive, delete or emergency-stop a campaign.
Every action here changes what happens next. Watching one run, or reading
its history, is campaign_status.
Args:
action: "launch", "pause", "resume", "archive", "delete",
"emergency_stop", "retry_failed", "repair_queue" or
"clear_coordinator_hold".
campaign_id: Which campaign. Uses the active one if empty.
confirm: Required by the actions that destroy work.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| confirm | No | ||
| campaign_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=true. The description adds useful behavior beyond that: the default campaign_id behavior ('Uses the active one if empty') and the confirm requirement for destructive actions. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact: two sentences of purpose/guidance followed by a tight argument list. It front-loads the primary verbs and then provides exact parameter semantics without redundancy. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter, 9-action tool with no output schema, the description covers the state-changing purpose, all action keywords, parameter defaults, and the confirm flag. It doesn't explain nuances like when to choose emergency_stop over pause, but these are not essential for a correct first invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and there are no enums, so the description carries the full burden. The Args section lists every allowed action value, explains the campaign_id default, and clarifies confirm's role. This adds substantial meaning to the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description lists a specific set of verbs ('Launch, pause, resume, archive, delete or emergency-stop a campaign') applied to a resource, and explicitly distinguishes itself from the read-only sibling campaign_status. This makes the tool's scope clear and separates it from alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: 'Every action here changes what happens next' and points to campaign_status for watching or reading history. It does not explicitly mention create/edit siblings, but the state-changing framing is enough to guide the agent toward when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
campaign_statusARead-onlyInspect
Watch a campaign run, or read its history of status changes. Changes nothing.
Args:
action: "monitor" (live progress) or "status_history".
campaign_id: Which campaign. Uses the active one if empty.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | monitor | |
| campaign_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The read-only behavior is already declared via readOnlyHint=true, and the description reinforces it with 'Changes nothing.' It adds useful detail about the 'Uses the active one if empty' fallback, but reveals little else about behavior such as output format or operational constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence establishes purpose and safety, and the Args section is neatly structured. Every sentence contributes meaningful information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with two optional parameters, the description is largely complete: it names both actions, explains defaults, and clarifies side-effect-free behavior. It loses one point because there is no output schema and the description does not hint at what the returned progress or history looks like, nor does it route the agent away from sibling status tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden of parameter documentation. It fully explains both parameters: action's allowed values ('monitor' vs 'status_history') and campaign_id's meaning plus default fallback behavior. This is exactly the compensation needed for a schema with no descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a clear verb and resource: 'Watch a campaign run, or read its history of status changes.' It clearly identifies the tool's subject (campaign status) and read-only nature, but does not explicitly differentiate among sibling tools like scheduler_status or show_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description communicates obvious contexts for use: monitoring active progress or reading status history. However, it does not mention when not to use it, prerequisites, or alternative tools, leaving usage guidance mostly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_repliesADestructiveInspect
Read new LinkedIn replies and record what they mean.
Fetches new messages, classifies each reply (positive, negative, question)
and lists the people worth answering first.
It sends nothing, but it does write: it marks an invitation accepted once
the person answers or connects, moves an outreach to replied, stores the
messages, and sets opted-out when someone asks not to be contacted, which
stops all future outreach to them. It is the only path that notices an
accepted invitation, so follow-ups depend on it having run.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by disclosing concrete side effects: marking invitations accepted, moving outreach to replied, storing messages, and setting opted-out in a way that stops all future outreach. It also explicitly states it sends nothing, which supports the readOnlyHint=false and destructiveHint=true annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact but information-dense: a one-sentence summary, a functional overview, and then the important side-effect and dependency details. Nothing is redundant, and the most critical behavioral constraints are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless tool with an output schema, the description fully covers what the tool does, what it changes, what it does not do, and why it matters for follow-ups. The dependency warning about accepted invitations is especially valuable context an agent needs before invoking it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema carries no parameter semantics burden and the baseline is 4. The description notes no arguments and instead focuses on behavior, which is entirely appropriate for a parameterless tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read new LinkedIn replies and record what they mean.' It then details what it fetches, classifies, and lists, and distinguishes itself from siblings by noting it sends nothing and is the only path that notices accepted invitations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: this tool reads, records, classifies, and prioritizes replies, and is the only path that detects accepted invitations, making it essential for follow-ups. It does not explicitly name alternative tools or when-not-to-use conditions, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
contactsARead-onlyInspect
Search, browse and read your contacts, and export them. Changes nothing.
Tagging, noting, re-staging and linking are update_contact.
Args:
action: "list", "search", "view", "stats", "export", "linkedin_search"
or "my_connections".
query: Search text for "search", "linkedin_search" and "my_connections".
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". Results are capped at 25 per call
because every result costs a profile fetch and a LinkedIn read.
contact_id: Which contact (view).
lifecycle_stage: Filter by stage.
min_fit_score: Only those scoring at least this.
limit: How many.
format: "table", "csv" or "json" (export).
campaign_id: Filter by campaign.
connected_since: Only those connected on or after this date.
connected_before: Only those connected before this date.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No | ||
| action | No | list | |
| format | No | table | |
| contact_id | No | ||
| campaign_id | No | ||
| min_fit_score | No | ||
| connected_since | No | ||
| lifecycle_stage | No | ||
| connected_before | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true, the description discloses meaningful behavioral details: results are capped at 25 due to cost, nothing is filtered locally, and the distinction between 'no matches' and a failed search is explained. It also specifies that natural-language LinkedIn queries are passed through unchanged and usually return empty, which is critical for expected behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then uses a clean 'Args:' block that maps directly to the schema. The longest section (query) earns its length by explaining the nuanced LinkedIn behavior. No sentences are filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complete for an agent: it explains when to use it, what it does not do, parameter semantics, error-reporting nuance, rate limits, and output formats. An output schema is present, so return values need not be described. The sibling routing is explicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description compensates fully: all 10 parameters are documented. The query parameter receives extra depth, including literal LinkedIn keyword matching, example formats, a warning about natural-language queries, and cap behavior—all meaning beyond the schema's type and default fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Search, browse and read your contacts, and export them.' It also explicitly declares 'Changes nothing' and names the sibling with mutating operations ('Tagging, noting, re-staging and linking are update_contact'), making the tool's scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly routes mutations to a sibling: 'Tagging, noting, re-staging and linking are update_contact.' The read-only context is reinforced with 'Changes nothing.' While it doesn't say 'use this when you need to read contacts,' the inclusion of the alternative and the clear non-mutating scope leaves no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_campaignADestructiveInspect
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.
Reaching people you can already name — an article author, a warm intro, a
speaker, one founder a customer mentioned — is the `people` argument: pass
their profile URLs and the campaign is seeded from exactly them, with no
LinkedIn search. Everything else is unchanged: draft until launch, rate
limits, sending window, opt-outs.
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.
people: LinkedIn profile URLs or public identifiers, comma or newline
separated (e.g. "linkedin.com/in/jane-doe, linkedin.com/in/john-doe").
The campaign is seeded from exactly these people: no LinkedIn
search runs, the goal <-> ICP audit is skipped (the audience is
stated, not inferred), a low ICP score does not drop anybody, and
discovery stays off so nothing tops the queue up with strangers.
Use it whenever the user names who to reach. Cannot be combined
with connections_only.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | autopilot | |
| force | No | ||
| icp_id | No | ||
| people | No | ||
| voice_mode | No | text_only | |
| company_url | No | ||
| campaign_name | No | ||
| campaign_type | No | ||
| project_brief | No | ||
| company_context | No | ||
| connections_only | No | ||
| target_description | Yes | ||
| exclude_connections | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations providing readOnly and destructive hints, the description adds substantial behavioral detail: campaigns are drafts until explicitly launched, exclude_connections is ON BY DEFAULT with specific refusal behavior, the people path skips search and audit, and force overrides only mismatch verdicts. These are meaningful behavioral traits not visible in the schema or annotations, and they do not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but structured with clear paragraphs and an Args list, making it navigable. It front-loads the core behavior before diving into parameters. A few sentences are redundant or promotional ('Supports lead generation... AI-powered ICP-based targeting'), but overall length is justified by the tool's 13-parameter complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers prerequisites (project_brief on first campaign), defaults, combination rules, safety behavior (nothing sent until launch), and edge-case handling (force, partial verdicts, exclude_connections). An output schema exists, so return-value documentation is not required here. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries full responsibility for explaining all 13 parameters. It does so thoroughly: each parameter has a purpose, example, default, or constraint (e.g., target_description examples, voice_mode values, people format, exclude_connections inverse relationship to connections_only). This fully compensates for the schema's lack of descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Create a LinkedIn outreach campaign from a natural language description.' It further clarifies the unique behavior—'saves a draft; nothing is sent until campaign(action='launch')'—which distinguishes it from send_message and edit_campaign. The scope is concrete and immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases ('sales prospecting, recruiting...'), specific user-phrase triggers for parameter choices ('Use when user says "existing connections"'), and prohibitions ('Cannot be combined with connections_only'). It also names the generate_icp tool as an alternative source for icp_id, giving clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_campaignADestructiveInspect
Change one running or drafted campaign's settings.
Pass only what you want to change; every field left empty keeps its current
value. Use it to rename a campaign, give it a booking link, feed it context
that makes the messages more specific (offerings, case studies, project
brief), say who it is for (campaign_intent, campaign_type), or set the
limits it sends under (volume, caps, follow-ups, business hours).
It edits settings only: it sends nothing and adds no prospects. A change
applies to the messages written from now on, not to ones already sent. Use
create_campaign for a new campaign, and campaign(action=...) to launch,
pause or stop one.
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: Send only in business hours: "on" or "off". On by default
(weekdays 08:00-22:00 in your own timezone, or London when it is unknown,
unless the workspace set its own window).
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.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | ||
| name | No | ||
| volume | No | ||
| go_live | No | ||
| product | No | ||
| offerings | No | ||
| voice_mode | No | ||
| active_days | No | ||
| campaign_id | No | ||
| voice_noise | No | ||
| booking_link | No | ||
| case_studies | No | ||
| must_confirm | No | ||
| campaign_type | No | ||
| max_followups | No | ||
| project_brief | No | ||
| social_proofs | No | ||
| enable_follows | No | ||
| voice_humanize | No | ||
| campaign_intent | No | ||
| engagement_mode | No | ||
| inmail_fallback | No | ||
| connections_only | No | ||
| enable_discovery | No | ||
| enable_followups | No | ||
| stale_invite_days | No | ||
| enable_engagements | No | ||
| enable_invitations | No | ||
| enable_reply_agent | No | ||
| inmail_first_touch | No | ||
| enable_auto_replies | No | ||
| enable_endorsements | No | ||
| exclude_competitors | No | ||
| exclude_connections | No | ||
| followup_delay_days | No | ||
| campaign_preferences | No | ||
| competitor_companies | No | ||
| enable_profile_views | No | ||
| inmail_fallback_days | No | ||
| weekly_meeting_target | No | ||
| enable_hot_lead_closer | No | ||
| send_in_business_hours | No | ||
| withdraw_stale_invites | No | ||
| enable_coordinator_agent | No | ||
| enable_strategist_replan_agent | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint=false, destructiveHint=true, and openWorldHint=true. The description goes beyond these by clarifying the non-sending nature ('It edits settings only: it sends nothing and adds no prospects') and the temporal effect ('A change applies to the messages written from now on, not to ones already sent'). This adds meaningful context about side effects and scope without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but appropriately so given 45 parameters. The opening is front-loaded with purpose and usage, and each parameter has a concise, meaningful explanation. While a few sentences could be tightened, every piece adds necessary value, so it earns a 4 rather than a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (45 params, no schema descriptions, output schema exists but not detailed), the description is complete. It covers all parameters, usage, side effects, and cross-parameter interactions. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% (no parameter descriptions in the schema). The description fully compensates by explaining each parameter's purpose, allowed values, defaults, and interactions (e.g., exclude_connections vs connections_only, campaign_type specifics, inmail_fallback tiers). This is far beyond the bare schema and provides critical guidance for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb-resource statement: 'Change one running or drafted campaign's settings.' It also distinguishes itself from siblings by explicitly naming create_campaign for new campaigns and campaign(action=...) for launch/pause/stop. The scope is precise, and it differentiates from other campaign-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool (rename, booking link, context, limits) and when not to: 'Use create_campaign for a new campaign, and campaign(action=...) to launch, pause or stop one.' It also clarifies the partial-update behavior and the side-effect boundary ('sends nothing and adds no prospects'), giving the agent clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_icpADestructiveInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| focus_query | No | ||
| company_context | No | ||
| target_description | Yes | ||
| decision_makers_only | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=false and destructiveHint=true, lowering the burden on the description. The description adds valuable behavioral detail beyond annotations: it explains that results are saved, can be reused via create_campaign(icp_id=...), and that decision_makers_only changes persona seniority levels. It does not clarify what destructive effect may occur, but it does not contradict the annotations either.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well structured, leading with the core purpose, then output characteristics, then reusable result, then a compact Args section. The only slight redundancy is the sentence listing overlapping capabilities such as 'buyer persona creation, ideal customer profiling, and B2B market research,' which adds retrieval keywords but little semantic value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one required parameter, an output schema present, and moderate complexity, the description is effectively complete. It tells the agent what to pass, what each optional input does, what output to expect, and what happens to the result. The only minor omission is the unexpanded destructiveHint, but the annotations already flag that behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, and it delivers. Every parameter gets a meaningful explanation with examples: target_description shows concrete phrasing, company_context explains its precision benefit, focus_query gives sample focus areas, and decision_makers_only spells out seniority levels plus when False is appropriate. This far exceeds what the bare schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Generate a rich Ideal Customer Profile with buyer personas,' and goes further by specifying the shape of the output (2-4 personas with pain points, fears, barriers, LinkedIn search parameters, and confidence scores). It also distinguishes itself from siblings by noting the result is saved and reusable with create_campaign, so an agent can tell it apart from related tools like icp or campaign without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly communicates the broad applicability: buyers, candidates, research participants, hiring managers, investors, or partners. It also lists supported use cases like target audience analysis and customer segmentation. However, it does not explicitly state when not to use this tool or name alternative tools to prefer in specific situations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inboxARead-onlyInspect
Read any conversation in your LinkedIn inbox, and the drafted replies.
Replying, approving a draft and discarding one are answer_inbox.
Args:
action: "list", "read" or "comment_drafts".
chat_id: Which conversation.
name: Find the conversation by the person's name.
limit: How many to show.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| limit | No | ||
| action | No | list | |
| chat_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description reinforces the read-only behavior by mentioning that drafted replies can be read and that write actions belong to answer_inbox. It adds useful behavioral context without contradicting the annotations, and no hidden side effects need to be disclosed for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: a direct purpose statement, a brief sibling-routing note, and a minimal argument list. Every sentence earns its place and there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
All parameters are semantically documented, the read/write boundary is explicit, and the presence of an output schema means return values need not be described in prose. The only minor gap is the lack of detail on how chat_id and name interact or take precedence, but this does not prevent correct usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage and no enums, so the description carries the full burden of explaining parameters. It defines all four: action with allowed values 'list', 'read', and 'comment_drafts'; chat_id as the conversation identifier; name for finding the conversation by person; and limit for display count. This fully compensates for the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and resource: 'Read any conversation in your LinkedIn inbox, and the drafted replies.' It also explicitly distinguishes itself from answer_inbox, which handles replying, approving, and discarding drafts, so an agent can easily tell this tool apart from its closest sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states which actions belong to answer_inbox instead of this tool: 'Replying, approving a draft and discarding one are answer_inbox.' This gives a clear when-not-to-use condition and names the alternative, providing strong routing guidance without leaving the decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prospectADestructiveInspect
Skip a prospect, close one with an outcome, or dismiss it.
Closing with outcome="opt_out" stops all future contact with that person.
Reading a prospect is prospect_view.
Args:
action: "skip", "close" or "dismiss".
outreach_id: Which outreach.
campaign_id: Which campaign. Uses the active one if empty.
outcome: "won", "lost" or "opt_out" (close).
reason: Why, recorded with the outcome.
meeting_link: The booked meeting, recorded with a won outcome.
confirm: Required where the action cannot be undone.
reason_code: A coded reason, for reporting.
reason_note: A free note alongside the code.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| reason | No | ||
| confirm | No | ||
| outcome | No | won | |
| campaign_id | No | ||
| outreach_id | No | ||
| reason_code | No | ||
| reason_note | No | ||
| meeting_link | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=truearen't a read-only tool. The description adds meaningful behavioral context beyond that: 'Closing with outcome="opt_out" stops all future contact' and 'confirm: Required where the action cannot be undone.' These are important side-effect disclosures. It does not detail exactly which actions are irreversible, so it is not a perfect 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tight and well-organized: a leading summary sentence, a key behavioral caveat, a sibling disambiguation, then a compact Args list. There is no filler or repetition, and the most decision-relevant information appears first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given nine parameters and no schema-level descriptions, the description covers every parameter with at least some functional meaning, including active-campaign fallback and outcome-specific recording. It stops short of specifying which actions actually require confirm=true and leaves the skip-vs-dismiss distinction implicit, so some gaps remain for a fully autonomous agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden of explaining parameters. It does this well with an Args section that glosses all nine parameters, including valid values for action and outcome)Skip: a 'skip', 'close' or 'dismiss'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Skip a prospect, close one with an outcome, or dismiss it.' It clearly lists the three distinct actions the tool performs and explicitly distinguishes it from the read-only sibling: 'Reading a prospect is prospect_view.' This makes the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description names prospect_view as the alternative for reading, giving a concrete when-not-to-use hint. It also communicates the core use cases: skipping, closing with an outcome, or dismissing. It does not exhaustively compare against all sibling tools, but the primary ambiguity with prospect_view is resolved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prospect_viewARead-onlyInspect
Read the message thread with one prospect, or their timeline. Changes nothing.
Args:
action: "conversation" or "timeline".
outreach_id: Which outreach.
campaign_id: Which campaign. Uses the active one if empty.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | conversation | |
| campaign_id | No | ||
| outreach_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description's 'Changes nothing' is consistent without adding much new behavioral information. It does add the actionable detail that campaign_id falls back to the active campaign, which is a useful behavioral nuance beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main behavior is stated in one sentence, followed by a compact Args list. Every line earns its place; no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with an output schema present, the description covers the action choices and the key campaign fallback. Minor ambiguity remains around what happens when outreach_id is empty, but overall an agent has enough to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the parameter meaning, and it does: action gets explicit enum-like values ('conversation' or 'timeline'), and campaign_id gets default-fallback semantics. outreach_id's 'Which outreach' is terse but sufficient to identify the parameter's role.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific read verb, a single resource ('message thread with one prospect'), and an alternative view ('their timeline'), which clearly distinguishes it from the mutation/send siblings like send_message and update_contact. The 'Changes nothing' clause reinforces that this is a pure read operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The read-only wording and the 'one prospect' scope imply when to choose this tool, but the description does not name alternatives or state when not to use it. It provides context for usage (viewing a conversation or timeline) without explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
schedulerADestructiveInspect
Turn the autonomous scheduler on or off, or change how it runs.
Off means nothing sends until it is on again. Reading its state, logs,
activity or diagnostics is scheduler_status.
Args:
action: "toggle", "observe", "always_on", "backfill_cloud",
"send_from" or "report".
enabled: True to enable, False to disable (toggle, report).
cloud: Act on the hosted scheduler rather than this machine's.
host: Which machine should send (send_from).
hours: The reporting interval (report).
campaign_id: Which campaign (report).
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | ||
| cloud | No | ||
| hours | No | ||
| action | Yes | ||
| enabled | No | ||
| campaign_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is not read-only and has destructive potential. The description adds useful behavioral context beyond that: turning it off halts sending until re-enabled, and the cloud/host arguments act on different scheduler scopes. It does not fully explain what each action value does, but it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the main purpose appears in the first sentence, the key caveat and sibling alternative appear next, and the parameter documentation is a tight bullet list. No sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with six parameters, zero schema-level descriptions, no enums, and a destructive hint, this is mostly complete. It scopes local vs cloud, explains the read alternative, and covers all arguments at a usable level. The main gap is that some action semantics are left implicit, but an output schema exists and the description is strong enough for an agent to invoke it correctly in most cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden for parameter meaning. It explains every parameter, including allowed action values, the enabled flag, cloud scope, host selection, reporting interval, and campaign ID. However, a few action values like 'observe' and 'backfill_cloud' are named but not deeply defined, which keeps this from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb and resource: 'Turn the autonomous scheduler on or off, or change how it runs.' It also distinguishes itself from the read-only sibling by stating that reading state, logs, activity, or diagnostics is scheduler_status, so an agent can tell the tools apart immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly routes read-oriented requests to scheduler_status: 'Reading its state, logs, activity or diagnostics is scheduler_status.' It also clarifies a key consequence of use ('Off means nothing sends until it is on again'), giving the agent both a when-to-use and a when-not-to-use signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scheduler_statusARead-onlyInspect
Read the scheduler: status, logs, activity, diagnostics or the daily report.
Args:
action: "status", "logs", "activity" or "diagnostics". The daily
report is the scheduler tool: it switches reporting on and off.
cloud: Read the hosted scheduler rather than this machine's.
hours: Lookback window in hours.
event_type: Filter the log by event type.
campaign_id: Filter by campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| cloud | No | ||
| hours | No | ||
| action | No | status | |
| event_type | No | ||
| campaign_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the read-only nature is covered. The description adds context that 'cloud' targets the hosted scheduler versus the local machine, and it clarifies that the daily-report action is handled by another tool. It doesn't disclose response behavior, pagination, or any limits, but this is acceptable for a read-only tool with an output schema present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded purpose sentence followed by a tight argument list. Each line in the list adds necessary information with no fluff. The structure makes it easy for an agent to scan the purpose and immediately find the parameter semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering read-only safety, the description's remaining job is to define the parameters and scope—which it does completely. The only possible gap, the exact return shape of each action, is presumably covered by the output schema. An agent has everything needed to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden—and it succeeds. Every one of the five parameters gets a concrete semantic definition: action lists its allowed values, cloud explains local vs. hosted, hours defines the lookback window, and event_type/campaign_id specify filtering behavior. This is exactly the kind of compensation needed when the schema provides only titles and defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read the scheduler: status, logs, activity, diagnostics...' This clearly identifies the tool's scope and enumerates the sub-information it exposes. It also distinguishes itself from the sibling 'scheduler' tool by explicitly stating that the daily report belongs to that tool, eliminating confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly explains the action parameter's valid values and the intended use case for each. It explicitly names the sibling scheduler tool as the correct alternative for daily-report toggling, providing a when-not-to-use note. However, it does not mention how this tool relates to other sibling read/status tools like show_status or campaign_status, so the guidance is not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageADestructiveInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | ||
| action | No | followup | |
| format | No | text | |
| campaign_id | No | ||
| outreach_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructive and open-world effects, but the description adds concrete behavior: delete is limited to messages sent within 60 minutes, inmail fails closed if preconditions aren't met, text auto-generates if empty, and empty campaign_id uses the active campaign. These details go well beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized into a clear Args block with each parameter on its own bullet and action-specific notes. Although detailed, every sentence carries task-relevant information and there is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with no required parameters and an output schema, the description covers all parameters, defaults, destructive behavior, and action-specific preconditions. It leaves no input ambiguity and the output schema handles return-value documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description fully compensates by explaining every parameter: action's allowed values, campaign_id defaulting, outreach_id requirement, format meaning, and text auto-generation plus delete overload. This is exactly the semantic enrichment an agent needs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Send') and resource ('follow-ups, replies, voice memos, or InMail to prospects') and enumerates distinct actions with clear outcomes. The LinkedIn context and action list make it distinguishable from sibling messaging tools like send_email.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit decision rules: InMail is only for non-connections and lists fail-closed preconditions, while 1st-degree connections should use followup/DM. It also specifies when outreach_id is required, how campaign_id defaults, and which format applies to followup/reply.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
setup_profileADestructiveInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| backend_jwt | No | ||
| backend_url | No | ||
| llm_api_key | No | ||
| llm_provider | No | gemini |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description aligns with annotations (readOnlyHint=false, destructiveHint=true) and adds substantial behavioral context beyond them. It explains that the tool analyzes LinkedIn profile and writing style to create a 'voice signature,' and that it performs LinkedIn automation setup and SDR onboarding. It also discloses the authentication requirement via a backend_jwt token and clarifies that no API keys are needed unless providing a custom LLM key. This fully prepares the agent for the tool's side effects and dependencies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized and front-loaded. It opens with a one-sentence summary, then a bolded requirement, a short explanatory paragraph, a clear 'First-time setup:' section with steps, and an 'Args:' section with bullet points. Every sentence earns its place; no fluff or redundancy. The structure aids quick comprehension for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (external login, token acquisition, multiple configuration options), the description is remarkably complete. It covers prerequisites, exact steps, parameter semantics, and the tool's role in the broader system. The presence of an output schema (indicated by 'has output schema: true') means return-value documentation is not required in the description. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, and it excels. Each parameter is explained: llm_api_key as optional with purpose, llm_provider with explicit allowed values, backend_url with a default behavior, and backend_jwt as the authentication token with instructions on how to obtain it. This is more than sufficient for an agent to fill the arguments correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear specific purpose: 'Set up HeyLead by connecting your LinkedIn account and analyzing your writing style.' It further distinguishes this from siblings by detailing it handles 'LinkedIn automation setup, SDR onboarding, account connection, and voice analysis' and explicitly marks it as 'REQUIRED for first-time users — must be called before any other tool.' No ambiguity remains.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit when-to-use guidance: 'REQUIRED for first-time users — must be called before any other tool.' It also gives a step-by-step walkthrough: sign in at a specific URL, connect LinkedIn, copy the setup message, and call the tool with the token. It notes 'No API keys needed on the hosted backend,' which preempts a common question. There is no need for alternative tools since this is a mandatory one-time setup.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show_statusARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true. The description adds valuable behavioral context by disclosing that hosted accounts receive a dashboard link and snapshot card, and that the link must be relayed because some clients show the image only to the model. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core purpose. It includes a useful relay caveat and parameter documentation without excessive padding. The conversational phrasing ('Ask how's my outreach anytime') is functional but slightly loose, keeping it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and no output schema, the description covers the dashboard contents, hosted-account behavior, and parameter semantics. It does not describe the exact shape of stats or error cases, but these are minor for this simple read-only tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully explain the parameter. It does: 'campaign_id: Show stats for a specific campaign. Shows all if empty.' This clarifies the optional single parameter's behavior and default semantics completely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: 'Show your outreach dashboard' with concrete contents like campaigns, stats, hot leads, and account health. It is more specific than the tool title but does not explicitly distinguish itself from the sibling 'analytics' tool, so it falls short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: the chat is the 'front door' to the dashboard and users can ask 'how's my outreach?' anytime. This implies broad, on-demand use but does not state when to prefer another tool or mention exclusions, so it lacks explicit routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_next_actionARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, which cover safety. The description adds valuable behavioral details: hosted accounts receive a dashboard link and snapshot card, the link should be relayed due to client rendering, and recommendations follow an explicit priority order. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized, around 70 words, and front-loads the core purpose. The hosted-accounts caveat is necessary operational detail. There is slight redundancy between 'Analyzes all active campaigns' and 'Analyzes all active if empty,' but it does not hurt clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, read-only suggestion tool with no output schema, the description covers purpose, input semantics, prioritization logic, and output hints (dashboard link and snapshot card). It could more concretely describe the structure of the returned recommendation, but it is complete enough for an agent to invoke and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It fully does for the only parameter: 'campaign_id: Focus on a specific campaign. Analyzes all active if empty.' This defines both the parameter's meaning and its empty-value behavior, which is complete and actionable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and resource: 'Suggest the best next action for your outreach.' It further specifies scope by saying it analyzes all active campaigns and prioritizes by impact. It does not explicitly contrast with sibling tools like scheduler or check_replies, so it stops short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It explains behavior and the campaign_id parameter, but never states when to prefer this tool over siblings such as scheduler or check_replies, nor does it give any exclusion criteria. The only instruction, about relaying the dashboard link, is post-invocation rather than selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_contactADestructiveInspect
Change one contact: tag it, note it, move its stage, or link it to a campaign.
Reading and searching contacts is the contacts tool.
Args:
action: "tag", "note", "stage", "link" or "enrich".
contact_id: Which contact.
lifecycle_stage: The stage to move it to.
tag: The tag to add.
note: The note to record.
campaign_id: Which campaign (link).
match: How to match when linking.
dry_run: Show what would change without changing it.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | ||
| note | No | ||
| match | No | name | |
| action | Yes | ||
| dry_run | No | ||
| contact_id | No | ||
| campaign_id | No | ||
| lifecycle_stage | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as destructive (destructiveHint=true) and non-read-only, and the description adds the safety-relevant dry_run behavior: 'Show what would change without changing it.' It does not contradict the annotations and provides useful context beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: first the purpose, then the routing instruction, then a terse Args block. No redundant preamble or repetition of the schema's default values.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter mutation tool with an output schema and a destructive annotation, the description covers the core decisions: which action, which contact, and dry_run semantics. It falls slightly short on explaining the 'enrich' action and the behavior of 'match', leaving some agent uncertainty for those less common cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the Args list is essential; it explains all 8 parameters and enumerates the allowed action values, which the schema leaves as a bare string. The main weakness is that 'match' is only glossed as 'How to match when linking' and 'enrich' is not explained, but the description still compensates for the schema's lack of parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and object—'Change one contact'—and enumerates the five supported mutations (tag, note, stage, link, enrich). It also explicitly contrasts itself with the read/search workflow by naming the contacts sibling tool, so an agent can distinguish it without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear when-not instruction: reading and searching contacts is the contacts tool, not update_contact. It does not spell out additional exclusion conditions relative to other mutation siblings such as edit_campaign, but the routing context is sufficient for the common case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
30 tool updates
v0.10.389- Changed
account2 fields changed- removed
Input schema / properties / action / defaultRemoved value: -"list" - added
Input schema / requiredAdded value: +[ + "action" +]
- Added
accounts - Added
answer_inbox - Removed
backfill_inbox - Removed
brand_strategy - Added
campaign_status - Changed
contacts4 fields changed- removed
Input schema / properties / dry_runRemoved value: -{ - "default": true, - "title": "Dry Run", - "type": "boolean" -} - removed
Input schema / properties / matchRemoved value: -{ - "default": "name", - "title": "Match", - "type": "string" -} - removed
Input schema / properties / noteRemoved value: -{ - "default": "", - "title": "Note", - "type": "string" -} - removed
Input schema / properties / tagRemoved value: -{ - "default": "", - "title": "Tag", - "type": "string" -}
- Changed
create_campaign1 field changed- added
Input schema / properties / peopleAdded value: +{ + "default": "", + "title": "People", + "type": "string" +}
- Removed
create_post - Removed
crm_sync - Removed
engage_prospect - Removed
generate_and_send - Removed
icp - Removed
import_prospects - Changed
inbox1 field changed- removed
Input schema / properties / textRemoved value: -{ - "default": "", - "title": "Text", - "type": "string" -}
- Removed
inspect - Removed
knowledge - Removed
manage_watchlist - Removed
network - Removed
organization - Removed
partner - Removed
product - Removed
profile - Removed
profile_signals - Added
prospect_view - Changed
scheduler3 fields changed- removed
Input schema / properties / action / defaultRemoved value: -"status" - removed
Input schema / properties / event_typeRemoved value: -{ - "default": "", - "title": "Event Type", - "type": "string" -} - added
Input schema / requiredAdded value: +[ + "action" +]
- Added
scheduler_status - Removed
send_email - Removed
signals - Added
update_contact
35 tool updates
v0.10.375- First observed
account - First observed
analytics - First observed
backfill_inbox - First observed
book_meeting - First observed
brand_strategy - First observed
campaign - First observed
check_replies - First observed
contacts - First observed
create_campaign - First observed
create_post - First observed
crm_sync - First observed
edit_campaign - First observed
engage_prospect - First observed
generate_and_send - First observed
generate_icp - First observed
icp - First observed
import_prospects - First observed
inbox - First observed
inspect - First observed
knowledge - First observed
manage_watchlist - First observed
network - First observed
organization - First observed
partner - First observed
product - First observed
profile - First observed
profile_signals - First observed
prospect - First observed
scheduler - First observed
send_email - First observed
send_message - First observed
setup_profile - First observed
show_status - First observed
signals - First observed
suggest_next_action
TDQS
Scored across 22 tools
Most tools form clearly distinct read/write pairs (contacts/update_contact, inbox/answer_inbox, accounts/account, scheduler/scheduler_status). However, send_message(action='reply') and answer_inbox both send replies to conversations, and show_status/analytics/suggest_next_action all surface overlapping campaign status and stats, creating minor boundary ambiguity.
Write/control tools use clear verb_noun forms (update_contact, create_campaign, book_meeting, check_replies), while read counterparts use plural nouns (contacts, accounts, inbox) or _status/_view suffixes (campaign_status, scheduler_status, prospect_view). The pattern is mostly predictable, though the read convention varies (whether a read tool is the plural noun, a _status tool, or a _view tool) without a single rigid rule.
At 22 tools this is on the heavier end, but the server's scope is genuinely broad—setup, account management, campaign lifecycle, contact/prospect handling, inbox messaging, scheduling, analytics, ICP generation, and meeting booking—so each tool has a legitimate role. It feels slightly dense but not bloated given the domain.
The full outreach lifecycle is covered: setup (setup_profile), campaign creation/editing/control (create_campaign, edit_campaign, campaign), monitoring (campaign_status), reply handling (inbox, answer_inbox, check_replies, send_message), prospect management (contacts, prospect, prospect_view), scheduling (scheduler, scheduler_status), and outcomes (book_meeting, prospect close). Minor gaps include no way to fully delete a contact and an awkward split of reply functionality between two tools.
Maintenance
Related MCP Connectors
Run LinkedIn outreach from your AI chat: find leads, launch campaigns, send, and reply.
Connect Claude or ChatGPT to your LinkedIn inbox. Research contacts and draft replies for review.
1- Gigi AIOAuthai.usegigi
LinkedIn outreach from Claude with a human veto: review, approve and send drafts, triage replies.
Self-driving LinkedIn prospecting: it sources, warms and invites daily. You approve every message.
2111
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceLinkedIn-native AI content creation, scheduling & analytics. Write and post on LinkedIn, create drafts, generate hooks & hashtags, schedule posts, and track engagement — all through natural language.22 npmMIT
- AlicenseNot gradedqualityBmaintenanceAI-powered content generation for LinkedIn outreach, helping sales teams and recruiters craft personalized connection requests, InMails, posts, comments, and multi-touch outreach sequences. It's a content assistant that generates text for human review and manual sending, fully compliant with LinkedIn's Terms of Service.11 npm46 PyPIMIT
- AlicenseNot gradedqualityCmaintenanceEnables sending LinkedIn messages and invitations, reading conversations, and managing outreach through natural language by automating a real LinkedIn session via a Chrome extension.13 npmMIT
- AlicenseNot gradedqualityCmaintenanceConnects AI assistants to LinkedIn outreach, enabling lead finding, campaign management, messaging, and analytics through natural language.MIT