HeyLead
This MCP server provides 22 tools to automate LinkedIn outreach, from setup and ICP generation through campaign management, messaging, inbox handling, meetings, and analytics.
Set up HeyLead, connect LinkedIn, and build a voice signature.
Generate ICPs/personas for sales, hiring, job search, partnerships, vendors, or research.
Create, edit, launch, pause, resume, archive, delete, or emergency-stop campaigns.
Find, import, skip, close, dismiss, and view prospects or conversations.
Send follow-ups, replies, InMails, and delete recent messages.
Check replies, classify sentiment, record opt-outs, and surface hot leads.
Read and reply to the LinkedIn inbox, approve/discard drafted replies.
Book Google Calendar meetings with invites and Meet links.
Track analytics, campaign status, scheduler status, and suggest next actions.
Manage accounts, contacts, tags, notes, lifecycle stages, and scheduler on/off.
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
HeyLead is an AI agent for LinkedIn outreach: it finds the right people, writes to them in the voice of your own LinkedIn posts, follows up, and handles replies. It runs from Claude Code, Cursor, any MCP client or a web dashboard. Sign in on the web, then talk to your AI and say "find me leads."
Use cases
A campaign has one of six goals, and the ICP, the fit check and the messages follow it: Sell a product or service, Find a job, Hire people, Find partners or investors, Find a vendor and Research interviews.
Sell a product or service: Reach the people who buy what you built.
Find a job: Reach the people who hire for the role you want.
Hire people: Reach candidates for a role you are filling. Works with a custom brief.
Find partners or investors: Reach the people who can sign a partnership or an investment. Works with a custom brief.
Find a vendor: You are the buyer. Reach the people who sell what you need.
Research interviews: Reach people to interview, survey or test with. Works with a custom brief.
Hire people, Find partners or investors and Research interviews run on a custom brief until their message sets exist.
Related MCP server: LinkedNav MCP
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
Claude Code, as a plugin (hosted, nothing to install):
/plugin marketplace add D4umak/linkedin-outreach-mcp
/plugin install heylead@heyleadThen run /mcp, pick heylead and choose Authenticate to sign in to your
HeyLead account. The plugin connects the hosted server at
https://heylead.dev/mcp and adds skills for starting a campaign, approving
waiting messages, answering replies, a weekly review, pausing, and adding a
list of people. Its source is in
plugins/heylead.
Or run the client 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, then run
heylead config set unipile_api_url <DSN>andheylead secrets set unipile_api_key(it prompts; the key is kept in your OS keychain, never in the config file).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?"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
Sending 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. HeyLead sends from your own LinkedIn account at a human pace: at most 20 invitations a day and 100 a week on a free LinkedIn account (more on Premium or Sales Navigator), Monday to Friday 08:00 to 22:00 in your time zone, minutes apart. It backs off when LinkedIn pushes back and resumes on its own. You can pause any campaign at any time. Launching is also what
commissions cloud sending — in observe mode nothing is commissioned and
nothing is sent, from either machine.
Approval mode (hosted): a workspace that has not chosen otherwise holds
every opening DM and follow-up until a person approves it, and the approved
text is what is sent. Read what is waiting on the dashboard's Approvals page or
with inspect(action="waiting"); decide with prospect(action="approve_message")
or discard_message. Autopilot sends them unread and is one switch away
(Settings → Sending, or scheduler(action="approval_mode", mode="autopilot")).
Invitations, InMail and replies are never held.
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 |
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 with your laptop closed, inside the sending window: invitations, opening DMs, first-touch InMail, follow-ups, engagements, follows, endorsements, email fallbacks, prospect top-ups, 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.
Pace — HeyLead sends from your own LinkedIn account at a human pace: at most 20 invitations a day and 100 a week on a free LinkedIn account (more on Premium or Sales Navigator), Monday to Friday 08:00 to 22:00 in your time zone, minutes apart. It backs off when LinkedIn pushes back and resumes on its own. You can pause any campaign at any time.
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 account per month | Up to 5 follow-ups per prospect |
A connected account is a LinkedIn seat or an email mailbox. Free includes one of either.
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, 3 ICP generations.
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
Tool-call telemetry — when you are signed in, your HeyLead workspace records each tool call: the tool, whether it worked, the error type, how long it took and the app that called it (Claude, ChatGPT, Cursor…). Never the arguments, the results, a prospect's name, a link or a message. Turn it off with
heylead config telemetry offorDO_NOT_TRACK=1
Power users: Pass your own LLM key (Gemini/Claude/OpenAI) during setup to use your own AI. Completely optional.
Where secrets are kept
HeyLead keeps its backend token, the Unipile key and any LLM keys in the OS
credential store (macOS Keychain, Windows Credential Manager, Linux Secret
Service), or in an owner-only secrets.json in the HeyLead folder when none
exists. The config file holds ordinary settings only. To inspect an install
without seeing a secret:
heylead config get backend_urlprints one ordinary settingheylead api get /api/v1/campaignsmakes an authenticated read of the hosted API, credentials maskedheylead secrets statuslists which secrets are stored, never their valuesheylead secrets cleanmoves secrets out of an older config file, drops keys a cloud-sending install does not use, and deletes old config backup copies
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 scheduled sending from the cloud with your laptop closed.
22 tools, from finding the right people to answering their replies: prospect discovery, ICP generation with buyer personas, connection invitations with a note, opening messages and follow-ups, warm-ups (profile views, follows, comments), reply handling that holds anything ambiguous for you, and outcome tracking.
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, show its plan, or read its status history. Changes nothing.
Args:
action: "monitor" (live progress; a draft is started with
campaign(action='launch')), "plan" (what happens after launch,
step by step: finding, warm-up, invitations, opening message,
follow-ups, replies, leads) 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?
Annotations already declare readOnlyHint=true and openWorldHint=true. The description adds 'Changes nothing' and explains that monitoring a draft requires launching via campaign(action='launch'), adding context beyond the annotations. No contradiction.
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 with the core purpose ('Watch a campaign run...'), then efficiently lists args with inline explanations. No wasted words; every sentence adds 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 read-only tool with no output schema, the description explains each action's output concept (live progress, step-by-step plan, history). It also links monitoring to the launch action, which is helpful. Minor gap: no mention of error conditions or return format, but not critical for a monitoring 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 coverage is 0%, so the description carries full responsibility. It explains each action value ('monitor', 'plan', 'status_history') with detailed meanings, and clarifies that campaign_id defaults to the active campaign. 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 states the tool watches a campaign run, shows its plan, or reads status history, with a specific verb and resource. It distinguishes from read-only operations but doesn't explicitly differentiate from siblings like show_status or scheduler_status, though the action options add specificity.
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?
Provides no guidance on when to use this tool versus alternatives. It explains each action (monitor, plan, status_history) but doesn't mention sibling tools or exclusions. An agent would have to infer context from the actions alone.
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 who you need to reach and HeyLead finds them on LinkedIn:
customers (lead generation, B2B prospecting, cold outreach), candidates
(recruiting and sourcing), hiring managers and referrals (job search),
investors and partners, vendors, and user-interview or research participants.
On first campaign, project_brief is asked explicitly, in the goal's words
(see project_brief below) — 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, in the goal's
words. sell: what you offer and who it is for. job_search: the role,
the kind of company, what you bring. hire: the role, who fits it, what
it offers. partner: what you want from a partner, what you bring.
buy: what you need, by when and how much, what a vendor must confirm.
research: what you research, who you want to hear from, what you ask.
Required before launch, resume, or auto-send.
mode: Always autopilot (copilot mode was removed). Whether opening DMs
and follow-ups wait for a person is the WORKSPACE's approval mode,
not this: a hosted workspace that never chose holds them
(inspect(action="waiting") lists them); scheduler(action=
"approval_mode") switches it.
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: "text_only". Messages are text.
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.
goal: What the campaign is for: "sell" (default), "job_search",
"hire", "partner", "buy" or "research". It sets campaign_type and
campaign_intent, picks whose profile the ICP describes, and picks
the fit question the goal <-> ICP audit asks. hire, partner and
research run on your project_brief until their message sets exist.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | ||
| 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?
Annotations declare destructiveHint=true and openWorldHint=true, but the description goes further by clarifying that nothing is sent until launch, that rate limits, sending window and opt-outs still apply, that project_brief is required before launch/resume/auto-send, and that approval behavior is a workspace setting surfaced via inspect/scheduler. It does not explicitly reconcile the destructiveHint against the fact that only a draft is created, which is the one 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?
Front-loaded with the purpose and the draft-until-launch rule, and arg docs are alphabetical and readable. However the use-case list is stated twice nearly verbatim (sales prospecting/recruiting/research in the opening paragraphs, then again as 'customers... candidates... investors...'), which is avoidable bloat in an already long description.
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, the description needn't explain return values, and everything else an agent needs for a 14-param, open-world, mutating tool — prerequisites, parameter interactions, defaults, and the goal taxonomy — is present.
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% across 14 parameters, so the description carries the full burden — and it does, documenting every parameter with defaults, conflicts (exclude_connections cannot combine with connections_only), and value enums for goal/campaign_type/voice_mode. Examples are supplied for target_description, company_url and people.
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 specific verb and resource ('Create a LinkedIn outreach campaign') plus the input modality ('from a natural language description') and immediately scopes it as a draft until campaign(action='launch'). An agent can distinguish this from campaign, edit_campaign, and generate_icp without opening a schema.
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?
Explicitly routes the agent: use the `people` argument when the user can already name targets (skips LinkedIn search), use `connections_only` for 'DM my network', use `exclude_connections='off'` when the user says 'include my existing connections', and use `force` only on a mismatch verdict. Alternatives and when-not conditions are named rather than implied.
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 was removed). Whether
messages wait for a person is the workspace's approval mode:
scheduler(action="approval_mode").
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", "recruit" or "research".
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.
goal: What the campaign is for: "sell", "job_search", "hire",
"partner", "buy" or "research". Rewrites campaign_type and
campaign_intent to match. Empty keeps the current value.
project_brief: Full project paste the model sees. Required before launch,
resume, or auto-send.
offer_outcome: The Offer card's outcome: what changes for the reader,
in their words. Editing it unconfirms the card.
offer_how: The Offer card's how: what the sender does, said only in a
reply. Editing it unconfirms the card.
offer_proof: The Offer card's proof, used at most once per thread.
Editing it unconfirms the card.
offer_ask: The Offer card's one question. Editing it unconfirms the card.
offer_confirm: "on" confirms the Offer card; first messages resume.
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: "text_only". Messages are text. 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.
invite_note: Invitations carry a note: "on" (default) or "off". Off sends
the bare invitation; the first words are the DM a working day after
they accept.
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 |
|---|---|---|---|
| goal | No | ||
| mode | No | ||
| name | No | ||
| volume | No | ||
| go_live | No | ||
| product | No | ||
| offer_ask | No | ||
| offer_how | No | ||
| offerings | No | ||
| voice_mode | No | ||
| active_days | No | ||
| campaign_id | No | ||
| invite_note | No | ||
| offer_proof | No | ||
| voice_noise | No | ||
| booking_link | No | ||
| case_studies | No | ||
| must_confirm | No | ||
| campaign_type | No | ||
| max_followups | No | ||
| offer_confirm | No | ||
| offer_outcome | 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 declare destructiveHint=true and openWorldHint=true, and the description adds genuinely new behavioral context beyond them: changes apply only to messages written from now on, editing any offer_* field unconfirms the Offer card, project_brief is required before launch/resume/auto-send, and exclude_connections/connections_only are mutually exclusive toggles. No contradiction with the annotation profile.
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?
Structure is well front-loaded (purpose, then patch semantics and alternatives, then Args), and for a 52-parameter tool with a bare schema the length is largely earned. There is some repetition ("Empty keeps the current value" / "0 to keep current" recurs many times) and the campaign_type paragraph could be tightened.
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?
An output schema exists so return values need no explanation, and the annotations carry the safety profile. The description still covers what an agent needs to call this correctly: partial-update semantics, defaults for empty values, prerequisite fields, and the exclusivity between exclude_connections and connections_only.
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% across 52 parameters, so the description carries the full burden and does so: it documents ~50 of 52 fields with meaning, accepted values ("on"/"off"/"observe", intent enums, ranges like 7-60), units, and cross-field interactions. Only voice_noise and voice_humanize are left undocumented.
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?
Opens with a specific verb+resource ("Change one running or drafted campaign's settings") and immediately distinguishes itself from create_campaign and campaign(action=...), which are named explicitly. An agent can select this tool over its siblings without opening any schema.
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 the patch semantics ("Pass only what you want to change; every field left empty keeps its current value") and names the alternatives with the condition that selects them: create_campaign for a new campaign, campaign(action=...) to launch/pause/stop. It also scopes the tool ("edits settings only: it sends nothing and adds no prospects").
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. Pass goal= so the
profile is of the right people.
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. Applies only to sell, partner
and buy; managers hire, so a job search keeps them.
goal: What the campaign is for, which decides whose profile this is:
"sell" (customers, the default), "job_search" (the people who hire for
or refer into the role), "hire" (candidates), "partner" (who can sign
a partnership or invest), "buy" (vendors), "research" (participants).
Always pass it; a job search with goal="sell" produces peers, not
hiring managers.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | sell | |
| 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 indicate readOnlyHint=false, openWorldHint=true, and destructiveHint=true. The description adds valuable behavioral context beyond that: the result is persisted ('The result is saved and can be reused with create_campaign(icp_id=...)'), and it details how decision_makers_only behaves differently across goals. 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 well-structured: an opening statement, a paragraph on scope and reuse, then a clear Args list. It front-loads the core purpose. However, the sentence 'Supports target audience analysis, customer segmentation, buyer persona creation, ideal customer profiling, and B2B market research.' is somewhat redundant with the opening line and adds length without new information. Still, every other 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?
This is a complex tool with 5 parameters and an output schema. The description covers each parameter's meaning, provides guidance on when to pass goal, explains the saved-and-reusable output, and addresses edge cases (e.g., job search vs. sell). There is an output schema present, so return-value details are not needed. 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. It thoroughly documents all five parameters in the Args section with examples ('CTOs at fintech startups', 'freelance UX designers in London'), explains the default behavior of decision_makers_only, and clarifies the semantics of goal across six distinct use cases. 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 opens with a specific verb and resource: 'Generate a rich Ideal Customer Profile with buyer personas.' It clearly states the deliverable (2-4 personas with pain points, fears, etc.) and enumerates supported use cases (target audience analysis, customer segmentation, etc.). This fully distinguishes it from sibling tools like create_campaign or update_contact.
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 when-to-use guidance, especially for the goal parameter: 'Always pass it; a job search with goal="sell" produces peers, not hiring managers.' It also explains the decision_makers_only flag and how company_context/focus_query improve results. It does not explicitly name alternatives or when-not-to-use scenarios, but the context is clear enough.
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.
Someone who is not a fit is skipped, not closed: skip leaves them out of
this campaign and records nothing else. Close records a result and
needs an outcome; won and lost are for people HeyLead has written to.
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". Required for close; there is
no default.
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: Why, for skip and close: "not_a_fit", "negative_reply",
"asked_to_stop", "handled_elsewhere" or "other".
reason_note: A free note alongside the code.
deal_value: What the won deal is worth (close with outcome="won").
deal_currency: Three-letter code, e.g. USD. Defaults to the last deal's.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| reason | No | ||
| confirm | No | ||
| outcome | No | ||
| deal_value | No | ||
| campaign_id | No | ||
| outreach_id | No | ||
| reason_code | No | ||
| reason_note | No | ||
| meeting_link | No | ||
| deal_currency | 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 destructiveHint=true and openWorldHint=true, so the description's job is to add detail, which it does: skip 'records nothing else,' close records a result, opt_out 'stops all future contact,' and confirm is 'required where the action cannot be undone.' It stops short of naming which specific actions are irreversible or what dismiss does relative to skip.
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?
Front-loaded with the three-action summary, then a prose block of selection rules, then a compact Args list. Every line is informative, though the reason/reason_code/reason_note trio is described somewhat repetitively.
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, return values need not be explained, and the action semantics, conditional requirements and defaults are well covered. The remaining gap is 'dismiss,' which is listed but never distinguished from skip or close.
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% across 11 params, so the description must carry the load, and it does: it enumerates action, outcome and reason_code values inline, marks outcome as required for close with no default, and documents defaults for campaign_id ('active one if empty') and deal_currency ('last deal's'). This adds substantial meaning beyond the bare typed properties.
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 opening sentence states three specific actions (skip, close, dismiss) on a named resource, and the closing line explicitly routes the read case to prospect_view. An agent can distinguish this from the sibling prospect_view without opening either schema.
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 states the selection rule directly: 'Someone who is not a fit is skipped, not closed,' explains what close requires versus skip, and names the alternative tool for reading. Conditions for outcome="opt_out" are also given, so there is little left to infer.
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: "cloud" (send_from); a hosted account never sends from here.
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 declare destructiveHint=true, readOnlyHint=false and openWorldHint=true, so the safety profile is covered. The description adds meaningful consequences beyond that: 'Off means nothing sends until it is on again' and that a hosted account never sends from the local machine, both of which affect how an agent reasons about the call.
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?
Purpose and the key behavioral caveat are front-loaded, then the argument list follows. The per-parameter lines are warranted given 0% schema coverage, though the prose is slightly loose and could be tightened without losing information.
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?
An output schema exists, so return values need not be explained, and all six parameters are documented. What remains thin is guidance on the multi-action mode itself (what each action does), which is a meaningful gap for a tool whose behavior changes entirely by action.
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 meets it: it enumerates the valid action values and explains all five remaining parameters (enabled, cloud, host, hours, campaign_id), including which actions each applies to and the 'cloud' sentinel for host.
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 specific verb and resource ('turn the autonomous scheduler on or off, or change how it runs') and explicitly names the sibling it is not: 'Reading its state, logs, activity or diagnostics is scheduler_status.' An agent can distinguish it from scheduler_status without opening either schema.
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 one clear alternative (scheduler_status for reading) with the condition that selects it, and maps each parameter to the actions it applies to (e.g. 'enabled ... (toggle, report)'). However, it never explains when to choose among toggle, observe, always_on, backfill_cloud, send_from, or report, so the core action-selection decision is left to inference.
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, 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
"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'. For followup/reply.
text: Custom message text. 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 the tool as non-read-only and destructive, so the description adds meaningful context beyond them: InMail fails closed on four specific preconditions, delete only applies to recently sent messages, and empty text auto-generates. It does not mention reversibility or side effects of deletion, hence 4.
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 important one-line purpose is followed by a dense, well-organized Args block with no filler. The detailed InMail preconditions are worth the space and are formatted as a scannable list.
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 five-parameter, multi-action messaging tool with preconditions and defaults, the description covers selection, required fields, failure behavior, and destructive scope. An output schema exists, so the absence of return-value detail is not a gap.
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 carries the full burden and succeeds: action gets enumerated values with per-value behavior, campaign_id gets default semantics, outreach_id gets a required-for-inmail flag, and text gets auto-generation plus special delete usage. Every parameter receives meaning beyond its bare name and type.
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 opening line names a precise verb and resource ('Send follow-ups, replies, or InMail to prospects') and the action list makes the scope concrete. It is clear, but it doesn't explicitly differentiate from sibling answer_inbox or say which nearby tool handles other messaging cases, so it earns 4 rather than 5.
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?
Each action value includes when to use it: follow-up after connection accepted, reply to a prospect who messaged you, delete within 60 minutes, and InMail to non-connections. The InMail path lists explicit preconditions and gives the internal DM fallback, while the delete action states its time constraint and the text param identifies auto-generation behavior.
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.
2 tool updates
v0.10.429- Changed
edit_campaign1 field changed- added
Input schema / properties / invite_noteAdded value: +{ + "default": "", + "title": "Invite Note", + "type": "string" +}
- Changed
prospect1 field changed- changed
Input schema / properties / outcome / defaultPrevious value: -"won"New value: +""
1 tool update
v0.10.425- Changed
edit_campaign5 fields changed- added
Input schema / properties / offer_askAdded value: +{ + "default": "", + "title": "Offer Ask", + "type": "string" +} - added
Input schema / properties / offer_confirmAdded value: +{ + "default": "", + "title": "Offer Confirm", + "type": "string" +} - added
Input schema / properties / offer_howAdded value: +{ + "default": "", + "title": "Offer How", + "type": "string" +} - added
Input schema / properties / offer_outcomeAdded value: +{ + "default": "", + "title": "Offer Outcome", + "type": "string" +} - added
Input schema / properties / offer_proofAdded value: +{ + "default": "", + "title": "Offer Proof", + "type": "string" +}
1 tool update
v0.10.402- Changed
prospect2 fields changed- added
Input schema / properties / deal_currencyAdded value: +{ + "default": "", + "title": "Deal Currency", + "type": "string" +} - added
Input schema / properties / deal_valueAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Deal Value" +}
3 tool updates
v0.10.398- Changed
create_campaign1 field changed- added
Input schema / properties / goalAdded value: +{ + "default": "", + "title": "Goal", + "type": "string" +}
- Changed
edit_campaign1 field changed- added
Input schema / properties / goalAdded value: +{ + "default": "", + "title": "Goal", + "type": "string" +}
- Changed
generate_icp1 field changed- added
Input schema / properties / goalAdded value: +{ + "default": "sell", + "title": "Goal", + "type": "string" +}
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
Descriptions explicitly cross-reference sibling tools and clarify most boundaries, but several pairs still overlap: account vs accounts, send_message vs answer_inbox for replying, and status/reporting tools such as show_status, analytics, campaign_status, and scheduler_status. The detailed descriptions reduce misselection, but the set has real overlapping purposes.
All names use snake_case and remain readable, but conventions are mixed: noun-only tools (campaign, prospect, inbox), noun_status tools (campaign_status, scheduler_status), and verb_noun tools (update_contact, create_campaign, send_message). Singular/plural pairs like account vs accounts also weaken predictability.
22 tools is borderline heavy for this domain. Many read/status tools could be consolidated, and some messaging tools overlap, so the set feels broader than tightly scoped even though the platform is complex.
The surface covers the main LinkedIn outreach lifecycle: setup, accounts, ICP generation, campaign creation/editing/control, prospects, contacts, inbox, sending, replies, scheduler, analytics, and meeting booking. Minor gaps exist, such as no dedicated contact creation/deletion or explicit list_campaigns, but agents can generally work around them.
Maintenance
Related MCP Connectors
LinkedIn outreach in Claude or ChatGPT: campaign stats, replies, leads, drafts. Never sends.
1Run LinkedIn outreach from your AI chat: find leads, launch campaigns, send, and reply.
Find LinkedIn prospects, draft outreach, and run human-paced campaigns from your AI agent.
- Gigi AIOAuthai.usegigi
LinkedIn outreach from Claude with a human veto: review, approve and send drafts, triage replies.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables 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
- AlicenseAqualityAmaintenanceLinkedIn prospect intelligence inside Claude. It automates the research behind outreach, not the sending: scrapes posts, profiles and comment threads into a local SQLite database, classifies what a person or company actually posts about, mines comment threads for people already describing your problem, and surfaces uncommon commonalities worth opening with.1832MIT
- AlicenseNot gradedqualityBmaintenanceLinkedIn from the user's own logged-in Chrome session for AI agents: search, profiles, post engagers, company employees, lists, sequences, inbox and a Research Pack, with hard caps and a human approval queue. Local-first, no headless browser.10MIT