# How to Add a Custom Job Portal Using `/add-portal` in AI Job Search

> Easily add a custom job portal using the /add portal command in AI Job Search. This guide explains the six-step wizard for converting job boards into reusable search skills.

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

---

**The `/add-portal` command is a guided six-step wizard that converts any public job board into a reusable search skill by scaffolding TypeScript CLI tools, validating live data extraction, and registering the portal for integration with the `/scrape` workflow.**

The `MadsLorentzen/ai-job-search` repository provides a modular framework for job search automation. Adding a custom job portal using `/add-portal` creates a fully-featured skill that adheres to the portal-skill contract, enabling standardized `search` and `detail` operations across any public job board while maintaining zero runtime dependencies.

## The Six-Step Portal Creation Pipeline

The `/add-portal` command implemented in [`.claude/commands/add-portal.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/add-portal.md) orchestrates a strict pipeline to ensure every generated skill meets production standards before registration.

### 1. Argument Parsing and Routing

The wizard detects execution flags to route the workflow. Supplying `--list` displays all installed portal skills, while providing a URL immediately initiates the investigation phase. If executed without arguments, the command launches an interactive interview to collect essential metadata.

### 2. Interview (Portal Metadata Collection)

The interactive phase seeds the scaffolding process by capturing four critical data points:

- **Portal URL**: The root domain of the job board
- **Skill name**: A kebab-case identifier ending in `-search` (e.g., `seek-search`)
- **Market/Language**: Geographic and linguistic context for localization
- **Test query**: A realistic search term used for mandatory validation

### 3. Portal Investigation

Using **WebFetch** or `curl` via Bash, the command probes the portal's search endpoint to derive query parameters, result field mappings, and detail-page URL patterns. This step validates [`robots.txt`](https://github.com/MadsLorentzen/ai-job-search/blob/main/robots.txt) compliance and surfaces terms-of-service restrictions, enforcing a personal-use-only warning when required. All technical findings are recorded in [`url-reference.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/url-reference.md) for the scaffold generation.

### 4. Scaffold the Skill Structure

The command copies the canonical structure from `.agents/skills/linkedin-search/` to create `.agents/skills/<skill-name>/`, generating three core components:

- **[`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md)**: Command definitions, trigger phrases, usage examples, and error handling specifications
- **[`url-reference.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/url-reference.md)**: Technical endpoint documentation derived from the investigation phase
- **`cli/`**: A minimal TypeScript CLI including [`package.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/package.json), [`tsconfig.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tsconfig.json), [`src/cli.ts`](https://github.com/MadsLorentzen/ai-job-search/blob/main/src/cli.ts), helper modules, and a test suite

The scaffold enforces the **portal-skill contract**: commands must support `search` and `detail` subcommands, standardized flags, JSON output shape, and zero runtime dependencies outside the generated code.

### 5. Live Test (Mandatory Validation)

Before registration, the skill must pass live data validation. The wizard executes a real search using the user-provided test query and verifies that results contain the required schema fields: `id`, `title`, `company`, `location`, `date`, and `url`. It then performs a `detail` fetch on one result to verify deep-linking functionality.

The CLI undergoes type checking (`bun run typecheck`) and the test suite (`bun run test`) must pass completely before the wizard proceeds to registration.

### 6. Registration and Integration

Optionally, the command appends the new portal's domain to [`.claude/skills/job-scraper/search-queries.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/search-queries.md), enabling the `/scrape` command to include the portal in multi-source searches. The wizard reminds users to commit the generated files to version control. No manual wiring is required because the [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) description auto-triggers the skill within the Claude environment.

## Command Usage Examples

List existing portal skills to verify naming conventions:

```bash
/add-portal --list

```

Initiate the wizard with a specific portal URL:

```bash
/add-portal https://www.seek.com.au

```

Launch interactive mode to provide metadata manually:

```bash
/add-portal

# → Prompt: Portal URL?

# → Prompt: Skill name? (e.g. seek-search)

# → Prompt: Market & language? (Australia, English)

# → Prompt: Test query? (Software Engineer)

```

## Testing Your New Portal Skill

After scaffolding completes in `.agents/skills/<skill-name>/`, validate the skill manually before production use:

Execute a live search with table-formatted output:

```bash
bun run .agents/skills/seek-search/cli/src/cli.ts search -q "Software Engineer" --limit 5 --format table

```

Fetch detailed information for a specific posting:

```bash
bun run .agents/skills/seek-search/cli/src/cli.ts detail 123456 --format plain

```

Run the automated test suite and TypeScript type checker:

```bash
cd .agents/skills/seek-search/cli && bun install && bun run test
bun run typecheck

```

## Skill Architecture and Source Templates

The generated skill follows the exact architecture of the reference implementation located at `.agents/skills/linkedin-search/`. According to the `MadsLorentzen/ai-job-search` source code, this ensures consistency across all portal integrations while maintaining the zero-dependency policy.

The system is country-agnostic and works for any public job board, though generated skills remain in the user's fork per upstream policy. All artifacts are version-controlled and documented, making future maintenance straightforward.

## Summary

- The `/add-portal` command creates reusable job portal skills through a six-step wizard: parsing, interview, investigation, scaffolding, live testing, and registration.
- Generated skills reside in `.agents/skills/<skill-name>/` and include [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md), [`url-reference.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/url-reference.md), and a TypeScript CLI with `search` and `detail` commands.
- Live validation requires successful extraction of `id`, `title`, `company`, `location`, `date`, and `url` fields, plus passing `bun run typecheck` and `bun run test`.
- Registration in [`.claude/skills/job-scraper/search-queries.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/search-queries.md) enables automatic inclusion in `/scrape` workflows without additional wiring.
- The canonical template is copied from `.agents/skills/linkedin-search/` to ensure strict adherence to the portal-skill contract.

## Frequently Asked Questions

### What prerequisites are required before running `/add-portal`?

You need **Bun** installed for TypeScript execution and package management, as the generated CLIs use `bun run` for type checking and testing. The repository must be cloned locally, and you should have `curl` or WebFetch available for the portal investigation phase that probes endpoints and checks [`robots.txt`](https://github.com/MadsLorentzen/ai-job-search/blob/main/robots.txt).

### Can I add portals that require authentication or API keys?

The tool is designed for public job boards accessible without authentication. The portal-skill contract assumes zero runtime dependencies and standard HTTP scraping. If a portal requires sessions or API keys, you would need to manually extend the generated CLI in `.agents/skills/<skill-name>/cli/src/cli.ts` to handle authentication headers or token management before running the live test.

### How does the `/scrape` command recognize my new portal?

When you complete the registration step, the `/add-portal` command appends the portal domain to [`.claude/skills/job-scraper/search-queries.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/search-queries.md). The [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md) file in your generated skill directory contains trigger phrases and command definitions that Claude uses to auto-detect when to invoke your portal skill during `/scrape` operations.

### What happens if the live test fails during wizard execution?

The wizard mandates successful validation before proceeding to registration. If the live search cannot extract the required fields (`id`, `title`, `company`, `location`, `date`, `url`) or the detail fetch fails, the wizard halts and displays error logs from the CLI execution. You must debug the portal's HTML structure or URL patterns, then restart the `/add-portal` process with corrected parameters or selectors.