Creating Skills
When does making a skill yourself make sense?
The autonomous skill system handles most things on its own, but building a skill directly is worth it when:
- You need exact repeatability: the same procedure runs identically every time it’s triggered.
- You want to share with teammates or other users: deploy one workflow so everyone can use it.
- You’re turning know-how into an asset: formalise onboarding material or recurring processes as a shareable skill.
Outside these cases, you don’t need to create skills at all — your agent finds and uses the right ones automatically.
Try it first, then save what worked
UpServe’s recommended flow for creating a skill:
[1] Instruct the agent
"Scrape this site's prices every day and tabulate them"
│
▼
[2] Agent completes the task with whatever tools fit
(browser / file write / code execution — freely combined)
│
▼
[3] Happy with the result? Ask to save it as a skill
"Save the workflow you just ran as a skill"
│
▼
[4] The agent automatically:
· collects the execution code and files
· writes an AgentSkills-compatible SKILL.md
· auto-normalises spec violations (spaces, uppercase, etc.)
· creates a draft skill and shows you a review screen
│
▼
[5] You review and approve → saved and publishedWhy this works well:
- Only workflows that actually worked get saved — you save a flow only after seeing it succeed, so you never end up with a skill that turns out not to run.
- The agent handles the messy parts — you just say “save the workflow you just ran as a skill”. You don’t need to know what files are created or how they’re organised.
- Refine it through chat until you’re happy — “show the results as a table”, “make the name shorter”, “handle this edge case too” — keep asking in plain conversation.
- You can edit it later at any time — making a skill isn’t a one-shot decision. Come back and ask the agent to tweak, extend, or fix specific parts whenever you want.
Phrases you can use with the agent
| Situation | What to say |
|---|---|
| Save the workflow you just ran | ”Save the workflow you just ran as a skill” |
| Save only one step | ”Make a skill out of just the price extraction part” |
| Specify a trigger condition | ”Make a skill that fires when the user says ‘check competitor prices‘“ |
| Pick the name yourself | ”Name it competitor-price-tracker and make it a skill” |
| Prepare for sharing | ”Make it a skill and prep it for marketplace publishing” |
Reviewing the draft and publishing
Skill creation is a review-required tool. The agent creates a draft and waits on the review screen for you to confirm. On that screen you can also edit the skill name, description, category, the file list, and the script contents before saving. When you’re happy, publish as one of:
- Private (default) — only your own agents can install and run this skill. It does not appear in the marketplace and other users cannot find it through search. Recommended for internal know-how, sensitive integrations, and skills you’re still iterating on.
- Public on the marketplace — anyone on UpServe can find and install the skill. The displayed name, description, and icon are shown as-is, and you can see install counts as analytics. Other users importing your skill do not affect your original.
You can flip between private and public at any time. Switching back to private only stops new users from finding it — copies already imported by others stay with them.
Cancelling or closing the review screen discards the draft. If you leave the screen open without responding for one hour, the draft is kept for later review.
After publishing — reviewing improvement proposals
Once your skill is public, other users’ agents may encounter defects while running it. When that happens, the feedback is automatically filed as an improvement proposal. Multiple reports describing the same underlying issue are deduplicated into a single proposal.
Where to find them: open your skill on the marketplace and look for the Improvement Proposals tab. This tab is visible only to the skill’s author. You can reach it from the skill’s detail page on the marketplace.
For each proposal you have three options:
| Action | Meaning |
|---|---|
| Accept | Marks the proposal as reviewed. Then edit the skill in the marketplace and publish a new version with the fix. |
| Reject | For proposals that aren’t valid. You can leave an optional note explaining why. |
| Leave pending | No action taken; stays as a pending proposal until you decide. |
Automatic patches the agent applies to skills you have imported are handled separately and do not appear on this page.
Import from the marketplace
Instead of building from scratch, you can install a skill someone else made from the Marketplace . Click Import on the skill detail page — an independent copy lands in your skill library, and you can attach it to your agents or refine it through chat.
For the full installation walkthrough, see Installing Skills & Presets.
Advanced
The material below is not required for everyday use. Refer to it only when you need to inspect skill internals, hand-edit a skill imported from outside, or exchange skills with other clients.
What an agent-built skill looks like
Directory layout
my-skill/
├── SKILL.md # Required: frontmatter + body
├── scripts/ # Optional: executable code
│ ├── main.py
│ └── requirements.txt
├── references/ # Optional: docs the agent loads on demand
│ └── api-spec.md
└── assets/ # Optional: templates, schemas, lookup tables
└── output-template.mdSKILL.md frontmatter
The standard requires only two fields.
---
name: my-skill # kebab-case, 1-64 chars, must match directory name
description: Use this skill when ... # ≤1024 chars, imperative
---Optional standard fields:
| Field | Purpose |
|---|---|
license | License name or reference to a bundled LICENSE file |
compatibility | Environment requirements (≤500 chars) — e.g. “Requires Python 3.14+ and uv” |
allowed-tools | Pre-approved tools the skill may use (experimental) |
metadata | Container for client-specific extensions |
UpServe extensions live under metadata:
UpServe-specific fields (secret bindings, action menus, trigger hints) go under the standard metadata: namespace. This keeps your SKILL.md valid for any other compliant client.
---
name: notion
description: Search, read, and write Notion pages and databases via OAuth. Use when the user asks to search Notion, read a page, query a database, or reference a Notion URL.
metadata:
display_name: Notion Integration
when_to_use:
- User asks to search their Notion workspace.
- User references a Notion URL or page id.
requires:
- oauth: notion # → ${SKILL_DIR}/.env will receive NOTION_TOKEN
entry_script: scripts/main.py
actions:
- search: "Search pages and databases by title/content"
- read: "Read a page's content"
files:
- scripts/main.py
load_before_use: true
---
# Notion Integration
## When to use this skill
...Progressive disclosure — the token-saving model
Skills load in three tiers.
| Tier | When loaded | Content | Token cost |
|---|---|---|---|
| 1. Catalog | Every turn | name + description only | ~50-100 tokens per skill |
| 2. Body | Once on first skill execution (re-delivered after conversation history is compacted) | Full SKILL.md body | < 5,000 tokens recommended |
| 3. Resources | When the body references a file | Individual scripts / references / assets | Variable |
Implication: with 20 skills installed, your agent’s behaviour instructions only carry 2-3KB. Only skills the agent actually uses expand to their full body. The agent’s instructions always hold only the frontmatter summary; the full body is delivered exclusively when a skill is first executed.
[Loaded every turn] ~50–100 tokens/skill
┌─────────────────────────┐
│ Tier 1 · Catalog │
│ name + description │
└─────────────────────────┘
│
│ Agent decides "use this skill"
▼ (first skill execution)
┌─────────────────────────┐
│ Tier 2 · Body │ < 5,000 tokens
│ Full SKILL.md │
└─────────────────────────┘
│
│ Body says "look at scripts/main.py"
▼ (per individual file read)
┌─────────────────────────┐
│ Tier 3 · Resources │ variable
│ scripts / refs / assets│
└─────────────────────────┘Secret injection
When a skill needs to call an external service, declare it in metadata.requires. At skill-execution time, UpServe writes the credentials into ${SKILL_DIR}/.env automatically. When the agent packages a skill, it auto-detects which credentials the workflow used and fills this field for you.
| Notation | Injected as |
|---|---|
oauth: <provider> | <PROVIDER>_TOKEN=... in ${SKILL_DIR}/.env |
apikey: <provider> | <PROVIDER>_API_KEY=... (platform-managed) |
scope: <scope> | UPSERVE_AGENT_TOKEN + UPSERVE_API_BASE (UpServe internal API) |
Scripts source the env with . ./.env && python3 scripts/main.py .... The .env file is scrubbed when the session ends.
Script design principles the agent follows
When the agent authors skill scripts, it defaults to these nine principles. You don’t write them yourself, but you can use this checklist when reviewing a packaged skill.
| Principle | Why |
|---|---|
| Non-interactive | Agents can’t answer interactive TTY input — accept all input via flags or env vars |
Expose --help | The primary way an agent learns your interface |
| Structured stdout | JSON / CSV / TSV — easy to parse |
| stderr for diagnostics | Keep data and progress separate |
| Helpful error messages | ”What went wrong / what was expected / what to try” |
| Idempotent | ”create-if-not-exists” beats “create-and-fail” — agents retry |
| Distinct exit codes | Per-failure-mode (404 / auth / validation) |
| Predictable output size | Default cap + --offset / --limit for pagination |
| PEP 723 inline deps (Python) | uv run scripts/x.py runs anywhere with one command |
If something needs fixing, just ask in chat: “add a --limit flag to the script”, “include suggested next actions in the error message”. See the AgentSkills script guide for full detail.
Lenient normalisation
The standard is strict, but UpServe loads leniently and surfaces warnings instead of rejecting. Whether you import an external zip or have the agent author SKILL.md, minor spec violations are auto-corrected.
| Violation | Handling |
|---|---|
name contains uppercase / spaces / underscores | Auto-normalised (Notion Integration → notion-integration); original preserved as metadata.display_name |
name exceeds 64 chars | Warning + truncate |
| Unquoted colons in YAML | Lenient parse retry |
description missing | Rejected (required — without it the agent can’t trigger) |
description exceeds 1024 chars | Rejected |
Exchange with other clients via zip
UpServe skills export and import as standard zips, so you can move them bidirectionally between Claude Code, Cursor, Goose, and any other compatible client.
Import a skill from another client
curl -X POST https://api.upserve.app/api/skills/import \
-H "Authorization: Bearer $UPSERVE_TOKEN" \
-F "file=@my-skill.zip"Safety limits: 200 files per zip, 500KB per file, 2MB total package size.
Export a UpServe skill to another client
curl -O -J https://api.upserve.app/api/skills/<skill-id>/export \
-H "Authorization: Bearer $UPSERVE_TOKEN"
# → my-skill.zipThe zip contains <slug>/SKILL.md plus scripts/, references/, and assets/ in standard layout. Unzip it into the other client’s skills directory and you’re done.
Learn more
- Installing skills from the marketplace — Use skills others built
- Equipping tools — Pick the tools that pair with your skills
- AgentSkills specification — The canonical standard
- Optimising skill descriptions — Improve trigger accuracy
- Evaluating skills — Test output quality
- Script writing guide — Full script design reference