Skip to content
Back to skills

Linkedin Apply

BSecurity

Scrape a LinkedIn job offer and score it against your profile using Claude LLM — produces APPLY / REVIEW / SKIP decision with 4-dimension scores. Triggers: "linkedin apply" | "analyze job" | "job match" | "linkedin-apply" | "score this job" | "should i apply for this job" | "evaluate this job posting" | "is this job a good fit" | "check this job offer" | "rate this job".

  • 9 stars
  • 0 votes
  • 2 copies
  • 3 views
  • Added September 23, 2026
ai-agentspythongobashapi

Works with

  • api

Security analysis

B85/100
  • highPerforms destructive filesystem operations
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 23, 2026

npx -y skills add Roxabi/roxabi-plugins --skill linkedin-apply --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Linkedin Apply?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Linkedin Apply
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/roxabi-linkedin-apply/badge)](https://www.skillsdirectory.com/skills/roxabi-linkedin-apply)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: linkedin-apply
description: 'Scrape a LinkedIn job offer and score it against your profile using Claude LLM — produces APPLY / REVIEW / SKIP decision with 4-dimension scores. Triggers: "linkedin apply" | "analyze job" | "job match" | "linkedin-apply" | "score this job" | "should i apply for this job" | "evaluate this job posting" | "is this job a good fit" | "check this job offer" | "rate this job".'
version: 0.1.0
allowed-tools: Read, Write, Bash, Glob
---

# LinkedIn Apply Skill

Analyze a LinkedIn job offer against your candidate profile and get an LLM-powered decision: **APPLY**, **REVIEW**, or **SKIP**.

Let:
  VL := ~/.roxabi-vault/linkedin-apply/
  SD := `$CLAUDE_PLUGIN_ROOT/scripts/`

## Phase 1 — Validate Arguments and Prerequisites

Extract LinkedIn URL from $ARGUMENTS. ¬URL → "Usage: /linkedin-apply <linkedin-job-url>" → stop.

URL valid ⟺ contains `linkedin.com` ∧ (`/jobs/view/` ∨ `/jobs/`).

Check prerequisites:
1. `VL/candidate.yaml` exists — ¬exists → run `/linkedin-apply-init` first
2. `python3 -c "import playwright, playwright_stealth, jinja2" 2>&1` — missing → `pip install playwright playwright-stealth jinja2 pyyaml`
3. Playwright Chromium installed — missing → `playwright install chromium`

## Phase 2 — Scrape the Job

```bash
cd <scripts_dir> && python3 scraper.py "<url>"
```

Capture stdout (JSON) + stderr (logs). Errors: `SessionExpiredError` → run `/linkedin-apply-init`; `PlaywrightNotAvailableError` → install playwright; `JobNotFoundError` → job no longer available; other → show message. Parse JSON output → job data dict.

## Phase 3 — Load Candidate and Criteria

```bash
cat ~/.roxabi-vault/linkedin-apply/candidate.yaml
```

Criteria (user override ≻ plugin default): `VL/criteria.yaml` if ∃, else `<plugin_dir>/config/criteria.yaml`.

## Phase 4 — Run LLM Matching

CV path: `~/.roxabi-vault/cv/cv_data.json` if ∃, else construct minimal JSON from `candidate.yaml`.

```bash
# Tempfile per ${CLAUDE_PLUGIN_ROOT}/../shared/references/tempfile-convention.md
[[ "$JOB_ID" =~ ^[A-Za-z0-9_-]+$ ]] || { echo "Invalid job id: $JOB_ID" >&2; exit 1; }
TMPDIR=$(mktemp -d -t "linkedin-apply-job-${JOB_ID}-XXXXXX")
trap 'rm -rf "$TMPDIR"' EXIT
JOB_JSON="$TMPDIR/job.json"
echo '<job_json>' > "$JOB_JSON"
cd <scripts_dir> && python3 matcher.py \
  --job-json "$JOB_JSON" \
  --cv-json <cv_data_path> \
  --criteria-yaml <criteria_path> \
  --output json
```

## Phase 5 — Save Results

```bash
cd <scripts_dir> && python3 -c "
import json, sys
from storage import save_analysis
# reconstruct dataclasses and call save_analysis(job, match)
"
```

## Phase 6 — Display Results

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  DECISION: APPLY  |  Score: 7.8/10
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Job:     <title> at <company>
  URL:     <url>
  Type:    <Easy Apply / External (ATS: greenhouse)>

  Scores:
    Tech:             8/10
    Seniority:        7/10
    Culture:          8/10
    Responsibilities: 8/10

  Dealbreakers: PASS

  Highlights:
  + <highlight 1>
  + <highlight 2>

  Prepare for:
  ? <expected question 1>
  ? <expected question 2>

  Summary: <analysis_summary>

  Saved to: ~/.roxabi-vault/linkedin-apply/applications/<path>
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

SKIP → show dealbreaker issues clearly. REVIEW → highlight what's uncertain/missing.

## Notes

- Scraper uses visible browser (¬headless) for anti-bot reliability
- Browser profile `~/.config/linkedin_browser_profile` persists session between runs
- Results stored in `VL/applications/YYYY-MM/`
- Phase 1 only: scraping + matching + display. Auto-application (Easy Apply form filling) is Phase 2.

$ARGUMENTS

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.