Skills
SKILL.md Reference
This is the authoritative reference for the SKILL.md format. A skill file consists of YAML frontmatter (delimited by ---) followed by a markdown instruction body.
Nebo implements the open Agent Skills Standard plus platform-specific extensions. Skills authored for Nebo are portable to any Agent Skills-compatible product (Cursor, Claude Code, VS Code Copilot, Goose, and others).
Frontmatter Schema
Agent Skills Standard Fields
These fields follow the Agent Skills Standard and are portable across all compatible platforms.
| Field | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
name |
string | Yes | -- | Kebab-case, 1-64 chars, no leading/trailing/consecutive hyphens | Unique identifier. Must match the parent directory name. |
description |
string | Yes | -- | 1-1024 chars | What the skill does and when to use it. Include keywords that help agents identify relevant tasks. |
license |
string | No | -- | License name or filename | License governing the skill (e.g. MIT, Apache-2.0, LICENSE.txt). |
compatibility |
string | No | -- | Max 500 chars, free text | Environment requirements: intended product, system packages, network access, etc. |
allowed-tools |
string | No | "" |
Space-delimited | Pre-approved tools the skill may use (experimental). e.g. "Bash(git:*) Read" |
metadata |
object | No | {} |
String keys → values | Arbitrary key-value pairs for additional properties. |
Note on
compatibility: Per the Agent Skills Standard, this is a free-text field describing environment requirements (e.g."Requires git, docker, jq"), not a semver range. Any agent can read this to decide whether it can support the skill.
Note on
allowed-tools: Per the standard, this is a space-delimited string, not an array. e.g.allowed-tools: Bash(git:*) Read. This field is experimental and support varies across platforms.
Nebo Extension Fields
These fields are specific to Nebo and control platform behavior, sandbox policy, and runtime configuration. Other Agent Skills-compatible products will ignore these fields.
| Field | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
version |
string | No | "1.0.0" |
Semver | Skill version. Must be bumped on each marketplace publish. |
author |
string | No | -- | -- | Author name or username. |
tags |
string[] | No | [] |
-- | Categorization tags for marketplace search and filtering. |
triggers |
string[] | No | [] |
-- | Activation phrases. Case-insensitive substring match against user messages. |
priority |
integer | No | 0 |
-- | Higher values are matched first when multiple skills have overlapping triggers. |
max_turns |
integer | No | -- | Positive int | Maximum conversation turns the skill stays active. |
dependencies |
string[] | No | [] |
Skill names | Other skills required. Auto-installed on install. |
platform |
string[] | No | [] (all) |
macos, linux, windows |
Target OS. Empty = all platforms. |
capabilities |
string[] | No | [] |
See table below | Runtime capabilities. Drive sandbox config. |
Capabilities
Capabilities declared in the frontmatter control what runtime resources the skill can access and whether sandboxing is enforced.
| Capability | Sandbox | Description |
|---|---|---|
python |
Yes | Execute Python scripts via bundled uv runtime. |
typescript |
Yes | Execute JS/TS scripts via bundled bun runtime. |
storage |
No | Writable data directory for persistent state. Path is injected as $NEBO_DATA_DIR. |
network |
No | Outbound network access. Scoped to metadata.allowed_domains when set. |
vision |
No | Image and vision processing. |
Sandbox Policy Summary
- Pure markdown skills (no
python/typescriptcapability): No sandbox. Instructions are injected into the agent context only. - Script-bearing skills (
pythonortypescript): Scripts execute inside a sandboxed process viaExecuteTool. The sandbox restricts filesystem access, network (unlessnetworkcapability is declared), and process spawning. storagecapability: Grants read/write access to a skill-specific data directory. The path is deterministic and stable across sessions.networkcapability: Withoutallowed_domains, permits all outbound connections. Withallowed_domains, restricts to the listed patterns (supports wildcards like*.example.com).
Secrets
Secrets are declared in metadata.secrets[]. Each entry describes a secret that will be injected as an environment variable at runtime.
metadata:
secrets:
- key: OPENAI_API_KEY
label: "OpenAI API Key"
hint: "https://platform.openai.com/api-keys"
required: true
- key: DATABASE_URL
label: "Database connection string"
required: false
allowed_domains:
- "api.openai.com"
- "*.supabase.co"
Secret Lifecycle
- Declaration: The skill author lists required secret names in
metadata.secrets[]. - Provisioning: The user provides values during installation. Values are encrypted with AES-256-GCM and stored in the Nebo vault.
- Injection: When a script executes, declared secrets are decrypted and injected as environment variables.
- Isolation: Secrets are scoped to the skill that declared them. Other skills cannot access them.
Resource File Structure
A skill directory can contain the following alongside SKILL.md:
my-skill/
SKILL.md # Required. Frontmatter + instructions.
scripts/
main.py # Executed via ExecuteTool (requires python capability)
helper.ts # Executed via ExecuteTool (requires typescript capability)
references/
api-docs.md # Supplementary context loaded on demand
schema.json # Reference data
assets/
icon.png # Marketplace icon
template.html # Static assets
| Directory | Purpose | Loaded |
|---|---|---|
scripts/ |
Executable code. Runs in sandbox via ExecuteTool. |
On tool invocation |
references/ |
Additional documents the agent can pull into context. | On demand |
assets/ |
Static files: icons, templates, images. | As needed |
Progressive Disclosure
Skills are structured for efficient use of context:
- Metadata (~100 tokens): The
nameanddescriptionfields are loaded at startup for all skills. - Instructions (under 5000 tokens recommended): The full
SKILL.mdbody is loaded when the skill is activated. - Resources (as needed): Files in
scripts/,references/, andassets/are loaded only when required.
Keep your main SKILL.md under 500 lines. Move detailed reference material to separate files.
Storage Tiers and Resolution
Skills are resolved in priority order. When two skills share the same name, the higher-tier version wins.
| Priority | Tier | Path Segment | Source |
|---|---|---|---|
| 1 (highest) | User | user/skills/<name>/ |
Manually created by the user |
| 2 | Installed | nebo/skills/<name>/ |
Marketplace .napp packages |
| 3 (lowest) | Bundled | bundled/skills/<name>/ |
Shipped with the Nebo application |
Platform-Specific Base Paths
| Platform | Base Path |
|---|---|
| macOS | ~/Library/Application Support/nebo/skills/ |
| Linux | ~/.local/share/nebo/skills/ |
| Windows | %APPDATA%\nebo\skills\ |
The full path to a user skill on macOS would be:
~/Library/Application Support/nebo/skills/user/skills/quick-research/SKILL.md
Hot Reload
Nebo watches the skills directories with a filesystem watcher. Changes to any SKILL.md or resource file are detected and reloaded automatically with a 1-second debounce. No restart or manual reload command is needed.
Install Codes
Published marketplace skills receive a unique install code:
SKIL-XXXX-XXXX
- Format:
SKIL-prefix + two groups of 4 Crockford Base32 characters - Crockford Base32 excludes ambiguous characters (I, L, O, U) for readability
- Users paste the code into Nebo to trigger installation
Versioning
Skills use semantic versioning (semver):
| Change Type | Version Bump | Example | When |
|---|---|---|---|
| Patch | 1.0.0 -> 1.0.1 |
Typo fixes, wording improvements | No behavior change |
| Minor | 1.0.0 -> 1.1.0 |
New triggers, additional instructions | Backward-compatible additions |
| Major | 1.0.0 -> 2.0.0 |
New capabilities, changed tool requirements | Breaking changes |
When submitting an update to the marketplace, the version field must be higher than the currently published version.
Security
All marketplace skills are subject to:
- VirusTotal scanning before distribution
- Ed25519 signature verification on download
- Sandbox enforcement based on declared capabilities
- User consent -- users review
allowed-toolsandcapabilitiesbefore installing - Secret encryption -- AES-256-GCM at rest, decrypted only during script execution
Complete Example
---
name: github-pr-reviewer
description: Reviews GitHub pull requests with focus on code quality, security, and test coverage. Use when asked to review a PR, check code, or analyze pull requests.
version: "2.1.0"
author: "devtools-team"
license: MIT
compatibility: Requires git CLI and network access to GitHub API
tags:
- code-review
- github
- developer-tools
triggers:
- review pr
- review pull request
- check this pr
platform: []
capabilities:
- typescript
- network
- storage
allowed-tools: web notepad
dependencies:
- code-style-guide
priority: 15
max_turns: 10
metadata:
secrets:
- key: GITHUB_TOKEN
label: "GitHub Personal Access Token"
hint: "https://github.com/settings/tokens"
required: true
allowed_domains:
- "api.github.com"
- "github.com"
---
# GitHub PR Reviewer
You are a code reviewer specializing in pull request analysis. When asked to review a PR:
## Process
1. Fetch the PR diff using the GitHub API
2. Analyze each changed file for:
- Code quality and readability
- Potential bugs or edge cases
- Security concerns (injection, auth, secrets in code)
- Test coverage gaps
3. Save your findings using the notepad tool
4. Deliver a structured review
## Output Format
### Summary
One paragraph overview of the PR's purpose and quality.
### Issues Found
- **Critical**: Must fix before merge
- **Warning**: Should fix, but not blocking
- **Suggestion**: Optional improvements
### Verdict
APPROVE, REQUEST_CHANGES, or COMMENT with a one-line justification.
## Guidelines
- Be constructive, not pedantic
- Focus on logic errors over style (defer to linters)
- If the PR is clean, say so briefly -- don't invent issues
- Always check for hardcoded secrets or credentials