How Portal Skills Are Defined and Discovered in the AI Job Search Framework
Portal skills in the AI Job Search Framework are modular job-portal integrations defined by YAML-front-matter SKILL.md files stored under .agents/skills/, which the system auto-discovers via glob patterns and orchestrates through the job-scraper skill during /scrape execution.
The MadsLorentzen/ai-job-search repository implements a plug-and-play architecture where each job portal exists as a standalone skill. Understanding how these portal skills are structured and discovered is essential for customizing or extending the framework's data aggregation capabilities.
What Are Portal Skills?
A portal skill is a self-contained integration package that encapsulates everything needed to scrape a specific job board. Rather than hardcoding portal logic into the core application, the framework treats each integration as a portable module living in its own directory under .agents/skills/.
Each portal skill is described by a SKILL.md file that combines machine-readable metadata with human-readable documentation. This design allows the AI agent to understand how to invoke the portal without requiring changes to the orchestration code.
SKILL.md Schema and Structure
The SKILL.md file serves as both configuration manifest and technical documentation. It uses YAML front-matter surrounded by triple dashes (---) followed by a Markdown body.
Required YAML Front-matter Fields
Every SKILL.md must declare these fields:
name: The human-readable portal identifier (e.g.,linkedin-search)version: Semantic version string (e.g.,1.0.0)description: Concise summary used for trigger matching and UI displayenabled: Boolean toggle (trueby default) that determines whether the portal participates in/scrapeoperationsallowed-tools: Declares the exact CLI command the framework may execute (e.g.,Bash(bun run skills/<name>/cli/src/cli.ts *))context: Origin marker (e.g.,fork,official) indicating the skill's provenance
Body Documentation
Following the front-matter, the Markdown body documents:
- Exact CLI flags and argument patterns
- Usage examples and query transformation rules
- Personal-use warnings or rate-limit notices
- Links to supplementary files like
url-reference.md
The Auto-Discovery Mechanism
When the /scrape command executes, the job-scraper skill located at .claude/skills/job-scraper/SKILL.md performs a four-step discovery process:
-
Glob the directory: The framework searches for files matching the pattern
.agents/skills/*/SKILL.mdusing filesystem globbing. -
Parse front-matter: Each discovered file is read and its YAML header parsed. The
enabledfield is evaluated immediately—portals are active unless explicitly set tofalse. -
Extract CLI invocation: The
allowed-toolsentry provides the exact shell command template (typicallybun runinvocations pointing to TypeScript CLI entry points). -
Execute portal CLI: The scraper transforms the user's query into portal-specific flags as documented in the skill, then invokes the extracted command.
Because discovery relies solely on filesystem presence and valid SKILL.md syntax, adding a new portal requires zero code changes to the core framework.
Enabling and Disabling Portals
The enabled field in SKILL.md front-matter acts as a soft-delete mechanism. When set to true (the default), the portal is included in the next /scrape run. When set to false, the framework skips the portal entirely without removing its files from .agents/skills/.
This toggle allows users to temporarily disable unreliable or rate-limited portals while preserving the integration for future use. The job-scraper skill explicitly honors this flag during its parsing phase, as documented in its own SKILL.md implementation.
Real-World Example: LinkedIn Search
The LinkedIn portal skill demonstrates the complete structure. Located at .agents/skills/linkedin-search/SKILL.md, the file defines:
---
name: linkedin-search
version: 1.0.0
description: Search LinkedIn job listings using the public `jobs-guest` endpoint.
enabled: true
allowed-tools: Bash(bun run skills/linkedin-search/cli/src/cli.ts *)
context: fork
---
When /scrape runs, the framework reads this file, confirms enabled: true, extracts the Bash(bun run ...) command, and executes it with appropriately translated query parameters. The body of the file contains the flag reference specifying how to map search terms to the CLI's expected arguments.
The same pattern appears in .agents/skills/freehire-search/SKILL.md, demonstrating how different API-based portals follow identical structural conventions.
Extending the Framework with New Portals
The /add-portal command utilizes the same discovery logic. When invoked with --list, it glob-reads all .agents/skills/*/SKILL.md files and renders a table displaying name, market focus, and data source for each installed portal.
To add a new portal, create a directory under .agents/skills/ containing:
- A properly formatted
SKILL.mdwith valid front-matter - An optional CLI implementation (typically TypeScript executed via
bun)
The next invocation of /scrape automatically detects and executes the new skill without requiring registration in any central configuration file. This architecture is documented in .claude/commands/add-portal.md.
Summary
- Portal skills are modular integrations stored as subdirectories under
.agents/skills/, each defined by aSKILL.mdfile. - Auto-discovery works via glob pattern matching (
.agents/skills/*/SKILL.md) performed by the job-scraper skill during/scrapeexecution. - The
enabledboolean in YAML front-matter controls participation in scraping without requiring file deletion. - Zero-code deployment is possible because the framework extracts CLI commands from the
allowed-toolsfield and executes them dynamically. - New portals are automatically picked up on the next run once their
SKILL.mdis placed in the correct directory structure.
Frequently Asked Questions
What file defines a portal skill in the AI Job Search Framework?
Each portal skill is defined by a SKILL.md file located at .agents/skills/<portal-name>/SKILL.md. This file contains YAML front-matter specifying metadata, enabled status, and the CLI command to execute, followed by Markdown documentation explaining usage and parameters.
How does the framework decide which portals to run during a scrape?
The job-scraper skill (.claude/skills/job-scraper/SKILL.md) glob-reads all SKILL.md files under .agents/skills/ and checks the enabled field in each file's front-matter. Only portals with enabled: true (the default) are invoked; those with enabled: false are skipped without deletion.
Can I add a new job portal without modifying the core codebase?
Yes. The framework uses drop-in discovery: create a new directory under .agents/skills/ containing a valid SKILL.md file and optional CLI code. The next /scrape command automatically detects and executes the new portal by reading its configuration—no central registry or code changes are required.
What is the purpose of the allowed-tools field in SKILL.md?
The allowed-tools field declares the exact shell command the AI agent is permitted to run for that portal, typically formatted as Bash(bun run skills/<name>/cli/src/cli.ts *). This declaration serves as both execution template and security boundary, ensuring the scraper only runs explicitly authorized binaries with the correct path structure.
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 →