# How to run a LinkedIn outreach campaign from your AI agent

Source: https://finchreach.com/blog/linkedin-outreach-campaign-ai-agent
Published 2026-10-29 by Finchreach team. Tags: linkedin, mcp, campaigns, outreach, how-to, approval-queue.

Ask Claude, ChatGPT or Cursor to build a LinkedIn sequence: daily lead search, invite, wait, DM, follow-up. It runs on our servers, with the approvals you pick.

## The short answer

Connect Finchreach to your AI agent, then describe the campaign in plain words: who to reach, what to say, how long to wait and how much review you want. The agent turns that into a Finchreach campaign: a saved LinkedIn people search that adds new leads every day, plus an ordered sequence of steps (invitation with a note, wait until accepted, a message, a follow-up). You check a preview, the agent launches it, and from then on it runs on Finchreach’s servers with your own LinkedIn account, even when your laptop is closed and the chat is gone.

You stay in control in three ways. You choose an approval mode: review every message, approve the templates once, or let it send. Every send goes through your account’s queue, inside your working hours and daily limits. And a lead who replies gets nothing more from the sequence, so the conversation is yours.

The rest of this guide walks through an example, “contact customer-service leaders in Austin”, step by step, with the real tool names your agent uses.

## What you need

Finchreach is a remote MCP server. MCP (Model Context Protocol) is a standard plug that lets AI apps use outside tools; Finchreach is the tool that gives your agent your LinkedIn account.

- A Finchreach account with your LinkedIn account connected.
- An MCP client. In [Claude](https://finchreach.com/integrations/claude), add a custom connector with `https://mcp.finchreach.com/mcp`, click Connect and sign in on Finchreach, where you choose the LinkedIn account and what Claude may do. In [ChatGPT](https://finchreach.com/guides/chatgpt), turn on Developer mode, create a connector with the same URL and Authentication: OAuth, then approve on Finchreach. Cursor and other clients that send headers can use an API key instead.
- Campaign permissions: the `campaigns:read` scope to see campaigns and stats, and `campaigns:write` to create and steer them. With OAuth you grant these when you approve the connection; with an API key, give the key those scopes.

Full setup for every client, plus the tool list, is in the [docs](https://finchreach.com/docs#tools).

## Step 1: describe the campaign to your agent

Be specific about the audience, the tone and the review you want. Something like this works:

> Ask your assistant: “Set up a LinkedIn campaign on my account to reach customer-service leaders in Austin. Each day, search for people like “head of customer service Austin” and add up to 20 new ones. Sequence: send an invitation with a short note that mentions their role, wait until they accept (withdraw the invitation if they haven’t after 21 days), then send a friendly message asking how their team handles support volume, and one follow-up 5 days later if they don’t answer. Use template_once approval. Show me the preview before launching anything.”

From that, the agent calls `linkedin_create_campaign` with a name, the approval mode and the steps. The campaign starts as a draft: nothing is sent while it is a draft, and creating it doesn’t touch LinkedIn at all.

## Step 2: the sequence and its steps

A campaign is an ordered list of up to 20 steps. Each lead moves through them one by one. These are the step types that exist today, and what each one does when a lead reaches it:

| Step | Settings | What happens |
| --- | --- | --- |
| `invite` | Optional note (up to 300 characters, LinkedIn’s limit); optional `withdrawAfterDays` | Queues a connection invitation with the note filled in for that lead |
| `wait` | `days`, or `untilAccepted: true` | Pauses the lead for N days, or until the invitation is accepted (checked every few hours) |
| `dm` | A message template | Queues a direct message to the lead |
| `follow_up` | A message template and `delayDays` | Queues another message after the delay, in the same thread as the first one |
| `view_profile` | None | Kept as a step in the sequence; in the current version it is recorded and the lead moves on without a separate profile visit |

Two details matter for the “wait until accepted” pattern. Acceptance is detected by reading your pending sent invitations: once the invitation was sent and the person is no longer on that list, the lead counts as connected and moves on. And if the invite step has `withdrawAfterDays`, a lead who still hasn’t accepted after that many days gets a withdrawal of the invitation queued (under the same approval mode) and leaves the campaign as not accepted.

Every step can also carry its own approval mode, which overrides the campaign’s. For example, a campaign on `template_once` can still have each follow-up reviewed by hand.

## Step 3: templates and variables

Invitation notes and messages are templates. The variables are `{{firstName}}`, `{{lastName}}`, `{{fullName}}`, `{{company}}` and `{{headline}}`, and any of them can take a fallback for leads where the value is missing: `{{company|your team}}`. A template that uses any other variable is rejected when the campaign is created or updated, so a typo fails early instead of landing in someone’s inbox.

Example invitation note:
```text
Hi {{firstName}}, I work with support teams in Austin and noticed your role at {{company|your company}}. Would be glad to connect.
```

Use fallbacks generously. People found by the saved search come in with a name and headline but not always a company, and an empty value without a fallback simply renders as nothing.

Before launching, ask the agent to run `linkedin_preview_campaign`. It renders each note and message for sample leads (yours, the campaign’s first leads, or a placeholder person) and sends nothing. Read it the way the recipient would.

## Step 4: where the leads come from

There are two ways to fill a campaign, and you can use both:

- `linkedin_set_campaign_search` saves a LinkedIn people search on the campaign. While the campaign is active, it runs once a day and adds up to `maxPerRun` new people (25 by default, at most 100). It takes the same people-search parameters as `linkedin_search`: keywords, connection degree, location ids and current company ids. Setting it to null removes it.
- `linkedin_add_campaign_leads` adds up to 500 people per call that the agent already found, for example with a `linkedin_search` people search or from a list you pasted.

Both paths use the same checks. A person is skipped, with the reason reported, if their profile can’t be identified, if they are already in this campaign, if another of your campaigns has already contacted them, or if they are on your do-not-contact list. So running the search every day doesn’t message the same person twice.

> People search that mixes location or company filters with connection degree (or goes past the first page) is in beta: it works, but the LinkedIn request shape isn’t verified yet and may change. A keyword-only search, like “customer service manager Austin”, is the simplest place to start.

## Step 5: pick an approval mode

The mode decides what happens each time a step produces an invitation, message or withdrawal:

| Approval mode | What happens | Good for |
| --- | --- | --- |
| `per_message` (default) | Every invitation and message waits in your approval queue; you approve, edit or reject each one | A first campaign, or high-stakes audiences |
| `template_once` | You approve the note and message templates once (`linkedin_approve_campaign_templates`, or on the Campaigns page in the dashboard); after that, sends are queued without per-message review. Launch is blocked until the templates are approved, and editing a template clears the approval | A sequence you have already tested and trust |
| `auto` | Sends are queued without review | Only when you are comfortable with every possible rendering of the templates |

With `per_message`, the pending invitations and messages show up in your [approval queue](https://finchreach.com/approvals), where you can edit the text before approving. Your agent can also list them with `linkedin_list_queue` (status `pending_approval`), but it can never approve its own proposals.

## Step 6: limits, working hours and the queue

A campaign never sends directly. Each invitation or message it produces goes into your account’s send queue, behind the one-off writes you or your agent queue by hand, and the per-account scheduler sends one at a time: within your working hours, under your account’s daily limits, and with spacing between sends. If a cap is reached or it’s outside hours, the action waits and the queue shows why.

- `linkedin_get_account_schedule` and `linkedin_update_account_schedule` read and set working hours: a timezone, working days and time windows. The default is Monday to Friday, 09:00 to 18:00 in the account’s timezone.
- `linkedin_list_queue` shows what is waiting and its estimated send time; `linkedin_cancel_action` and `linkedin_reschedule_action` change individual sends.
- `linkedin_list_events` includes `campaign.step_enqueued` events, so an agent can see each step a campaign produced without polling every lead.

## Step 7: launch, then let it run

`linkedin_launch_campaign` starts the draft. The leads become due, the daily search starts, and the agent can leave: the campaign runs on Finchreach’s servers with your own LinkedIn session, not in the chat. When you want an update, ask:

> Ask your assistant: “How is my Austin customer-service campaign doing? Show me the stats, who replied, and anything that failed.”

The agent uses `linkedin_campaign_stats` (lead counts by state, such as queued, waiting, connected, replied, finished and failed, plus the reply rate) and `linkedin_list_campaign_leads` (each lead’s state, current step, next run, invited, accepted and replied times, and the last error).

To steer it: `linkedin_pause_campaign` stops advancing leads (sends already in the queue stay there until you cancel them), `linkedin_resume_campaign` continues, and `linkedin_archive_campaign` ends it for good. Steps and the approval mode can be changed while the campaign is a draft or paused.

## Stop on reply and the do-not-contact list

Before a lead who was invited moves to a wait, message or follow-up step, the campaign checks your inbox. If the latest message in your one-to-one thread with that person came from them, the lead is marked as replied and gets nothing else from the sequence. You take the conversation from there, by hand or with your agent’s help in the normal per-message flow.

The do-not-contact list applies to every campaign on your Finchreach account. `linkedin_block_contacts` adds people (with an optional reason, and optionally only until a date), `linkedin_list_blocked_contacts` shows the list and `linkedin_unblock_contacts` removes people. Blocked people aren’t added as leads, and leads already in a campaign are skipped from then on. Add customers and anyone who asked not to be contacted before you launch.

## A note on risk

Automating a personal LinkedIn account carries risk under LinkedIn’s User Agreement, and no tool can promise your account won’t be restricted. Finchreach can’t either. What lowers the risk is a person in the loop, a human pace and messages written for one person at a time. That’s why `per_message` is the default, why every send waits for your working hours and daily limits, and why a reply stops the sequence.

Start small: a narrow audience, a modest daily search size, `per_message` approval for the first batch, and a careful read of the preview. For a fuller picture of what tends to get accounts restricted, read [LinkedIn automation without getting banned](https://finchreach.com/blog/linkedin-automation-without-getting-banned), and for how Finchreach works as an MCP server in general, see [the LinkedIn MCP server guide](https://finchreach.com/blog/linkedin-mcp-server).
