mcpField
A
apply

apply

github.com/proficientlyjobs生产力443106 次安装33 周前更新
代码仓库

关于 apply

apply 是用于 Greenhouse、Lever 和 Workday 求职申请表单的浏览器自动化技能,面向需要整理并填写申请材料的求职者。它先汇总字段答案供确认,再填写表单,并要求提交前获得明确确认。

主要功能

  1. 01支持 Greenhouse、Lever 和 Workday
  2. 02按职位整理简历与申请资料
  3. 03扫描字段并提出答案供审核
  4. 04经确认后填写多步骤表单
  5. 05提交前要求明确确认

适用场景

  1. 01为特定职位准备并填写申请
  2. 02复用个人资料处理多份申请
  3. 03检查表单要求并准备定制简历

安装

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

$npx skills add https://github.com/proficientlyjobs/proficiently-claude-skills --skill apply

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

附带文件scripts/fill-page.md

详细介绍

申请职位

优先级层级:如需解决冲突,请参阅 shared/references/priority-hierarchy.md。

使用浏览器自动化在 Greenhouse、Lever 和 Workday 上填写职位申请表。

快速开始

  • /proficiently:apply - 开始流程(系统会询问职位 URL,或使用最近的职位)
  • /proficiently:apply https://... - 申请特定职位
  • /proficiently:apply last - 使用最近的职位文件夹进行申请
  • /proficiently:apply current - 填写当前活动浏览器标签页中已打开的申请表

文件结构

scripts/
  fill-page.md              # Form-filling subagent prompt

数据目录

按照 shared/references/data-directory.md 确定数据目录。


工作流

步骤 0:检查前置条件

确定数据目录,然后按照 shared/references/prerequisites.md 检查前置条件。必须提供简历文件。如果 DATA_DIR/application-data.md 存在,则加载该文件(如果不存在,将在步骤 2 创建)。

步骤 1:确定目标职位

解析 $ARGUMENTS:

如果是 URL:

  • 检查 DATA_DIR/jobs/ 中是否存在匹配的职位文件夹(按文件夹名称中的公司 slug 或 URL 匹配)。如果找到,则从该文件夹加载 posting.md、resume.md 和 cover-letter.md。
  • 如果没有匹配项,则按照 shared/references/browser-setup.md 设置浏览器,获取职位信息,并将其保存到 DATA_DIR/jobs/[company-slug]-[date]/posting.md 的新文件夹中。

如果是 "last" 或为空:

  • 查找 DATA_DIR/jobs/ 中最近修改的职位文件夹
  • 加载其中的 posting.md、resume.md 和 cover-letter.md
  • 向用户确认申请的是哪个职位

如果是 "current":

  • 跳过导航 — 直接使用当前浏览器标签页
  • 将标签页 URL 与已保存的职位文件夹进行匹配,以便在可能时加载相关信息

报告已加载的内容:

Applying to [Role] at [Company].
步骤 2:创建或加载申请资料

如果 DATA_DIR/application-data.md 存在,则读取并加载其中的值。

如果不存在:

  1. 从简历中提取可用信息:姓名、电子邮件、电话号码、LinkedIn、所在地
  2. 向用户展示提取的信息。请用户确认并补充缺失信息:工作授权、签证担保、EEO 偏好(所有 EEO 项默认选择“拒绝自我认定”)
  3. 按照以下格式保存到 DATA_DIR/application-data.md:
# Application Data

## Personal Information
- First Name: ...
- Last Name: ...
- Email: ...
- Phone: ...
- City: ...
- Country: United States

## Online Profiles
- LinkedIn: ...
- GitHub: ...
- Portfolio: ...

## Standard Answers
- How did you hear about us: Job Board
- Previously worked at this company: No
- Authorized to work in the US: Yes
- Requires visa sponsorship: No

## EEO / Voluntary Disclosures
- Gender: Decline to self-identify
- Race/Ethnicity: Decline to self-identify
- Veteran status: I am not a veteran
- Disability: I don't wish to answer
步骤 3:前往申请表并检查要求

按照 shared/references/browser-setup.md 设置浏览器(tabs_context → tabs_create → navigate)。

如果 $ARGUMENTS 是 "current":跳过导航。调用 tabs_context_mcp 获取活动标签页。

否则,根据 URL 模式检测 ATS 类型(参见 shared/references/ats-patterns.md),并按相应方式导航:

Lever(jobs.lever.co/...):

  • 前往职位发布页面的 URL 并在末尾添加 /apply,或前往职位发布页面并点击“APPLY FOR THIS JOB”

Greenhouse(boards.greenhouse.io/... 或包含 grnhse_iframe 的页面):

  • 前往职位发布页面
  • 使用 javascript_tool 提取 iframe 令牌:
    const iframe = document.getElementById('grnhse_iframe');
    const url = new URL(iframe.src);
    JSON.stringify({
      boardToken: url.searchParams.get('for'),
      jobToken: url.searchParams.get('token')
    });
    
  • 前往直接表单 URL:https://job-boards.greenhouse.io/embed/job_app?for={boardToken}&token={jobToken}

Workday(*.myworkdayjobs.com/...):

  • 前往职位发布页面。点击“Apply Now”。
  • 如果出现包含 Autofill/Manual 选项的着陆页,点击“Apply Manually”。
  • 如果出现身份验证页面,请告知用户登录,并在准备好后回复“continue”。创建账户属于禁止操作 — 用户必须自行处理身份验证。

未知 ATS:

  • 前往该 URL 并截取屏幕截图
  • 尝试识别表单。如果无法识别,请告知用户并询问如何处理。

检查表单。 进入申请表后,快速浏览表单(read_page(filter="interactive");Workday 表单则滚动查看),确定:

  • 表单是否包含简历/CV 上传字段?
  • 表单是否包含求职信上传字段或文本字段?
  • 是否有需要特别注意的特殊必填字段?

记录这些要求 — 它们决定步骤 4 中需要准备哪些材料。

步骤 4:生成缺少的材料

目标是在开始填写前准备好所有材料,让用户尽量少做工作。

始终针对职位定制简历。 检查此职位是否存在 DATA_DIR/jobs/[job-folder]/resume.md:

  • 如果存在:简历已针对该职位定制。跳过。
  • 如果不存在:直接运行 tailor-resume 技能。按照 skills/tailor-resume/SKILL.md 中的工作流程,使用职位发布信息(已加载)、原始简历和工作经历档案生成定制简历。保存到职位文件夹中。继续之前,将简历交给用户快速审核。

仅在表单要求时生成求职信。 如果第 3 步的侦察发现有求职信字段:

  • 检查是否存在 DATA_DIR/jobs/[job-folder]/cover-letter.md
  • 如果存在:已完成。跳过。
  • 如果不存在:直接运行 cover-letter 技能。按照 skills/cover-letter/SKILL.md 中的工作流程,使用职位发布信息、定制后的简历和档案。保存到职位文件夹中。交给用户快速审核。

如果表单没有求职信字段,则完全跳过求职信生成。

告知用户生成了哪些内容:

Prepared for [Role] at [Company]:
- Tailored resume: [generated / already existed]
- Cover letter: [generated / already existed / not required by form]

Ready to fill the application. Proceeding...
步骤 5:扫描所有字段

填写任何内容之前,扫描整个表单,找出所有字段。此步骤中不要填写字段,只读取。

对于 Lever/Greenhouse(单页表单):

  • 调用 read_page(tabId, filter="interactive") 一次获取所有字段

对于 Workday(多步骤向导):

  • 从上到下滚动扫描当前页面,并在每个视口位置调用 read_page
  • 收集所有字段标签、类型及其是否为必填项
  • 注意:到达每个向导页面时再扫描该页面(参见步骤 7)

对于找到的每个字段,记录:

  • 字段标签
  • 字段类型(文本、下拉菜单、单选框、复选框、文件上传)
  • 是否为必填项
  • 供后续填写时使用的元素引用
步骤 6:提出答案并征求批准

按照以下优先级为每个字段生成建议答案:

  1. 申请数据 — 根据下方的字段匹配参考,从 application-data.md 中匹配
  2. 合理的默认值 — 对于申请数据中未包含的常见字段:
    • 法定名/姓 → 与名/姓相同
    • 电子签名 → 全名
    • 仲裁/条款协议 → 接受(告知用户)
    • 面试流程确认 → 接受
    • AI 转录同意 → 接受
    • 合同/临时工作相关问题 → “否”(除非申请数据另有说明)
  3. 自定义答案 — 检查 application-data.md 的“自定义答案”部分,查看之前缓存的答案
  4. 最佳推测 — 对于其余字段,根据字段标签和职位背景生成合理答案
  5. 无法确定 — 仅在确实含糊且没有合理默认值时使用

向用户提供一份汇总:

Here's my plan for the [Company] application:

**Auto-fill from your data:**
- First Name: Jane
- Last Name: Doe
- Email: [email protected]
- Phone: 555-0123
- LinkedIn: https://linkedin.com/in/janedoe
...

**Proposed answers (please review):**
- Legal First Name: Jane (same as first name)
- Electronic signature: Jane Doe
- Arbitration agreement: Accept
- Contract work: No
- [Any other non-obvious fields]: [proposed answer]

**Needs your input:**
- [Only truly ambiguous fields, if any]

**Manual upload needed:**
- Resume: [file path]
- Cover letter: [file path] (if applicable)

Approve and I'll fill everything in. Or tell me what to change.

核心原则:只询问一次,只填写一次。 不要针对每个字段分别提问。唯一需要用户参与的环节应是这次审批(以及步骤 8 中最终提交前的确认)。

用户批准(并提出任何修改)后,将新增答案缓存到 DATA_DIR/application-data.md 的“自定义答案”部分,以便在今后的申请中重复使用。

步骤 7:填写表单

获得批准后,一次性填写所有内容。

委派给子 Agent。 调用 scripts/fill-page.md,并提供:

  • ATS 类型(lever/greenhouse/workday/unknown)
  • 已批准的字段→值映射(所有答案,不只是申请资料)
  • 标签页 ID
  • 简历和求职信的文件路径

子 Agent 会填写当前页面的所有字段,然后返回已填写和剩余的内容。

对于多页表单(Workday):

  1. 填写当前页面 → 点击“Save and Continue”
  2. 如果出现验证错误:读取错误信息,修正字段,然后重试
  3. 在新页面上:扫描字段(步骤 5 的逻辑),与已批准的答案匹配,填写并继续
  4. 重复以上步骤,直到到达审核页面

文件上传处理: MCP 工具只能通过 upload_image 上传图片。对于 PDF/DOCX 格式的简历和求职信,请告知用户文件路径,并让用户手动上传。这是已知限制——在步骤 6 的摘要中附上路径,以便用户审核时上传。

步骤 8:提交前审核

到达审核/确认页面,或填写完单页表单的所有字段后:

  1. 截取屏幕截图
  2. 确认所有内容看起来正确
  3. 在提交前向用户明确征求确认——根据浏览器自动化规则,这是必须获得明确许可的操作

用户确认之前,切勿点击 Submit/Send。

步骤 9:记录申请

提交后(或用户决定不提交时):

创建 DATA_DIR/jobs/[company-slug]-[date]/applied.md:

# Application Log

- **Date**: YYYY-MM-DD
- **ATS**: Greenhouse/Lever/Workday
- **Status**: Submitted / Draft (not submitted)
- **Notes**: [any relevant notes]

更新 DATA_DIR/job-history.md——找到该职位对应的条目,并附上申请状态和日期。

向用户展示:

Applied to [Role] at [Company] on [date].
Files saved to: DATA_DIR/jobs/[folder]/

Next: /proficiently:apply [next-job-url] (apply to another job)
      /proficiently:job-search (find more jobs)

Built by Proficiently. Want someone to handle applications and connect
you with hiring managers? Visit proficiently.com

字段匹配参考

将表单字段标签(不区分大小写,模糊匹配)与申请资料对应:

标签模式数据来源输入方式
first namePersonal.FirstNameform_input / type
last namePersonal.LastNameform_input / type
full namePersonal.FirstName + LastNameform_input / type
emailPersonal.Emailform_input / type
phonePersonal.Phoneform_input / type
city, location, current locationPersonal.Cityform_input / type / combobox
countryPersonal.Country下拉菜单选择
linkedinProfiles.LinkedInform_input / type
githubProfiles.GitHubform_input / type
portfolio, websiteProfiles.Portfolioform_input / type
resume, cv文件上传:简历 PDF文件上传
cover letter文件上传:求职信文件上传
how did you hearStandardAnswers.HowHeard下拉菜单:“Job Board”
previously workedStandardAnswers.PreviouslyWorked单选按钮/复选框:“No”
authorized to work, work authorizationStandardAnswers.WorkAuth单选按钮/下拉菜单
sponsorshipStandardAnswers.Sponsorship单选按钮/下拉菜单
genderEEO.Gender下拉菜单:“Decline”
race, ethnicityEEO.Race下拉菜单:“Decline”
veteranEEO.Veteran下拉菜单/单选按钮:拒绝回答选项
disabilityEEO.Disability下拉菜单/单选按钮:拒绝回答选项

无法识别的字段:检查字段是否为必填。如果是必填,请询问用户。如果是可选字段,则跳过。将用户的答案缓存在 DATA_DIR/application-data.md 的“Custom Answers”下,以便重复使用。

ATS 特定交互说明

Lever:对于所有字段类型(包括下拉菜单),使用 form_input 并设置 value 或 text 即可直接填写。

Greenhouse:导航到表单直达 URL(iframe 外)后,使用 form_input 并设置 value 即可填写。

Workday:

  • read_page(filter="interactive") 只会返回视口中可见的元素。必须从上到下滚动,并在每个滚动位置调用 read_page。
  • read_page 不会返回单选按钮——请使用 find 工具,或通过 computer 在坐标处点击。
  • 下拉菜单是会打开弹出面板的 button 元素。点击按钮 → 使用 find 或 read_page 定位选项 → 点击选项。对于分层下拉菜单(例如“How Did You Hear”),请使用弹出面板中的 Search 文本框进行搜索。

响应格式

面向用户的输出需包含以下部分:

  1. 申请状态——说明已填写和跳过的内容,以及是否确认提交
  2. 已保存文件——列出已保存申请日志的路径
  3. 后续步骤——如果缺少求职信,建议补充;否则建议继续寻找下一份工作

所需权限

添加到 ~/.claude/settings.json:

{
  "permissions": {
    "allow": [
      "Read(~/.claude/skills/**)",
      "Read(~/.proficiently/**)",
      "Write(~/.proficiently/**)",
      "Edit(~/.proficiently/**)",
      "mcp__claude-in-chrome__*"
    ]
  }
}

评论

支持 Markdown