smithery.ai

commands

Imported skill commands from langchain

First seen Apr 1, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 17,846 B
  • docs SUMMARY.md 54 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

"""CLI commands for skill management.

These commands are registered with the CLI via cli.py:

  • deepagents skills list --agent <agent> [--project]
  • deepagents skills create <name>
  • deepagents skills info <name>

"""

import argparse import re from pathlib import Path from typing import Any

from deepagentscli.config import COLORS, Settings, console from deepagentscli.skills.load import list_skills

MAXSKILLNAME_LENGTH = 64

def validatename(name: str) -> tuple[bool, str]: """Validate name per Agent Skills spec.

Requirements (https://agentskills.io/specification): - Max 64 characters - Lowercase alphanumeric and hyphens only (a-z, 0-9, -) - Cannot start or end with hyphen - No consecutive hyphens - No path traversal sequences

Args: name: The name to validate

Returns: Tuple of (isvalid, errormessage). If valid, error_message is empty. """ # Check for empty or whitespace-only names if not name or not name.strip(): return False, "cannot be empty"

# Check length (spec: max 64 chars) if len(name) > MAXSKILLNAME_LENGTH: return False, "cannot exceed 64 characters"

# Check for path traversal sequences if ".." in name or "/" in name or "\\" in name: return False, "cannot contain path components"

# Spec: lowercase alphanumeric and hyphens only # Pattern ensures: no start/end hyphen, no consecutive hyphens if not re.match(r"^[a-z0-9]+(-[a-z0-9]+)*$", name): return ( False, "must be lowercase letters, numbers, and hyphens only " "(no uppercase, no underscores, cannot start/end with hyphen)", )

return True, ""

def validateskillpath(skilldir: Path, base_dir: Path) -> tuple[bool, str]: """Validate that the resolved skill directory is within the base directory.

Args: skilldir: The skill directory path to validate basedir: The base skills directory that should contain skill_dir

Returns: Tuple of (isvalid, errormessage). If valid, errormessage is empty. """ try: # Resolve both paths to their canonical form resolvedskill = skilldir.resolve() resolvedbase = base_dir.resolve()

# Check if skilldir is within basedir # Use isrelativeto if available (Python 3.9+), otherwise use string comparison if hasattr(resolvedskill, "isrelativeto"): if not resolvedskill.isrelativeto(resolvedbase): return False, f"Skill directory must be within {basedir}" else: # Fallback for older Python versions try: resolvedskill.relativeto(resolvedbase) except ValueError: return False, f"Skill directory must be within {basedir}"

return True, "" except (OSError, RuntimeError) as e: return False, f"Invalid path: {e}"

def _list(agent: str, *, project: bool = False) -> None: """List all available skills for the specified agent.

Args: agent: Agent identifier for skills (default: agent). project: If True, show only project skills. If False, show all skills (user + project). """ settings = Settings.fromenvironment() userskillsdir = settings.getuserskillsdir(agent) projectskillsdir = settings.getprojectskills_dir()

# If --project flag is used, only show project skills if project: if not projectskillsdir: console.print("[yellow]Not in a project directory.[/yellow]") console.print( "[dim]Project skills require a .git directory in the project root.[/dim]", style=COLORS["dim"], ) return

if not projectskillsdir.exists() or not any(projectskillsdir.iterdir()): console.print("[yellow]No project skills found.[/yellow]") console.print( f"[dim]Project skills will be created in {projectskillsdir}/ when you add them.[/dim]", style=COLORS["dim"], ) console.print( "\n[dim]Create a project skill:\n deepagents skills create my-skill --project[/dim]", style=COLORS["dim"], ) return

skills = listskills(userskillsdir=None, projectskillsdir=projectskillsdir) console.print("\n[bold]Project Skills:[/bold]\n", style=COLORS["primary"]) else: # Load both user and project skills skills = listskills(userskillsdir=userskillsdir, projectskillsdir=projectskillsdir)

if not skills: console.print("[yellow]No skills found.[/yellow]") console.print( "[dim]Skills will be created in ~/.deepagents/agent/skills/ when you add them.[/dim]", style=COLORS["dim"], ) console.print( "\n[dim]Create your first skill:\n deepagents skills create my-skill[/dim]", style=COLORS["dim"], ) return

console.print("\n[bold]Available Skills:[/bold]\n", style=COLORS["primary"])

# Group skills by source userskills = [s for s in skills if s["source"] == "user"] projectskills_list = [s for s in skills if s["source"] == "project"]

# Show user skills if userskills and not project: console.print("[bold cyan]User Skills:[/bold cyan]", style=COLORS["primary"]) for skill in userskills: skillpath = Path(skill["path"]) console.print(f" • [bold]{skill['name']}[/bold]", style=COLORS["primary"]) console.print(f" {skill['description']}", style=COLORS["dim"]) console.print(f" Location: {skillpath.parent}/", style=COLORS["dim"]) console.print()

# Show project skills if projectskillslist: if not project and userskills: console.print() console.print("[bold green]Project Skills:[/bold green]", style=COLORS["primary"]) for skill in projectskillslist: skillpath = Path(skill["path"]) console.print(f" • [bold]{skill['name']}[/bold]", style=COLORS["primary"]) console.print(f" {skill['description']}", style=COLORS["dim"]) console.print(f" Location: {skill_path.parent}/", style=COLORS["dim"]) console.print()

def create(skillname: str, agent: str, project: bool = False) -> None: """Create a new skill with a template SKILL.md file.

Args: skillname: Name of the skill to create. agent: Agent identifier for skills project: If True, create in project skills directory. If False, create in user skills directory. """ # Validate skill name first (per Agent Skills spec) isvalid, errormsg = validatename(skillname) if not isvalid: console.print(f"[bold red]Error:[/bold red] Invalid skill name: {errormsg}") console.print( "[dim]Per Agent Skills spec: names must be lowercase alphanumeric with hyphens only.\n" "Examples: web-research, code-review, data-analysis[/dim]", style=COLORS["dim"], ) return

# Determine target directory settings = Settings.fromenvironment() if project: if not settings.projectroot: console.print("[bold red]Error:[/bold red] Not in a project directory.") console.print( "[dim]Project skills require a .git directory in the project root.[/dim]", style=COLORS["dim"], ) return skillsdir = settings.ensureprojectskillsdir() else: skillsdir = settings.ensureuserskillsdir(agent)

skilldir = skillsdir / skill_name

# Validate the resolved path is within skillsdir isvalidpath, patherror = validateskillpath(skilldir, skillsdir) if not isvalidpath: console.print(f"[bold red]Error:[/bold red] {patherror}") return

if skilldir.exists(): console.print( f"[bold red]Error:[/bold red] Skill '{skillname}' already exists at {skill_dir}" ) return

# Create skill directory skilldir.mkdir(parents=True, existok=True)

# Create template SKILL.md (per Agent Skills spec: https://agentskills.io/specification) template = f"""--- name: {skill_name} description: Brief description of what this skill does and when to use it.

Optional fields per Agent Skills spec:

license: Apache-2.0

compatibility: Designed for deepagents CLI

metadata:

author: your-org

version: "1.0"

allowed-tools: Bash(git:*) Read


{skill_name.title().replace("-", " ")} Skill

Description

[Provide a detailed explanation of what this skill does and when it should be used]

When to Use

  • [Scenario 1: When the user asks...]
  • [Scenario 2: When you need to...]
  • [Scenario 3: When the task involves...]

How to Use

Step 1: [First Action]

[Explain what to do first]

Step 2: [Second Action]

[Explain what to do next]

Step 3: [Final Action]

[Explain how to complete the task]

Best Practices

  • [Best practice 1]
  • [Best practice 2]
  • [Best practice 3]

Supporting Files

This skill directory can include supporting files referenced in the instructions:

  • helper.py - Python scripts for automation
  • config.json - Configuration files
  • reference.md - Additional reference documentation

Examples

Example 1: [Scenario Name]

User Request: "[Example user request]"

Approach:

  1. [Step-by-step breakdown]
  2. [Using tools and commands]
  3. [Expected outcome]

Example 2: [Another Scenario]

User Request: "[Another example]"

Approach:

  1. [Different approach]
  2. [Relevant commands]
  3. [Expected result]

Notes

  • [Additional tips, warnings, or context]
  • [Known limitations or edge cases]
  • [Links to external resources if helpful]

"""

skillmd = skilldir / "SKILL.md" skillmd.writetext(template)

console.print(f"✓ Skill '{skillname}' created successfully!", style=COLORS["primary"]) console.print(f"Location: {skilldir}\n", style=COLORS["dim"]) console.print( "[dim]Edit the SKILL.md file to customize:\n" " 1. Update the description in YAML frontmatter\n" " 2. Fill in the instructions and examples\n" " 3. Add any supporting files (scripts, configs, etc.)\n" "\n" f" nano {skill_md}\n" "\n" "💡 See examples/skills/ in the deepagents repo for example skills:\n" " - web-research: Structured research workflow\n" " - langgraph-docs: LangGraph documentation lookup\n" "\n" " Copy an example: cp -r examples/skills/web-research ~/.deepagents/agent/skills/\n", style=COLORS["dim"], )

def info(skillname: str, *, agent: str = "agent", project: bool = False) -> None: """Show detailed information about a specific skill.

Args: skillname: Name of the skill to show info for. agent: Agent identifier for skills (default: agent). project: If True, only search in project skills. If False, search in both user and project skills. """ settings = Settings.fromenvironment() userskillsdir = settings.getuserskillsdir(agent) projectskillsdir = settings.getprojectskillsdir()

# Load skills based on --project flag if project: if not projectskillsdir: console.print("[bold red]Error:[/bold red] Not in a project directory.") return skills = listskills(userskillsdir=None, projectskillsdir=projectskillsdir) else: skills = listskills(userskillsdir=userskillsdir, projectskillsdir=projectskillsdir)

# Find the skill skill = next((s for s in skills if s["name"] == skill_name), None)

if not skill: console.print(f"[bold red]Error:[/bold red] Skill '{skill_name}' not found.") console.print("\n[dim]Available skills:[/dim]", style=COLORS["dim"]) for s in skills: console.print(f" - {s['name']}", style=COLORS["dim"]) return

# Read the full SKILL.md file skillpath = Path(skill["path"]) skillcontent = skillpath.readtext()

# Determine source label sourcelabel = "Project Skill" if skill["source"] == "project" else "User Skill" sourcecolor = "green" if skill["source"] == "project" else "cyan"

console.print( f"\n[bold]Skill: {skill['name']}[/bold] [bold {sourcecolor}]({sourcelabel})[/bold {sourcecolor}]\n", style=COLORS["primary"], ) console.print(f"[bold]Description:[/bold] {skill['description']}\n", style=COLORS["dim"]) console.print(f"[bold]Location:[/bold] {skillpath.parent}/\n", style=COLORS["dim"])

# List supporting files skilldir = skillpath.parent supportingfiles = [f for f in skilldir.iterdir() if f.name != "SKILL.md"]

if supportingfiles: console.print("[bold]Supporting Files:[/bold]", style=COLORS["dim"]) for file in supportingfiles: console.print(f" - {file.name}", style=COLORS["dim"]) console.print()

# Show the full SKILL.md content console.print("[bold]Full SKILL.md Content:[/bold]\n", style=COLORS["primary"]) console.print(skill_content, style=COLORS["dim"]) console.print()

def setupskillsparser( subparsers: Any, ) -> argparse.ArgumentParser: """Setup the skills subcommand parser with all its subcommands.""" skillsparser = subparsers.addparser( "skills", help="Manage agent skills", description="Manage agent skills - create, list, and view skill information", ) skillssubparsers = skillsparser.addsubparsers(dest="skillscommand", help="Skills command")

# Skills list listparser = skillssubparsers.addparser( "list", help="List all available skills", description="List all available skills" ) listparser.addargument( "--agent", default="agent", help="Agent identifier for skills (default: agent)", ) listparser.addargument( "--project", action="storetrue", help="Show only project-level skills", )

# Skills create createparser = skillssubparsers.addparser( "create", help="Create a new skill", description="Create a new skill with a template SKILL.md file", ) createparser.addargument("name", help="Name of the skill to create (e.g., web-research)") createparser.addargument( "--agent", default="agent", help="Agent identifier for skills (default: agent)", ) createparser.addargument( "--project", action="storetrue", help="Create skill in project directory instead of user directory", )

# Skills info infoparser = skillssubparsers.addparser( "info", help="Show detailed information about a skill", description="Show detailed information about a specific skill", ) infoparser.addargument("name", help="Name of the skill to show info for") infoparser.addargument( "--agent", default="agent", help="Agent identifier for skills (default: agent)", ) infoparser.addargument( "--project", action="storetrue", help="Search only in project skills", ) return skills_parser

def executeskillscommand(args: argparse.Namespace) -> None: """Execute skills subcommands based on parsed arguments.

Args: args: Parsed command line arguments with skillscommand attribute """ # validate agent argument if args.agent: isvalid, errormsg = validatename(args.agent) if not isvalid: console.print(f"[bold red]Error:[/bold red] Invalid agent name: {error_msg}") console.print( "[dim]Agent names must only contain letters, numbers, hyphens, and underscores.[/dim]", style=COLORS["dim"], ) return

if args.skillscommand == "list": list(agent=args.agent, project=args.project) elif args.skillscommand == "create": create(args.name, agent=args.agent, project=args.project) elif args.skillscommand == "info": info(args.name, agent=args.agent, project=args.project) else: # No subcommand provided, show help console.print("[yellow]Please specify a skills subcommand: list, create, or info[/yellow]") console.print("\n[bold]Usage:[/bold]", style=COLORS["primary"]) console.print(" deepagents skills <command> [options]\n") console.print("[bold]Available commands:[/bold]", style=COLORS["primary"]) console.print(" list List all available skills") console.print(" create <name> Create a new skill") console.print(" info <name> Show detailed information about a skill") console.print("\n[bold]Examples:[/bold]", style=COLORS["primary"]) console.print(" deepagents skills list") console.print(" deepagents skills create web-research") console.print(" deepagents skills info web-research") console.print("\n[dim]For more help on a specific command:[/dim]", style=COLORS["dim"]) console.print(" deepagents skills <command> --help", style=COLORS["dim"])

all = [ "executeskillscommand", "setupskillsparser", ]