Skip to content

Composable Skills

How to build skills that are self-contained, testable, and portable across projects.

What makes a skill composable

A composable skill works correctly regardless of which workflow, agent, or project invokes it. It declares its own dependencies, restricts its own tools, and produces predictable output.

The four properties:

  1. Self-contained — complete SKILL.md with all required frontmatter fields
  2. Tool-restricted — declares allowed-tools to limit what it can do
  3. Dependency-aware — declares skills for other skills it needs
  4. Independently testable — can be invoked in isolation and produce meaningful output

allowed-tools frontmatter

Restrict a skill to only the tools it needs:

---
name: code-analyzer
description: Analyze code quality without modifying files.
allowed-tools:
  - Read
  - Grep
  - Glob
  - Bash
---

This skill cannot use Write, Edit, or WebFetch. If it tries, the tool call is blocked.

Use allowed-tools when:

  • The skill should be read-only (analysis, review, research)
  • The skill should not access the network (no WebFetch, no WebSearch)
  • The skill should not spawn sub-agents (no Agent tool)

Agent dependencies declaration

Agents declare which other agents they need using the skills field:

---
name: my-orchestrator
skills:
  - defense-in-depth
  - test-driven-development
---

When this agent runs, the listed skills are loaded into its context. This makes the dependency explicit rather than relying on the skills being globally available.

Portable governance pattern

Skills that enforce rules (like defense-in-depth or testing-anti-patterns) should work identically in any project. To make a governance skill portable:

  1. No hardcoded paths — reference files relative to the project root, not absolute paths
  2. No project-specific logic — check for patterns, not specific filenames
  3. Graceful degradation — if a referenced tool or config is missing, warn rather than fail
  4. Clear frontmatter — all required fields populated so the skill loads in any context

Example: complete governance skill

---
name: input-validation
description: |
  Use when writing code that accepts user input.
  Enforces validation at system boundaries.
allowed-tools:
  - Read
  - Grep
  - Glob
  - Edit
  - Write
skills:
  - defense-in-depth
hooks:
  PostToolUse:
    - matcher: "Write|Edit"
      hooks:
        - type: command
          command: "~/.claude/hooks/security-lint.sh"
---

# Input Validation Skill

Validate all user input at system boundaries...

This skill:

  • Declares its tool restrictions
  • Lists its skill dependency
  • Attaches a post-write security lint hook
  • Can be installed in any project via the manifest

See also