Custom Skills
Create your own skills to extend agent capabilities.
Overview
Custom skills allow you to add new functionality to your agents. Skills are script-based modules that agents can invoke to perform specific tasks.
Skill Structure
A skill consists of two files:
skills/
└── my_skill/
├── manifest.toml # Skill metadata and configuration
└── run.sh # Entry point scriptmanifest.toml
name = "my_skill"
description = "What this skill does"
version = "1.0.0"
run_command = "sh"
entrypoint = "run.sh"
needs_network = false
needs_fs_read = true
needs_fs_write = false
needs_env = false| Field | Description |
|---|---|
name | Skill identifier (lowercase, underscores) |
description | What the skill does (shown to agent) |
version | Semantic version |
run_command | Command to run (sh, bash, python) |
entrypoint | Script file to execute |
needs_network | Requires network access |
needs_fs_read | Requires filesystem read |
needs_fs_write | Requires filesystem write |
needs_env | Requires environment variables |
run.sh
#!/bin/bash
# Arguments are passed as JSON array via stdin
# Read arguments
read -r args
# Parse first argument
arg1=$(echo "$args" | jq -r '.[0]')
# Do something
result="Processed: $arg1"
# Output is returned to the agent
echo "$result"Creating a Skill
Method 1: Manual Creation
Create skill directory:
bashmkdir -p ~/.moxxy/agents/default/skills/my_skillCreate manifest:
bashcat > ~/.moxxy/agents/default/skills/my_skill/manifest.toml << 'EOF' name = "my_skill" description = "My custom skill" version = "1.0.0" run_command = "bash" entrypoint = "run.sh" needs_network = false needs_fs_read = true needs_fs_write = false needs_env = false EOFCreate script:
bashcat > ~/.moxxy/agents/default/skills/my_skill/run.sh << 'EOF' #!/bin/bash read -r args arg=$(echo "$args" | jq -r '.[0]') echo "Hello, $arg!" EOF chmod +x ~/.moxxy/agents/default/skills/my_skill/run.shRestart agent:
bashmoxxy agent restart default
Method 2: Via Agent
Ask your agent to create the skill:
Create a skill called "file_counter" that counts files in a directoryThe agent will use the create_skill skill to generate the code.
Method 3: Install from Repository
Install the skill from https://github.com/user/moxxy-skills/tree/main/weatherSkill Types
Shell Scripts (Bash)
#!/bin/bash
read -r args
# Parse arguments
file=$(echo "$args" | jq -r '.[0]')
# Process
if [ -f "$file" ]; then
wc -l < "$file"
else
echo "Error: File not found"
fiPython Scripts
# manifest.toml
run_command = "python"
entrypoint = "run.py"# run.py
import sys
import json
# Read arguments from stdin
args = json.loads(sys.stdin.read())
# Process
result = f"Received: {args[0]}"
# Output
print(result)Complex Skills
For complex skills, you can include multiple files:
skills/
└── api_client/
├── manifest.toml
├── run.sh
├── lib.py # Helper library
└── config.json # ConfigurationInput/Output
Input
Arguments are passed as a JSON array via stdin:
["arg1", "arg2", "arg3"]For MCP skills, an object is passed:
{"param1": "value1", "param2": "value2"}Output
Whatever the script prints to stdout is returned to the agent:
# Simple output
echo "Task completed successfully"
# JSON output (for structured data)
echo '{"status": "success", "count": 42}'Error Handling
Print errors to stderr for proper handling:
if [ error_condition ]; then
echo "Error: Something went wrong" >&2
exit 1
fiExamples
File Processor Skill
# manifest.toml
name = "file_processor"
description = "Process a file and extract information"
version = "1.0.0"
run_command = "bash"
entrypoint = "run.sh"
needs_fs_read = true
needs_fs_write = false#!/bin/bash
# run.sh
read -r args
file=$(echo "$args" | jq -r '.[0]')
operation=$(echo "$args" | jq -r '.[1] // "info"')
case "$operation" in
"info")
echo "File: $file"
echo "Size: $(stat -f%z "$file" 2>/dev/null || stat -c%s "$file") bytes"
echo "Lines: $(wc -l < "$file")"
;;
"head")
head -n 10 "$file"
;;
"tail")
tail -n 10 "$file"
;;
*)
echo "Unknown operation: $operation" >&2
exit 1
;;
esacAPI Client Skill
# manifest.toml
name = "api_client"
description = "Make HTTP requests to external APIs"
version = "1.0.0"
run_command = "bash"
entrypoint = "run.sh"
needs_network = true#!/bin/bash
# run.sh
read -r args
method=$(echo "$args" | jq -r '.[0]')
url=$(echo "$args" | jq -r '.[1]')
data=$(echo "$args" | jq -r '.[2] // empty')
case "$method" in
"GET")
curl -s "$url"
;;
"POST")
curl -s -X POST -H "Content-Type: application/json" -d "$data" "$url"
;;
*)
echo "Unsupported method: $method" >&2
exit 1
;;
esacDatabase Query Skill
# manifest.toml
name = "db_query"
description = "Execute SQL queries against a database"
version = "1.0.0"
run_command = "bash"
entrypoint = "run.sh"
needs_fs_read = true#!/bin/bash
# run.sh
read -r args
query=$(echo "$args" | jq -r '.[0]')
db_path=$(echo "$args" | jq -r '.[1] // "$HOME/.moxxy/data.db"')
sqlite3 -json "$db_path" "$query"Best Practices
Naming
- Use lowercase with underscores:
file_processor - Be descriptive:
csv_analyzer, notprocess - Use verbs:
send_email,fetch_data
Documentation
Include usage examples in the skill:
#!/bin/bash
# Skill: file_processor
# Description: Process files with various operations
#
# Usage:
# <invoke name="file_processor">["path/to/file", "operation"]</invoke>
#
# Operations:
# - info: Show file information
# - head: Show first 10 lines
# - tail: Show last 10 linesError Handling
#!/bin/bash
set -e
read -r args
# Validate input
if [ -z "$args" ]; then
echo "Error: No arguments provided" >&2
exit 1
fi
# Parse safely
file=$(echo "$args" | jq -r '.[0] // empty')
if [ -z "$file" ]; then
echo "Error: File path required" >&2
exit 1
fi
# Check file exists
if [ ! -f "$file" ]; then
echo "Error: File not found: $file" >&2
exit 1
fi
# Process...Security
- Validate inputs - Never trust user input
- Sanitize paths - Prevent directory traversal
- Limit permissions - Request minimal capabilities
- Use WASM - For untrusted operations
Testing Skills
Manual Testing
# Test the skill directly
echo '["test_input"]' | ~/.moxxy/agents/default/skills/my_skill/run.shVia Agent
Test the my_skill skill with the argument "hello"Via API
curl -X POST http://localhost:17890/api/agents/default/skills/my_skill/invoke \
-H "Content-Type: application/json" \
-d '{"args": ["test_input"]}'Distributing Skills
GitHub Repository
Structure a repository for sharing:
moxxy-skills/
├── skills/
│ ├── weather/
│ │ ├── manifest.toml
│ │ └── run.sh
│ ├── translate/
│ │ ├── manifest.toml
│ │ └── run.py
│ └── ...
└── README.mdUsers can install with:
Install the skill from https://github.com/user/moxxy-skills/tree/main/skills/weatherSkill Registry (Future)
A centralized skill registry is planned for easier discovery and installation.