# How the AI‑Job‑Search Framework Handles Job Applications for Different Countries

> Learn how the AI-Job-Search framework adapts to global markets with its country-agnostic core and modular portal skills. Effortlessly handle job applications worldwide.

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

---

**The AI‑Job‑Search framework uses a country‑agnostic core with modular portal skills that can be enabled, configured, or extended to support any geographic market.**

This open‑source Python framework automates AI‑powered job searching and application drafting. According to the repository maintained by MadsLorentzen, the core workflow is designed to be **language‑ and country‑agnostic**, while country‑specific behavior is injected through discoverable portal skills and eligibility filters.

---

## Core Architecture: Country‑Agnostic by Design

The main application pipeline—spanning **self‑profiling → fit evaluation → drafter‑reviewer**—contains no hard‑coded country logic. This is explicitly documented in [`README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/README.md) at lines 42‑44: the core workflow is "language‑ and country‑agnostic." This design allows the same code to run regardless of whether you're job‑hunting in Denmark, Germany, or Japan.

Country specifics are handled at two extension points:

- **Portal skills** (where job listings are scraped)
- **Eligibility filters** (where legal work‑permit requirements are validated)

---

## Portal Skill Discovery and Configuration

All job‑portal integrations live under the hidden directory `.agents/skills/`. The `/scrape` command auto‑discovers every [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) file in this tree and invokes its associated CLI.

From [`.claude/skills/job-scraper/search-queries.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/search-queries.md) (lines 7‑9):

> The scraper walks `.agents/skills/**/SKILL.md` and executes any skill with `enabled: true`.

### Built‑In Country‑Agnostic Portals

| Portal | Location Support | SKILL.md Reference |
|--------|----------------|-------------------|
| `linkedin-search` | Any city, region, or country name via `--location` | [`.agents/skills/linkedin-search/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.agents/skills/linkedin-search/SKILL.md) lines 6‑10 |
| `freehire-search` | ISO‑3166 alpha‑2 country codes via `--country` and `--region` flags | [`.agents/skills/freehire-search/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.agents/skills/freehire-search/SKILL.md) lines 24‑30 |

Both skills advertise "any country/region" support in their front matter, making them immediately usable for global searches without modification.

---

## Market‑Specific Demo Implementations

The repository includes **four Danish job portals as demonstration implementations**:

- `jobindex-search`
- `jobbank-search`
- `jobdanmark-search`
- `jobnet-search`

These are documented in [`README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/README.md) (lines 306‑311) and each ships with `enabled: false` in its [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) front matter.

To activate Denmark‑specific scraping, modify the front matter as shown in [`.claude/commands/setup.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/setup.md) (lines 336‑342):

```yaml
---
name: jobindex-search
enabled: true          # <-- toggle from false to true

---

```

After enabling, run:

```bash
/ai-job-search> /scrape

```

The Jobindex CLI executes and returns Danish listings.

---

## Adding New Country‑Specific Portals

For markets not covered by existing skills, the `/add-portal` command scaffolds a new integration. Per [`.claude/commands/add-portal.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/add-portal.md) (lines 3‑9):

```bash
/ai-job-search> /add-portal

# Interactive prompts:

# • Market & language: e.g., "Japan / Japanese"

# • Trigger phrases: e.g., "求人", "仕事探し"

```

This creates `.agents/skills/japan-search/` with a [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) pre‑configured with `enabled: true`. Re‑running `/scrape` automatically includes the new skill in the discovery loop.

---

## Country‑Based Eligibility Filtering

Before any job is scored, the framework runs a **hard filter** that validates legal ability to work in the target country. This logic lives in [`.claude/skills/job-application-assistant/04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/04-job-evaluation.md) (lines 11‑14) within the `job-application-assistant` skill.

The filter evaluates two distinct dimensions:

- **Work‑permit timing** — Can the candidate work the required hours immediately?
- **Eligibility** — Is the candidate legally permitted to hold this position at all?

This ensures that applications are only drafted for positions where the candidate meets visa and citizenship requirements, regardless of which portal surfaced the listing.

---

## Practical Code Examples

### Search LinkedIn for roles in a specific country

```bash
/ai-job-search> linkedin-search --query "data scientist" --location "Germany"

```

The `--location` parameter accepts any country name, region, or city ([`.agents/skills/linkedin-search/url-reference.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.agents/skills/linkedin-search/url-reference.md), lines 42‑44).

### Search Freehire across multiple countries

```bash
/ai-job-search> freehire-search --category devops --country FR,GB

```

The `--country` flag accepts comma‑separated ISO‑3166 alpha‑2 codes, and `--region` can be repeated for sub‑national filtering ([`.agents/skills/freehire-search/url-reference.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.agents/skills/freehire-search/url-reference.md), lines 72‑74).

### Enable Danish market scraping

```yaml

# .agents/skills/jobbank-search/SKILL.md

---
name: jobbank-search
enabled: true
---

```

```bash
/ai-job-search> /scrape

```

---

## Key Source Files for Country Handling

| File Path | Purpose |
|-----------|---------|
| [`README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/README.md) | Documents country‑agnostic core and demo portals (lines 42‑44, 306‑311) |
| [`.agents/skills/linkedin-search/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.agents/skills/linkedin-search/SKILL.md) | Country‑agnostic LinkedIn skill definition |
| [`.agents/skills/freehire-search/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.agents/skills/freehire-search/SKILL.md) | Country‑agnostic skill with explicit country‑code support |
| [`.claude/skills/job-application-assistant/04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/04-job-evaluation.md) | Eligibility filter for work‑permit validation |
| [`.claude/skills/job-scraper/search-queries.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/search-queries.md) | Portal skill auto‑discovery logic (lines 7‑9) |
| [`.claude/commands/setup.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/setup.md) | Instructions for toggling market‑specific portals (lines 336‑342) |
| [`.claude/commands/add-portal.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/add-portal.md) | Workflow for scaffolding new country‑specific portals |

---

## Summary

- **The core pipeline is country‑agnostic** — no geographic logic in the main application flow.
- **Portal skills are auto‑discovered** from `.agents/skills/**/SKILL.md` files.
- **Built‑in portals** (`linkedin-search`, `freehire-search`) support any country via flags.
- **Demo portals** for Denmark show how to add market‑specific scrapers; enable with `enabled: true`.
- **New markets** are added via `/add-portal` command, which scaffolds a skill from a template.
- **Eligibility filters** prevent applications to positions where work authorization is lacking.

---

## Frequently Asked Questions

### Can I use the framework for job markets outside Denmark?

Yes. The framework ships with two country‑agnostic portals (`linkedin-search` and `freehire-search`) that support any geographic market. The Danish portals are optional demonstrations. For other markets, use the `/add-portal` command to scaffold a new skill.

### How do I enable or disable country‑specific job portals?

Open the [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) file for the desired portal in `.agents/skills/<portal-name>/` and set `enabled: true` or `enabled: false` in the YAML front matter, then re‑run `/scrape`. This is documented in [`.claude/commands/setup.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/setup.md).

### Does the framework check if I'm legally allowed to work in a country?

Yes. Before drafting any application, the `job-application-assistant` skill runs an eligibility filter that validates work‑permit timing and legal authorization requirements, as implemented in [`.claude/skills/job-application-assistant/04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/04-job-evaluation.md).

### What parameters should I use for country‑specific searches?

For LinkedIn, pass the country name to `--location`. For Freehire, use `--country` with ISO‑3166 alpha‑2 codes. Multiple countries can be queried with comma‑separated values or repeated `--country` flags.