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 team colleagues 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 posts a card in the chat
│
▼
[5] Open the card whenever you like to review and publishWhy 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 publishing” |
Reviewing the draft and publishing
Creating a skill doesn’t pause the agent. The moment it builds a draft, a card appears in the chat and the agent moves straight on to whatever’s next. Open the card whenever you’re ready (web, iOS, and Android all offer the same review screen) — it lets you check and edit the skill name, description, category, the body (SKILL.md), and the file list before publishing. Publishing is always something you do yourself; the agent can’t publish on your behalf. Once you’re happy, publish as one of:
- Private (default) — only your own agents can install and run this skill. It does not appear in Explore and other users cannot find it through search. Recommended for internal know-how, sensitive integrations, and skills you’re still iterating on.
- Public — 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.
If a bundled file looks like it contains personal information or sensitive data, the review screen flags it with a warning. You can uncheck a flagged file to exclude it from the skill — excluded files are actually deleted once you publish. You can also run Validate before publishing to check whether the draft would pass, without committing to it yet.
Cancelling or closing the publish dialog discards the draft; otherwise it stays put until you publish or discard it.
Publishing requires passing an automatic check. When you try to go public, the system scans the skill’s files for leftover secrets (API keys, tokens, etc.) and checks that the name, description, and body aren’t empty. If a secret is found or required fields are missing, publishing is rejected and an error message is shown. Skills built from an official UpServe skill, or forked from another user’s still-private skill, also cannot be published.
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 from the Skills tab — the skill detail page shows an Improvement Proposals section further down. It is visible only to the skill’s author.
For each proposal you have four options:
| Action | Meaning |
|---|---|
| Accept | Only marks the proposal as reviewed — it does not change the skill content and does not lead to a separate edit screen afterward. Use it when you want to close the proposal without shipping a fix. |
| Edit & publish | Edit the skill content right inside the proposal card and publish it as a new version. If you actually want to ship the fix, use this instead of Accept. |
| 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.
Deleting a skill
You can delete any skill you created at any time (official skills can’t be deleted). Open the skill’s card, click Delete, and confirm.
One of two things happens:
- A skill that has never run — it’s deleted permanently. This can’t be undone.
- A skill that has run at least once, been imported or forked by someone else, or used by a team — instead of erasing it, UpServe archives it. This protects traces the skill already left behind elsewhere (work files your agent produced with it, things it remembered, conversation history) from suddenly pointing at something that no longer exists.
What changes once a skill is archived?
- Its card stays in your list with an Archived badge — the same on web, iOS, and Android.
- The confirmation you see after deleting correctly says “archived,” not “deleted.”
- Your own agents stop using it. From their next run onward it drops out of their skill list, and you can’t attach it to a new agent either.
- Copies already imported by other users are unaffected and keep working normally — archiving your original doesn’t stop anyone who already installed it.
- If you change your mind, click Restore on the skill’s detail page to bring it back as a private skill you can attach to your agents again.
Import from Explore
Instead of building from scratch, you can install a skill someone else made from Explore , under the Skills tab. 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.
[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 at the end of every turn (each time the agent finishes a response), and is automatically rewritten the next time the skill runs — you don’t need to manage this yourself.
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, 5MB per file, 20MB total package size. Binary files such as images, audio, and fonts are preserved byte-for-byte.
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 & Presets — 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