Skills are folders of instructions, scripts, and resources that Claude loads dynamically to improve performance on specialized tasks. At the core of every Skill is a SKILL.md file — a packaged set of instructions you upload once and then attach to any messages.create call. You're teaching Claude how you do something: your status report format, your review checklist, your release notes. Claude reads the Skill, follows the procedure, and produces output in your shape.
It's worth being clear on the difference, because the two solve different problems:
A simple way to remember it: tools are about what Claude can do, while Skills are about how you want it done.
One more thing worth knowing: Skills don't load fully into context on startup. Only the name and description load at first. When your agent decides a Skill is relevant, it then loads the full Skill into context. That keeps your context lean even when many Skills are available.
Skills are uploaded once to your workspace, then referenced by ID. You can upload directly on the Claude Platform, or do it programmatically:
skill = client.skills.create(
display_name="Status Report Generator",
files=files_from_dir("status-report-skill"), # folder containing SKILL.md
)
print(skill.id) # reference this ID in future requests
For this example, I want a status report generator. All the rules for what makes a good status report — sections, tone, how to summarize, how to handle blockers — live in a Skill packaged ahead of time. The activity log itself is just a string passed in at request time.
Skills attach to a request through the container configuration — a skills array inside the container, where each entry names a skill_id and . Here's the full call for the status report generator:
సైన్ ఇన్ చర్చలో చేరండి
versionresponse = client.messages.create(
model="claude-opus-5",
max_tokens=4096,
container={
"skills": [
{
"type": "custom",
"skill_id": skill.id,
"version": "latest",
}
]
},
tools=[
{
"type": "code_execution_20250825",
"name": "code_execution",
}
],
messages=[
{
"role": "user",
"content": f"Generate the daily status report from this activity log:\n\n{activity_log}",
}
],
)
A few things worth pointing out:
client.messages.create, with no beta header. Skills are generally available on the Claude API, so the skills-2025-10-02 beta header is no longer required; requests that still send it continue to work unchanged.container.skills is where the Skill attaches. It's a list, so you can layer multiple Skills onto one call.The output is a status report formatted exactly the way the Skill says to format it. Sections, tone, blocker handling — all of it comes from the SKILL.md file you uploaded. The user prompt is one line; the procedure lives in the Skill.
In a production app, this is how a team standardizes output across an entire feature. With this daily status report endpoint, every PM gets the same structure, the same tone, the same sections, in the same order — without anyone copy-pasting a template into a prompt.
SKILL.md file (plus any scripts and resources) teaches Claude how you want something done.client.skills.create, then attach with container.skills on any messages.create call — a list, so you can layer multiple Skills.