Chuyển tới nội dung chính

Skill Development Guide

A Skill is an extension package for the Agent system, made up of a prompt + tool scripts + reference material. Skills let you inject domain-specific knowledge and custom tool capabilities into the AI.

Skill directory structure

my-skill/
├── SKILL.cat.md # Required: metadata + prompt (entry file)
├── scripts/ # Optional: SkillScript tool scripts
│ ├── search.js
│ └── export.js
└── references/ # Optional: reference material files
├── api-docs.md
└── examples.json

SKILL.cat.md is the Skill's entry file. When installing from a URL, ScriptCat fetches this file first, then fetches the other files by their relative paths based on the scripts and references declared in its frontmatter.

SKILL.cat.md format

SKILL.cat.md uses YAML frontmatter to declare metadata, with the Markdown body serving as the prompt given to the AI.

---
name: "weather-assistant"
description: "Weather lookup assistant, supports weather queries and forecasts for cities worldwide"
config:
apiKey:
title: "OpenWeather API Key"
type: "text"
secret: true
required: true
unit:
title: "Temperature unit"
type: "select"
values: ["celsius", "fahrenheit"]
default: "celsius"
detailed:
title: "Detailed mode"
type: "switch"
default: false
maxDays:
title: "Forecast days"
type: "number"
default: 7
---

# Weather assistant

You can use the following tools to look up weather information:

## Tool description

- **get_weather**: look up the current weather and forecast for a specified city
- The `city` parameter is the city name (Chinese and English names both supported)
- The `days` parameter is the number of forecast days

## Usage rules

1. When the user asks about weather, confirm the city name first
2. By default, return current weather + a 3-day forecast
3. Display temperature according to the configured unit

Metadata fields

FieldTypeRequiredDescription
namestringYesUnique Skill identifier (kebab-case English recommended)
descriptionstringYesShort description (shown in the list)
versionstringNoVersion (semver format, e.g. 1.0.0), used for update checks
scriptsstring[]NoList of script filenames (e.g. ["search.js"]); fetched automatically from the scripts/ directory when installing via URL
referencesstring[]NoList of reference-material filenames (e.g. ["api-docs.md"]); fetched automatically from the references/ directory when installing via URL
configobjectNoConfiguration field definitions

Configuration field types

typeDescriptionType-specific properties
textText inputsecret: whether it's masked in the UI
numberNumber input
selectDropdownvalues: option list (string[])
switchToggle

Common properties:

PropertyTypeDescription
titlestringDisplay title
requiredbooleanWhether it's required
defaultunknownDefault value
secretbooleanWhether it's sensitive information

The user fills in these config values in the Skill's settings on the management page.

The prompt body

The Markdown body is injected as the AI's system prompt. Writing tips:

  • Describe the tools the Skill provides and what they're for
  • Explain what each tool's parameters mean and the rules for using them
  • Give typical usage scenarios and things to watch out for
  • If there's reference material, explain how to consult it

SkillScript tool scripts

A SkillScript is a tool script the AI can call. Each SkillScript file gets registered as one LLM tool.

Metadata format

// ==SkillScript==
// @name get_weather
// @description Look up weather information for a specified city
// @param city string [required] City name, Chinese and English names both supported
// @param days number Number of forecast days, defaults to 3
// @param format string [json,text] Output format
// @grant CAT.agent.opfs
// @require https://cdn.example.com/utils.js
// @timeout 60
// ==SkillScript==

Metadata fields

TagDescriptionExample
@nameTool name (used when the AI calls it)get_weather
@descriptionTool description (the AI uses this to decide when to call it)Look up city weather
@paramParameter definition (can appear multiple times)see below
@grantThe GM API permission it needsCAT.agent.opfs
@requireExternal library URL (loaded and cached)https://cdn.example.com/lib.js
@timeoutExecution timeout in seconds60 (default 300)

@param syntax

@param paramName type[enumValues] [required] description

Types: string, number, boolean

Enum values (optional): wrapped in square brackets, comma-separated

Required marker: [required] before the description

// Required string parameter
// @param city string [required] City name

// String parameter with an enum
// @param unit string [celsius,fahrenheit] Temperature unit

// Optional number parameter
// @param days number Number of forecast days

// Boolean parameter
// @param detailed boolean Whether to return detailed information

Parameter definitions are automatically converted to JSON Schema for the LLM to use when calling the tool.

Writing the script

// ==SkillScript==
// @name get_weather
// @description Look up weather information for a specified city
// @param city string [required] City name
// @param days number Number of forecast days
// @timeout 30
// ==SkillScript==

// 1. Receive the parameters the AI passed in via arguments[0]
const { city, days = 3 } = arguments[0];

// 2. CAT_CONFIG provides the Skill configuration the user filled in on the management page
const apiKey = CAT_CONFIG.apiKey;
const unit = CAT_CONFIG.unit || "celsius";

// 3. Do the actual work
const url = `https://api.openweathermap.org/data/2.5/forecast?q=${city}&cnt=${days}&units=${unit === "celsius" ? "metric" : "imperial"}&appid=${apiKey}`;
const response = await fetch(url);

if (!response.ok) {
throw new Error(`API request failed: ${response.status}`);
}

const data = await response.json();

// 4. Return the result to the AI via `return`
return {
city: data.city.name,
country: data.city.country,
forecasts: data.list.map(item => ({
date: item.dt_txt,
temp: item.main.temp,
description: item.weather[0].description
}))
};

Execution environment

FeatureDescription
Execution locationA sandboxed, isolated environment (no DOM access)
Getting parametersarguments[0] — the parameter object the AI passed in
Getting configCAT_CONFIG — a global, read-only object containing the user's configuration
Return valueThe return statement returns a JSON-serializable value
Async supportasync/await, fetch, and Promise are all supported
External librariesLoaded via @require, cached locally
Timeout300 seconds by default, customizable via @timeout
GM APIUsable once declared via @grant (e.g. CAT.agent.opfs)

@require external libraries

// ==SkillScript==
// @name analyze
// @description Data analysis
// @require https://cdn.jsdelivr.net/npm/lodash@4/lodash.min.js
// ==SkillScript==

// A library loaded via @require can be used directly
const result = _.groupBy(data, "category");
return result;

External libraries are cached the first time they're loaded, and subsequent executions use the cached version directly.

Reference material

Files in the references/ directory serve as reference material the AI can consult. When the AI needs them, it reads them via the built-in read_reference tool.

Content that's a good fit for reference material:

  • API documentation
  • Data format specifications
  • Collections of usage examples
  • Domain knowledge documents

Example repository

There's an officially maintained repository of Skill examples, containing several ready-to-use Skills and script API examples:

scriptscat/skills

Skill list:

DirectoryDescriptionInstall
browser-automation/Page analysis, DOM manipulation, form filling, screenshots, navigationInstall
scheduled-tasks/Cron scheduled tasks (internal + event mode)Install
skill-creator/Helps create, test, and package new SkillsInstall
file-parser/Parses common file formats (Excel, PDF, Word, CSV, PPT)Install
scriptcat-dev/ScriptCat/Tampermonkey script development assistantInstall
synology-office-sheet/Read/write Synology Office spreadsheetsInstall
wechat-publisher/WeChat Official Account operations assistant — content gathering, article writing, and publishingInstall
xiaohongshu-publisher/Xiaohongshu (RED) operations assistant — note writing, image generation, and publishingInstall

Example code:

DirectoryDescription
examples/conversation/Conversation API examples — chat, streaming, tool calls
examples/dom/DOM API examples — reading pages, filling forms, tab management
examples/config/Skill config examples — declaring config fields and using CAT_CONFIG
examples/page_copilot.user.jsA complete user script example — a right-click AI assistant with a streaming UI

It's a good idea to start learning Skill development from the code in the example repository.

Installation methods

Install from a URL

Open a SKILL.cat.md URL directly in your browser; ScriptCat will intercept it and pop up an install page.

You can also do this from the management page → Agent → Skill management:

  1. Click the URL-install button
  2. Paste the SKILL.cat.md URL
  3. Confirm the install

ScriptCat fetches SKILL.cat.md first, then fetches the other files by their relative paths based on the scripts and references declared in its frontmatter. After installing, installUrl is recorded, so updates can later be checked by version number.

Install from a script

// ==UserScript==
// @grant CAT.agent.skills
// ==/UserScript==

await CAT.agent.skills.install(
skillMdContent,
[{ name: "search.js", code: scriptCode }],
[{ name: "docs.md", content: docsContent }]
);

How Skills are loaded

Skills use three-tier progressive loading to optimize context usage:

TierWhenContent
SummaryAt the start of a conversationSkill name + description + tool list (injected into the system prompt)
PromptWhen the AI actively calls load_skillThe full body of SKILL.cat.md
ToolsAfter load_skillSkillScripts are registered as callable LLM tools

The AI calls load_skill automatically when it needs to load a Skill's full content and tools.

Full example

Directory structure

translator-skill/
├── SKILL.cat.md
├── scripts/
│ └── translate.js
└── references/
└── language-codes.md

SKILL.cat.md

---
name: "translator"
description: "Multilingual translation tool, supports 100+ languages"
version: "1.0.0"
scripts:
- translate.js
references:
- language-codes.md
config:
apiKey:
title: "Translation API Key"
type: "text"
secret: true
required: true
defaultTarget:
title: "Default target language"
type: "select"
values: ["zh", "en", "ja", "ko", "fr", "de", "es"]
default: "zh"
---

# Translation assistant

Use the `translate` tool to translate text. Refer to language-codes.md for the full list of language codes.

## Usage rules

- If the user hasn't specified a target language, use the default language from the configuration
- Long text is automatically translated in chunks
- Preserve the original formatting (Markdown, code blocks, etc.)

scripts/translate.js

// ==SkillScript==
// @name translate
// @description Translate text into a specified language
// @param text string [required] The text to translate
// @param target string Target language code (uses the config value by default)
// @param source string Source language code (auto-detected by default)
// @timeout 60
// ==SkillScript==

const { text, target, source } = arguments[0];
const apiKey = CAT_CONFIG.apiKey;
const targetLang = target || CAT_CONFIG.defaultTarget || "zh";

const response = await fetch("https://api.example.com/translate", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${apiKey}`
},
body: JSON.stringify({
text,
target_language: targetLang,
source_language: source || "auto"
})
});

if (!response.ok) {
throw new Error(`Translation failed: ${response.statusText}`);
}

const result = await response.json();
return {
original: text,
translated: result.translated_text,
source_language: result.detected_language,
target_language: targetLang
};

references/language-codes.md

# Language code reference

| Code | Language |
|------|------|
| zh | Chinese |
| en | English |
| ja | Japanese |
| ko | Korean |
| fr | French |
| de | German |
| es | Spanish |
| ... | ... |