Skill Sources
Skyll aggregates skills from multiple sources, providing a unified search interface.
Available Sources
| Source | Description | Install Counts | Status |
|---|---|---|---|
| skills.sh | Vercel's skill marketplace | ✅ Yes | Enabled by default |
| Skyll Registry | Community-curated list | ❌ No | Enabled by default |
How Multi-Source Works
- Parallel search: All enabled sources are queried simultaneously
- Result merging: Results are combined into a single list
- Deduplication: Skills are deduplicated by
owner/repo/skill-id(skills.sh takes priority) - Content fetch: GitHub API fetches actual SKILL.md content
- Ranking: Combined results are ranked by relevance score
skills.sh
The primary source, powered by skills.sh. Provides:
- Search API with full-text search
- Install counts (popularity data)
- Metadata about skill repositories
Skills from skills.sh have popularity data, which contributes to ranking.
Skyll Registry
A community-curated list maintained in this repository at registry/SKILLS.md.
Contributing to the Registry
- Edit
registry/SKILLS.md - Add your skill in the format:
- skill-id | owner/repo | path/to/skill | Short description - Submit a PR
Requirements:
- Your repo must have a valid
SKILL.mdfile - Follow the Agent Skills Spec
- Keep descriptions under 80 characters
See registry/README.md for full guidelines.
Adding Custom Sources
Implement the SkillSource protocol:
# src/sources/my_source.py
from src.sources.base import SkillSource, SkillSearchResult
class MyCustomSource:
"""Custom skill source."""
REGISTRY_NAME = "my-source"
def __init__(self, enabled: bool = True):
self._enabled = enabled
@property
def name(self) -> str:
return self.REGISTRY_NAME
@property
def enabled(self) -> bool:
return self._enabled
async def __aenter__(self):
# Initialize (e.g., load data, connect to API)
return self
async def __aexit__(self, *args):
# Cleanup
pass
async def search(self, query: str, limit: int = 10) -> list[SkillSearchResult]:
"""Search for skills matching the query."""
results = []
# Your search logic here
# Return SkillSearchResult objects:
results.append(SkillSearchResult(
id="skill-id",
name="Skill Name",
source="owner/repo",
source_registry=self.REGISTRY_NAME,
installs=0, # Set to 0 if no popularity data
description="What the skill does",
))
return results[:limit]
Register the Source
In src/core/service.py:
from src.sources.my_source import MyCustomSource
# In SkillSearchService.__init__:
self._sources = [
SkillsShSource(enabled=True),
SkillRegistrySource(enabled=True),
MyCustomSource(enabled=True), # Add your source
]
Export from Package
In src/sources/__init__.py:
from src.sources.my_source import MyCustomSource
__all__ = [
# ... existing exports
"MyCustomSource",
]
Disabling Sources
Use environment variables:
# Disable the community registry
ENABLE_REGISTRY=false uvicorn src.main:app --port 8000
Source Priority
When the same skill appears in multiple sources:
- skills.sh wins: It has install counts, so its data is preferred
- First seen wins: For ties, the first source to return the skill wins
This ensures popularity data is preserved while allowing community sources to fill gaps.