Skip to Content

Getting Started

TL;DR

Install the SDK (pip install cmdop-skill), run cmdop-skill init to scaffold a project, write your commands, test with make test, and install locally with make install-skill.

Install the SDK

pip install cmdop-skill

Scaffold a new skill

cmdop-skill init

The interactive wizard asks for:

  • Name β€” package name (checked against PyPI for availability)
  • Description β€” what the skill does
  • Author β€” your name

Category, tags, and visibility are determined automatically by the server during publish.

Project structure

my-skill/ β”œβ”€β”€ pyproject.toml # Package metadata, deps, build config β”œβ”€β”€ Makefile # Dev shortcuts β”œβ”€β”€ README.md β”œβ”€β”€ .gitignore β”œβ”€β”€ skill/ β”‚ β”œβ”€β”€ config.py # SkillConfig manifest β”‚ └── readme.md # LLM system prompt β”œβ”€β”€ src/my_skill/ β”‚ β”œβ”€β”€ __init__.py β”‚ └── _skill.py # Skill commands └── tests/ β”œβ”€β”€ conftest.py └── test_my_skill.py

pyproject.toml

Single source of truth for name, version, description, dependencies, and build config. The SDK resolves these automatically β€” no need to duplicate them elsewhere.

[project] name = "my-skill" version = "0.1.0" description = "Does something useful" requires-python = ">=3.11" dependencies = [ "cmdop-skill", "httpx>=0.27", ] [project.scripts] my-skill = "my_skill._skill:main" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"]

skill/config.py

Minimal β€” everything is auto-resolved from pyproject.toml:

from cmdop_skill import SkillConfig config = SkillConfig()

Optional fields for publish:

config = SkillConfig( changelog="Fixed timeout handling.", short_description="Brief summary (max 300 chars).", )

skill/readme.md

The LLM system prompt. Write as instructions to an AI assistant. Keep under 4000 characters.

# My Skill You help users do X. When asked, run the `check` command and report results. ## Commands - `my-skill check <domain>` β€” Check something for a domain - `my-skill check <domain> --timeout 30` β€” With custom timeout ## Output Format Report results as a table: domain, status, details.

Always include a Commands section with exact CLI syntax and an Output Format section describing how to present results.

Write your first command

Edit src/my_skill/_skill.py:

from cmdop_skill import Arg, Skill skill = Skill() @skill.command async def check( domain: str = Arg(help="Domain to check", required=True), timeout: int = Arg("--timeout", help="Timeout in seconds", default=10), ) -> dict: """Check something for a domain.""" # Your logic here return {"domain": domain, "status": "ok"} def main() -> None: skill.run()

Test locally

pip install -e '.[dev]' make test

Install into CMDOP

make install-skill

This symlinks your skill directory into ~/.cmdop/skills/my-skill. The agent picks it up immediately β€” no restart needed.

Makefile commands

CommandDescription
make installInstall package from PyPI
make testRun tests with pytest
make lintRun ruff linter
make install-skillSymlink skill into CMDOP skills directory
make publishPublish to CMDOP marketplace
make releaseBump version + PyPI + CMDOP marketplace

Next steps

Last updated on