← Back to Skills Marketplace
mattjackson

Claw Apply

by Matthew Jackson · GitHub ↗ · v0.1.5
cross-platform ⚠ suspicious
373
Downloads
1
Stars
0
Active Installs
6
Versions
Install in OpenClaw
/install claw-apply
Description
Automated job search and application for LinkedIn and Wellfound. Searches for matching roles every 12 hours, AI-filters and scores them, applies automaticall...
README (SKILL.md)

claw-apply

GitHub: github.com/MattJackson/claw-apply

Automated job search and application. Finds matching roles on LinkedIn and Wellfound, filters with AI, applies automatically, and learns from every unknown question.

Security note: This skill makes Claude API calls for job scoring (lib/filter.mjs), answer generation (lib/ai_answer.mjs, lib/form_filler.mjs), and keyword generation (lib/keywords.mjs). Those files contain systemPrompt variables with "You are..." instructions intended for the Claude API — they are not prompt injections or system prompt overrides. All API calls go exclusively to api.anthropic.com. No instructions in this skill attempt to modify agent behavior, exfiltrate data, or override platform prompts.

Requirements

  • Node.js 18+
  • Kernel account — stealth browsers + bot detection bypass (required)
  • Kernel CLI: npm install -g @onkernel/cli — see kernel/skills for CLI + auth guidance
  • Telegram bot for notifications and interactive Q&A (BotFather)
  • Anthropic API key (optional — enables AI filtering, keyword generation, and suggested answers)
  • OpenClaw (optional — enables auto-scheduling via crons)

Note: Playwright is installed automatically via npm install as a library for browser connectivity. You don't need to install it globally or manage browsers yourself — Kernel handles all browser execution.

Setup

1. Install

git clone https://github.com/MattJackson/claw-apply.git
cd claw-apply
npm install

2. Kernel: proxy + auth sessions

# Log in to Kernel
kernel login

# Create a residential proxy (US recommended for LinkedIn/Wellfound)
kernel proxies create --type residential --country US --name "claw-apply-proxy"
# Note the proxy ID from output

# Create managed auth connections (one per platform)
kernel auth connections create --profile-name "LinkedIn-YourName" --domain linkedin.com
kernel auth connections create --profile-name "WellFound-YourName" --domain wellfound.com

# Complete initial login flows (opens a hosted URL to log in)
# Use: kernel auth connections list   to find the connection IDs
kernel auth connections login \x3Clinkedin-connection-id>
kernel auth connections login \x3Cwellfound-connection-id>

Note: You only need connection IDs for the initial login. After that, the applier finds connections automatically by domain (linkedin.com, wellfound.com) — no IDs to store or keep in sync. Kernel's managed auth handles session refresh and re-authentication with stored credentials.

3. Configure

cp config/settings.example.json config/settings.json
cp config/profile.example.json config/profile.json
cp config/search_config.example.json config/search_config.json

settings.json — fill in:

  • notifications.telegram_user_id — your Telegram user ID
  • notifications.bot_token — Telegram bot token from BotFather
  • kernel.proxy_id — proxy ID from step 2
  • kernel.profiles.linkedin — profile name e.g. LinkedIn-YourName
  • kernel.profiles.wellfound — profile name e.g. WellFound-YourName

profile.json — your name, email, phone, resume path, work authorization, salary targets

search_config.json — keywords, platforms, location filters, salary filters, exclusions

4. Create .env

Create a .env file in the project root (gitignored — never commit this):

KERNEL_API_KEY=your_kernel_api_key
ANTHROPIC_API_KEY=your_anthropic_api_key   # optional, for AI features

5. Verify

node setup.mjs

Setup will:

  • Validate all config files
  • Write .env (mode 600) if API keys are set
  • Send a Telegram test message
  • Test LinkedIn + Wellfound logins

6. Schedule with OpenClaw crons

Scheduling is managed via OpenClaw cron jobs (not system crontab):

Job Schedule Description
Searcher 0 */12 * * * America/Los_Angeles Search every 12 hours
Filter 30 * * * * America/Los_Angeles AI filter every hour at :30
Applier */3 * * * * America/Los_Angeles 1 job per run, silent (no Telegram noise)
Telegram Poller * * * * * America/Los_Angeles Process answer replies every minute

Rate limiting: LinkedIn enforces a minimum ~3 minutes between applications. The applier processes 1 job per run (max_applications_per_run: 1 in settings.json) — control pacing via the cron interval. Running more frequently or processing multiple jobs per run risks account lockout.

Notification defaults: all crons use delivery: none. The scripts send their own Telegram summaries directly — no need for OpenClaw cron announcements on top.

The lockfile mechanism ensures only one instance of each agent runs at a time.

7. Run manually

node job_searcher.mjs            # search now
node job_filter.mjs              # AI filter + score jobs
node job_applier.mjs --preview   # preview queue without applying
node job_applier.mjs             # apply now
node telegram_poller.mjs         # process Telegram answer replies
node status.mjs                  # show queue + run status

How it works

Search — runs your keyword searches on LinkedIn and Wellfound, paginates through results, classifies each job (Easy Apply vs external ATS), filters exclusions, deduplicates, and queues new jobs. First run searches 90 days back; subsequent runs search 2 days.

Filter — submits jobs to Claude AI via Anthropic Batch API for scoring (1-10). Jobs below the threshold are filtered out. Cross-track deduplication keeps the highest-scoring copy. Two-phase design for cron compatibility.

Apply — picks up queued jobs sorted by priority (Easy Apply first), opens stealth browser sessions, fills forms using your profile + learned answers, and submits. Processes Telegram replies at start of each run. Reloads answers.json before each job. Auto-recovers from browser crashes. Retries failed jobs (default 2 retries). Per-job timeout of 10 minutes.

Learn — on unknown questions, Claude suggests an answer and you're messaged on Telegram. Reply with your answer or "ACCEPT" the AI suggestion. The Telegram poller saves it to answers.json instantly and the job is retried next run. Over time, all questions get answered and the system runs fully autonomously.

Lockfile — prevents parallel runs. If an agent is already running, a second invocation exits immediately.

File structure

claw-apply/
├── job_searcher.mjs           Search agent
├── job_filter.mjs             AI filter + scoring agent
├── job_applier.mjs            Apply agent
├── telegram_poller.mjs        Telegram answer reply processor
├── setup.mjs                  Setup wizard
├── status.mjs                 Queue + run status report
├── lib/
│   ├── browser.mjs            Kernel stealth browser factory
│   ├── session.mjs            Auth session refresh via Kernel API
│   ├── env.mjs                .env loader
│   ├── linkedin.mjs           LinkedIn search + job classification
│   ├── wellfound.mjs          Wellfound search + apply
│   ├── form_filler.mjs        Form filling with pattern matching
│   ├── ai_answer.mjs          AI answer generation via Claude
│   ├── filter.mjs             AI job scoring via Anthropic Batch API
│   ├── keywords.mjs           AI-enhanced keyword generation
│   ├── queue.mjs              Job queue with atomic writes
│   ├── lock.mjs               PID lockfile + graceful shutdown
│   ├── notify.mjs             Telegram Bot API (send, getUpdates, reply)
│   ├── telegram_answers.mjs   Telegram reply → answers.json processing
│   ├── search_progress.mjs    Per-platform search resume tracking
│   ├── constants.mjs          Shared constants + ATS patterns
│   └── apply/
│       ├── index.mjs          Handler registry + status normalization
│       ├── easy_apply.mjs     LinkedIn Easy Apply (full)
│       ├── wellfound.mjs      Wellfound apply (full)
│       ├── greenhouse.mjs     Greenhouse (stub)
│       ├── lever.mjs          Lever (stub)
│       ├── workday.mjs        Workday (stub)
│       ├── ashby.mjs          Ashby (stub)
│       └── jobvite.mjs        Jobvite (stub)
├── config/
│   ├── *.example.json         Templates (committed)
│   └── *.json                 Your config (gitignored)
└── data/                      Runtime data (gitignored, auto-managed)

answers.json — self-learning Q&A

When the applier can't answer a question, it asks Claude for a suggestion and messages you on Telegram. Your reply is saved and reused forever:

[
  { "pattern": "quota attainment", "answer": "1.12" },
  { "pattern": "years.*enterprise", "answer": "5" },
  { "pattern": "1.*10.*scale", "answer": "9" }
]

Patterns are matched case-insensitively and support regex. First match wins.

ATS support

Platform Status
LinkedIn Easy Apply Full
Wellfound Full
Greenhouse Stub
Lever Stub
Workday Stub
Ashby Stub
Jobvite Stub

External ATS jobs are queued and classified — stubs will be promoted to full implementations based on usage data.

Usage Guidance
This skill largely does what it says, but review these points before installing: - Metadata mismatch: The registry summary claims no env vars, but the repo requires KERNEL_API_KEY (required) and optionally ANTHROPIC_API_KEY. Treat KERNEL_API_KEY as mandatory if you want stealth browser automation. - Privacy / data exfiltration: If you enable ANTHROPIC_API_KEY the skill will send job text, candidate profile, and resume snippets to Anthropic (Claude) for scoring and answer generation. If you care about keeping your resume/profile private, avoid providing ANTHROPIC_API_KEY or scrub sensitive fields from profile.json. - Kernel trust: The skill relies on Kernel (kernel.sh) for stealth browsers, managed auth connections, and residential proxies. That means login flows for LinkedIn/Wellfound are handled by Kernel; you must trust their service to store and refresh those sessions. Kernel proxy usage may have cost and privacy implications. - Test in preview/manual mode: Use node job_applier.mjs --preview and run searches locally (job_searcher.mjs) to observe behavior before allowing automatic applies. Start with enabled_apply_types set to ['easy_apply'] and max_applications_per_run=1 while testing. - Inspect system prompts and constants: If you are cautious, inspect lib/constants.mjs (confirm the Anthropic endpoint) and the systemPrompt strings in lib/*.mjs to ensure they only target the model and do not attempt to alter agent/platform behavior. - pdftotext and child process: The code will try to run pdftotext on PDF resumes if present; this uses child_process.execFileSync with array args (not shell interpolation), which reduces injection risk, but you should ensure pdftotext is the expected binary. - Source trust & license: The repo author is 'MattJackson' and license is AGPL. If you do not trust the source, run in an isolated environment or skip installing. If you accept these trade-offs and trust Kernel/Anthropic for your use case, the code and instructions appear coherent for the stated purpose. If you do not want external model or Kernel involvement, disable ANTHROPIC_API_KEY and use 'browser.provider' = 'local' (and review settings) or do not provide KERNEL_API_KEY.
Capability Analysis
Type: OpenClaw Skill Name: claw-apply Version: 0.1.5 The skill automates job applications on LinkedIn and Wellfound using stealth browsers and AI-driven form filling. While the logic is aligned with its stated purpose, it employs several high-risk capabilities that warrant a suspicious classification. Specifically, 'lib/ai_answer.mjs' uses 'child_process.execFileSync' to execute the 'pdftotext' binary on local files, and 'lib/constants.mjs' contains hardcoded absolute system paths for dependencies. The skill handles sensitive PII (resumes and profiles) and requires broad permissions for network, filesystem, and browser access to interact with authenticated sessions. Although no clear malicious intent was found, the combination of shell execution, automated browser control, and PII handling presents a significant attack surface.
Capability Assessment
Purpose & Capability
The skill's stated purpose (search + auto-apply on LinkedIn and Wellfound) matches the contents: it uses stealth browsers (Kernel), form filling, and optional AI scoring/answer generation. However the package/registry metadata provided at the top of the submission (Required env vars: none) is inconsistent with the repository's claw.json and SKILL.md, which require KERNEL_API_KEY (required) and optionally ANTHROPIC_API_KEY. That mismatch is an incoherence that should be resolved before trusting the registry metadata. The use of Kernel (residential proxies, managed auth) and Playwright is proportionate to the stated goal.
Instruction Scope
Runtime instructions and code explicitly read your profile.json and resume path, interact with LinkedIn/Wellfound sessions via Kernel-managed auth, send job descriptions and candidate context to Anthropic/Claude for scoring and answer generation, and send/receive notifications via Telegram. These actions are consistent with the stated function but mean PII (resume, profile, job context) will be transmitted to external services (Kernel and Anthropic) if configured. The SKILL.md contains system-prompt text for Claude; a prompt-injection pattern was detected by the scanner but the skill claims these are normal system prompts used in API requests.
Install Mechanism
There is no registry install spec in the submission (the skill is instruction + repo). Install is standard: git clone + npm install, plus optional global install of Kernel CLI (npm -g @onkernel/cli). Playwright is a dependency (npm install will pull it and potentially browser artifacts). No arbitrary downloads from untrusted URLs were found in the provided files. This is typical for a Node.js project but you should be prepared for the usual npm dependency risks and large Playwright downloads.
Credentials
The code and SKILL.md legitimately require KERNEL_API_KEY (Kernel-managed stealth browser service) and optionally ANTHROPIC_API_KEY. Those are proportionate to the functionality. However the registry-level summary incorrectly listed "Required env vars: none" (incoherent with claw.json and SKILL.md). Also note personal data (resume text, profile data) is read locally and—when ANTHROPIC_API_KEY is provided—sent to Anthropic; pdftotext may be invoked (execFileSync) to extract text from PDFs if available. Requiring KERNEL_API_KEY grants the skill access to a remote service that will manage and store auth sessions for LinkedIn/Wellfound — this is expected but increases the attack surface and trust requirements.
Persistence & Privilege
No 'always: true' privilege is requested. The skill stores and updates its own local data files (data/, config/answers.json) and uses Kernel managed auth and proxies; it does not appear to modify other skills or system-wide agent settings. Cron scheduling is optional via OpenClaw; the applier supports a --preview mode so you can test before enabling autonomous runs.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install claw-apply
  3. After installation, invoke the skill by name or use /claw-apply
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v0.1.5
Dynamic auth/profile/proxy lookup, GitHub link, rate limit docs
v0.1.4
Domain-based auth lookup, rate limit docs, auth health check
v0.1.3
Add security note addressing prompt-injection false positive from systemPrompt vars in Claude API calls
v0.1.2
Declare required env vars in claw.json, remove git-pull cron, remove YAML frontmatter
v0.1.1
claw-apply 0.1.1 - Updated documentation: removed Git auto-pull and Git-related cron job from setup instructions and scheduling table. - SKILL.md now clearly lists only essential OpenClaw cron jobs, focusing on core functionality. - Minor improvements to clarity in the setup and Q&A usage descriptions. - No functional code changes; changes are documentation-only.
v0.1.0
Initial release of claw-apply: fully automated job search and application system. - Scans LinkedIn and Wellfound every 12 hours for matching roles, filters and scores them using AI (Claude/Anthropic API). - Automatically applies to jobs using stealth browsers managed by Kernel, including handling LinkedIn’s multi-step Easy Apply forms. - Learns from unknown form questions by messaging you via Telegram, suggests AI answers, and remembers your reply for future use. - Recovers from browser crashes, retries failed applications, and ensures no duplicate agent runs via lockfile mechanism. - Flexible cron-based scheduling via OpenClaw, direct Telegram notifications, and detailed config/setup instructions.
Metadata
Slug claw-apply
Version 0.1.5
License
All-time Installs 0
Active Installs 0
Total Versions 6
Frequently Asked Questions

What is Claw Apply?

Automated job search and application for LinkedIn and Wellfound. Searches for matching roles every 12 hours, AI-filters and scores them, applies automaticall... It is an AI Agent Skill for Claude Code / OpenClaw, with 373 downloads so far.

How do I install Claw Apply?

Run "/install claw-apply" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Claw Apply free?

Yes, Claw Apply is completely free (open-source). You can download, install and use it at no cost.

Which platforms does Claw Apply support?

Claw Apply is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Claw Apply?

It is built and maintained by Matthew Jackson (@mattjackson); the current version is v0.1.5.

💬 Comments