Live LinkedIn discovery via browser automation — alumni-first search, 2nd-degree targeting, draft 5 personalized connection-note variations per prospect, log to the tracker via Supabase MCP. Use for live sourcing sessions where you browse LinkedIn as the authenticated user. For bulk profile enrichment from a list of URLs, use `linkedin-datasearch` instead. INTEL GATHERING ONLY — the user always sends connection requests manually.
How this skill is triggered — by the user, by Claude, or both
Slash command
/linkedin-tracker-plugin:linkedin-browser-automationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Live LinkedIn networking — alumni-first, relationship-first, intel-only. Uses your authenticated browser session to access alumni filters, connection-degree markings, and mutual-connection signals (data you cannot get from third-party APIs).
Live LinkedIn networking — alumni-first, relationship-first, intel-only. Uses your authenticated browser session to access alumni filters, connection-degree markings, and mutual-connection signals (data you cannot get from third-party APIs).
For bulk enrichment from a list of profile URLs without browser/session, use the sibling skill linkedin-datasearch (Bright Data API).
references/golden-goose-referral-tactics.md — full tactics guide (why referrals, objection handling, timing)references/connection-note-strategies.md — creative openers, timing, tracking, coffee-chat asksreferences/50-proven-email-scripts.md — Ramit Sethi email principles applied to LinkedIn🚫 NEVER send connection requests. This skill finds prospects, drafts messages, and logs them. The user sends every message manually on LinkedIn. You are an intel/drafting assistant — not a spam cannon.
🛡️ Browser automation ONLY for LinkedIn fetching. Never web_search or web_fetch LinkedIn URLs — LinkedIn blocks scrapers and flags/bans accounts. Use a browser tool (Playwright MCP, or the user's configured browser profile) with 10+ second delays and max 20-30 profile views per session.
👤 Human in the loop for every send. Draft, log, review — the user clicks "Send" on LinkedIn themselves.
This skill reads per-user config from ~/.linkedin-automation.config.yml. Config is loaded at skill activation:
!cat ~/.linkedin-automation.config.yml 2>/dev/null || echo "NOT_CONFIGURED"
If the config above reads NOT_CONFIGURED, you must onboard the user before doing any LinkedIn work. Ask conversationally (do NOT dump a form):
default)"Then write the answers to ~/.linkedin-automation.config.yml using the schema in ${CLAUDE_SKILL_DIR}/config.example.yml. Confirm the file was written. Only proceed with LinkedIn work after config exists.
Config values that are secrets (API keys, database passwords) MUST live in env vars — never in the config file. The config file stores only the env-var name to reference (e.g., api_key_env: TRACKER_API_KEY). At runtime, the skill reads the named env var via printenv.
browser action:navigate targetUrl:https://www.linkedin.com/school/{school_slug}/people/?keywords={company} profile:{browser_profile}
# wait 10+ seconds
browser action:snapshot profile:{browser_profile}
{school_slug} = the LinkedIn school URL slug (e.g., saddleback-college, mit). If the user's school isn't found, try the generic LinkedIn search with alumni filters.
Visit the profile, snapshot, and extract:
Then generate 5 personalized connection-note variations (see Connection Notes section below) and log to the tracker.
browser action:navigate targetUrl:https://www.linkedin.com/mynetwork/invitation-manager/sent/ profile:{browser_profile}
# wait 5 seconds
browser action:snapshot profile:{browser_profile}
Update tracker: flip status from Pending → Connected for each accepted request.
X prospects found, Y status updates, Z ready for follow-up.ALWAYS generate 5 variations per prospect. The user picks the best one. Store all 5 in the tracker so they're not lost.
[name] placeholders. Ready to copy-paste.Hi {first_name}, I want to connect — I'm a {year} at {school} studying {major} and I'd love to intern at {company} someday. Would love to hear about your experience if you have a few minutes. Thanks!
1. Alumni Bond (highest-priority when {school} matches)
Hi {first_name}, fellow {school} alum here! I'm a {year} studying {major} hoping to intern at {company}. Would love to hear about your path there if you have time. Thanks!
2. Relatable / Casual (similar age or background)
Going from {their_previous} to {their_current} is crazy — I'm on a similar path at {school}. Would love to connect!
3. Respect the Journey (nontraditional paths — career switchers, bootcamp → FAANG, etc.)
Hi {first_name}, I really admired your journey from {previous_role} to {current_role}. Takes real grit — would love to connect and hear what helped you get there.
4. Hook-Based (specific thing from their profile — project, post, award)
Hi {first_name}, noticed you're also into {hook}. That's awesome — I'm a {major} student at {school} exploring {company}. Would love to connect.
5. Local / Shared Context ({location} match)
Hi {first_name}, fellow {location} local here! Always cool to see {school} people at {company}. Would love to connect.
6. Recruiter / Post Response (they posted about hiring)
Hi {first_name}, saw your post about the {role} opening at {company}. I'm a {major} student at {school} and already applied — would love to connect and learn more.
7. Mutual Connection Leverage
Hi {first_name}, I see we're both connected to {mutual}! I'm a {major} student at {school} interested in {company}. Would love to hear about your experience there.
Before inserting notes, you MAY pipe them through a second model (Gemini, another Claude instance, etc.) for tone review. Useful when the user says "make sure these don't sound like AI." Prompt template:
"Review these LinkedIn connection notes for a {year} student. Check for: casual genuine tone, not pushy/fake, no AI jargon, sounds human. Brief feedback only."
The skill supports multiple backends, chosen in config. All backends must support this minimum schema:
| Field | Type | Purpose |
|---|---|---|
name | string (required) | Prospect full name |
company | string | Current employer |
position | string | Current title |
profile_url | string | LinkedIn URL |
location | string | City / region |
connection_status | enum | To Review / Pending / Sent / Connected / New Message |
connection_degree | int | 1, 2, or 3 |
is_alumni | bool | School match with user |
profile_hook | string | Specific hook used in notes |
connection_notes | jsonb (array of strings) | 5 note variations |
target_roles | text[] | Role tags |
follow_up_date | date (YYYY-MM-DD) | Next touchpoint |
follow_up_count | int | Touchpoints sent so far |
rating | decimal (0-10, 0.5 step) | User-set priority |
tags | text[] | Custom tags |
archived | bool | Soft-delete flag |
source | string | manual / extension_save / agent / etc. |
user_id | uuid | Required (RLS). FK to auth.users.id. |
created_at | timestamptz | auto |
updated_at | timestamptz | auto |
Project: <your-tracker-project-id> · Table: public.prospects · RLS: enabled
Prefer the Supabase MCP (plugin:supabase:supabase) for all reads and writes — it uses the authenticated session, so auth.uid() resolves correctly for RLS. Do NOT use the REST API with a hard-coded anon key; that bypasses RLS policy enforcement.
Insert flow:
user_id once per session — query public.user_profiles WHERE email = '<user's email>' and cache the UUID.user_id populated. connection_notes must be a JSON array (not a bare string).INSERT INTO public.prospects (...) VALUES (...) RETURNING id; via supabase.execute_sql.SELECT id, name, connection_status FROM prospects WHERE id = '<returned_id>'; — confirm the row is there.UPDATE prospects SET connection_status = ..., updated_at = now() WHERE id = ... AND user_id = ...;Store at the path in config (default ~/.linkedin-automation.db). Use sqlite3 CLI. Generate schema on first use if missing.
Use gspread via Python, or the user's configured Sheets MCP if available. The Sheet must have tabs: Prospects, Job Listings.
Append to {config.tracker.path} — one Markdown table per Sheet. Useful for single-user setups who don't want a database.
If the user has an internship tracker configured, cross-reference fresh postings against the prospect list. When a fresh posting matches a target company:
target_app_date: "OPEN NOW".| Metric | Target |
|---|---|
| Prospects found / session | 15-20 |
| Acceptance rate | 10-20% |
| Response rate | 5-10% |
| Calls scheduled / week | 2-3 |
If acceptance drops below 10%, re-read references/connection-note-strategies.md — the notes are probably too templated.
Posts with role keywords.Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub tylervovan/linkedin-tracker-plugin --plugin linkedin-tracker-plugin