Skip to content

Add experimental MCP skills extension support (SEP-2640)#207

Open
jancurn wants to merge 2 commits intomainfrom
claude/implement-mcp-skills-lYFVi
Open

Add experimental MCP skills extension support (SEP-2640)#207
jancurn wants to merge 2 commits intomainfrom
claude/implement-mcp-skills-lYFVi

Conversation

@jancurn
Copy link
Copy Markdown
Member

@jancurn jancurn commented Apr 28, 2026

Summary

Implements support for the experimental MCP skills extension (io.modelcontextprotocol/skills, SEP-2640), adding two new CLI commands (skills-list and skills-get) that provide sugar over the existing resources primitive for discovering and reading Agent Skills.

Key Changes

  • New skills command module (src/cli/commands/skills.ts):

    • Implements skill discovery via skill://index.json with fallback to resource scanning for skill://*/SKILL.md URIs
    • listSkills(): Discovers and lists skills exposed by the server
    • getSkill(): Reads a skill's SKILL.md content by name or URI
    • resolveSkillUri(): Converts user-friendly skill names to full skill:// URIs
    • Includes parsing and validation logic for the skills index format
  • CLI integration (src/cli/index.ts):

    • Added skills-list command with discovery strategy documentation
    • Added skills-get <name> command with --raw flag for markdown-only output
    • Registered commands in parser's KNOWN_SESSION_COMMANDS
  • Output formatting (src/cli/output.ts):

    • formatSkills(): Renders skill list with names, descriptions, and types
    • formatSkillDetail(): Displays skill content with URI and MIME type metadata
    • Updated formatServerDetails() to advertise skills capability when server declares the extension
  • Documentation:

    • Updated README.md and CHANGELOG.md with new commands
    • Comprehensive help text explaining skill discovery, URI forms, and --raw mode

Implementation Details

  • Skills are discovered using a two-tier strategy: first attempts the well-known skill://index.json index; if unavailable, falls back to scanning all resources for skill://**/SKILL.md patterns (per spec requirement to not treat absent index as proof of no skills)
  • Skill name resolution supports bare names (git-workflow), nested paths (acme/billing/refunds), and full URIs
  • Graceful error handling: malformed index entries are silently dropped; missing index triggers fallback rather than failure
  • Output modes support both human-readable formatting and JSON for programmatic use
  • --raw flag enables piping skill markdown directly to other tools without formatting overhead

https://claude.ai/code/session_01PyzCAbMiMXTbLrFXUP3nQJ

claude added 2 commits April 28, 2026 22:33
Implements the experimental `io.modelcontextprotocol/skills` extension as
sugar over the existing Resources primitive. Skills are markdown documents
(SKILL.md + YAML frontmatter) served under `skill://` URIs, with optional
discovery via `skill://index.json`.

- `skills-list` reads the well-known index, falling back to scanning
  resources for `skill://*/SKILL.md` URIs (per spec, an absent index does
  not imply zero skills)
- `skills-get <name>` reads the SKILL.md; `--raw` prints just the markdown
  for piping to LLMs or files
- Session overview surfaces `skills` under capabilities when the server
  advertises `capabilities.extensions["io.modelcontextprotocol/skills"]`
- JSON output is documented for both commands so AI agents can consume it
Coverage:
- Unit: parseIndex (well-formed, malformed, drops bad entries, JSON
  errors), skillsFromResources (URI matching, nested paths, ignores
  non-skill-md files), resolveSkillUri (bare names, nested paths, full
  URIs, trailing slashes), extractTextContent, discoverSkills (index
  path, fallback path, paginated resource scan)
- Unit: formatSkills (count, descriptions, types, empty state),
  formatSkillDetail (markdown body, missing MIME, blob fallback,
  truncation), formatServerDetails capability surfacing under both
  `capabilities.extensions` (per spec) and `capabilities.experimental`
  (SDK-preserved escape hatch)
- Unit: parser suggests `skills-list` for `skills`/`list-skills`
- E2E: opt-in `WITH_SKILLS=true` server flag exposes skill:// resources
  and advertises the extension capability. Three scenarios covered:
  index-path discovery, no-index fallback (`SKILLS_NO_INDEX=true`), and
  no-extension server. Verifies --json shapes, --raw mode, nested skill
  paths, full-URI input, and that --json+--raw still emits the full
  ReadResourceResult so `jq -r '.contents[0].text'` works.

Implementation tweak: capability detection now also accepts
`capabilities.experimental[skills]` since current MCP SDKs strip
unknown capability fields like `extensions`. Test server advertises
under both keys for forward compatibility.

Internal helpers (parseIndex, skillsFromResources, extractTextContent,
discoverSkills) are exported with `@internal` markers for testability.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants