MCP server for skill discovery, retrieval, and management with support for skill indexing, searching, and metadata validation
This is a multi-implementation MCP server (TypeScript + Python + Rust) for skill discovery and management. Definition quality is INCONSISTENT across implementations. TypeScript (skills-mcp-server) has well-structured schemas with proper enums, descriptions, and constraints. Python and Rust implementations show schemas but with less consistent documentation. Overall assessment: 22 tools across three implementations; 13 TypeScript tools (avg 68), 9 Rust tools (avg 41). The server suffers from DUPLICATE TOOL DEFINITIONS across languages (skills_list vs list_skills, skills_get vs get_skill) without clear documentation of which is canonical or why duplication exists. Descriptions range from adequate (TypeScript) to minimal (Rust). Parameter validation is present in TypeScript (enums, minLength, maxLength, pattern constraints) but sparse in Rust. Output schemas are not explicitly documented anywhere. Error handling guidance is absent, tools return success/failure but no recovery paths.
Get the main SKILL.md content for a skill
Load multiple skills in a single request
Get usage statistics
Get sub-skill content
List all available skill domains
Reload the skill index from disk
Search content by full-text matching
DUPLICATE TOOL DEFINITIONS across TypeScript and Rust implementations without canonical designation. 'skills_list' (TypeScript) and 'list_skills' (Rust) serve identical purposes. LLMs will be confused about which to call, and clients supporting both implementations cannot disambiguate.
RUST IMPLEMENTATION LACKS DESCRIPTION DEPTH. Tools in rust/skills-mcp/src/mcp/tools.rs (list_skills, get_skill, get_sub_skill, search_skills, etc.) have descriptions under 50 characters. E.g., 'Get the main SKILL.md content for a skill' is generic, missing guidance on when to use, what format is returned, or what fields to expect downstream.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 48 | <=2025-11-25 | v2 |
Search skills by metadata
Create a new skill scaffold
Delete a skill
Export a skill as ZIP
Get a skill's main SKILL.md content
Get multiple skills/sub-skills in one request
Get a sub-skill's content
List all skill domains
Reload the skill index from disk
Search by metadata (name, description, tags, triggers)
Full-text content search across all skill files
Get usage statistics
Update skill content or metadata
Validate skill structure and metadata
Validate all skills
RUST TOOLS LACK PARAMETER DESCRIPTIONS. Tools in Rust implementation (e.g., get_skill with param 'name', search_skills with 'query') have type annotations but NO description text explaining what the parameter controls, expected format, or constraints. LLMs cannot infer parameter semantics from names alone.
NO OUTPUT SCHEMAS DOCUMENTED. Across all 22 tools, there is no explicit definition of what fields are returned, their types, or structure. E.g., skills_list returns an 'array' but does not specify: array of what? Objects with what fields? Is there pagination? Count totals? Without output schemas, LLMs cannot reason about downstream tool calls or extract required fields (e.g., domain name to pass to skills_get).
MISSING ERROR HANDLING GUIDANCE. Tools do not document failure modes or recovery paths. E.g., if skills_get fails because a skill domain does not exist, what should the LLM do next? Call skills_search to discover valid domains? This is not stated anywhere. Per pattern:recovery-guide, error responses must tell the LLM what to do next.
DESTRUCTIVE OPERATIONS LACK CONFIRMATION STEP. skills_delete and related deletion tools accept a 'confirm' boolean parameter, but this is USER-SIDE validation only, no server-side confirmation or dry-run step. Agents can still make deletion mistakes if the confirm param is set to true without explicit user approval in the conversation.
INCONSISTENT PARAMETER NAMING ACROSS IMPLEMENTATIONS. TypeScript uses 'response_format' enum; Rust tools lack this parameter entirely. Also, TypeScript uses 'sub_skill' as parameter name; Rust uses the same but lacks description. This inconsistency makes it difficult for LLMs to reason across the two implementations.