What is a Skill?
A skill is a folder containing aSKILL.md file and optionally script files. The agent teaches itself how to use them by reading the SKILL.md, then runs the scripts via bash.
Key principles:
- No new tools registered — Skills are not TypeScript functions or API endpoints
- No build step — Just markdown and scripts
- Works with both agents — Pi and Claude Code share the same
skills/active/directory - Progressive disclosure — Agent only reads full instructions when the skill is relevant
How Skills Work
Directory Structure
Loading Mechanism
On-demand (progressive disclosure):- Agent starts, scans skill directories
- Reads only name + description from each
SKILL.mdfrontmatter - Puts skill descriptions in system prompt
- Full instructions are not loaded until agent decides skill is relevant
Runtime Flow Example
Usingbrave-search as an example:
- Startup: Agent scans skills, sees
brave-search/SKILL.md, puts description in system prompt - User request: “Search for python async tutorials”
- Skill selection: Agent sees the description, decides brave-search is relevant
- Load instructions: Agent reads the full SKILL.md to learn the commands
- Execute: Agent runs
skills/brave-search/search.js "python async tutorials" - Script runs:
search.jsruns as child process, reads$BRAVE_API_KEY, calls API, prints to stdout - Response: Agent reads results, responds to user
SKILL.md Format
Every skill must have aSKILL.md file with YAML frontmatter:
Search
Extract Page Content
search.js (simplified)
Building a Simple Bash Skill
Most skills are simple bash scripts. Here’s a complete example:transcribe skill
skills/transcribe/SKILL.md:Building a Node.js Skill
When bash + curl isn’t sufficient (e.g., HTML parsing, complex API clients), use Node.js:Requirements
- package.json — Declare dependencies
- Shebang —
#!/usr/bin/env nodeat the top of .js files - Executable —
chmod +x script.js
Example: YouTube Transcript
skills/youtube-transcript/SKILL.md:Usage
Skill Activation
Skills are activated by symlinking intoskills/active/:
.pi/skills→skills/active/.claude/skills→skills/active/- One activation controls both agents
Credential Setup
If a skill needs an API key:Single-line Secrets
AGENT_LLM_ prefix, exposed as an env var in the Docker container.
Also add to .env for local development:
Multi-line Secrets (JSON files)
For service account files, pipe via stdin:$(cat credentials.json) — it can break on special characters and newlines.
Secret Prefixes
| Prefix | Accessible to Agent? | Use Case |
|---|---|---|
AGENT_ | No (filtered) | Protected secrets (database keys, admin tokens) |
AGENT_LLM_ | Yes | Skill API keys, service credentials |
env-sanitizer extension.
browser-tools Skill
A special built-in skill that uses Chrome DevTools Protocol (CDP) directly — not Playwright, not Puppeteer.How It Works
- Chrome runs with
--remote-debugging-port=9222 - Standalone JS scripts connect to CDP
- Agent calls scripts via bash
Available Scripts
browser-nav.js— Navigate to URLsbrowser-eval.js— Execute JS in the active tabbrowser-search.js— Google searchbrowser-screenshot.js— Take screenshotsbrowser-click.js— Click elementsbrowser-picker.js— Interactive element selector
Requirements
- Visible Chrome window (not headless)
--remote-debugging-port=9222flag- Node.js
Finding More Skills
pi-skills Repository
Official skills collection: github.com/badlogic/pi-skills Available skills:- brave-search
- browser-tools
- gccli (Google Calendar CLI)
- gdcli (Google Drive CLI)
- gmcli (Gmail CLI)
- subagent
- transcribe
- vscode
- youtube-transcript
Installation
For The Pope Bot:- pi-coding-agent
- Claude Code
- Codex CLI
- Amp
- Droid (Factory)
Security Considerations
LLM-Accessible Secrets
Skills run via bash. The agent has access to environment variables:- Protected secrets (
AGENT_*) are filtered byenv-sanitizerextension - LLM-accessible secrets (
AGENT_LLM_*) are deliberately left available for skills - Only give the agent API keys it needs for legitimate tasks
- Rotate keys regularly
Code Execution
Skills execute arbitrary code. Only install skills from trusted sources:- Official pi-skills repository
- Skills you wrote yourself
- Community skills you’ve reviewed
Best Practices
Keep Skills Simple
One skill = one purpose. Avoid monolithic skills that do too much.
Use Descriptive Names
Skill names should be clear and match their function. Use kebab-case.
Write Clear Descriptions
The description is how the agent decides to use the skill. Be specific about when to use it.
Include Examples
Show real command examples in SKILL.md. The agent learns by example.
Handle Errors Gracefully
Check for required env vars, validate arguments, print helpful error messages.
Use Project-Relative Paths
Always use
skills/skill-name/script.sh, not ./script.sh or relative paths.Troubleshooting
Skill Not Appearing in System Prompt
Cause: Not activated or SKILL.md missing frontmatter Solution:Skill Script Not Executable
Cause: Missing execute permissions Solution:Dependencies Not Found
Cause: npm install not run in skill directory Solution:API Key Not Found
Cause: Secret not set or wrong prefix Solution:Advanced Patterns
Multi-Script Skills
One SKILL.md can document multiple related scripts:List PRs
Skills with State
Skills can maintain state in files:Related Documentation
- Security — Secret filtering and credential management
- Docker Agent — How skills run in Docker agent containers
- Skills Format Docs — Official specification