Skills & Tools
Build AgentSkills with hard constraints to avoid token bloat, use the quota checker script, and integrate tools safely. Includes prompt templates and the full check-quotas.sh script.
Skill Builder
About AgentSkills
The AgentSkills specification provides a structure for creating maintainable, token-efficient skills. This prompt follows that model.
Why hard constraints matter
Vague instructions produce bloated, token-hungry skills every time. The hard constraint on line count (~500 lines) forces the agent to:
- Put core workflow in SKILL.md
- Move details into
references/for on-demand loading - Keep token usage low
- Make the skill maintainable
Without constraints, you'll get a 2,000-line skill file that eats half your context window.
Skill structure
A well-structured skill looks like:
skills/
โโโ your-skill-name/
โโโ SKILL.md # Core workflow (~500 lines max)
โโโ references/ # Loaded on-demand
โ โโโ api-docs.md
โ โโโ examples.md
โโโ scripts/ # Optional executables
โโโ helper.shPrompt template
Copy and customize this prompt to have your agent create or refactor a skill:
I need help creating or optimizing an AgentSkill.
Skill name:
[your-skill-name]
Purpose:
What the skill does and when it should activate.
Triggers:
What kinds of tasks or questions should activate this skill.
Tools needed:
Any tools, commands, or APIs the skill will use.
Reference docs:
Docs or specs that should live in references/ for on-demand loading.
Existing skill (if applicable):
Path to the current SKILL.md if this is a refactor.
Please:
- Create or optimize the skill following AgentSkills best practices
- Keep the core workflow in SKILL.md and move details into references/
- Keep SKILL.md under ~500 lines
- Validate the structure using the AgentSkills validator
- Show the final file structure and contentsExample: Creating a new skill
I need help creating an AgentSkill.
Skill name:
weather-checker
Purpose:
Check current weather and forecasts using wttr.in (no API key required).
Triggers:
Questions about weather, temperature, forecast.
Tools needed:
curl to fetch from wttr.in, parsing text output.
Reference docs:
wttr.in documentation should live in references/wttr-in-docs.md
Please:
- Create the skill following AgentSkills best practices
- Keep the core workflow in SKILL.md under ~500 lines
- Move API details into references/
- Show the final file structure and contentsExample: Refactoring an existing skill
I need help optimizing an AgentSkill.
Existing skill:
~/.openclaw/workspace/skills/my-bloated-skill/SKILL.md
Purpose:
The skill works but SKILL.md is 1,800 lines and burns too many tokens.
Please:
- Refactor following AgentSkills best practices
- Keep core workflow in SKILL.md under ~500 lines
- Move details into references/ for on-demand loading
- Validate the structure
- Show what changedBest practices
๐ Keep SKILL.md focused
- โข Describe when to trigger
- โข Show the core workflow
- โข Reference details in
references/
๐ Use references/ for
- โข API documentation
- โข Detailed examples
- โข Error handling tables
- โข Command syntax reference
๐งช Test before deploying
- โข Run a test task
- โข Check token usage
- โข Verify it loads only what it needs
Community skills
Be cautious with third-party skills. A poorly written or malicious skill can cause real problems. Treat community skills as inspiration rather than drop-ins.
Building your own gives you:
- Full understanding of what it does
- Control over token usage
- No dependency on external maintainers
- Better debugging at 2am
Skill security
Set basic rules in your workspace memory files:
- Never expose secrets or API keys
- Ask before external actions
- Verify before destructive operations
Not foolproof, but it helps as a guardrail. See the Security Hardening chapter for more.
Quota Checker Script
check-quotas.sh
Simple script to check API quota status across multiple providers. Returns JSON so you can pipe it to jq or use it in agent prompts.
Installation
cp check-quotas.sh ~/.local/bin/check-quotas
chmod +x ~/.local/bin/check-quotas
# Verify ~/.local/bin is in your PATH
echo $PATH | grep -q "$HOME/.local/bin" || \
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrcConfiguration
The script looks for API keys in ~/.openclaw/credentials/ by default.
mkdir -p ~/.openclaw/credentials
# Add your API keys (raw tokens only, no quotes)
echo "your-api-key-here" > ~/.openclaw/credentials/openrouter
echo "your-api-key-here" > ~/.openclaw/credentials/synthetic
echo "your-api-key-here" > ~/.openclaw/credentials/anthropic
# Set proper permissions
chmod 700 ~/.openclaw/credentials
chmod 600 ~/.openclaw/credentials/*sk-ant-api03-xxxxxraw token only
API_KEY=sk-ant...no ENV format
"sk-ant-api03..."no quotes
Full script
#!/bin/bash
# Check API quotas for various providers
# Returns JSON with quota status
#
# Usage: ./check-quotas.sh
#
# Configure paths below or set environment variables:
# OPENCLAW_SECRETS_DIR - Path to your secrets directory
# CLAUDE_KEYCHAIN_ITEM - macOS Keychain item name for Claude credentials
set -euo pipefail
# Configuration - adjust these paths for your setup
CREDENTIALS_DIR="${OPENCLAW_CREDENTIALS_DIR:-$HOME/.openclaw/credentials}"
CLAUDE_KEYCHAIN="${CLAUDE_KEYCHAIN_ITEM:-Claude Code-credentials}"
# Check Claude Code quota (macOS Keychain)
check_claude_code() {
if ! command -v security &> /dev/null; then
echo "null"
return
fi
local token=$(security find-generic-password \
-s "$CLAUDE_KEYCHAIN" -w 2>/dev/null | \
jq -r '.claudeAiOauth.accessToken' 2>/dev/null || echo "")
if [ -z "$token" ] || [ "$token" = "null" ]; then
echo "null"
return
fi
curl -s https://api.anthropic.com/api/oauth/usage \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "User-Agent: claude-code/2.0.32" \
-H "Authorization: Bearer $token" \
-H "anthropic-beta: oauth-2025-04-20" 2>/dev/null || echo "null"
}
# Check Synthetic quota
check_synthetic() {
local api_key=$(cat "$CREDENTIALS_DIR/synthetic" 2>/dev/null || echo "")
if [ -z "$api_key" ]; then echo "null"; return; fi
curl -s https://api.synthetic.new/v2/quotas \
-H "Authorization: Bearer $api_key" 2>/dev/null || echo "null"
}
# Check OpenRouter quota
check_openrouter() {
local api_key=$(cat "$CREDENTIALS_DIR/openrouter" 2>/dev/null || echo "")
if [ -z "$api_key" ]; then echo "null"; return; fi
curl -s https://openrouter.ai/api/v1/key \
-H "Authorization: Bearer $api_key" 2>/dev/null || echo "null"
}
# Check Anthropic API quota (direct API key)
check_anthropic() {
local api_key=$(cat "$CREDENTIALS_DIR/anthropic" 2>/dev/null || echo "")
if [ -z "$api_key" ]; then echo "null"; return; fi
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $api_key" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-3-haiku-20240307","max_tokens":1,
"messages":[{"role":"user","content":"test"}]}' \
2>/dev/null | \
jq -r 'if .error then "error" else "valid" end' || echo "null"
}
# Build combined JSON output
claude_quota=$(check_claude_code)
synthetic_quota=$(check_synthetic)
openrouter_quota=$(check_openrouter)
anthropic_quota=$(check_anthropic)
jq -n \
--argjson claude "$claude_quota" \
--argjson synthetic "$synthetic_quota" \
--argjson openrouter "$openrouter_quota" \
--arg anthropic "$anthropic_quota" \
'{
claude_code: $claude,
synthetic: $synthetic,
openrouter: $openrouter,
anthropic_api: $anthropic,
checked_at: (now | strftime("%Y-%m-%dT%H:%M:%SZ"))
}'Output format
{
"claude_code": { "usage": {...}, "limit": {...} },
"synthetic": { "credits_remaining": 1000 },
"openrouter": { "usage": 45.23, "limit": 100.00 },
"anthropic_api": "valid",
"checked_at": "2026-02-09T20:28:00Z"
}Parsing output
# Check if a provider is over 90% quota
check-quotas | jq '.openrouter | (.usage / .limit) > 0.9'
# Get remaining Synthetic credits
check-quotas | jq -r '.synthetic.credits_remaining'
# Pretty print for humans
check-quotas | jq .Integration with OpenClaw
# Before spawning expensive agent, check quotas
QUOTAS=$(check-quotas)
OPENROUTER_USAGE=$(echo $QUOTAS | jq -r '.openrouter.usage // 0')
if [ "$OPENROUTER_USAGE" -gt 90 ]; then
echo "OpenRouter quota high, using fallback"
fiAdding new providers
check_yourprovider() {
local api_key=$(cat "$CREDENTIALS_DIR/yourprovider" 2>/dev/null || echo "")
if [ -z "$api_key" ]; then
echo "null"
return
fi
curl -s https://api.yourprovider.com/quota \
-H "Authorization: Bearer $api_key" 2>/dev/null || echo "null"
}Then add it to the final jq output.
Requirements & limitations
๐ฆ Requirements
- โข
bash - โข
curl - โข
jq - โข
security(macOS only, for Keychain)
โ ๏ธ Limitations
- โข Claude Code check only works on macOS
- โข Anthropic API has no public quota endpoint โ just verifies key
- โข Rate limits may apply to quota check APIs