How to Use the /add-portal Command to Add a New Job Portal to AI Job Search

The /add-portal command is a guided wizard that turns any public job board into a fully-featured search skill by scaffolding a TypeScript CLI, validating it with live tests, and registering it for the /scrape workflow.

The MadsLorentzen/ai-job-search repository provides a Claude-hosted command system for automating job search workflows. The /add-portal command, defined in .claude/commands/add-portal.md, implements a six-step pipeline that transforms raw job board URLs into maintainable, version-controlled search skills compatible with the repository's job scraping architecture.

Understanding the /add-portal Architecture

The command follows a strict six-step pipeline designed to ensure every generated skill meets the portal-skill contract—a standard requiring specific commands, JSON output shapes, and zero-runtime-dependency policies.

Step 1: Argument Parsing and Initial Routing

When you invoke the command, it first detects execution context. Supplying --list displays all installed portal skills, while providing a URL immediately initiates the wizard with that endpoint. If invoked without arguments, the system enters interactive mode to collect the portal URL and other required metadata.

Step 2: Interactive Interview for Portal Metadata

The wizard conducts an interview to gather essential scaffolding data:

  • Portal URL: The base address of the job board
  • Skill name: A kebab-case identifier ending in -search (e.g., seek-search)
  • Market and language: Geographic region and localization settings
  • Test query: A realistic search term used for validation (e.g., "Software Engineer")

This metadata seeds the directory structure and configuration files created in subsequent steps.

Step 3: Portal Investigation with WebFetch

The system performs automated reconnaissance on the target job board using WebFetch or curl via Bash scripts. This investigation phase retrieves:

  • Search endpoint patterns and query parameters
  • Result field mappings (HTML selectors or API responses)
  • Detail-page URL structures
  • robots.txt compliance checks and terms-of-service validation

When restrictive terms are detected, the system enforces a personal-use-only warning before proceeding. All technical findings are recorded for reference during scaffolding.

Step 4: Scaffold the Skill from the linkedin-search Template

The command clones the canonical structure from .agents/skills/linkedin-search/—the reference implementation—and creates a new directory at .agents/skills/<skill-name>/. This scaffold includes:

The generated code implements the mandatory search and detail commands with standardized flags (--limit, --format) and JSON output shapes containing required fields: id, title, company, location, date, and url.

Step 5: Live Testing and Type Validation

Before registration, the command executes a mandatory live test using your provided query. The validation pipeline:

  1. Runs a real search and verifies the response contains all required JSON fields
  2. Executes a detail fetch on one result to confirm deep-linking works
  3. Type-checks the TypeScript source with bun run typecheck
  4. Executes the test suite via bun run test

The wizard blocks progression until all tests pass, ensuring the skill is production-ready before integration.

Step 6: Registration with the /scrape Workflow

Upon successful validation, the command optionally registers the new portal by adding its domain to .claude/skills/job-scraper/search-queries.md. This registration enables the /scrape command to include your new portal in multi-source job searches. The system reminds you to commit all generated files, though no additional wiring is required—the SKILL.md description auto-triggers the skill when relevant queries are detected.

Command Usage Examples

List all currently installed portal skills:

/add-portal --list

Start the wizard with a specific job board URL:

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

Enter interactive mode to manually specify parameters:

/add-portal

# → Prompt: Portal URL?

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

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

# → Prompt: Test query? (Software Engineer)

After generation, test the new skill manually:


# Execute a search

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

# Fetch specific posting details

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

Run the generated test suite to verify compliance:

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

Generated Skill Structure

Each new portal skill creates a version-controlled directory structure under .agents/skills/<skill-name>/:

File Purpose
SKILL.md Auto-triggers the skill; contains trigger phrases and API documentation
url-reference.md Technical reference for endpoints and selectors
cli/src/cli.ts Main TypeScript entry point implementing search and detail commands
cli/package.json Bun-based runtime configuration with zero external dependencies
cli/tests/ Unit and integration tests validating the portal contract

Summary

  • The /add-portal command provides a six-step wizard that converts job board URLs into TypeScript search skills
  • It enforces a strict portal-skill contract requiring standardized commands, JSON output fields, and error handling
  • Skills scaffold from the canonical linkedin-search template located in .agents/skills/linkedin-search/
  • Mandatory live testing validates that results contain id, title, company, location, date, and url fields
  • Generated skills auto-integrate with the /scrape workflow when registered in .claude/skills/job-scraper/search-queries.md
  • All artifacts are country-agnostic and remain in your fork per upstream policy

Frequently Asked Questions

What job portals are compatible with the /add-portal command?

Any public job board with accessible search endpoints works with the command. The wizard uses WebFetch or curl to investigate HTML-based portals and APIs, automatically extracting query parameters and result selectors. The system is country-agnostic and works for regional boards (like Seek in Australia) or global platforms, provided they don't block automated access in robots.txt.

The kebab-case -search suffix identifies the directory as a search-capable skill within the .agents/skills/ namespace. This naming convention allows the Claude system to distinguish portal skills from other agent capabilities and ensures consistency with the linkedin-search reference implementation used for scaffolding.

How does the command validate that a new portal skill works correctly?

The validation pipeline performs a mandatory live test using your provided query. It executes a real search, verifies the response JSON contains all required fields (id, title, company, location, date, url), fetches details for one result, runs TypeScript type checking with bun run typecheck, and executes the full test suite with bun run test. The wizard blocks completion until all validations pass.

Where are the generated skill files stored?

The command creates a new directory at .agents/skills/<skill-name>/ relative to the repository root. This directory contains SKILL.md, url-reference.md, and a cli/ subdirectory with TypeScript source code, configuration files, and tests. Optionally, the portal domain is appended to .claude/skills/job-scraper/search-queries.md to enable /scrape integration.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →