SKILL.md Schema for CLI-Anything: A Complete Guide to Metadata Extraction and Structure

The SKILL.md schema defines a structured Markdown format for CLI "skills" that combines YAML front-matter with auto-generated sections extracted from Python source code, README files, and package metadata.

CLI-Anything uses the SKILL.md document to create machine-readable specifications for command-line wrappers. The schema follows a deterministic Markdown structure generated by skill_generator.py that bridges Python Click-based CLIs and agent systems. Understanding this schema helps developers trace how command groups, constraints, and version information flow from source code into standardized documentation.

SKILL.md Schema Structure

The SKILL.md file follows a fixed Markdown template with eight distinct sections. Each section serves a specific purpose in describing the CLI capabilities to downstream systems.

YAML Front-Matter

The document opens with YAML front-matter containing two required fields:

  • name — The skill's identifier (e.g., zotero)
  • description — A short tagline summarizing the tool's purpose

This block is generated by generate_skill_md_simple at lines 95–101 in zotero/agent-harness/skill_generator.py.

Document Body Sections

Following the front-matter, the schema includes these Markdown sections:

Title and Introduction

  • # <skill-name> — The main heading derived from the package directory name

  • Intro paragraph — Extracted from the first non-header lines of the package's README.md via extract_intro_from_readme (lines 51–68)

Installation and Entry Points

  • Installation — Contains a minimal pip install -e . snippet (hard-coded at lines 105–108)
  • Entry Points — Lists the CLI wrapper (cli-anything-<software>) and module entry point (python -m cli_anything.<software>) at lines 110–115

Runtime Constraints

  • Important Constraints — Optional bulleted list of runtime limits or required configuration generated by generate_important_constraints (lines 60–70)

Command Documentation

  • Command Groups — One or more groups parsed from Click decorators. Each group contains:

    • A description
    • A Markdown table with columns | Command | Description |

    This section iterates over metadata.command_groups at lines 124–129.

Usage Examples

  • Examples — Ready-to-run command snippets with titles and descriptions, produced by generate_examples (lines 50–57)

Version Tracking

  • Version — The package version string extracted from setup.py via extract_version_from_setup (lines 71–78)

How Metadata Is Extracted

The extraction pipeline in skill_generator.py transforms raw Python source code into structured metadata through seven discrete steps.

Step 1: Detect the Software Package

The generator locates the software directory by scanning for Python packages containing __init__.py:

harness_root = Path(harness_path)
cli_root = harness_root / "cli_anything"
software_dir = next(p for p in cli_root.iterdir()
                    if p.is_dir() and (p / "__init__.py").exists())
software_name = software_dir.name

This logic appears in extract_cli_metadata at lines 73–77.

Step 2: Extract Introduction Text

The extract_intro_from_readme function (lines 51–68) reads the package's README.md and concatenates the first non-header lines to create the human-readable introduction paragraph.

Step 3: Parse Version Information

Version strings are extracted from setup.py using regular expressions that match PACKAGE_VERSION or standard version fields. See extract_version_from_setup at lines 71–78.

Step 4: Parse Command Groups and Commands

The generator uses Python's ast module to analyze the CLI source file (e.g., zotero_cli.py). The extract_commands_from_cli function (lines 13–47) identifies:

  • Groups — Functions decorated with @cli.group
  • Commands — Functions decorated with @cli.command within those groups

If decorators specify explicit names, those are used; otherwise, the generator derives defaults from function names using _default_group_name and _default_command_name.

Step 5: Generate Constraints

Runtime constraints are handled by generate_important_constraints (lines 60–70). While the Zotero skill returns a static list of limitations, other implementations may return empty lists if no constraints apply.

Step 6: Create Usage Examples

The generate_examples function (lines 50–57) produces hard-coded usage snippets customized with the specific software name, providing ready-to-run demonstrations of common workflows.

Step 7: Compile Metadata and Render

All extracted data is wrapped into a SkillMetadata dataclass (lines 39–48) and passed to generate_skill_md. If Jinja2 is unavailable, the fallback generate_skill_md_simple (lines 92–135) constructs the Markdown directly without template dependencies.

Template-Based vs. Programmatic Generation

CLI-Anything supports two rendering strategies:

  • Jinja2 Template — When available, the system uses zotero/agent-harness/templates/SKILL.md.template for flexible customization
  • Simple Generator — The fallback generate_skill_md_simple function writes Markdown sections programmatically, ensuring the tool works without optional dependencies

An example rendered output appears at sbox/agent-harness/cli_anything/sbox/skills/SKILL.md, demonstrating the final structure produced by this pipeline.

Summary

  • The SKILL.md schema combines YAML front-matter with standardized Markdown sections for installation, entry points, command groups, examples, and version information.
  • Metadata extraction relies on AST parsing of Click decorators (@cli.group, @cli.command) via extract_commands_from_cli to build the command documentation.
  • Auxiliary data flows from README.md (intro text), setup.py (version), and hard-coded generators (examples, constraints).
  • The SkillMetadata dataclass (lines 39–48) serves as the central data structure before rendering through either Jinja2 templates or generate_skill_md_simple.

Frequently Asked Questions

What is the purpose of the SKILL.md file in CLI-Anything?

The SKILL.md file serves as a machine-readable contract between Python CLI tools and agent systems. It standardizes how commands, constraints, and usage patterns are declared, allowing automated systems to discover and interact with CLI wrappers without executing the code.

How does CLI-Anything extract command groups from Python source code?

The system uses Python's ast module in extract_commands_from_cli (lines 13–47) to statically analyze the CLI file (e.g., zotero_cli.py). It searches for Click decorators—specifically @cli.group for groups and @cli.command for individual commands—then extracts function names or explicit decorator arguments to populate the command tables.

What metadata is required versus optional in the SKILL.md schema?

Required sections include the YAML front-matter (name, description), the skill title, introduction paragraph, installation instructions, entry points, command groups, and version. Optional sections include Important Constraints and Examples, which the generator includes only when data is present in the source.

Which specific files does the skill generator analyze to build the SKILL.md?

The generator reads four key locations: (1) the README.md for introductory text, (2) setup.py for version strings, (3) the CLI Python file (e.g., zotero/agent-harness/cli_anything/zotero/zotero_cli.py) for command structures via AST parsing, and (4) optionally templates/SKILL.md.template if Jinja2 rendering is desired.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →