Skip to content
Automation
Command

/outreach

The outreach flow does two things at a target company:

From plugin
claude-linkedin-assistant
2078 skills8 commands

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/outreach

Context preview

What this command does when you run it.

The outreach flow does two things at a target company:

Command definition

outreach.md

OUTREACH (cold sweep at a company)

The outreach flow does two things at a target company:

1. **Send connection requests** to 2nd-degree contacts (recruiters, peers, leads). Always "Send without a note" — LinkedIn rate-limits personalized invites. 2. **Send a first DM** to your existing 1st-degree connections at the company.

Out of scope (you handle these manually):

  • ❌ Replying to DMs once a thread is warm
  • ❌ Follow-up nudges on stale outreach
  • ❌ Sending a resume / file attachments

---

Step 1 — Pick a company

**If the command was called with an argument** (`/jobs outreach Mixpanel`), use that company. Skip the rest of this step.

**Otherwise**, read `job_tracker.csv` for outreach candidates: rows where `Referral Needed=YES` AND `Referral Status` ∈ `Outreach Pending` / `Connection Pending`.

  • **Has candidates** → auto-pick the most urgent one: smallest `Days Left` (Referral Deadline − today; negative = overdue first). Tiebreaker: oldest `Discovered Date`. Print:

> `Picked: <Company> — <Role> (deadline in <N> days)`

Proceed to Step 2 immediately. No confirmation prompt. (If you want to override, stop the run and re-invoke as `/jobs outreach <OtherCompany>`.)

  • **No candidates in the tracker** → ASK the user: "Tracker has no companies queued for outreach. Which company do you want to run outreach on? (You can also run `/jobs find` first to discover jobs.)" Wait for a company name, then proceed with that.

If the picked company is `Connection Pending`, jump to **Step 4 — Check pending acceptances** instead of Step 2.

---

Step 2 — Find contacts (1st-degree FIRST, then 2nd)

LinkedIn via Chrome:

1. Navigate to `https://www.linkedin.com/company/<slug>/people/`. Extract the numeric company ID by scanning the page for `urn:li:fsd_company:<id>` and picking the most-frequent match.

2. **Step 2A (MANDATORY): 1st-degree only**, no keyword filter:

   https://www.linkedin.com/search/results/people/?currentCompany=["<id>"]&network=["F"]

Read every result. These are your existing connections at the company and are always the top picks for direct DMs.

3. **Step 2B: 2nd-degree fallback**, with role-relevant keywords:

   https://www.linkedin.com/search/results/people/?currentCompany=["<id>"]&network=["S"]&keywords=recruiter OR <role keyword>

Use role keywords inferred from the user's resume(s) in `resumes/` (e.g. "data scientist" / "engineer" / "product manager").

4. **Never combine `network=["F","S"]` in one search.** LinkedIn sorts combined results by keyword relevance, which buries 1st-degree contacts below 2nd-degree ones. Always do the two searches separately.

5. URL params are `network` and `currentCompany`, NOT `facetNetwork` / `facetCurrentCompany`.

Extract per contact: name, title, connection degree, mutual-connection count, profile URL.

**Priority order:**

1. **Any 1st-degree connection** at the company — always beats 2nd-degree, regardless of title. Goes through Step 3 (DM flow). 2. **2nd-degree recruiter / Talent Acquisition.** Connection request via Step 4. 3. **2nd-degree peer** (data scientist, engineer, product, etc. — match on the user's role from their resume in `resumes/`). Connection request via Step 4. 4. **2nd-degree lead / manager** in the user's function. Connection request via Step 4.

Show two ranked tables, one per network tier:

1st-degree (DM directly):
# | Name | Title | LinkedIn URL | Mutuals

2nd-degree (connection request):
# | Name | Title | LinkedIn URL | Mutuals

---

Step 2C — Connection-request quota (per company)

Use a per-company quota based on how many 1st-degree connections the user already has there:

quota = max(0, (10 − count_1st_degree) × 5)

| 1st-degree available | Connection requests to send | |---|---| | 10+ | 0 (already have plenty of internal contacts) | | 9 | 5 | | 8 | 10 | | 7 | 15 | | 5 | 25 | | 2 | 40 | | 1 | 45 | | 0 | 50 |

**No global weekly cap is enforced.** Send the per-company quota in full. The only stop signal is LinkedIn itself — see Step 4B for the CAPTCHA / rate-limit handling.

---

Step 3 — DM existing 1st-degree connections

For each 1st-degree contact selected:

A. Open profile and verify connection level

Navigate to the contact's profile URL. Confirm they show as 1st connection.

B. Prior-thread check (MANDATORY before drafting)

Click Message to open the chat overlay. Scan the thread history:

| Thread state | Action | |---|---| | No prior messages | Proceed to **C (draft message)** | | Prior message from user, contact replied | Skip — warm thread, user handles manually | | Prior message from user, no reply, ≥7 days ago | **SKIP** — do not re-engage. Log `Skipped (prior unanswered DM <date>)` | | Prior message from user, no reply, <7 days ago | Skip for now (still in reply window). Log and move on |

Close the dialog if skipping.

C. Draft and send the first DM

**Step 1: Build the pitch from the user's resume.** Read whatever is in `resumes/`. Extract:

  • The user's **first name** (top of the resume)
  • The user's **current title** + **employer** (most recent role)
  • **Years of experience** (from the experience timeline)
  • **Top 2-3 specializations** (from the headline / summary / repeated keywords)

Construct a single first-person sentence about the user. Examples of the right shape: > "I'm a senior data scientist with 5+ years in experimentation and product analytics, currently at <Employer>." > "I'm a staff ML engineer with 8+ years building production LLM systems, currently at <Employer>."

Don't invent details not in the resume.

**Message style rules (strictly enforced):**

  • Short: 2-3 sentences max
  • Conversational, not corporate
  • No em-dashes (—) anywhere
  • No filler phrases like "I hope you're doing well"
  • No "Best, <name>" sign-off — end naturally
  • **First person throughout** — the DM is sent from the user's account, so it must read as the user speaking. Never use third person ("He is...", "She is...") in any outgoing mes
Read more
Ships withclaude-linkedin-assistant

Minimal Claude Code workspace for tracking jobs + sending first-DM LinkedIn outreach via the Claude in Chrome extension. Tracker CRUD, job discovery, and 1st-degree-only outreach. Reply handling, follow-ups, and applications stay manual.

Get the whole plugin
Stats
207
Stars
47
Forks
Maintained
Maintenance
MIT
License
2mo ago
Last commit
3mo ago
Created

Repo: FarzamHejaziK/claude-linkedin-assistant