Portal CLIs Component in the AI Job Search Framework: Architecture and Usage
The Portal CLIs component provides a standardized, plug-and-play interface that allows the AI Job Search framework to query any job board through a uniform CLI contract, enabling automatic discovery and parallel execution across multiple portals.
The Portal CLIs subsystem in the MadsLorentzen/ai-job-search repository serves as the abstraction engine that unifies disparate job board APIs into a consistent query interface. This component eliminates bespoke wiring for each portal by enforcing a strict contract that every job board integration must follow. By living under .agents/skills/*/, these command-line interfaces enable the framework to scrape listings from LinkedIn, FreeHire, and custom portals without modifying core logic.
Core Architecture of the Portal CLIs Component
The architecture centers on a standardized search contract that every portal must implement. This contract ensures that regardless of the underlying job board's API structure, the framework receives data in a predictable format.
Standardized Search Contract
Each portal CLI must provide two primary commands: search and detail. The search command accepts location, keywords, and result limits, while the detail command retrieves full posting information via URL. According to the source code in .agents/skills/linkedin-search/SKILL.md and similar files, each CLI exposes a --format flag supporting json, table, or plain output modes.
Portals declare their availability through an enabled: flag within their respective SKILL.md files. This boolean flag allows users to toggle specific job boards without removing code, as the job-scraper skill reads these declarations during initialization.
Command Structure and Flags
Every Portal CLI follows identical invocation patterns. The framework calls these CLIs using bun run commands, passing standardized arguments that map to the job board's query parameters. For example, the LinkedIn search CLI accepts --keywords, -l for location, and --limit to cap result counts.
# Execute a search against the LinkedIn portal CLI
bun run .agents/skills/linkedin-search/cli/src/cli.ts search \
--format json \
-l "Berlin, Germany" \
--keywords "data scientist" \
--limit 20
The detail command operates similarly, requiring only a --url parameter to fetch specific posting data:
# Retrieve detailed job posting information
bun run .agents/skills/linkedin-search/cli/src/cli.ts detail \
--format json \
--url "https://www.linkedin.com/jobs/view/1234567890"
Automatic Discovery and Execution
The framework eliminates manual registration through an automatic discovery mechanism that scans the skills directory at runtime.
SKILL.md Parsing
The job-scraper skill, defined in .claude/skills/job-scraper/SKILL.md, implements the discovery logic. During the /scrape command execution, the system scans every SKILL.md file located under .agents/skills/. It parses these markdown files to locate the correct bun run invocation for each enabled portal, then executes them in parallel without requiring explicit configuration lists.
This design means adding a new job board requires only creating a new subdirectory under .agents/skills/ with a compliant SKILL.md file. The scraper automatically detects and includes it in the next execution cycle.
Parallel Execution Model
The scraper orchestrates multiple portal CLIs concurrently. According to the job-scraper skill documentation, Step 1b outlines how the framework reads portal configurations and executes corresponding CLIs simultaneously. This parallelization reduces total scrape time when querying multiple job boards, while the standardized JSON output ensures the ranking and application modules receive uniform data structures regardless of the source.
Extensibility via the Add-Portal Command
New job board integrations require minimal setup thanks to the /add-portal command infrastructure. Documented in .claude/commands/add-portal.md, this generator scaffolds a complete portal CLI folder that automatically conforms to the framework's contract.
The command inspects the target portal's search URL patterns, result structure, and robots.txt rules to generate a self-contained CLI implementation. This scaffolding includes the mandatory search and detail command handlers, proper argument parsing, and the required SKILL.md with the enabled: flag. Once generated, the new portal participates immediately in future scrape operations without additional wiring.
Zero-Runtime-Dependency Design
Security and portability drive the zero-runtime-dependency architecture of the Portal CLIs component. Most shipped implementations, such as linkedin-search and freehire-search, execute using only the Bun runtime with no external package dependencies.
As noted in the repository's README.md under the country-agnostic portals section, these CLIs run with "just bun", eliminating the security surface area associated with npm package trees. This design choice ensures that job board queries execute in isolated, dependency-free environments that resist supply-chain attacks while maintaining fast startup times.
Fail-Safe Behavior and Error Handling
The Portal CLIs component implements robust fail-safe behavior to prevent individual portal failures from crashing the entire scrape operation. According to Steps 1a through 1c in the job-scraper skill documentation, the system handles multiple edge cases gracefully.
If a portal CLI exits with a non-zero status code, the scraper logs the specific failure and continues processing results from other portals. When the Bun runtime is unavailable on the host system, the framework automatically falls back to a plain WebSearch implementation. This fallback chain ensures that users receive job search results even when specific portal integrations malfunction or runtime prerequisites are missing.
Summary
- The Portal CLIs component provides a standardized command-line interface for querying any job board, requiring implementations to support
searchanddetailcommands with--formatflags. - Automatic discovery occurs through scanning
.agents/skills/*/SKILL.mdfiles, enabling parallel execution of enabled portals without manual registration. - The zero-dependency design ensures most CLIs run using only Bun, minimizing security risks and installation complexity.
- Fail-safe mechanisms prevent individual portal failures from halting the entire job search pipeline, with automatic fallback to web search when necessary.
- New portals can be added via the
/add-portalcommand, which generates compliant scaffolding in.agents/skills/that immediately participates in the next scrape cycle.
Frequently Asked Questions
What commands must a Portal CLI implement to integrate with the framework?
Every Portal CLI must implement exactly two commands: search and detail. The search command accepts parameters for location, keywords, and result limits, while the detail command requires a URL parameter to fetch comprehensive posting information. Both commands must support a --format flag accepting json, table, or plain values, and the CLI must declare an enabled: boolean in its SKILL.md file for discovery purposes.
How does the framework automatically discover new portal CLIs?
The job-scraper skill, located at .claude/skills/job-scraper/SKILL.md, implements recursive scanning of the .agents/skills/ directory during the /scrape command execution. It parses every SKILL.md file to extract the enabled: status and the corresponding bun run invocation path. This discovery mechanism requires no central registry; simply adding a compliant portal folder under .agents/skills/ makes it available for the next scrape cycle.
What happens when a Portal CLI encounters an error during execution?
The framework implements a fail-safe execution model where individual portal failures do not terminate the scrape operation. If a portal CLI exits with an error code, the job-scraper logs the specific failure and continues processing results from other enabled portals. Additionally, if the Bun runtime is unavailable on the host system, the framework automatically falls back to a plain WebSearch implementation to maintain job search functionality.
How can developers add support for a new job board to the AI Job Search framework?
Developers use the /add-portal command, documented in .claude/commands/add-portal.md, to scaffold a new portal integration. This command generates a complete CLI structure under .agents/skills/ that includes the mandatory command handlers, argument parsing, and SKILL.md configuration. The generator analyzes the target job board's search patterns and robots.txt rules to create a compliant implementation that automatically participates in future scrape operations without additional configuration.
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 →