Can AI Understand Natural Language Job Descriptions? Inside the MadsLorentzen/ai-job-search Framework
Yes, the AI parses, evaluates, and drafts responses to free-form natural language job descriptions supplied either as URLs or raw pasted text.
The MadsLorentzen/ai-job-search repository is an AI-driven job-application framework that treats unstructured job postings as first-class inputs. Whether you paste a description verbatim or point the tool at a URL, the pipeline extracts structured signals from raw text and uses them to evaluate fit and draft tailored application documents. The entire workflow centers on the ability to understand natural language job descriptions safely and accurately.
How the /apply Command Processes Natural Language Job Descriptions
The core parsing and reaction logic lives in .claude/commands/apply.md. This file orchestrates a three-step pipeline that transforms free-form text into structured actions.
Step 0 — Parse Input from URLs or Raw Text
The workflow first inspects the argument to determine whether it resembles a URL. If so, the system fetches the posting using WebFetch; otherwise, it consumes the raw text directly. According to the source code in .claude/commands/apply.md, the parser treats the posting as untrusted data and never as executable instructions. It extracts the company name, role title, department, location, and language, which become the foundation for every downstream step.
Step 1 — Evaluate Fit Against Structured Criteria
The extracted description is compared against the candidate’s profile using the evaluation framework defined in .claude/skills/job-application-assistant/04-job-evaluation.md. This step scores skills, experience, cultural fit, and optional salary benchmarks. The AI maps ambiguous natural-language requirements to concrete structured signals, demonstrating genuine comprehension of the post’s intent.
Step 2 — Draft CV and Cover Letter
The same parsed information feeds the drafting stage in Step 2. The AI ensures that every requirement from the posting is either addressed in the generated documents or honestly acknowledged as a gap. This closes the loop by turning raw text into tailored application materials.
Job Scraper Tools That Feed Natural Language Data
The repository includes CLI agents in .agents/skills/—such as jobindex-search and linkedin-search—that retrieve listings from various portals. These tools are thin wrappers around HTTP requests and HTML parsing. They return the raw posting text that the AI subsequently consumes, pumping external natural language job descriptions into the same /apply pipeline.
Security: Treating Postings as Untrusted Data
Because the workflow explicitly treats every posting as untrusted data, it safely ingests arbitrary natural language job descriptions while preserving security guarantees. The parser never executes embedded instructions, so even maliciously crafted text cannot hijack the agent.
Practical Code Examples
Apply to a Posting via URL
Invoke the full pipeline by passing a job URL directly to the Claude CLI:
claude /apply https://jobindex.dk/job/1234567
The command fetches the page, parses the natural language job description, evaluates fit, drafts the documents, and returns the final PDFs.
Apply by Pasting the Description
When no URL is provided, the command falls back to raw text input:
claude /apply
Paste the full job description when prompted. The /apply command uses the same parsing logic for pasted text as it does for fetched HTML.
Run a Scraper Manually
You can retrieve listings locally using the Bun-based LinkedIn scraper:
cd .agents/skills/linkedin-search/cli
bun run src/main.ts --query "machine learning engineer" --location "Berlin, Germany"
The scraper prints JSON-encoded job postings that can be piped into /apply or inspected manually.
Programmatic Evaluation with Salary Lookup
During Step 1, the framework can enrich the fit report with salary data by invoking salary_lookup.py:
import subprocess, json
result = subprocess.check_output(
['python', 'salary_lookup.py', 'Danske Bank', '--json', '--city', 'Copenhagen']
)
salary_info = json.loads(result)
print(salary_info)
The JSON result is merged into the fit report generated by the evaluation step in .claude/commands/apply.md.
Key Files in the Natural Language Pipeline
Several files define how the system interprets natural language job descriptions:
.claude/commands/apply.md— Orchestrates the full drafter-reviewer pipeline and parses natural-language postings in Step 0..claude/skills/job-application-assistant/04-job-evaluation.md— Defines the structured evaluation framework that maps description text to fit scores..agents/skills/linkedin-search/cli/src/main.ts— Example CLI scraper that supplies raw job-description text to the AI.salary_lookup.py— Utility invoked during fit evaluation to enrich the AI’s understanding with salary benchmarks.CLAUDE.md— Holds the candidate profile that the AI matches against parsed job descriptions.
Summary
- The
/applycommand in.claude/commands/apply.mdaccepts natural language job descriptions via URL or raw text and extracts structured fields such as company, role, and location. - Step 1 evaluates fit by mapping parsed requirements against the candidate profile in
CLAUDE.mdusing the framework in04-job-evaluation.md. - Step 2 generates tailored CV and cover letter content, addressing each requirement or noting gaps honestly.
- Scraper tools in
.agents/skills/feed external job board text into the same pipeline. - The system treats all input as untrusted data, preventing instruction injection while fully processing free-form descriptions.
Frequently Asked Questions
Can the AI process job descriptions pasted as plain text instead of URLs?
Yes. The /apply command falls back to raw text parsing when no URL is provided. It uses the same extraction logic to identify company name, role title, department, location, and language before proceeding to evaluation and drafting.
How does the AI evaluate whether a candidate fits a natural language job description?
Step 1 of the /apply workflow compares the parsed description against the candidate profile stored in CLAUDE.md. It uses the framework defined in .claude/skills/job-application-assistant/04-job-evaluation.md to generate structured scores for skills, experience, cultural fit, and optional salary benchmarks.
Are job postings treated as safe input?
Yes, by design. The workflow explicitly treats every posting as untrusted data. It parses the text for information but never executes embedded instructions, enabling safe ingestion of arbitrary natural language job descriptions.
What tools fetch job listings for the AI to process?
The CLI agents in .agents/skills/—including jobindex-search and linkedin-search—retrieve raw posting text from various portals. These thin HTTP wrappers feed natural language job descriptions into the same /apply pipeline.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →