AI Assistant

Skills System

Skills are prompt-based extensions that add slash-command capabilities to Claude Code. They can be bundled into the binary, loaded from disk, provided by plugins, or exposed through MCP servers.

Skill Sources

Claude Code loads skills from multiple sources, merged at startup:

bundledsource

Compiled into the CLI binary via registerBundledSkill(). Available to all users unconditionally.

projectsource

Markdown files in .claude/skills/ relative to the project root. Scoped to a single repository.

usersource

Markdown files in ~/.claude/skills/. Available across all projects for a given user.

pluginsource

Skills provided by installed plugins. Loaded from the plugin's commands path.

managedsource

Skills from managed/policy settings paths. Used for enterprise policy-controlled skills.

mcpsource

Skills built dynamically from MCP server tool discovery via registerMCPSkillBuilders().

The LoadedFrom type captures these origins:

type LoadedFrom =
  | 'commands_DEPRECATED'
  | 'skills'
  | 'plugin'
  | 'managed'
  | 'bundled'
  | 'mcp'

BundledSkillDefinition

Bundled skills are registered programmatically at startup. The BundledSkillDefinition type defines their shape:

type BundledSkillDefinition = {
  name: string
  description: string
  aliases?: string[]
  whenToUse?: string
  argumentHint?: string
  allowedTools?: string[]
  model?: string
  disableModelInvocation?: boolean
  userInvocable?: boolean
  isEnabled?: () => boolean
  hooks?: HooksSettings
  context?: 'inline' | 'fork'
  agent?: string
  files?: Record<string, string>
  getPromptForCommand: (
    args: string,
    context: ToolUseContext,
  ) => Promise<ContentBlockParam[]>
}
namestring
The slash-command name (e.g., "batch" becomes /batch).
descriptionstring
Short description shown in autocomplete and help.
whenToUsestring | undefined
Hint for the model on when to invoke this skill autonomously.
allowedToolsstring[]
Restricts which tools the skill can use when executing.
modelstring | undefined
Override the model used for this skill's prompt.
hooksHooksSettings | undefined
Lifecycle hooks specific to this skill.
filesRecord<string, string> | undefined
Reference files extracted to disk on first invocation. The skill prompt is prefixed with a base directory path so the model can Read/Grep these files.
context'inline' | 'fork'
Whether the skill runs in the current conversation or forks a subagent.
getPromptForCommandfunction
Async function that produces content blocks from the user's arguments.

registerBundledSkill()

The registerBundledSkill() function converts a BundledSkillDefinition into a Command and adds it to an internal registry:

function registerBundledSkill(definition: BundledSkillDefinition): void

When a skill has files, the function wraps getPromptForCommand to lazily extract those files to ~/.claude/bundled-skills/<name>/ on first invocation. Extraction is memoized at the promise level so concurrent callers share a single write.

Bundled Skills

The following skills ship with the CLI (registered in src/skills/bundled/):

SkillDescription
batchRun operations across multiple files or inputs
claude-apiBuild apps with the Claude API or Anthropic SDK
claude-in-chromeChrome extension integration
debugDebug failing tests or runtime errors
keybindingsCustomize keyboard shortcuts
loopRun a prompt or slash command on a recurring interval
lorem-ipsumGenerate placeholder text
rememberSave information to memory files
scheduleCreate and manage scheduled remote agents
simplifyReview changed code for reuse, quality, and efficiency
skillifyConvert a workflow into a reusable skill
stuckHelp when Claude is stuck in a loop
update-configConfigure the Claude Code harness via settings.json
verifyVerify that a task was completed correctly

Disk-Based Skills

Skills loaded from .claude/skills/ and ~/.claude/skills/ are Markdown files with YAML frontmatter:

---
description: "Generate unit tests for a module"
whenToUse: "When the user asks for tests"
allowedTools:
  - Read
  - Write
  - Bash
hooks:
  PostToolUse:
    - matcher: "Write"
      hooks:
        - type: command
          command: "npm test"
---

Write comprehensive unit tests for the specified module.
Use the project's existing test framework and conventions.

Frontmatter Fields

descriptionstring
Description shown in skill listings and used for model matching.
whenToUsestring
Guidance for when the model should invoke this skill.
allowedToolsstring[]
Tool allowlist for the skill execution context.
modelstring
Override model for this skill.
hooksHooksSettings
Lifecycle hooks validated against the HooksSchema.
argumentHintstring
Placeholder hint for arguments (e.g., "<file-path>").

Shell Command Execution in Prompts

Skill prompts can embed shell commands using backtick-fenced blocks with a sh or bash language tag. These commands are executed before the prompt is sent to the model, and their output is substituted inline via executeShellCommandsInPrompt().

Argument Substitution

Skill prompts support $ARGUMENTS placeholders. When a user invokes /my-skill some args, the argument string is parsed via parseArgumentNames() and substituted into the prompt via substituteArguments().

MCP Skill Builders

The registerMCPSkillBuilders() function bridges the MCP server layer with the skills system. It provides two functions to the MCP subsystem:

  • createSkillCommand: converts MCP tool metadata into a Command object
  • parseSkillFrontmatterFields: parses frontmatter from MCP-provided skill content

This avoids a circular dependency: MCP servers need to create skill commands, but the skill loader transitively imports most of the codebase. The builders are registered at module init time (via static import from commands.ts) before any MCP server connects.

type MCPSkillBuilders = {
  createSkillCommand: typeof createSkillCommand
  parseSkillFrontmatterFields: typeof parseSkillFrontmatterFields
}

Skill Deduplication

When loading from multiple sources, skills are deduplicated by resolving symlinks to canonical file paths via realpath(). This prevents the same skill from appearing twice when accessed through different paths (e.g., symlinks or overlapping parent directories).

Token Estimation

Skill metadata tokens are estimated via estimateSkillFrontmatterTokens(), which counts tokens across the skill's name, description, and whenToUse fields. Full content is only loaded on invocation, keeping the idle system prompt lightweight.