Overview
Auto-Skill integrates with Skills.sh , a community registry of 27,000+ coding agent skills. The External Skill Loader enables runtime skill discovery, loading, and execution from multiple sources:
Skills.sh API : 27,000+ community skills
GitHub registries : Direct repository integration
.well-known endpoints : RFC 8615 skill discovery
Architecture
Skill Sources
The loader supports pluggable skill source providers:
src/core/external-skill-loader.ts
export interface SkillSource {
name : string ;
enabled : boolean ;
search ( query : string , limit : number ) : Promise < SkillSearchResult []>;
}
ExternalSkill Interface
export interface ExternalSkill {
id : string ;
title : string ;
description : string | null ;
source : string ; // owner/repo
installCount : number ;
relevanceScore : number ;
content : string | null ; // Full SKILL.md content
rawUrl : string | null ;
skillsShUrl : string | null ;
githubUrl : string | null ;
version ?: string ;
allowedTools ?: string [];
tags ?: string [];
}
Usage
1. Basic Search
Search for skills across all sources:
Basic Search
Fetch Content
import { createExternalSkillLoader } from "auto-skill" ;
const loader = createExternalSkillLoader ();
await loader . start ();
const response = await loader . search ( "nextjs" , {
limit: 10 ,
includeContent: false , // Don't fetch full content yet
});
console . log ( `Found ${ response . count } skills:` );
for ( const skill of response . skills ) {
console . log ( `- ${ skill . title } ` );
console . log ( ` Source: ${ skill . source } ` );
console . log ( ` Installs: ${ skill . installCount } ` );
console . log ( ` URL: ${ skill . skillsShUrl } ` );
}
await loader . stop ();
2. GitHub Integration
The loader automatically fetches skills from GitHub:
Detect Default Branch
The loader detects the repository’s default branch (main/master)
Find SKILL.md
Searches for SKILL.md in standard locations:
skills/{skillId}/SKILL.md
{skillId}/SKILL.md
SKILL.md
Fetch Content
Downloads the raw SKILL.md content via GitHub’s raw.githubusercontent.com
src/core/external-skill-loader.ts
class GitHubClient {
async fetchSkill ( source : string , skillId : string ) : Promise < GitHubFetchResult > {
const [ owner , repo ] = source . split ( "/" );
// 1. Get default branch
const branch = await this . getDefaultBranch ( owner , repo );
// 2. Find SKILL.md path
const skillPath = await this . findSkillPath ( owner , repo , branch , skillId );
if ( ! skillPath ) {
return { success: false , error: "SKILL.md not found" };
}
// 3. Fetch raw content
const rawUrl = `https://raw.githubusercontent.com/ ${ owner } / ${ repo } / ${ branch } / ${ skillPath } ` ;
const response = await fetch ( rawUrl );
const content = await response . text ();
return { success: true , content , rawUrl };
}
}
3. Caching
The loader uses an in-memory cache to reduce API calls:
class InMemoryCache {
private cache = new Map < string , CacheEntry < unknown >>();
private defaultTtl : number = 86400 ; // 24 hours
async get < T >( key : string ) : Promise < T | null > {
const entry = this . cache . get ( key );
if ( ! entry || entry . expiresAt < Date . now ()) {
return null ;
}
return entry . value ;
}
async set < T >( key : string , value : T , ttl ?: number ) : Promise < void > {
const ttlMs = ( ttl ?? this . defaultTtl ) * 1000 ;
this . cache . set ( key , {
value ,
expiresAt: Date . now () + ttlMs ,
});
}
}
Cache entries expire after 24 hours by default. Configure with cacheTtl option.
Skills.sh Integration
The Skills.sh source provider searches the community registry:
src/core/external-skill-loader.ts
class SkillsShSource implements SkillSource {
name = "skills.sh" ;
enabled = true ;
private baseUrl = "https://skills.sh" ;
async search ( query : string , limit : number ) : Promise < SkillSearchResult []> {
const url = new URL ( ` ${ this . baseUrl } /api/search` );
url . searchParams . set ( "q" , query );
url . searchParams . set ( "limit" , String ( limit ));
const response = await fetch ( url . toString (), {
headers: {
"Accept" : "application/json" ,
"User-Agent" : "auto-skill/5.0.0" ,
},
});
const data = await response . json ();
return data . results . map (( item ) => ({
id: item . id ,
name: item . name ,
source: ` ${ item . owner } / ${ item . repo } ` ,
sourceRegistry: "skills.sh" ,
installs: item . install_count ?? 0 ,
}));
}
}
Relevance Ranking
Skills are ranked by relevance to improve search results:
class RelevanceRanker {
rank ( skills : ExternalSkill [], query : string ) : ExternalSkill [] {
// Multi-signal ranking:
// 1. Query match score
// 2. Install count (popularity)
// 3. Content relevance (when available)
// For now: sort by install count
return skills . sort (( a , b ) => b . installCount - a . installCount );
}
}
API Reference
createExternalSkillLoader(options?)
Factory function to create an ExternalSkillLoader instance.
GitHub personal access token for increased rate limits (60 → 5,000 requests/hour)
Cache TTL in seconds (default: 24 hours)
ExternalSkillLoader Methods
Start the loader and initialize the cache cleanup interval.
Stop the loader and clear cache cleanup interval.
search
(query: string, options?) => Promise<SkillSearchResponse>
Search for skills across all enabled sources. Options:
limit?: number - Maximum results (default: 10)
includeContent?: boolean - Fetch full SKILL.md content (default: false)
Returns: interface SkillSearchResponse {
query : string ;
count : number ;
skills : ExternalSkill [];
}
getCacheStats
() => Promise<CacheStats>
Get cache statistics. Returns: interface CacheStats {
size : number ;
hits : number ;
misses : number ;
}
Example: Manual Skill Loading
examples/proactive-discovery.ts
import {
createExternalSkillLoader ,
createProactiveDiscovery ,
createSkillRecommendationEngine ,
} from "auto-skill" ;
const loader = createExternalSkillLoader ();
const discovery = createProactiveDiscovery ( loader );
const engine = createSkillRecommendationEngine ( loader , discovery );
await loader . start ();
// Search for a specific skill
const skills = await engine . searchSkills ( "vercel deployment" , 5 );
if ( skills . length > 0 ) {
// Load the first skill with full content
const firstSkill = skills [ 0 ];
const fullSkill = await engine . loadExternalSkill (
firstSkill . source ,
firstSkill . id
);
if ( fullSkill ?. content ) {
console . log ( "✅ Skill loaded successfully!" );
console . log ( `Content length: ${ fullSkill . content . length } chars` );
}
}
await loader . stop ();
Best Practices
Use includeContent: false for listings
When displaying search results, set includeContent: false to avoid fetching full SKILL.md files. Only fetch content when the user selects a specific skill.
Set GITHUB_TOKEN environment variable or pass githubToken option to increase rate limits from 60 to 5,000 requests/hour.
Always call start() and stop()
Call loader.start() before searching and loader.stop() when done to properly manage cache cleanup.
See Also
Proactive Discovery Context-aware skill recommendations
Skill Graduation Promote external skills to local