Before the topics, an overview from above. A SKILL.md for production isn't a wall of text: it's a document with named sections, each answering a Claude question at runtime. The diagram below shows the backbone of the file we're about to dissect.
The backbone of the SKILL.md — illustrative. Each section feeds into the final page.
Detailed content
🗺️ The Promise: "What This Skill Does"
The file’s first content section is a single paragraph, but it’s the most important one. It defines the output concretely: "a self-contained, interactive HTML page with light/dark theme, animated flight routes, a day-by-day schedule, expandable flight cards, checklists that persist in localStorage, and multi-trip navigation". And it wraps up with the phrase that captures the whole philosophy: "looks like a premium travel app—not a document".
🎯 The contract in one sentence
Every mature skill starts by saying plainly what it will deliver. This paragraph is a three-level contract:
- •Output shape: one HTML file — not a PDF, not a text response.
- •Features: the resource list becomes an implicit checklist that Claude tries to complete.
- •Feel: "premium app, not document" is the quality bar.
Real excerpt from the SKILL.md
## What This Skill Does
Generates a stunning, interactive HTML travel
itinerary — a single self-contained file with
dark/light theme toggle, animated flight paths,
interactive day-by-day schedule, expandable
flight cards ... and multi-trip navigation.
The output looks like a premium travel app —
not a document.
💡 Practical tip
When writing your skill, force yourself to describe the output in one verifiable sentence. If you can’t do it, Claude won’t be able to either. “Generate something useful about travel” is a bad prompt; “generate an interactive HTML with an itinerary, flights, and budget” is a target.
💬 The conversational Setup Flow
Here’s the heart of the skill, and it makes a point of stating: "Setup Flow — CRITICAL". Before generating ANYTHING, Claude needs to go through a four-step conversational discovery process. That’s why the output feels magical: it’s built on real details from the user’s life, not assumptions.
Basic trip details
The anchor questions
Where you're going, on what dates, where you're departing from, whether it's for a specific event, and who's traveling. Five questions that define the rest of the conversation.
Integration check
"ask every time"
Offer to pull real data from email, calendar, Drive, messages, and URLs. We cover this in Topic 3 — it’s what distinguishes an assistant from a text generator.
In-depth details (gaps)
Fill in what’s missing
Based on what it has gathered so far, ask about flights, lodging, events, transportation, pets, budget, activities, and special requirements—only what’s still blank.
Confirm & generate
The gate before output
Show a summary of everything gathered and confirm before building. Only then is the HTML page generated.
📊 Why “collect before generating” works
- Specificity: real data produce a page that looks made for that trip, not a template.
- Confidence: by confirming the summary, the user corrects errors before spending tokens generating the entire HTML.
- Order: the steps go from cheapest (questions) to most expensive (generating), reducing rework.
🔌 Integrations via MCP: Real Data
Step 2 of setup is where the skill gains superpowers. It instructs Claude to offer—every time—to check the user’s data sources: email, calendar, Drive/Docs, Slack/messages, URLs, and Notion. If the user authorizes it, Claude uses the corresponding MCP tools (Gmail, Google Calendar, Google Drive) to pull flight confirmations, reservations, and event tickets directly into the document.
✓ What to DO
- ✓Offer the integration and wait for authorization from the user.
- ✓Use the right MCP tool for each source (Gmail for email, Calendar for scheduling).
- ✓Fill in the document with the actual data returned.
- ✓Return to the questions (Step 3) for what the integration didn’t cover.
✗ What NOT to do
- ✗Access email or calendar without asking.
- ✗Make up flight numbers or reservations when there’s no data.
- ✗Skip the offer because "it must be a lot of work" — the skill says "ask every time".
- ✗Mix placeholder data with real data without labeling it.
The sources the skill offers to check
💡 Practical tip
The skill’s description, "I can pull in real data to make this way more useful", is a copywriting template. It explains the benefit before asking for permission—the user understands why and is more likely to say yes. Copy this pattern in your skills with integrations.
📦 Output Format: One File, Zero Dependencies
Very short, but decisive. The "Output Format" section locks in the output with explicit rules: a single self-contained HTML file, with all the CSS in a <style> and all the JS in one <script>; images as base64 data URIs or emoji; no external dependencies beyond Google Fonts (Inter); and a standardized file name.
Real excerpt from the SKILL.md
## Output Format
Generate a single self-contained HTML file.
All CSS inline in <style>. All JS inline in
<script>. Images as base64 data URIs or emoji
fallbacks. No external dependencies except
Google Fonts (Inter).
Save as travelwings-{destination}.html
📊 What each restriction prevents
- "Single file": avoids scattered files that the user has to gather.
- "Inline CSS/JS": avoids links to stylesheets/scripts that break when the file is moved.
- "base64 / emoji": avoids images that won't load offline.
- "No external deps": avoids CDN dependencies that disappear over time.
⚠️ Attention
Without an Output Format section, Claude tends to “overhelp” — proposing a project with multiple folders, a framework, and a build. For a skill that generates an artifact for the end user, that’s the opposite of what you want. Designing means setting constraints.
🧩 Example Sections: the page blueprint
This section lists 13 suggested blocks for the page — hero, event banner, stats, route map, outbound flights, hotel, pets, day-by-day itinerary, return flights, budget, checklists, footer, and theme. But the detail that matters is in parentheses: "adapt per trip". It’s a blueprint, not a straitjacket.
✓ How the list helps
- ✓Gives Claude a reference order of the blocks.
- ✓Remember easy-to-forget sections (footer, checklists).
- ✓Mark which ones are conditional ("if attending an event", "if applicable").
✗ What to avoid
- ✗Dump everyone the 13 blocks even without data for them.
- ✗Create a pet section for a trip without pets.
- ✗Treat the suggested order as mandatory and fixed.
The 13 suggested blocks (adapt per trip)
💡 Practical tip
"Adapt per trip" is one of the two most powerful words in a generation skill. Whenever you list blocks, mark which one is conditional. This gives you structure without producing bloated pages with empty sections.
⭐ Key Principles: the compass
The final section is six short principles that sum up the spirit of the skill. While the steps explain what to do, the principles say how to decide when the situation wasn’t in the script. They’re Claude’s rule of thumb.
🧭 The six principles
- 1.Real data > placeholder data. Always try to pull from real data first.
- 2.Ask before assuming. The setup conversation is what gives it value.
- 3.One file, zero dependencies. Everything self-contained.
- 4.Feels like a premium app, not a document. The quality bar.
- 5.Interactive > static. Checklists save state, days are clickable, flights expand.
- 6.Colour-code everything. Blue outbound, green confirmed, orange return, lavender connection, gold event.
📊 Steps vs. Principles
- Steps cover the happy path: do A, then B, then C.
- Principles cover the unexpected cases: what if data is missing? What if there’s a conflict? Decide using the rubric.
- Together, they make the skill robust — works even outside the expected workflow.
💡 Practical tip
Good principles are short and opposable: each one rules out a concrete alternative ("real > placeholder" rules out making up data). If one of your principles rules nothing out, it's just decoration — rewrite it.
Hands-on exercises
1. Map the sections
Open any skill that generates an artifact and identify: where is the promise? Is there a setup flow? Is there an Output Format section? Are there principles? Note what's missing.
2. Write the promise
In one verifiable sentence, describe the output of a skill you wish you had. Put the sentence to the test: can you check whether the output met the goal?
3. Create a runnable SKILL.md
Save the file below as ~/.claude/skills/menu-planner/SKILL.md, restart Claude Code and type /menu. Watch the skill guide its own setup flow.
---
name: menu-planner
description: Generates a self-contained HTML weekly
meal plan. Trigger on "/menu", "plan my meals",
"weekly menu", "meal prep". Asks about diet,
people, budget and pantry BEFORE generating.
---
# Menu Planner
## What This Skill Does
Generates a single self-contained HTML weekly meal
plan: 7 day cards, a shopping list grouped by aisle,
a budget total, and a print button. Looks like an
app, not a document.
## Setup Flow — CRITICAL
Before generating, ask:
1. How many people, and any diets/allergies?
2. Budget for the week?
3. What's already in the pantry? (offer to read a
note/doc if they have one)
4. Confirm a summary, THEN generate.
## Output Format
One HTML file. CSS in <style>, JS in <script>.
No external deps except Google Fonts (Inter).
Save as menu-{week}.html.
## Key Principles
1. Ask before assuming.
2. One file, zero dependencies.
3. Interactive > static (check off items, save state).
4. Colour-code by meal type.
🎯 Module Summary
Next Module:
2.2 — Setup flow, design system, and output: from prompt to HTML page