# How to Set Up the AI Job Search Framework Locally

> Set up the AI job search framework locally. Install essential tools, fork the repository, and run the setup command to generate your skill files. Start your AI job search journey now.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: how-to-guide
- Published: 2026-08-28

---

**Setting up the AI Job Search framework locally requires installing Claude Code, Python 3.10+, Bun, and a LaTeX distribution, then forking the repository, installing portal CLI dependencies, and running the `/setup` command to generate your canonical profile skill files.**

The MadsLorentzen/ai-job-search repository provides a self-contained, Claude Code-driven workflow for automating every stage of a modern job hunt. To set up the AI job search framework locally, you will configure a **thin-pointer architecture** where mutable user data lives in canonical skill files under `.claude/skills/job-application-assistant/` while the immutable framework handles CLI tools, LaTeX templates, and CI scripts.

## Prerequisites

Before cloning the repository, ensure your local environment meets the following requirements.

- **Claude Code CLI** – Install globally via npm (`npm i -g @anthropic-ai/claude-code`). The framework uses this as its primary execution engine to interpret commands like `/setup`, `/scrape`, and `/apply` defined in [`.claude/settings.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/settings.json).
- **Python 3.10+** – Required for utility scripts such as [`tools/check_upstream_updates.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/check_upstream_updates.py) and [`tools/convert_salary_excel.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/convert_salary_excel.py).
- **Bun** – A fast JavaScript runtime needed to execute the TypeScript-based portal scrapers. Install with `curl -fsSL https://bun.sh/install | bash`.
- **LaTeX Distribution** – Install TeX Live, MacTeX, TinyTeX, or MiKTeX to compile CVs and cover letters. The CV uses `lualatex` while cover letters require `xelatex` due to custom font dependencies.
- **Optional Dependencies** – Install `pypdf` for ATS compatibility checks and `poppler` (specifically `pdftotext`) for PDF verification workflows.

## Installation Steps

### Fork and Clone the Repository

Create a personal fork of the repository to store your private profile data and customizations.

```bash
gh repo fork MadsLorentzen/ai-job-search --clone
cd ai-job-search

```

*Reference:* [`SETUP.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SETUP.md) – Fork and clone

### Install Portal CLI Dependencies

The framework uses modular **portal CLI tools** written in TypeScript/Bun to fetch listings from specific job boards. Each portal has its own `cli/` directory that must be initialized.

Run the following bash loop from the repository root to install all portal dependencies:

```bash
for tool in jobbank-search jobdanmark-search jobindex-search jobnet-search linkedin-search freehire-search; do
  (cd .agents/skills/$tool/cli && bun install)
done

```

Each CLI provides a uniform `search`/`detail` contract, and the `/scrape` command auto-discovers any skill with `enabled: true` in its configuration.

*Reference:* [`.agents/skills/jobindex-search/cli/package.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.agents/skills/jobindex-search/cli/package.json)

### Run the Onboarding Interview

Launch Claude Code and invoke the setup wizard to populate your profile files. The system auto-detects whether you have an existing `documents/` folder, a single CV, or prefer an interview-style questionnaire, then populates all canonical skill files accordingly.

```bash
claude        # opens Claude Code REPL

/setup        # inside the REPL; choose Path A, B, or C

```

This process generates the core profile files:
- [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md) (education, experience, skills)
- [`02-behavioral-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/02-behavioral-profile.md) (behavioral traits)
- [`04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md) (fit rubric)
- [`05-cv-templates.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/05-cv-templates.md) (CV structure preferences)
- [`07-interview-prep.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/07-interview-prep.md) (interview strategy)

*Reference:* [`.claude/commands/setup.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/setup.md)

## Understanding the Core Architecture

The framework follows a **thin-pointer design** that separates immutable system logic from mutable user data. All personalized content lives in `.claude/skills/job-application-assistant/`, while the framework manages compilation pipelines and security guards.

Key architectural components include:

- **Skill Files** – Markdown files under `.claude/skills/job-application-assistant/` serve as the single source of truth for your personal data. The `/apply` command reads these files to generate tailored LaTeX documents.
- **LaTeX Templates** – The CV uses the `moderncv` class (`cv/main_example.tex`), while cover letters use a custom `cover.cls` requiring Lato and Raleway fonts.
- **Utility Scripts** – Python scripts in `tools/` handle salary benchmarking ([`convert_salary_excel.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/convert_salary_excel.py)), upstream update checks ([`check_upstream_updates.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/check_upstream_updates.py)), and security validation ([`security_guards.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/security_guards.py)).

## Testing Your Setup

Verify the installation by processing a real job posting. The `/apply` command evaluates fit against your [`04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md) rubric, drafts LaTeX files, runs a reviewer agent, and produces final PDFs.

```bash
/apply https://jobindex.dk/job/1234567

```

After the command completes, compile the generated documents:

```bash
cd cv && lualatex main_<company>_<role>.tex && cd ..
cd cover_letters && xelatex cover_<company>_<role>.tex && cd ..

```

## Maintaining Your Fork

When the upstream repository releases updates, use the provided triage tools to preview which personalized files will be affected before merging.

```bash
python tools/check_upstream_updates.py
python tools/upstream_triage.py

```

The [`upstream_triage.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/upstream_triage.py) script generates `git cherry-pick` commands for selective integration, ensuring your profile data in the skill files remains intact while receiving framework improvements.

## Summary

- Install **Claude Code**, **Python 3.10+**, **Bun**, and a **LaTeX** distribution before cloning.
- Fork the repository to keep your profile data separate from the immutable framework.
- Run `bun install` in each `.agents/skills/*/cli/` directory to enable job portal scraping.
- Execute `/setup` inside Claude Code to generate your canonical skill files in `.claude/skills/job-application-assistant/`.
- Use `/apply <url>` to test the full workflow, then compile PDFs with `lualatex` (CV) and `xelatex` (cover letter).
- Maintain your fork using [`tools/check_upstream_updates.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/check_upstream_updates.py) to avoid overwriting personalized data.

## Frequently Asked Questions

### What are the minimum Python and Node versions required?

The framework requires **Python 3.10 or higher** for the utility scripts located in `tools/`. While Node.js is not strictly required for the core framework, you need **npm** solely to install the Claude Code CLI globally (`npm i -g @anthropic-ai/claude-code`). The portal scrapers run on **Bun**, not Node.js.

### Why does the cover letter compilation require XeLaTeX instead of LuaLaTeX?

The custom `cover.cls` file in `cover_letters/` uses system fonts (specifically Lato and Raleway) that require fontspec features only available in **XeLaTeX**. The CV template (`cv/main_example.tex`) uses the `moderncv` class and compiles with **LuaLaTeX**, which handles micro-typography optimizations better for CV layouts.

### How do I add a new job portal to the scraping workflow?

Create a new directory under `.agents/skills/` with a `cli/` subdirectory containing a TypeScript project. The CLI must export uniform `search` and `detail` commands and include an `enabled: true` flag in its configuration. The `/scrape` command auto-discovers any skill matching this pattern without requiring changes to the core framework.

### Where is my personal data stored to ensure it doesn't conflict with upstream updates?

All mutable personal data resides exclusively in `.claude/skills/job-application-assistant/` (the skill files) and generated documents like `cv/main_<company>_<role>.tex`. The framework's **thin-pointer architecture** ensures that upstream updates to CLI tools, LaTeX classes, or CI scripts never touch these directories. Use [`tools/upstream_triage.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/upstream_triage.py) to verify this boundary before pulling updates.