Custom scripts, formatting rules, type checks, and framework templates accumulate quickly. Treating every helper as a permanent instruction consumes context before the first real request. This guide shows how to inventory skills, separate persistent rules from on-demand workflows, and test whether Claude still discovers the right one.
How skills affect the initial session window
In a normal session, Claude Code puts the name and description of skills set to on into context. name-only keeps only the name; user-invocable-only and disable-model-invocation: true hide the description from the model; off hides the skill entirely. The full SKILL.md loads after invocation and remains in that session. Supporting files are read when needed, while scripts run as tools. See the official Skills documentation.
Context cost has three layers:
-
Listing announcement: the short name and frontmatter
descriptionused to match a request. - Instruction body: detailed rules, steps, and examples loaded when the skill is activated.
- Resources and scripts: references read through an explicit route and scripts run through the CLI.
Avoid putting large manuals, documentation dumps, or rigid code-generation rules directly in description or global CLAUDE.md.
With your own BetterToken API key, use the Dashboard to compare test requests by model, time, status, input, output, and cache tokens. That confirms an API workflow; it neither identifies a local skill's context cost nor replaces /context. Check current Claude Code setup in BetterToken Docs.
When the list is too large, start with /skill-doctor
Run /skill-doctor in a local Claude Code session. It reports skill context cost and invocation frequency, highlights loaded but unused skills, and opens an interactive report in the Stats tab of /plugin; bundled and enterprise skills are outside its scope. See the report documentation.
- Compare the list with work you actually do. No calls do not prove a recovery skill is useless.
- For an occasional personal or project skill, choose
user-invocable-only(user-only) in/skills; useoffonly if it is no longer needed there. Manage plugin skills through/plugin. - Start a new session, compare
/context, run one ordinary task, and explicitly invoke the retained rare skill.
The command appeared in v2.1.261, while current documentation lists v2.1.252 as the minimum. Check claude --version and feature flags. Remote Control does not provide the report; run it in the terminal on the machine hosting the session. If the command is missing, use the manual inventory below.
Inventory skills by frequency and scenario
List project skills in .claude/skills/ and personal skills in ~/.claude/skills/. A nested skill can become available after the corresponding subdirectory is first read or changed. Plugin skills use a plugin namespace and are not controlled through skillOverrides. Synced skills can be discovered differently in local sessions, Cowork, and cloud, so compare the file inventory with /skills in every environment you use.
| Frequency | Example work | Best placement |
|---|---|---|
| Daily / always-on | Basic style, test commands, git status
|
Compact rules in CLAUDE.md or a base skill |
| Task-triggered | Database migration, OpenAPI generation, release checklist | A separate skill with a narrow description
|
| Rare / architectural | Initial security audit, new service deployment | An explicit user-only skill with scripts |
Keep rare safety, recovery, and release procedures explicitly available until real scenarios have been checked.
Put each rule in the mechanism that enforces it
For a generated-documentation workflow, different needs require different mechanisms:
| Need | Put it in | Verify |
|---|---|---|
| Reminder in almost every task | Short rule in CLAUDE.md
|
The file loads in a fresh session |
| Procedure only during documentation updates | Dedicated skill | Explicit invocation finds the source and generator command |
| Reject a particular write before it happens |
PreToolUse hook |
The matched tool is denied and the file is unchanged |
| Independently inspect output | Subagent with only needed tools | Its report does not exceed the task's permissions |
| Read an external system | MCP connection | One permitted request reaches the required server |
CLAUDE.md and skills give the model instructions; they do not prove that a write is blocked. Test a hook's event, matcher, and actual denial: blocking Write does not block a Bash write, and a subagent's separate context is not automatically read-only. See the mechanism overview and Hooks reference.
Do not copy one procedure into all five places. Keep a short rule and skill link in CLAUDE.md, and enforce the action at the point where it matters. For related examples, see CLAUDE.md rules, Stop Hook verification, and choosing MCP or a command.
Separate always-on rules from background resources
Keep the skill's entry point compact and move invoked material to files.
1. Optimize YAML frontmatter
Write clear trigger terms and a short purpose in description:
---
name: db-migrator
description: >-
Use when validating and applying Prisma migrations after a database schema change.
---
Move detailed tables and examples into references/ rather than placing long examples in the header.
2. Delegate deterministic logic to scripts
Put repeatable parsing or validation in a shell or Python script instead of asking the model to recreate a long command:
<!-- Inside SKILL.md -->
To check schema integrity, run:
```bash
python3 "${CLAUDE_SKILL_DIR}/scripts/validate_schema.py" --strict
```
The SKILL.md then supplies the route and acceptance criteria, while a versioned script performs the repeatable check. Do not disable required security checks, linters, or type validators to save tokens.
Test discovery and invocation
After restructuring, test whether Claude still identifies and loads the right instructions.
Step 1: separate four checks
Do not replace YAML validation with test -f. Check separately:
-
SKILL.mdexists. - Its frontmatter parses as YAML and has a nonempty
description. - Links to
references/,examples/, andscripts/resolve from the skill directory. - The script runs on safe test input and returns the expected exit code.
An executable bit is unnecessary for a Python file called through python3; syntax and a real safe test matter.
Step 2: check visibility and explicit invocation
Open a fresh session, use /skills to confirm name, source, and invocation mode, then explicitly invoke /db-migrator on a safe test task. This separates a discovery error from an instruction error.
Step 3: test the automatic trigger
In another clean session, make a matching request without naming the skill:
"I need to update the User model in the Prisma schema and verify the migration."
The agent should identify the request from description, load db-migrator, and propose the prepared validation script.
Step 4: measure listing and startup context
Use /skill-doctor as above, then run /doctor and record the Skills line in /context. After one change, such as shortening a description or moving a rare skill to user-only, repeat both in a new session. Check correct behavior as well as tokens: a should-trigger request should load the skill, while a should-not-trigger request should not. Classify skills as always-on, auto-triggered, user-only, name-only, or off; do not remove security or recovery skills merely because they are rarely used.
Originally published on the BetterToken blog.
BetterToken provides pay-as-you-go access to AI model APIs through
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring
Claude Code, Codex, or your own tooling to a custom base URL.
See the docs to get started.
Top comments (0)