Skip to main content
Glama

List All Loaded Skills

list_skills

View all available skills with their descriptions, sources, and document counts to explore capabilities or troubleshoot skill availability.

Instructions

Returns a complete inventory of all loaded skills with their names, descriptions, sources, and document counts. Use this for exploration or debugging to see what skills are available. NOTE: For finding relevant skills for a specific task, use the 'search_skills' tool instead - it performs semantic search to find the most appropriate skills for your needs.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Primary handler function _handle_list_skills for the MCP stdio server class SkillsMCPServer. Lists all loaded skills with name, description, source (formatted), and document count. Handles loading state.
    async def _handle_list_skills(self, arguments: dict[str, Any]) -> list[TextContent]:
        """Handle list_skills tool calls.
    
        Parameters
        ----------
        arguments : dict[str, Any]
            Tool arguments (empty for list_skills).
    
        Returns
        -------
        list[TextContent]
            Complete list of all skills with metadata.
        """
        response_parts = []
    
        # Add loading status if skills are still being loaded
        status_msg = self.loading_state.get_status_message()
        if status_msg:
            response_parts.append(status_msg)
    
        if not self.search_engine.skills:
            if not self.loading_state.is_complete:
                return [
                    TextContent(
                        type="text",
                        text=status_msg
                        or "" + "No skills loaded yet. Please wait for skills to load.",
                    )
                ]
            return [TextContent(type="text", text="No skills currently loaded.")]
    
        response_parts.extend(
            [
                f"Total skills loaded: {len(self.search_engine.skills)}\n",
                "=" * 80,
                "\n",
            ]
        )
    
        for i, skill in enumerate(self.search_engine.skills, 1):
            # Format source as owner/repo for GitHub URLs
            import re
    
            source = skill.source
            if "github.com" in source:
                # Extract owner/repo from GitHub URL
                match = re.search(r"github\.com/([^/]+/[^/]+)", source)
                if match:
                    source = match.group(1)
    
            doc_count = len(skill.documents)
    
            response_parts.append(f"{i}. {skill.name}")
            response_parts.append(f"   Description: {skill.description}")
            response_parts.append(f"   Source: {source}")
            response_parts.append(f"   Documents: {doc_count} file(s)")
            response_parts.append("")
    
        return [TextContent(type="text", text="\n".join(response_parts))]
  • Standalone handler function handle_list_skills used by the HTTP server. Identical logic to _handle_list_skills but without self references.
    async def handle_list_skills(
        arguments: dict[str, Any], search_engine, loading_state
    ) -> list[TextContent]:
        """Handle list_skills tool calls (standalone version for HTTP server)."""
        import re
    
        response_parts = []
    
        # Add loading status if skills are still being loaded
        status_msg = loading_state.get_status_message() if loading_state else None
        if status_msg:
            response_parts.append(status_msg)
    
        if not search_engine.skills:
            if loading_state and not loading_state.is_complete:
                return [
                    TextContent(
                        type="text",
                        text=(status_msg or "")
                        + "No skills loaded yet. Please wait for skills to load.",
                    )
                ]
            return [TextContent(type="text", text="No skills currently loaded.")]
    
        response_parts.extend(
            [
                f"Total skills loaded: {len(search_engine.skills)}\n",
                "=" * 80,
                "\n",
            ]
        )
    
        for i, skill in enumerate(search_engine.skills, 1):
            # Format source as owner/repo for GitHub URLs
            source = skill.source
            if "github.com" in source:
                # Extract owner/repo from GitHub URL
                match = re.search(r"github\.com/([^/]+/[^/]+)", source)
                if match:
                    source = match.group(1)
    
            doc_count = len(skill.documents)
    
            response_parts.append(f"{i}. {skill.name}")
            response_parts.append(f"   Description: {skill.description}")
            response_parts.append(f"   Source: {source}")
            response_parts.append(f"   Documents: {doc_count} file(s)")
            response_parts.append("")
    
        return [TextContent(type="text", text="\n".join(response_parts))]
  • FastMCP tool registration for list_skills in the HTTP server, including schema (empty input), title, description, and wrapper that delegates to handle_list_skills.
    @mcp.tool(
        name="list_skills",
        title="List available skills",
        description=(
            "Returns the full inventory of loaded skills (names, descriptions, sources, document counts) "
            "for exploration or debugging. For task-driven work, prefer calling 'find_helpful_skills' first "
            "to locate the most relevant option before reading documents."
        )
    )
    async def list_skills() -> list[TextContent]:
        """List all loaded skills."""
        return await handle_list_skills({}, search_engine, loading_state_global)
  • Stdio MCP server tool registration in list_tools() and dispatch in call_tool() for list_skills, including schema and handler invocation.
    @self.server.list_tools()
    async def list_tools() -> list[Tool]:
        """List available tools."""
        return [
            Tool(
                name="find_helpful_skills",
                title="Find the most helpful skill for any task",
                description=(
                    "Always call this tool FIRST whenever the question requires any domain-specific knowledge "
                    "beyond common sense or simple recall. Use it at task start, regardless of the task and whether "
                    "you are sure about the task, It performs semantic search over a curated library of proven skills "
                    "and returns ranked candidates with step-by-step guidance and best practices. Do this before any "
                    "searches, coding, or any other actions as this will inform you about the best approach to take."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "task_description": {
                            "type": "string",
                            "description": (
                                "Description of the task you want to accomplish. Be specific about your goal, "
                                "context, or problem domain for better results (e.g., 'debug Python API errors', "
                                "'process genomic data', 'build React dashboard')"
                            ),
                        },
                        "top_k": {
                            "type": "integer",
                            "description": f"Number of skills to return (default: {self.default_top_k}). Higher values provide more options but may include less relevant results.",
                            "default": self.default_top_k,
                            "minimum": 1,
                            "maximum": 20,
                        },
                        "list_documents": {
                            "type": "boolean",
                            "description": "Include a list of available documents (scripts, references, assets) for each skill (default: True)",
                            "default": True,
                        },
                    },
                    "required": ["task_description"],
                },
            ),
            Tool(
                name="read_skill_document",
                title="Open skill documents and assets",
                description=(
                    "Use after finding a relevant skill to retrieve specific documents (scripts, references, assets). "
                    "Supports pattern matching (e.g., 'scripts/*.py') to fetch multiple files. Returns text content or URLs "
                    "and never executes code. Prefer pulling only the files you need to complete the current step."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "skill_name": {
                            "type": "string",
                            "description": "Name of the skill (as returned by find_helpful_skills)",
                        },
                        "document_path": {
                            "type": "string",
                            "description": (
                                "Path or pattern to match documents. Examples: 'scripts/example.py', "
                                "'scripts/*.py', 'references/*', 'assets/diagram.png'. "
                                "If not provided, returns a list of all available documents."
                            ),
                        },
                        "include_base64": {
                            "type": "boolean",
                            "description": (
                                "For images: if True, return base64-encoded content; if False, return only URL. "
                                "Default: False (URL only for efficiency)"
                            ),
                            "default": False,
                        },
                    },
                    "required": ["skill_name"],
                },
            ),
            Tool(
                name="list_skills",
                title="List available skills",
                description=(
                    "Returns the full inventory of loaded skills (names, descriptions, sources, document counts) "
                    "for exploration or debugging. For task-driven work, prefer calling 'find_helpful_skills' first "
                    "to locate the most relevant option before reading documents."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {},
                    "required": [],
                },
            ),
        ]
    
    @self.server.call_tool()
    async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
        """Handle tool calls."""
        if name == "find_helpful_skills":
            return await self._handle_search_skills(arguments)
        elif name == "read_skill_document":
            return await self._handle_read_skill_document(arguments)
        elif name == "list_skills":
            return await self._handle_list_skills(arguments)
        else:
            raise ValueError(f"Unknown tool: {name}")
  • Tool schema definition for list_skills with empty input schema (no parameters required).
    Tool(
        name="list_skills",
        title="List available skills",
        description=(
            "Returns the full inventory of loaded skills (names, descriptions, sources, document counts) "
            "for exploration or debugging. For task-driven work, prefer calling 'find_helpful_skills' first "
            "to locate the most relevant option before reading documents."
        ),
        inputSchema={
            "type": "object",
            "properties": {},
            "required": [],
        },
    ),
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden of behavioral disclosure. It clearly indicates this is a read operation ('Returns') and specifies the scope ('complete inventory of all loaded skills'). However, it doesn't mention potential limitations like pagination, rate limits, or authentication requirements that might be relevant for a complete behavioral understanding.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly structured in two sentences: the first states the purpose and output format, the second provides usage guidance and sibling differentiation. Every sentence adds value with zero wasted words, making it easy to parse and understand quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with no parameters and no output schema, the description provides excellent context about what the tool does and when to use it. The main gap is the lack of information about the return format structure, which would be helpful since there's no output schema. However, given the tool's simplicity, the description is largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0 parameters and 100% schema coverage, the baseline would be 4. The description appropriately acknowledges this by not discussing parameters at all, focusing instead on the tool's purpose and usage guidelines. This is efficient and avoids redundancy.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific verb ('Returns') and resource ('complete inventory of all loaded skills'), listing the exact data fields included (names, descriptions, sources, document counts). It explicitly distinguishes this from its sibling 'search_skills' by stating this is for exploration/debugging rather than task-specific relevance.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool ('for exploration or debugging to see what skills are available') and when not to use it, naming the alternative tool 'search_skills' for finding relevant skills for specific tasks. This gives clear context for tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/OrionLi545/claude-skills-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server