Overview
Skill registration is the process of making skills available to AI agents through the FastSkill service. Skills can be registered manually through the API or discovered automatically from the filesystem.
Once registered, skills become available for discovery, routing, and execution by AI agents and frameworks.
Before registering a skill, you need to understand the skill definition format. Each skill is defined by a JSON object with specific required and optional fields:
Required Fields
Unique identifier for the skill. Must be alphanumeric with dashes and underscores only. Example: "text-processor", "pdf-extractor-v2".
Human-readable name for the skill. Should be descriptive and user-friendly. Example: "Text Processing Suite", "PDF Document Extractor".
Detailed description of what the skill does and its capabilities. Used for discovery and routing.
Version number following semantic versioning (e.g., “1.0.0”, “2.1.3”). Helps track skill evolution and compatibility.
Optional Fields
Name or organization of the skill creator. Useful for skill attribution and support.
Comma-separated list of tags for categorization. Example: "text,nlp,analysis,extraction".
Comma-separated list of specific capabilities. Example: "text_extraction,sentiment_analysis,keyword_detection".
Path to the skill implementation file (relative to storage path). Example: "text-processor/SKILL.md".
Whether the skill is enabled for use. Defaults to true. Disabled skills are not available for discovery or execution.
Maximum execution time in seconds for this skill. Overrides the global default.
Memory limit in MB for skill execution. Overrides the global default.
List of dependencies required by the skill. Example: ["python-docx", "nltk", "spacy"].
Additional metadata as key-value pairs. Useful for custom extensions.
Manual Registration
Python API
Create skill definition
skill_definition = {
"id" : "text-processor" ,
"name" : "Text Processing Suite" ,
"description" : "Comprehensive text processing capabilities including extraction, analysis, and transformation" ,
"version" : "1.0.0" ,
"author" : "FastSkill Team" ,
"tags" : "text,nlp,analysis,extraction,transformation" ,
"capabilities" : "text_extraction,text_analysis,sentiment_analysis,keyword_extraction,text_transformation" ,
"skill_file" : "text-processor/SKILL.md" ,
"enabled" : True ,
"execution_timeout" : 30 ,
"memory_limit_mb" : 256 ,
"dependencies" : [ "nltk" , "spacy" , "python-docx" ],
"metadata" : {
"category" : "text-processing" ,
"complexity" : "intermediate" ,
"supported_formats" : [ "txt" , "pdf" , "docx" , "html" ]
}
}
Register the skill
from fastskill import FastSkillService
async def register_skill ():
service = FastSkillService()
await service.initialize()
# Register the skill
skill_id = await service.register_skill(skill_definition)
print ( f "✅ Skill registered with ID: { skill_id } " )
# Verify registration
skills = await service.list_skills()
print ( f "📋 Total skills: { len (skills) } " )
await service.shutdown()
# Run the registration
import asyncio
asyncio.run(register_skill())
Update existing skill
async def update_skill ():
service = FastSkillService()
await service.initialize()
# Update skill definition
updated_skill = {
"id" : "text-processor" ,
"name" : "Advanced Text Processing Suite" ,
"description" : "Enhanced text processing with AI-powered analysis" ,
"version" : "1.1.0" , # Version bump
"tags" : "text,nlp,analysis,extraction,transformation,ai" ,
"capabilities" : "text_extraction,text_analysis,sentiment_analysis,keyword_extraction,text_transformation,ai_analysis" ,
"enabled" : True
}
# Update the skill
success = await service.update_skill( "text-processor" , updated_skill)
if success:
print ( "✅ Skill updated successfully" )
else :
print ( "❌ Skill update failed" )
await service.shutdown()
asyncio.run(update_skill())
Rust API
use fastskill :: { FastSkillService , ServiceConfig };
use serde_json :: json;
#[tokio :: main]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
let config = ServiceConfig {
skill_storage_path : PathBuf :: from ( "./skills" ),
.. Default :: default ()
};
let service = FastSkillService :: new ( config ) . await ? ;
service . initialize () . await ? ;
// Create skill definition
let skill_definition = json! ({
"id" : "text-processor" ,
"name" : "Text Processing Suite" ,
"description" : "Comprehensive text processing capabilities" ,
"version" : "1.0.0" ,
"tags" : "text,nlp,analysis" ,
"capabilities" : "text_extraction,text_analysis" ,
"enabled" : true
});
// Register skill
let skill_id = service . skill_manager ()
. register_skill ( skill_definition )
. await ? ;
println! ( "✅ Skill registered: {}" , skill_id );
Ok (())
}
REST API
# Register a skill via REST API
curl -X POST http://localhost:8080/api/skills \
-H "Content-Type: application/json" \
-d '{
"id": "text-processor",
"name": "Text Processing Suite",
"description": "Comprehensive text processing capabilities",
"version": "1.0.0",
"tags": "text,nlp,analysis",
"capabilities": "text_extraction,text_analysis",
"enabled": true
}'
Auto-Discovery
FastSkill can automatically discover and register skills from the filesystem:
Directory Structure
Organize your skills in a directory structure like this:
skills/
├── text-processor/
│ ├── SKILL.json # Skill definition
│ ├── implementation.py # Python implementation
│ └── README.md # Documentation
├── data-analyzer/
│ ├── SKILL.json
│ ├── analyze.py
│ └── requirements.txt
└── web-scraper/
├── SKILL.json
├── scraper.py
└── config.yaml
Enable Auto-Discovery
Configure auto-discovery
from fastskill import ServiceConfig
from pathlib import Path
config = ServiceConfig(
skill_storage_path = Path( "./skills" ),
enable_auto_discovery = True ,
auto_discovery_patterns = [ "**/SKILL.json" , "**/skill.json" ],
auto_discovery_extensions = [ ".json" , ".yaml" , ".yml" ]
)
service = FastSkillService(config)
await service.initialize() # Skills are auto-discovered on startup
Manual discovery trigger
# Trigger discovery manually
await service.skill_manager.discover_skills()
# Or discover from specific paths
await service.skill_manager.discover_skills_from_paths([
Path( "./new-skills" ),
Path( "./custom-skills" )
])
Batch Operations
Register multiple skills efficiently:
Python Batch Registration
async def batch_register_skills ():
service = FastSkillService()
await service.initialize()
# Define multiple skills
skills_to_register = [
{
"id" : "text-extractor" ,
"name" : "Text Extractor" ,
"description" : "Extract text from various document formats" ,
"version" : "1.0.0" ,
"tags" : "text,extraction,documents" ,
"capabilities" : "text_extraction,pdf_processing,docx_processing"
},
{
"id" : "data-validator" ,
"name" : "Data Validator" ,
"description" : "Validate and clean data structures" ,
"version" : "1.0.0" ,
"tags" : "data,validation,cleaning" ,
"capabilities" : "data_validation,data_cleaning,format_checking"
},
{
"id" : "file-organizer" ,
"name" : "File Organizer" ,
"description" : "Organize files by type and content" ,
"version" : "1.0.0" ,
"tags" : "files,organization,management" ,
"capabilities" : "file_management,directory_operations,content_sorting"
}
]
# Register all skills
registered_ids = []
for skill_data in skills_to_register:
try :
skill_id = await service.register_skill(skill_data)
registered_ids.append(skill_id)
print ( f "✅ Registered: { skill_data[ 'name' ] } -> { skill_id } " )
except Exception as e:
print ( f "❌ Failed to register { skill_data[ 'name' ] } : { e } " )
print ( f " \n 🎯 Successfully registered { len (registered_ids) } out of { len (skills_to_register) } skills" )
return registered_ids
Batch Update
async def batch_update_skills ():
service = FastSkillService()
await service.initialize()
# Update multiple skills
updates = [
( "text-extractor" , { "version" : "1.0.1" , "enabled" : True }),
( "data-validator" , { "version" : "1.0.1" , "tags" : "data,validation,cleaning,quality" }),
( "file-organizer" , { "version" : "1.0.1" , "execution_timeout" : 60 })
]
for skill_id, update_data in updates:
success = await service.update_skill(skill_id, update_data)
if success:
print ( f "✅ Updated { skill_id } " )
else :
print ( f "❌ Failed to update { skill_id } " )
Validation
FastSkill validates skill definitions before registration:
Manual validation
# Validate before registration
from fastskill.validation import validate_skill_definition
skill_data = {
"id" : "my-skill" ,
"name" : "My Skill" ,
"description" : "A test skill" ,
"version" : "1.0.0"
}
try :
validate_skill_definition(skill_data)
print ( "✅ Skill definition is valid" )
# Register only if valid
skill_id = await service.register_skill(skill_data)
print ( f "✅ Registered: { skill_id } " )
except ValidationError as e:
print ( f "❌ Validation failed: { e } " )
# Fix the issues before registering
Batch validation
# Validate multiple skills
skills_to_validate = [skill1, skill2, skill3]
valid_skills = []
invalid_skills = []
for skill_data in skills_to_validate:
try :
validate_skill_definition(skill_data)
valid_skills.append(skill_data)
except ValidationError as e:
invalid_skills.append((skill_data, str (e)))
print ( f "✅ Valid skills: { len (valid_skills) } " )
print ( f "❌ Invalid skills: { len (invalid_skills) } " )
# Register only valid skills
for skill_data in valid_skills:
await service.register_skill(skill_data)
CLI Registration
Use the FastSkill CLI for command-line registration:
# Register a skill from JSON file
fastskill register ./skills/text-processor/skill.json
# Register from directory (auto-discovery)
fastskill register --auto ./skills/
# Register with validation
fastskill register --validate ./skill.json
# Batch register multiple files
fastskill register ./skills/ ** / * .json
Best Practices
Use descriptive identifiers
Choose skill IDs that are descriptive and likely to be unique. Include version numbers for skill variants.
Provide comprehensive metadata
Include detailed descriptions, relevant tags, and specific capabilities to improve discoverability.
Version properly
Use semantic versioning and update versions when making breaking changes or adding new features.
Validate before registration
Always validate skill definitions before registering them to catch issues early.
Use auto-discovery for development
Enable auto-discovery during development for faster iteration, but use manual registration in production.
Troubleshooting
Duplicate ID : Each skill must have a unique ID. Check if a skill with the same ID already exists.# Check existing skills
existing_skills = await service.list_skills()
existing_ids = [s[ 'id' ] for s in existing_skills]
Invalid format : Ensure all required fields are present and have the correct types.# Use validation before registration
validate_skill_definition(skill_data)
File not found : If using skill_file, ensure the path exists relative to the storage directory.
Pattern matching : Auto-discovery uses glob patterns. Ensure your files match the configured patterns.
Permission denied : Check that FastSkill has read permissions for skill directories.
Debug discovery : Enable debug logging to see which files are being discovered and why others are skipped.
Performance Considerations
Skill registration is the foundation of FastSkill’s functionality. Take time to understand the skill definition format and validation requirements to avoid common issues.