| name | fal-skill-creator |
| description | Generate Claude Code Skills from fal.ai model IDs. Fetches OpenAPI schemas from fal.ai Platform API, generates complete skill directories with SKILL.md, wrapper scripts, and queue config. Use when creating new skills for fal.ai models or running fal.ai API jobs with queue management. |
fal.ai Skill Creator
Generate reusable Claude Code Skills from fal.ai model IDs using the Platform API.
Authentication
All fal.ai operations require the FAL_KEY environment variable:
export FAL_KEY="your-fal-api-key"
File Upload (for image/audio/video inputs)
Many models require URL inputs for media files. Use fal_client to upload local files:
python -c "import fal_client; url=fal_client.upload_file(r'/path/to/file.png'); print(f'URL: {url}')"
python -c "import fal_client; url=fal_client.upload_file('/home/user/image.png'); print(f'URL: {url}')"
python -c "import fal_client; url=fal_client.upload_file('/storage/emulated/0/Download/image.png'); print(f'URL: {url}')"
Supported formats: png, jpg, gif, webp, mp3, wav, mp4, webm, etc.
Quick Start
Generate Skill from Model ID
python .claude/skills/fal-skill-creator/scripts/generate_fal_skill.py \
--model-id fal-ai/flux/dev
python .claude/skills/fal-skill-creator/scripts/generate_fal_skill.py \
--model-id fal-ai/flux/dev --lazy
python .claude/skills/fal-skill-creator/scripts/generate_fal_skill.py \
--model-id fal-ai/flux/dev --standalone
python .claude/skills/fal-skill-creator/scripts/generate_fal_skill.py \
--model-id fal-ai/flux/dev --public
python .claude/skills/fal-skill-creator/scripts/generate_fal_skill.py \
--model-id fal-ai/flux/dev \
--model-id fal-ai/flux/schnell
Output: .claude/skills/<model-name>/
Search for Models
python .claude/skills/fal-skill-creator/scripts/generate_fal_skill.py \
--search "flux" --category "text-to-image"
Direct API Call
python .claude/skills/fal-skill-creator/scripts/fal_api_call.py \
--model-id fal-ai/flux/schnell \
--args '{"prompt": "a cat in a garden"}' \
--output ./output
Using Generated Skills
After generation, use the wrapper script:
python .claude/skills/fal-ai-flux-dev/scripts/fal_ai_flux_dev.py \
--args '{"prompt": "sunset over mountains"}' \
--output ./output
CLI Reference
generate_fal_skill.py
| Option | Short | Description |
|---|
--model-id | -m | fal.ai model ID (can specify multiple) |
--search | -s | Search for models by query |
--category | -c | Filter search by category |
--output | -o | Output directory (default: .claude/skills) |
--name | -n | Custom skill name (single model only) |
--lazy | -l | Minimal SKILL.md (details in YAML) |
--standalone | | Copy shared scripts into generated skill (no symlink) |
--public | | Public-ready mode (--standalone + full skill-tree symlink checks) |
--api-key | -k | DEPRECATED; disabled by default (set FAL_ALLOW_API_KEY_ARG=1 for temporary compatibility) |
fal_api_call.py
| Option | Short | Description | Default |
|---|
--model-id | -m | fal.ai model ID (required) | - |
--args | -a | Submit arguments (JSON) | - |
--args-file | | Load args from JSON file | - |
--api-key | -k | DEPRECATED; disabled by default (set FAL_ALLOW_API_KEY_ARG=1 for temporary compatibility) | FAL_KEY env |
--output | -o | Output directory | ./output |
--output-file | -O | Output file path (--output配下のみ) | auto |
--auto-filename | | {request_id}_{timestamp}.{ext} | off |
--poll-interval | | Status poll interval (seconds) | from config |
--max-polls | | Max poll attempts | computed |
--save-logs | | Save logs to {output}/logs/ | off |
--save-logs-inline | | Save logs alongside output | off |
--no-queue | | Skip queue daemon only (direct queue submit/status/result flow) | off |
--sync-only | | Use fal.run sync API directly (skip queue submit/poll) | off |
Download size limit: 100MB per file.
Queue Management
python .claude/skills/fal-skill-creator/scripts/queue_daemon.py --background
python .claude/skills/fal-skill-creator/scripts/queue_client.py --status
python .claude/skills/fal-skill-creator/scripts/queue_client.py --shutdown
Generated Skill Structure
.claude/skills/<model-name>/
├── SKILL.md
├── queue_config.yaml
├── agents/
│ └── openai.yaml # UI metadata (display_name / prompt)
├── scripts/
│ ├── fal_api_call.py # default: symlink / --standalone: copy
│ ├── queue_client.py # default: symlink / --standalone: copy
│ ├── queue_protocol.py # default: symlink / --standalone: copy
│ ├── queue_daemon.py # default: symlink / --standalone: copy
│ └── <model_name>.py # Wrapper with MODEL_ID preset
└── references/
├── model_config.json # {model_id, name, category, description}
└── tools/ # lazy mode only
└── <model-name>.yaml # Input/output schema + usage examples
fal.ai Queue API Flow
1. SUBMIT → POST queue.fal.run/{model_id} → Get request_id
2. STATUS → GET .../requests/{id}/status → Wait for COMPLETED
3. RESULT → GET .../requests/{id} → Get output URLs
4. DOWNLOAD → Save files locally
Status values: IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED
Recovery behavior:
- If submit returns timeout/network error or HTTP 405, attempt request recovery via Platform API (
/v1/models/requests/by-endpoint) and continue with recovered request_id.
- If queue result endpoints return 405 after submit, do not auto-fallback to sync (duplicate billing risk). Return metadata-only result with
status=RESULT_ENDPOINT_ONLY and platform_request when possible.
Queue Daemon Configuration (queue_config.yaml)
| Setting | Default | Description |
|---|
max_concurrent | 2 | Max simultaneous jobs |
start_interval | 1.0 | Seconds between job starts |
poll_interval | 5.0 | Seconds between status polls |
job_timeout | 600 | Job timeout (10 min) |
global_rate_per_min | 10 | Global rate limit |
global_burst | 5 | Burst allowance |
model_rates | {} | Per-model rate overrides |
client_idle_timeout | 0 | Client idle timeout in seconds (0 = disabled) |
sync_only | true | Keep queue manager enabled but execute each queued job via fal.run sync API (set false to use queue submit/status/result in worker) |
Environment variable overrides: FAL_QUEUE_MAX_CONCURRENT, FAL_QUEUE_RATE_PER_MIN, FAL_QUEUE_CLIENT_IDLE_TIMEOUT, etc.
Security: queue daemon enforces runtime dir ownership/permissions (0700) and only removes stale socket paths when the existing path is a socket/symlink.
Runtime scope:
- Generated wrappers isolate runtime dirs per skill/model (
~/.cache/fal-queue/<skill>__<model>__v2), so concurrency/rate limits apply per skill-model daemon.
- Queue client restarts stale daemons when local scripts/config are newer than the daemon start marker (PID file mtime), reducing mixed old/new behavior risks.
Programmatic Usage
import sys, os
sys.path.insert(0, os.path.join(".claude", "skills", "fal-skill-creator", "scripts"))
from fal_api_call import run_fal_api_job
result = run_fal_api_job(
model_id="fal-ai/flux/schnell",
submit_args={"prompt": "a cat in a garden"},
output_dir="./output",
)
print(result.get("saved_path") or result)
Error Handling
- API errors (4xx/5xx) with automatic retry on transient errors (429, 5xx)
- Job failures (
FAILED status) with descriptive messages
- Timeout after max polls
- Download failures
- Queue daemon connection failures with fallback to direct API
- On submit timeout/network/405, recover
request_id from Platform API before deciding fallback
- If queue submit succeeds but queue endpoints return 405, sync fallback is blocked to prevent duplicate execution/billing
- If queue result endpoints remain unavailable, return
RESULT_ENDPOINT_ONLY with platform_request metadata (no automatic retry)
All errors raise exceptions with descriptive messages.