In addition to writing instructions in SKILL.md, you can also add executable code to skills through the scripts directory.
This section will teach you how to use scripts to extend the functionality of your skills.
* * *
## Why Use Scripts
Using scripts allows you to:
* Encapsulate complex logic, avoiding writing large amounts of code in SKILL.md
* Provide tested and reliable implementations
* Allow agents to reuse the same tools and functions
* Handle more complex input/output operations
> Tip: When you find an agent repeatedly implementing the same logic across multiple executions, it is often a good time to create a script.
* * *
## Script Directory Structure
Scripts should be placed in the scripts/ subdirectory of the skill directory:
## Directory Structure
my-skill/
βββ SKILL.md
βββ scripts/
βββ script1.py
βββ script2.sh
βββ helper.js
* * *
## Script Writing Guidelines
### 1. Self-contained
Scripts should be as self-contained as possible, or clearly document their dependencies.
## Self-contained Script Example
#!/usr/bin/env python3
"""
PDF text extraction script
Dependencies: pip install pdfplumber
Run: python scripts/extract_pdf.py input.pdf
"""
import sys
import pdfplumber
def extract_text_from_pdf(pdf_path):
"""Extract text from PDF file"""
with pdfplumber.open(pdf_path)as pdf:
text =""
for page in pdf.pages:
text += page.extract_text()or""
return text
if __name__ =="__main__":
if len(sys.argv)<2:
print("Usage: python extract_pdf.py ")
sys.exit(1)
pdf_path =sys.argv
text = extract_text_from_pdf(pdf_path)
print(text)
### 2. Clear Error Handling
Scripts should provide helpful error messages to help the agent understand what went wrong.
## Error Handling Example
import sys
def main():
if len(sys.argv)<2:
print("Error: Missing required argument",file=sys.stderr)
print("Usage: python script.py ",file=sys.stderr)
sys.exit(1)
input_file =sys.argv
try:
# Execute main logic
process_file(input_file)
except FileNotFoundError:
print(f"Error: File not found {input_file}",file=sys.stderr)
sys.exit(1)
except PermissionError:
print(f"Error: No permission to read file {input_file}",file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Error: Unknown error occurred while processing file: {e}",file=sys.stderr)
sys.exit(1)
if __name__ =="__main__":
main()
### 3. Handle Edge Cases
Scripts should gracefully handle various edge cases instead of crashing.
## Edge Case Handling Example
def validate_input(text):
"""Validate if input is valid"""
if not text:
return False,"Input cannot be empty"
if len(text)>10000:
return False,"Input length exceeds limit (maximum 10000 characters)"
return True,""
# Use validation
is_valid, error_msg = validate_input(user_input)
if not is_valid:
print(f"Validation failed: {error_msg}")
sys.exit(1)
* * *
## Referencing Scripts in SKILL.md
When a skill needs to execute a script, explain how to invoke it in SKILL.md.
Reference script:
## PDF Text ExtractionUse the script to extract text from PDF:```bash python scripts/extract_pdf.py input.pdf ```The script will extract all text from input.pdf and output it to standard output. If you need to save the results to a file:```bash python scripts/extract_pdf.py input.pdf > output.txt ```
> Note: Use paths relative to the skill root directory when referencing scripts.
* * *
## Supported Script Languages
Supported script languages depend on the agent implementation you are using. Common options include:
| Language | Description |
| --- | --- |
| Python | The most common choice, powerful and easy to write |
| Bash | Suitable for system operations and command-line tools |
| JavaScript | Suitable for web-related tasks |
> Tip: Consider the target users' runtime environment when choosing a script language. If unsure, Python is the safest choice.
* * *
## Complete Example: PDF Processing Skill
Let's look at a complete example showing how to combine SKILL.md and scripts:
## Skill Structure
pdf-tool/
βββ SKILL.md
βββ scripts/
βββ extract.py
βββ fill_form.py
βββ merge.py
SKILL.md content:
--- name: pdf-tool description: Process PDF files, including extracting text, filling forms, and merging files. Use cases: process PDF, extract text, fill forms, merge PDF.---## Extract PDF TextExtract text content from a PDF file:```bash python scripts/extract.py input.pdf ```The output is the extracted plain text content.## Fill PDF FormFill a PDF form using JSON data:```bash python scripts/fill_form.py input.pdf data.json output.pdf ``` data.json format:```json { "field_name": "Field Value", "another_field": "Another Value" } ```## Merge PDFMerge multiple PDF files into one:```bash python scripts/merge.py output.pdf input1.pdf input2.pdf input3.pdf ```## Install DependenciesRequires installing pdfplumber and PyPDF2:```bash pip install pdfplumber PyPDF2 ```
* * *
## Two Usage Modes
There are two ways to use code in a Skill:
| Mode | Applicable Scenarios | Requires scripts/ Directory |
| --- | --- | --- |
| One-off command | Only need to call existing tools, no custom logic required | No |
| Self-contained script | Complex logic that needs to be reused | Yes |
* * *
## One-off Commands
When existing package manager tools already meet your needs, you can directly reference them in the SKILL.md instructions without creating a scripts/ directory.
Here are common execution methods for various language ecosystems:
### uvx (Python)
uvx is the built-in tool run command for uv. It runs Python packages in an isolated environment with aggressive caching, making repeated runs almost instantaneous.
## Example
# Run specified version of ruff to check code
uvx ruff@0.8.0 check .
# Run specified version of black to format code
uvx black@24.10.0 .
### pipx (Python)
pipx is a mature alternative to uvx, which can be installed via system package managers (e.g., `brew install pipx`).
## Example
# Run specified version of black
pipx run 'black==24.10.0' .
# Run specified version of ruff
pipx run 'ruff@0.8.0' check .
### npx (Node.js)
npx comes with npm, downloading and running npm packages on demand.
## Example
# Run ESLint check
npx eslint@9 --fix .
# Create project using Vite
npx create-vite@6 my-app
### go run (Go)
Go's built-in tool run command, directly compiles and runs remote packages.
## Example
# Run goimports to format imports
go run golang.org/x/tools/cmd/goimports@v0.28.0 .
# Run golangci-lint check
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 run
> Tips for writing one-off commands: Pin version numbers (e.g., `npx eslint@9.0.0`) to ensure consistent behavior; declare prerequisites in SKILL.md (e.g., "Requires Node.js 18+"); when commands become complex, they should be extracted into the scripts/ directory.
* * *
## Referencing Scripts in SKILL.md
Use relative paths starting from the Skill directory root to reference packaged files.
The Agent will automatically resolve these paths, so no absolute paths are needed.
First, list the available scripts in SKILL.md:
## Example
## Available Scripts
- **`scripts/validate.sh`** β Validate configuration files
- **`scripts/process.py`** β Process input data
- **`scripts/report.py`** β Generate analysis reports
Then reference them in the operation steps:
## Example
## Operation Flow
1. Run the validation script:
```bash
bash scripts/validate.sh "$INPUT_FILE"
2. Process the data:
```bash
python3 scripts/process.py --input results.json
> Script execution paths are relative to the Skill directory root, because the Agent runs commands from the Skill directory. This also applies to auxiliary files like references/*.md.
* * *
## Self-contained Scripts
When you need reusable logic, you can package scripts in the `scripts/` directory and declare dependencies within the script.
The Agent only needs a single command to run it, with no additional installation steps required.
### Python Self-contained Scripts (PEP 723)
PEP 723 defines a standard format for declaring dependencies within Python scripts.
Use `# ///` markers to wrap TOML-formatted dependency declarations:
## Example: Python Self-contained Script
# /// script
# dependencies = [
# "beautifulsoup4",
# ]
# ///
from bs4 import BeautifulSoup
# Sample HTML content
html ='
Welcome
TUTORIAL test
'
# Parse HTML using BeautifulSoup
soup = BeautifulSoup(html,"html.parser")
# Extract paragraph text with class="info"
info_text = soup.select_one("p.info").get_text()
print(info_text)
How to run:
## Example
# Run using uv (recommended)
uv run scripts/extract.py
# Run using pipx
pipx run scripts/extract.py
TUTORIAL test
### Deno Self-contained Scripts
Deno achieves self-containment through `npm:` and