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.txtcompliance 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:
SKILL.md: Complete definition, trigger phrases, command reference, and usage examplesurl-reference.md: Technical documentation derived from the investigation phasecli/: A minimal TypeScript CLI containingpackage.json,tsconfig.json,src/cli.ts, helper modules, and a test suite
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:
- Runs a real search and verifies the response contains all required JSON fields
- Executes a
detailfetch on one result to confirm deep-linking works - Type-checks the TypeScript source with
bun run typecheck - 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-portalcommand 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-searchtemplate located in.agents/skills/linkedin-search/ - Mandatory live testing validates that results contain
id,title,company,location,date, andurlfields - Generated skills auto-integrate with the
/scrapeworkflow 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.
Why does the skill name need to end with "-search"?
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →