Skills
A skill is a directory with one file of prose: SKILL.md. It is not a program to run — an
agent’s own instructions gain a name and a description per declared skill, and a load_skill
tool it can call to read the full body once it decides one applies. No subprocess, no separate
executable contract.
.agentdeck/skills/parse-request/
├── SKILL.md # frontmatter + instructions for the model
└── scripts/ # optional: anything the instructions tell the model to run itselfSKILL.md
YAML frontmatter, then prose. name must match the directory name; description is what
disclosure_text puts in an agent’s instructions when deciding whether this skill applies —
both are required, or Deck.build() fails naming the bundle.
---
name: parse-request
description: Extract pickup, dropoff, and date from a free-text booking request.
---
Split the request on "->". The part before is the pickup city, the part after is the dropoff
city. If a date appears, use it; otherwise ask the user for one.Declaring a skill on an agent
# .agentdeck/agents/booking/agent.py
from agentdeck import Agent
booking = Agent(name="Booking", instructions="Help the user book a ride.", skills=["parse-request"])from agentdeck import Deck
deck = Deck(agents=[booking], skills="./skills") # or Deck.from_project(), discovering skills/*skills= on the Deck is one or more root directories, scanned direct-child only
(<root>/<name>/SKILL.md, never recursive) and merged into one name-keyed registry — a name
declared under two roots fails build() naming both. Agent(skills=[...]) names which of those
this particular agent may use; a name absent from the roots, or from a Deck with no skills=
at all, fails build() the same way an unknown handoff or MCP server does.
What an agent actually sees
Two things, and only two: the disclosure block appended to its instructions (every declared
skill’s name and description, never the body), and a load_skill(name) tool scoped to that
agent’s own skills=[...] — a name outside that list is unreachable even though the registry
knows it.
### Skills available
Each entry below is a name and a description. Call `load_skill(name)` to read the
full instructions before following one.
- parse-request: Extract pickup, dropoff, and date from a free-text booking request.The model decides whether a skill applies from the description alone, then calls load_skill to
read the full SKILL.md body before following it — the same two-step a human would take skimming
a table of contents before opening a page.
Why not a subprocess
A skill used to be a script AgentDeck ran in a subprocess, with a typed-output contract for
workflows. That executable model is gone: nothing in the package or its tests used the typed
output path, and running arbitrary scripts is a sandboxing concern that is disabled and tracked
separately. A skill today is instructions plus what the agent itself already has — its own
tools — so anything a skill’s script used to do, an ordinary tool= callable does instead, with
the skill’s SKILL.md describing when to reach for it.