mcpField
J
job-auto-apply

job-auto-apply

github.com/liruihan000生产力565 次安装29 周前更新
代码仓库

关于 job-auto-apply

job-auto-apply 是用于管理求职搜索、申请材料准备和提交流程的 Claude 技能。它将职位筛选与调研、定制简历、申请跟踪以及可配置的人工审核或自主提交结合起来。

主要功能

  1. 01搜索职位并筛选资格
  2. 02记录公司与职位调研
  3. 03生成定制简历和求职信
  4. 04检查 ATS 与文档格式
  5. 05跟踪申请及提交状态
  6. 06支持人工审核或自主模式

适用场景

  1. 01按每日目标寻找并筛选职位
  2. 02准备针对职位的申请材料
  3. 03在浏览器提交前审核申请
  4. 04跟踪已提交和待处理申请

MCP 相关

该技能可使用 Playwright MCP 搜索职位并通过浏览器执行申请步骤。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/liruihan000/claude-job-auto-apply --skill job-auto-apply

安装后在 Claude Code 中输入/job-auto-apply确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.gitignore
SETUP.md
config.example.json
package.json
package-lock.json
ats-handlers/
generic.md
jobvite.md
indeed.md
lever.md
ashby.md
greenhouse.md
sap.md
oracle.md
taleo.md
workday.md
evals/
test-bootstrap.sh
test-config-change.md
test-tailoring.md
references/
filing-guide.md
cover-letter-guide.md
resume-format-spec.md
user-profile.example.md
selection-strategy.md
template-guide.md
tailoring-guide.md
search-guide.md
scripts/
ats_score.js
create_cover_letter.js
bootstrap.js

详细介绍

自动申请职位

配置:启动时,运行 node ${CLAUDE_SKILL_DIR}/scripts/bootstrap.js 以加载所有运行时参数。 以下所有以 config.* 为前缀的值均来自 config.json。 如果 bootstrap.js 返回 ready: false,请读取 ${CLAUDE_SKILL_DIR}/SETUP.md 并引导用户完成设置。 每个 Playwright 实例可用的工具:browser_snapshot、browser_navigate、browser_click、browser_type、browser_fill_form、browser_select_option、browser_file_upload、browser_press_key、browser_evaluate、browser_take_screenshot、browser_wait_for、browser_tabs、browser_hover


阶段 -1:启动时自动检查(必须执行)

每次调用此技能时:

  1. 检查用户意图:
    • 如果用户询问职位相关问题,或表示要“讨论”/“分析”/“审查”/“看看”某个职位 → 进入讨论模式(见下文)。
    • 如果用户针对特定职位 URL 或职位表示“申请”/“提交”/“投” → 进入单次申请模式:针对该职位执行阶段 1 的调研步骤(获取职位描述、提取关键词、调研公司、创建文件夹),然后直接进入该职位的阶段 2 → 阶段 2.5 → 阶段 3。
    • 否则 → 继续自动申请流程。
  2. 运行 node ${CLAUDE_SKILL_DIR}/scripts/bootstrap.js → 加载配置并检查准备状态
    • 如果 ready: false → 读取 ${CLAUDE_SKILL_DIR}/SETUP.md,并引导用户补齐缺失项。不要进入任何阶段。不要尝试变通方案或使用替代工具。
    • bootstrap.js 会自动创建目录和 TRACKER.md
  3. 读取 applications/TRACKER.md
  4. 统计「已提交」列中日期为今天的条目数 → today_submitted
  5. 列出材料已准备好的 ⬜ 未提交条目
  6. 报告:“今天:已提交 X/{config.daily_target},待处理 Y”
  7. 如果 today_submitted >= config.daily_target → 报告已完成并停止
  8. 否则 → 立即进入自动申请工作流

自主性:如果 config.automation.manual_review: false → 完全自主执行,绝不询问用户,也绝不中途停止循环。如果为 true → 每个阶段之间暂停,等待用户审核后再继续。


讨论模式

当用户想讨论某个职位,而不是自动申请时:

  1. 读取职位信息(通过 WebFetch、Playwright 或用户提供的文本)
  2. 分析:职位要求、技术栈、团队、公司信息
  3. 对照用户在 uploaded-resumes/ 中的简历和 user-profile.md
  4. 与用户讨论:匹配度评估、优缺点、简历策略、需要询问的问题
  5. **不要进入自动申请工作流。**继续对话,直到用户表示要申请或结束讨论。
  6. 如果用户表示“申请”或“提交” → 将该职位添加到 TRACKER.md,并仅针对该职位继续执行阶段 2。

自动申请工作流

阶段 1:搜索 + 调研

持续查找职位,直到 pending + today_submitted >= config.daily_target。

按照 ${CLAUDE_SKILL_DIR}/references/search-guide.md 中的说明,并行搜索 config.search.platforms。 搜索可使用 Playwright MCP、WebSearch 或 WebFetch 来发现职位。 按照 ${CLAUDE_SKILL_DIR}/references/selection-strategy.md 进行筛选。去重。

对每个候选职位,必须完成所有步骤后才能继续处理下一个职位:

  1. 获取完整的职位描述文本(此时不要添加到 TRACKER)

  2. 应用 ${CLAUDE_SKILL_DIR}/references/selection-strategy.md 中的所有筛选条件——尤其要检查担保和公民身份要求。如果职位未通过任何一项筛选 → 完全跳过,不创建文件夹,也不添加到 TRACKER

  3. 只有职位通过所有筛选后,才完成以下所有事项,然后再继续处理下一个职位: a. 在 TRACKER.md 中添加一行,状态为 ⬜ NOT SUBMITTED b. 创建文件夹 applications/YYYY-MM-DD_Company_Role/ c. 将完整的职位描述文本保存到 {APP_FOLDER}/jd.md d. 提取职位描述中的关键词 → {APP_FOLDER}/jd-keywords.json(格式:{"required_skills":[], "preferred_skills":[], "keywords":[]}) e. 查找并阅读公司的 About/Mission 页面;将摘要保存到 {APP_FOLDER}/notes.md(包括:行业、产品、规模、阶段、文化、职位描述 URL) f. 将 {APP_FOLDER}/STATUS.md 写为 ⬜ NOT SUBMITTED

    只有在 6 项文件均已存在时,职位才算在阶段 1 中“完成”:TRACKER 行 + 文件夹 + jd.md + jd-keywords.json + notes.md + STATUS.md。部分完成 = 未完成。

审核检查点(若 config.automation.manual_review: true): 向用户展示找到的职位列表(公司、职位、平台、URL)。等待用户确认要继续处理哪些职位。从 TRACKER.md 和相应文件夹中移除任何被拒绝的职位。

阶段 1.5:人脉扫描(可选——需要在 Playwright 配置文件中登录 LinkedIn)

针对 TRACKER.md 中状态为 ⬜ 的每家公司:

  1. 前往 LinkedIn:linkedin.com/search/results/people/?keywords={COMPANY}&network=%5B%22F%22%5D(筛选一级人脉)
  2. 如果在该公司找到人脉 → 在 TRACKER.md 中该职位的 Notes 列添加对方姓名和职位(例如:“🤝 John Doe - SWE @ Company”)
  3. 将有人脉的职位提高优先级

如果未登录 LinkedIn 或访问被拦截,则跳过此阶段。每家公司处理时间不得超过 30 秒。

阶段 2:准备(仅简历 + 求职信)

针对 STATUS.md 中包含 ⬜ NOT SUBMITTED 且文件夹中包含 jd.md 的每个职位。所有调研均已完成——仅阅读本地文件,无需发送网络请求。

  1. 阅读 {APP_FOLDER}/jd.md — 完整的职位描述文本
  2. 阅读 {APP_FOLDER}/jd-keywords.json — 提取的关键词
  3. 阅读 {APP_FOLDER}/notes.md — 公司信息
  4. 按照 ${CLAUDE_SKILL_DIR}/references/template-guide.md 从 uploaded-resumes/ 中选择模板
  5. 阅读 user-profile.md 获取个人信息(联系方式、工作授权、EEO)
  6. 按照 ${CLAUDE_SKILL_DIR}/references/tailoring-guide.md 定制简历
  7. 按照 ${CLAUDE_SKILL_DIR}/references/cover-letter-guide.md 生成求职信(如果 config.prepare.cover_letter_required)
  8. 生成 DOCX + PDF
  9. 将 STATUS.md 写为 📁 PREPARED — NOT SUBMITTED

可通过子 Agent 并行处理(无需浏览器)。使用下方的准备子 Agent 提示词模板。

所有准备子 Agent 完成后——同步 TRACKER.md: 扫描所有 applications/*/STATUS.md。对于状态为 📁 PREPARED 或 ✅ SUBMITTED 的每个文件夹,确保对应的 TRACKER.md 行反映了该状态。

第 2.5 阶段:自动审核(强制 — 始终运行)

准备好所有材料后,主 Agent 会审核每份申请。运行以下检查:

  1. 内容:应用 ${CLAUDE_SKILL_DIR}/references/tailoring-guide.md 中的相同规则,确认内容符合要求。
  2. 格式:阅读生成的 PDF 并检查渲染问题 — 多余的 Markdown 字符(*、**、#)、格式错误、乱码、缺失章节。
  3. 页面适配:确认正好 1 页 — 不溢出,也不要太短。
  4. AI 写作检测 + ATS 关键词评分:运行 node ${CLAUDE_SKILL_DIR}/scripts/ats_score.js {APP_FOLDER}/resume.md {APP_FOLDER}/jd-keywords.json。(jd-keywords.json 已在第 1 阶段创建 — 不要重新生成。)检查结果:
    • ats_score < 60 → 在简历中自然地补充缺失的关键词,然后重新生成
    • ai_phrases_found → 将标记的短语替换为建议的替代表达
    • ai_patterns_found → 重写受影响的句子
  5. ATS 解析检查:运行 node ${CLAUDE_SKILL_DIR}/scripts/ats_parse_check.js {APP_FOLDER}/resume.pdf。检查结果:
    • status: FAIL → 修复错误(缺失章节、格式错误),然后重新生成
    • status: WARN → 查看警告,尽可能修复

自动修复发现的问题;如有更改,重新生成 DOCX + PDF。

审核检查点(如果 config.automation.manual_review: true): 自动审核后,向用户展示每份已准备申请的摘要,以及发现或修复的问题。等待用户确认要提交哪些申请。将被拒绝的申请标记为 TRACKER.md 中的 ❌ SKIPPED。

第 3 阶段:提交

根据 config.automation.manual_review 分为两种模式:

人工审核模式(manual_review: true)— 并行子 Agent,由用户手动提交

子 Agent 仍会在 N 个 Playwright 实例中并行运行。每个子 Agent 的任务在审核页面结束 — 用户在浏览器中手动提交。

子 Agent 行为(manual_review: true):

1. Navigate to job URL (opens a new tab in the assigned Playwright browser instance)
2. Fill all forms and upload tailored resume as normal
3. Navigate to the final review/confirmation page — do NOT click Submit
4. Take screenshot → {APP_FOLDER}/review-screenshot.png
5. Return "REVIEW_READY: {COMPANY} — {ROLE} | screenshot: {APP_FOLDER}/review-screenshot.png"
   (Task is complete — browser tab stays open at the review page)

主 Agent 行为(manual_review: true):

active_subagents = 0
WHILE today_submitted < config.daily_target OR active_subagents > 0:
    // Dispatch up to N subagents (N = config.submit.parallel_instances)
    WHILE active_subagents < N AND more jobs with 📁 PREPARED:
        Launch next subagent (run_in_background: true, mode=REVIEW_ONLY)
        active_subagents++

    // Handle incoming results (non-blocking — process as they arrive)
    When a subagent returns REVIEW_READY:
        active_subagents--
        Show user: "✋ {COMPANY} — {ROLE} ready. Screenshot: {APP_FOLDER}/review-screenshot.png
                    Submit in browser → reply 'submitted {COMPANY}' | 'skip {COMPANY}' | 'stop'"

    When user replies:
        "submitted {COMPANY}" → update TRACKER.md ✅, today_submitted++
        "skip {COMPANY}"      → update TRACKER.md ❌ SKIPPED
        "stop"                → drain active subagents then exit loop
END WHILE
自主模式(manual_review: false)— 并行子 Agent
WHILE today_submitted < config.daily_target:
    1. Pick up to N jobs whose STATUS.md contains `📁 PREPARED` (N = config.submit.parallel_instances)
    2. Launch N subagents (run_in_background: true), each assigned a unique Playwright prefix
    3. Wait for ALL subagents in this batch to complete
    4. For EACH completed subagent — immediately update TRACKER.md:
       SUCCESS → change Status to ✅ SUBMITTED, fill Submitted date column, today_submitted++
       FAILED  → change Status to ❌ SKIPPED, add reason to Notes column
       Do NOT batch these updates — update one row at a time as each result comes in.
    5. After updating TRACKER.md, verify the row was written correctly by re-reading it.
    6. If more pending → repeat. If none → back to Phase 1.
END WHILE

TRACKER.md 更新规则:TRACKER.md 由主 Agent 负责。每次结果出现后立即更新 — 不要批量更新或跳过。

第 4 阶段:回顾(达到每日目标或会话结束后)

检查子 Agent 的返回消息中是否有 FRICTION: 行:

  1. 新的 ATS + 摩擦问题 → 使用变通方法创建 ${CLAUDE_SKILL_DIR}/ats-handlers/{platform}.md
  2. 已知 ATS + 摩擦问题 → 将修复方法作为一个项目追加到现有处理文档中
  3. 没有摩擦问题行 → 跳过,无需更新

准备子 Agent 提示词模板

替换 {variables},传递给 Agent 工具:

Prepare application materials for {COMPANY} — {ROLE}.

**Application folder**: {APP_FOLDER}

Start from the research already saved in {APP_FOLDER}. You may do additional web research if needed (e.g. deeper company info, product details for cover letter).

**Input files (already exist in {APP_FOLDER}):**
- `jd.md` — full job description text
- `jd-keywords.json` — extracted JD keywords
- `notes.md` — company info (industry, product, size, culture)

**Steps:**
1. Read `{APP_FOLDER}/jd.md`, `{APP_FOLDER}/jd-keywords.json`, `{APP_FOLDER}/notes.md`
   **JD completeness check**: If `jd.md` is missing, empty, or clearly truncated (< 300 words, no responsibilities/requirements section), re-fetch the full JD from the URL in `notes.md` and overwrite `jd.md` and `jd-keywords.json`.
2. Select the best matching template from `uploaded-resumes/` per `${CLAUDE_SKILL_DIR}/references/template-guide.md` — read its full content for experience/skills
3. Read `user-profile.md` for personal info (contact, work auth, EEO)
4. Tailor resume per `${CLAUDE_SKILL_DIR}/references/tailoring-guide.md`
   **Format**: follow `${CLAUDE_SKILL_DIR}/references/resume-format-spec.md` exactly. `create_resume.js` enforces this automatically.
5. Write `resume-config.json` (structured data for DOCX generation)
6. Generate DOCX: `node ${CLAUDE_SKILL_DIR}/scripts/create_resume.js {APP_FOLDER}/resume-config.json {APP_FOLDER}/resume.docx`
7. Generate PDF: `libreoffice --headless --convert-to pdf --outdir {APP_FOLDER} {APP_FOLDER}/resume.docx`
8. **Page check**: Read the generated PDF and verify exactly 1 page. If not, reduce bullets per role (min 1) and regenerate. Repeat until exactly 1 full page.
9. If `config.prepare.cover_letter_required`: write `cover-letter-config.json`, generate cover_letter.docx + PDF — reference specific company details from notes.md
10. Write `STATUS.md` as `📁 PREPARED — NOT SUBMITTED`
11. Do NOT submit anything — only prepare materials
12. Do NOT fabricate experience — only use info from the resume template
13. Return "PREPARED: {COMPANY} — {ROLE}" when done

提交子 Agent 提示词模板

替换 {variables},传递给 Agent 工具:

Submit application to {COMPANY} — {ROLE}.

**Mode:** {SUBMIT_MODE}  (either "AUTO_SUBMIT" or "REVIEW_ONLY")

**Goal:**
- AUTO_SUBMIT: Fill all forms, upload resume, and click Submit.
- REVIEW_ONLY: Fill all forms, upload resume, navigate to review/confirmation page — do NOT click Submit. Take screenshot and return "REVIEW_READY".

**Tools:** ONLY use `{PLAYWRIGHT_PREFIX}*` tools. Never use other playwright instances.

**Data sources:**
- `user-profile.md` — personal info, contact, work auth, EEO defaults
- `secrets.md` — credentials for login/registration
- Resume: {RESUME_PATH}
- Cover letter: {COVER_LETTER_PATH} (if exists)
- Additional documents: {ADDITIONAL_DOCS}
- ATS strategies: `${CLAUDE_SKILL_DIR}/ats-handlers/` (read matching platform file if recognized)

**Approach:** Observe the page at each step, decide what to do next. Every ATS is different — adapt to what you see rather than following a fixed sequence. General flow: navigate → find apply button → fill forms → upload files → review → submit. But let the page guide you.

**Constraints:**
- Auto-agree all terms/cookies/eSignatures (if config.automation.auto_agree_terms)
- Auto-register accounts if needed (if config.automation.auto_register_accounts)
- Fill ALL required fields — never leave a field empty or on "Select..."
- **Resume upload**: ALWAYS upload {RESUME_PATH} — never use a previously saved resume from the ATS profile, even if one is already shown. Actively replace it.
- Screening questions: authorized=Yes, sponsorship=Yes (+explanation), 18+=Yes, background=Yes, previously worked=No. Check for follow-up fields after each answer.
- Experience/Education dates must match the tailored resume exactly — never guess
- Before submitting: verify all required fields are filled
- Screenshot before submit → {APP_FOLDER}/review-screenshot.png (if config.submit.screenshot_review)
- Screenshot after submit → {APP_FOLDER}/confirmation-screenshot.png (if config.submit.screenshot_confirmation)
- If stuck on any interaction for >config.submit.max_retries_per_form retries, skip and report why

**Output:**
- AUTO_SUBMIT: Write {APP_FOLDER}/STATUS.md as ✅ SUBMITTED. Return "SUCCESS" or "FAILED: [reason]"
- REVIEW_ONLY: Take screenshot → {APP_FOLDER}/review-screenshot.png. Do NOT write STATUS.md. Return "REVIEW_READY: {COMPANY} — {ROLE}"
- If friction encountered, append: "FRICTION: [what happened] → [what worked]"

参考资料

  • 求职搜索:${CLAUDE_SKILL_DIR}/references/search-guide.md — 平台方法、去重
  • 职位选择:${CLAUDE_SKILL_DIR}/references/selection-strategy.md — 筛选条件、优先级排序
  • 简历定制:${CLAUDE_SKILL_DIR}/references/tailoring-guide.md — 8 步检查清单
  • 简历格式:${CLAUDE_SKILL_DIR}/references/resume-format-spec.md — Times New Roman、黑色标题、2 行公司格式、项目符号技能
  • 求职信:${CLAUDE_SKILL_DIR}/references/cover-letter-guide.md — 结构、规则
  • 模板选择:${CLAUDE_SKILL_DIR}/references/template-guide.md — 不同 JD 应选用哪个模板
  • 归档与跟踪:${CLAUDE_SKILL_DIR}/references/filing-guide.md — 文件夹结构、TRACKER 格式
  • 用户档案:user-profile.md — 个人信息、联系方式、工作授权、EEO
  • 凭据:secrets.md — ATS 登录、注册、Google Sign-In

关键规则

  • 浏览器工具规则:
    • 搜索职位:WebSearch、WebFetch 和 Playwright 均可使用。
    • 所有与网页交互的操作(填写表单、点击、上传、提交、登录、注册):只能使用 Playwright MCP(mcp__playwright*)。 切勿使用 BrowserMCP、Claude-in-Chrome 或其他浏览器工具。
    • 如果 Playwright 不可用,停止并运行 SETUP——不要尝试使用其他浏览器工具。
  • 为每份简历量身定制。 切勿直接提交模板。
  • 切勿捏造经历——只能使用 uploaded-resumes/ 中简历模板里的信息。
  • 提交前验证——点击提交前,使用 JS 检查所有必填字段。
  • 发生错误时:最多重试 config.submit.max_retries_per_form 次,然后跳过并记录原因。
  • 每日目标达成前绝不停止。
  • 使用与用户相同的语言(参见 config.preferences.response_language)。
  • 自动更新:用户要求添加新的搜索平台、ATS 处理程序或更改配置时,立即更新相应文件(config.json、${CLAUDE_SKILL_DIR}/references/search-guide.md、${CLAUDE_SKILL_DIR}/ats-handlers/*.md)——不要让用户手动编辑。

评论

支持 Markdown