Portal Skills in the AI Job Search Framework: Extension Architecture Constraints

Portal skills in the AI Job Search Framework must implement a strict CLI contract with search and detail commands, JSON error handling on stderr, automatic retry logic for rate limits, zero runtime dependencies, and metadata declaration via SKILL.md to enable plug-and-play integration.

Portal skills are the modular extension points that allow the AI Job Search Framework to query disparate job boards using a unified interface. According to the MadsLorentzen/ai-job-search repository architecture, these plugins reside in the .agents/skills/ directory and are auto-discovered by the core workflow commands (/scrape, /rank, /apply). To maintain interoperability, every portal skill must obey a rigorous set of constraints defined in CONTRIBUTING.md and enforced by continuous integration.

CLI Contract: Search and Detail Commands

Every portal skill must expose a command-line interface with two mandatory subcommands.

search command returns a JSON array of job objects. It must accept standard pagination flags and support filtering via query parameters.

detail command accepts a job identifier and returns a single JSON object representing the complete posting.

Both commands must implement the --format flag accepting json, table, or plain values. While table and plain are optional UI helpers, the framework exclusively consumes the json output format for downstream processing. In CONTRIBUTING.md (lines 69-70), this contract is defined as the fundamental integration requirement for all portal skills.

Error Handling and Resilience Constraints

Robust error propagation ensures the core scraper can handle failures uniformly across all portal implementations.

Standardized error output: All errors must be written to stderr as JSON objects and the process must exit with status 1. This convention allows the framework to parse error details programmatically rather than scraping text output.

Automatic retry with back-off: When encountering HTTP 429 (rate limiting) or any 5xx server error, the CLI must implement automatic exponential back-off and retry logic. The CI pipeline verifies this retry policy to prevent transient failures from breaking scraping workflows.

Configuration Metadata and Data Contracts

Portal skills must declare their operational status and adhere to strict data formatting rules.

SKILL.md metadata: Each skill folder contains a SKILL.md file that must include an enabled: true|false declaration. Disabled skills are automatically skipped by the /scrape command, as documented in .claude/skills/job-scraper/search-queries.md (lines 5-9).

Mandatory date field: Every job object returned by the search or detail commands must contain a top-level date key. The value must be ISO-8601 formatted or null. The scraper uses this field for recency filtering, as specified in CHANGELOG.md (lines 44-53).

Security and Compliance Requirements

The framework enforces ethical scraping and secure credential management through architectural constraints.

Environment-based API keys: When a portal requires authentication, tokens must be read from environment variables. The /add-portal scaffolding command creates .env placeholders automatically. Hard-coding credentials is strictly prohibited per CHANGELOG.md (lines 573-580).

Personal-use warnings: For portals with terms of service restricting automated access, the skill must display a prominent "personal-use only" notice. CI ensures such skills are not enabled by default, as noted in CONTRIBUTING.md (line 70).

Robots.txt compliance: Generated CLIs must set a descriptive user-agent string (Mozilla/5.0 (compatible; <portal>-cli/1.0)) and respect robots.txt. If a portal disallows access, the skill generation process must halt, according to CHANGELOG.md (lines 586-590).

Zero Runtime Dependencies and Validation

To ensure portability and fast cold starts, portal skills should minimize external dependencies.

Zero-dependency preference: By default, skills must not pull in heavy libraries such as Selenium. The reference implementation freehire-search achieves this by using pure HTTP/HTML parsing with zero runtime dependencies.

Strict flag validation: All portal CLIs must reject unknown flags with exit status 1. This prevents silent misconfiguration and is verified by CI, as detailed in CHANGELOG.md (lines 242-248).

Implementation Example

Below is a minimal implementation skeleton demonstrating the contract requirements:

SKILL.md configuration:


# Jobindex portal skill

enabled: true
description: |
  Provides search & detail commands for jobindex.dk.
type: portal-search
cli: jobindex-search

search command implementation (TypeScript/Bun):

#!/usr/bin/env bun
import { fetchJobs } from "./fetch.ts";

const args = parseArgs(process.argv.slice(2));

if (!args.query) {
  console.error(JSON.stringify({error: "Missing --query"}));
  process.exit(1);
}

const page = Number(args["page"] ?? 1);
const perPage = Number(args["per-page"] ?? 20);

(async () => {
  const jobs = await fetchJobs(args.query, {page, perPage});
  console.log(JSON.stringify({jobs}));
})().catch(err => {
  console.error(JSON.stringify({error: err.message}));
  process.exit(1);
});

detail command implementation:

#!/usr/bin/env bun
import { fetchDetail } from "./fetch.ts";

const id = process.argv[2];
if (!id) {
  console.error(JSON.stringify({error: "Missing job id"}));
  process.exit(1);
}

(async () => {
  const job = await fetchDetail(id);
  console.log(JSON.stringify(job));
})().catch(err => {
  console.error(JSON.stringify({error: err.message}));
  process.exit(1);
});

Framework invocation:


# Auto-discover and run all enabled portal skills

ai-job-search /scrape

# Health check a specific portal

ai-job-search /scrape health jobindex

# Force JSON output for downstream processing

ai-job-search /scrape --format json

Summary

  • Portal skills are CLI-based plugins located in .agents/skills/ that integrate with the AI Job Search Framework core.
  • Mandatory commands: Every skill must implement search (list jobs) and detail (single job) subcommands with --format json support.
  • Error contract: Write JSON errors to stderr and exit with status 1; implement automatic retry with back-off for HTTP 429/5xx responses.
  • Metadata requirements: Include enabled: true|false in SKILL.md and always return a top-level date field in ISO-8601 format.
  • Security constraints: Read API tokens from environment variables only, display personal-use warnings for restricted portals, and respect robots.txt.
  • CI enforcement: Zero runtime dependencies, strict unknown flag rejection, and retry policies are verified by the continuous integration pipeline.

Frequently Asked Questions

What happens if a portal skill does not implement the --format flag?

The core framework will fail to parse the output during the /scrape workflow. While the CLI contract defined in CONTRIBUTING.md requires support for json, table, and plain formats, only JSON is consumed by the framework. Missing this flag causes the scraper to treat the skill as non-compliant.

How does the framework handle rate limiting from job portals?

Portal skills must implement automatic retry logic with exponential back-off when receiving HTTP 429 or 5xx status codes. This constraint is enforced by CI tests that verify the skill's resilience. The framework itself does not handle retries; it expects the CLI to manage transient failures and either return valid JSON or exit with status 1.

Can I use Selenium or Puppeteer in a portal skill?

While technically possible, the architecture strongly discourages heavy runtime dependencies. The constraint for zero runtime dependencies means skills should use pure HTTP clients and HTML parsers like the reference freehire-search implementation. Heavy browser automation libraries violate the lightweight, portable design philosophy unless explicitly justified.

Where should I declare if my portal skill requires an API key?

API tokens must never be hard-coded. Instead, declare the requirement in your skill's documentation and use a .env file placeholder created by the /add-portal scaffolding command. The skill must read the token from environment variables at runtime, as specified in the token handling section of CHANGELOG.md (lines 573-580).

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 →