Claude Code
Build, deploy, debug, and share AI agents on Oya from your terminal.
Overview
The Oya Claude Code skill turns Claude Code into the fastest place to ship and debug agents on the Oya runtime. Once installed, you describe what you want in natural language and Claude Code drives the oya CLI under the hood — designing the persona, picking the right skills, scheduling routines, walking gateway OAuth, and deploying. When something breaks, it lists runs, drills into a failed job_id, reads the full stdout/stderr, matches the symptom against a built-in failure cookbook, proposes a fix, and applies it after you confirm.
Two surfaces, one product:
- oya — a public Python CLI on PyPI. Use it directly, in CI, in scripts.
- Oya Claude Code skill — the natural-language layer that drives the CLI for you.
Install
The skill ships bundled with the CLI package. One install gets you both.
pipx install oya-cli # or: pip install oya-cli
oya login # opens https://oya.ai/api-keys, paste the key
oya install-claude-skill # copies the skill to ~/.claude/skills/oya/Restart Claude Code (or open a new session) so the skill list refreshes.
oya install-claude-skill --link --force to symlink the install — edits to the source dir take effect on the next Claude Code session.The three flows
The skill recognizes your intent and runs the matching flow. You don't pick the flow explicitly — just say what you want.
Build
Triggered when you ask for a new agent: “Create an Oya agent for X”, “Build a [role] for [purpose]”, or similar.
The skill picks the closest curated template (AI SDR, Executive Assistant, ICP Outreach, LinkedIn SDR, ...), applies its full config to a new agent, walks you through OAuth for required gateways, and deploys. If nothing fits, it designs the agent from scratch — persona, behavior rules, welcome message, 8–14 skills, 2–4 scheduled routines, knowledge base entries — to template quality.
Debug
Triggered when you say things like “Why did my agent fail last night?”, “Fix my [agent]”, or “[agent] isn't sending emails”. This is the killer feature.
The skill walks the full diagnostic chain:
- Resolves the agent (oya agent list, fuzzy-match by name).
- Pulls recent runs (oya agent runs <id> --status failed --limit 10).
- Drills into a failed run (oya agent run <id> <job_id>) for full payload + stdout/stderr/error.
- Reads the chat thread (oya agent thread <thread_id>) and Langfuse trace if linked.
- Matches the symptom against the failure cookbook (missing creds, gateway auth expired, skill exception, silent error, rule conflict, model rate-limit, overdue routine, sandbox crash).
- Proposes a fix as a markdown summary, asks for confirmation, then executes — re-auth, edit rules, swap a skill, patch a routine prompt, redeploy.
- Re-triggers the failed routine and confirms green.
Share
Every Oya agent can be exported as a portable JSON spec — soul, skills, routines, and knowledge base in one file, credentials stripped. Drop it in a gist or repo and anyone with the CLI can oya agent fork <url> to clone it.
# Export your agent as a portable spec (creds stripped, safe to share):
oya agent export <id> -o my-sdr.oya.json
# Anyone else can clone it:
oya agent fork ./my-sdr.oya.json
oya agent fork https://gist.githubusercontent.com/.../my-sdr.oya.jsonAfter forking, you wire up your own gateways and credentials, then deploy. The format is documented as OyaAgentSpec v1 below.
What you can ask Claude Code
Concrete prompts that work:
- "Build me a Facebook SDR agent for my SaaS"
- "Why did my AI SDR routine fail at 2am?"
- "Add a daily 9am pipeline summary routine to my SDR"
- "Make my Executive Assistant more concise"
- "Swap apollo for hunter on my SDR — it's rate-limiting"
- "My agent needs to call the Plausible API and there's no skill for it" — Claude Code authors a brand-new sandbox skill
- "Fork this agent: https://gist.githubusercontent.com/.../my-sdr.oya.json"
- "List my agents and tell me which ones are unhealthy"
- "Connect Slack to my Weather agent"
Authoring custom skills
When the agent needs a capability that isn't in the catalog, the skill writes a new one — not a workaround in rest-api, and not extra rules in the persona. A skill is a folder with SKILL.md (YAML frontmatter + markdown body) and script.py (reads INPUT_JSON env var, prints JSON to stdout). Once written, oya import uploads it and the new skill_id is reusable across all your future agents.
# What Claude Code does behind the scenes when you say
# "my agent needs to call the Plausible API":
mkdir -p /tmp/oya-skill-plausible
# (writes SKILL.md + script.py)
oya import /tmp/oya-skill-plausible/ # → returns new skill_id
oya agent skills add <agent_id> plausible-pageviews \
--credentials-json '{"PLAUSIBLE_API_KEY":"..."}'
oya agent deploy <agent_id>Knowledge base vs persona
These are two different surfaces and the skill never confuses them — neither should you when editing manually.
- Persona / behavior rules (oya agent soul) — identity and rules. Loaded every turn, in full. Tight: ~6-line persona, 6–10 specific rules. Long content here dilutes rules and balloons every chat.
- Knowledge base (oya agent kb upload) — reference content the agent retrieves on demand: playbooks, ICP, FAQs, brand voice, examples, product specs. Loaded only when relevant via search-kb. Generous: 5-page playbook is fine.
oya agent kb upload fails. Fix the underlying failure instead. Inlining a 3,000-char pricing table into the persona means every chat carries it forever and the rules get drowned out.OyaAgentSpec v1
The portable JSON format produced by oya agent export and consumed by oya agent fork:
{
"version": "1",
"agent": {
"name": "AI SDR",
"description": "Outbound sales development rep",
"mode": "skills"
},
"soul": {
"persona": "...",
"mission": "...",
"welcome_message": "...",
"behavior_rules": ["...", "..."]
},
"skills": [
{"skill_id": "web-search"},
{"skill_id": "apollo"},
{"skill_id": "memory", "config": {}}
],
"routines": [
{
"name": "Daily lead discovery",
"schedule": "every weekday at 9am",
"schedule_cron": "0 9 * * 1-5",
"prompt": "Pull 25 new leads matching the ICP..."
}
],
"knowledge_base": [
{"filename": "playbook.md", "content": "..."}
]
}Credentials, OAuth tokens, and any field name in {credentials, secrets, tokens, access_token, refresh_token, api_key} are stripped on export. Forks get the structure; you bring the keys.
CLI reference (what the skill drives)
The skill calls these commands in normal use:
# Read / debug
oya agent list
oya agent get <id>
oya agent runs <id> --status failed
oya agent run <id> <job_id>
oya agent thread <thread_id>
oya agent trace <trace_id>
oya agent skills list <id>
oya agent gateway list <id>
oya agent routine list <id>
oya agent kb list <id>
# Re-run
oya agent run-script <id> --message "..."
oya routine run <routine_id>
# Edit
oya agent soul <id> --persona "..." --rule "..." --rule "..." --welcome "..."
oya agent skills add/update/remove/sync <id> ...
oya agent gateway connect <id> <platform>
oya agent routine add/update <id|routine_id> ...
oya agent kb upload <id> <file> --folder "..."
oya agent kb delete <entry_id>
oya agent deploy <id>
# Share
oya agent export <id> -o agent.oya.json
oya agent fork ./agent.oya.json
oya agent fork https://...
# Templates + skill catalog
oya template list/get
oya agent template apply <template_id> <agent_id>
oya list # browse the skill catalog
oya import ./my-skill/ # upload a custom skill
oya export <skill_id> out.zip # download a skillRun oya <subcommand> --help for full options on any command.
Config
- OYA_API_TOKEN — your API key. Stored at ~/.oya/config.json after `oya login`. Used by the CLI for every request.
- OYA_API_URL — defaults to https://oya.ai. Set to https://dev.oya.ai for the dev environment.
Troubleshooting
401 from oya whoami
Token isn't resolving. Run oya logout && oya login. If the token is set via env, double-check it doesn't have a trailing newline.
Claude Code doesn't recognize the skill
Verify ~/.claude/skills/oya/SKILL.md exists. If you ran install-claude-skill and it's not present, re-run with --force. Restart Claude Code (skills are loaded on session start, not invocation).
OAuth flow doesn't complete
Some platforms (Facebook Messenger, WhatsApp, Instagram DM, LinkedIn Messaging) use Unipile-hosted auth pages — open the install URL in a browser and authenticate there. Then run oya agent gateway list <id> to verify the row appears before deploying.
Run history shows no failures but the agent isn't working
Look for silent failures: the skill exited with code 0 but printed an error JSON to stdout. oya agent run <id> <job_id> on a successful-looking run will show this. Common cause: gateway credentials expired and the skill caught its own exception. Re-auth with oya agent gateway connect.
Links
- PyPI: https://pypi.org/project/oya-cli/
- API keys: https://oya.ai/api-keys
- Support: [email protected]