Generates PowerPoint presentations through Felo's API directly from Claude Code. You give it a topic or outline, it creates a task, polls until complete, and returns a shareable PPT link. Supports custom themes if you look them up first, and handles timeouts gracefully by letting you resume with the same task ID instead of creating duplicates. The workflow is straightforward: check for an API key, run the bundled Node script with your prompt, wait for terminal status. Useful when you need actual slide decks instead of markdown outlines, though you'll need a Felo API key from their settings page first.
npx -y skills add felo-inc/felo-skills --skill felo-slides --agent claude-codeInstalls into .claude/skills of the current project.
Trigger this skill for requests about creating presentation files:
Trigger keywords:
/felo-slides, "use felo slides"Do NOT use this skill for:
felo-search)Linux/macOS:
export FELO_API_KEY="your-api-key-here"
Windows PowerShell:
$env:FELO_API_KEY="your-api-key-here"
Use Bash tool commands and follow this workflow exactly.
if [ -z "$FELO_API_KEY" ]; then
echo "ERROR: FELO_API_KEY not set"
exit 1
fi
If key is missing, stop and return setup instructions.
Use the bundled script (no jq dependency):
node felo-slides/scripts/run_ppt_task.mjs \
--query "USER_PROMPT_HERE" \
--interval 10 \
--max-wait 1800 \
--timeout 60
To apply a specific theme, first list available themes with felo ppt-themes, then pass the theme ID:
node felo-slides/scripts/run_ppt_task.mjs \
--query "USER_PROMPT_HERE" \
--theme "THEME_ID_HERE" \
--interval 10 \
--max-wait 1800 \
--timeout 60
Script behavior:
POST https://openapi.felo.ai/v2/ppts--theme <id> to apply a PPT theme (sends ppt_config.ai_theme_id)--livedoc-id <id> to reuse an existing LiveDoc instead of auto-creating a new one--task-id <id> to resume polling an existing task (skips creation)GET https://openapi.felo.ai/v2/tasks/{task_id}/historicalCOMPLETED/SUCCESS as success terminal (case-insensitive)FAILED/ERROR as failure terminalppt_url on success (fallback: live_doc_url)Optional debug output:
node felo-slides/scripts/run_ppt_task.mjs \
--query "USER_PROMPT_HERE" \
--interval 10 \
--max-wait 1800 \
--json \
--verbose
This outputs structured JSON including:
task_idtask_statusppt_urllive_doc_urllivedoc_short_idppt_business_iderror_messageThe script polls the historical endpoint automatically. Wait for it to exit before responding:
COMPLETED or SUCCESS, and the script prints
ppt_url (fallback: live_doc_url)FAILED or ERROR; return the error format belowtask_id and tell the user to resume with --task-id
instead of creating a duplicate PPT taskOn success, return:
ppt_url immediately (script default output, fallback live_doc_url)--json is used, also include task_id, terminal status, and optional metadataUse this response structure:
## PPT Generation Result
- Task ID: <task_id>
- Status: <status>
- PPT URL: <ppt_url>
- Live Doc URL: <live_doc_url or N/A>
## Notes
- livedoc_short_id: <value or N/A>
- ppt_business_id: <value or N/A>
Error format:
## PPT Generation Failed
- Error Type: <error code or category>
- Message: <readable message>
- Suggested Action: <next step>
Known API error codes:
INVALID_API_KEY (401): key invalid or revokedPPT_TASK_CREATE_FAILED (502): create task downstream failedPPT_TASK_QUERY_FAILED (502): query task downstream failedTimeout handling:
task_id so user can query again--task-id instead of --query to avoid creating a duplicate PPT:node felo-slides/scripts/run_ppt_task.mjs \
--task-id "TASK_ID_HERE" \
--interval 10 \
--max-wait 1800
task_id so follow-up queries can continue from the same task.larksuite/cli
googleworkspace/cli
googleworkspace/cli
googleworkspace/cli